On Thu, Feb 15, 2018 at 7:57 AM, Daniel Stone <dani...@collabora.com> wrote:
> From: Louis-Francis Ratté-Boulianne <l...@collabora.com> > > Add support for DRI3 v1.1, which allows pixmaps to be backed by > multi-planar buffers, or those with format modifiers. This is both > for allocating render buffers, as well as EGLImage imports from a > native pixmap (EGL_NATIVE_PIXMAP_KHR). > > Signed-off-by: Louis-Francis Ratté-Boulianne <l...@collabora.com> > Reviewed-by: Eric Engestrom <eric.engest...@imgtec.com> > Reviewed-by: Emil Velikov <emil.veli...@collabora.com> > Reviewed-by: Daniel Stone <dani...@collabora.com> > Signed-off-by: Daniel Stone <dani...@collabora.com> > --- > src/egl/drivers/dri2/egl_dri2.c | 7 + > src/egl/drivers/dri2/egl_dri2.h | 3 + > src/egl/drivers/dri2/platform_x11_dri3.c | 105 +++++++++-- > src/glx/dri3_glx.c | 10 +- > src/loader/loader_dri3_helper.c | 306 > +++++++++++++++++++++++++++---- > src/loader/loader_dri3_helper.h | 17 +- > 6 files changed, 393 insertions(+), 55 deletions(-) > > diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_ > dri2.c > index 17b646e7ede..9a7e43bafb6 100644 > --- a/src/egl/drivers/dri2/egl_dri2.c > +++ b/src/egl/drivers/dri2/egl_dri2.c > @@ -881,6 +881,13 @@ dri2_setup_extensions(_EGLDisplay *disp) > if (!dri2_bind_extensions(dri2_dpy, mandatory_core_extensions, > extensions, false)) > return EGL_FALSE; > > +#ifdef HAVE_DRI3 > + dri2_dpy->multibuffers_available = > + (dri2_dpy->dri3_major_version > 1 || (dri2_dpy->dri3_major_version > == 1 && > + dri2_dpy->dri3_minor_version > >= 1)) && > + (dri2_dpy->image && dri2_dpy->image->base.version >= 15); > +#endif > + > dri2_bind_extensions(dri2_dpy, optional_core_extensions, extensions, > true); > return EGL_TRUE; > } > diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_ > dri2.h > index d36d02c3c49..00c4768d421 100644 > --- a/src/egl/drivers/dri2/egl_dri2.h > +++ b/src/egl/drivers/dri2/egl_dri2.h > @@ -199,6 +199,9 @@ struct dri2_egl_display > xcb_screen_t *screen; > bool swap_available; > #ifdef HAVE_DRI3 > + bool multibuffers_available; > + int dri3_major_version; > + int dri3_minor_version; > struct loader_dri3_extensions loader_dri3_ext; > #endif > #endif > diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c > b/src/egl/drivers/dri2/platform_x11_dri3.c > index 6ead4d0a222..15c349eb828 100644 > --- a/src/egl/drivers/dri2/platform_x11_dri3.c > +++ b/src/egl/drivers/dri2/platform_x11_dri3.c > @@ -39,6 +39,23 @@ > #include "loader.h" > #include "loader_dri3_helper.h" > > +static uint32_t > +dri3_format_for_depth(uint32_t depth) > +{ > + switch (depth) { > + case 16: > + return __DRI_IMAGE_FORMAT_RGB565; > + case 24: > + return __DRI_IMAGE_FORMAT_XRGB8888; > + case 30: > + return __DRI_IMAGE_FORMAT_XRGB2101010; > + case 32: > + return __DRI_IMAGE_FORMAT_ARGB8888; > + default: > + return __DRI_IMAGE_FORMAT_NONE; > + } > +} > + > static struct dri3_egl_surface * > loader_drawable_to_egl_surface(struct loader_dri3_drawable *draw) { > size_t offset = offsetof(struct dri3_egl_surface, loader_drawable); > @@ -156,7 +173,9 @@ dri3_create_surface(_EGLDriver *drv, _EGLDisplay > *disp, EGLint type, > > if (loader_dri3_drawable_init(dri2_dpy->conn, drawable, > dri2_dpy->dri_screen, > - dri2_dpy->is_different_gpu, dri_config, > + dri2_dpy->is_different_gpu, > + dri2_dpy->multibuffers_available, > + dri_config, > &dri2_dpy->loader_dri3_ext, > &egl_dri3_vtable, > &dri3_surf->loader_drawable)) { > @@ -262,20 +281,8 @@ dri3_create_image_khr_pixmap(_EGLDisplay *disp, > _EGLContext *ctx, > return NULL; > } > > - switch (bp_reply->depth) { > - case 16: > - format = __DRI_IMAGE_FORMAT_RGB565; > - break; > - case 24: > - format = __DRI_IMAGE_FORMAT_XRGB8888; > - break; > - case 30: > - format = __DRI_IMAGE_FORMAT_XRGB2101010; > - break; > - case 32: > - format = __DRI_IMAGE_FORMAT_ARGB8888; > - break; > - default: > + format = dri3_format_for_depth(bp_reply->depth); > + if (format == __DRI_IMAGE_FORMAT_NONE) { > _eglError(EGL_BAD_PARAMETER, > "dri3_create_image_khr: unsupported pixmap depth"); > free(bp_reply); > @@ -303,13 +310,78 @@ dri3_create_image_khr_pixmap(_EGLDisplay *disp, > _EGLContext *ctx, > return &dri2_img->base; > } > > +#if XCB_DRI3_MAJOR_VERSION > 1 || (XCB_DRI3_MAJOR_VERSION == 1 && > XCB_DRI3_MINOR_VERSION >= 1) > +static _EGLImage * > +dri3_create_image_khr_pixmap_from_buffers(_EGLDisplay *disp, _EGLContext > *ctx, > + EGLClientBuffer buffer, > + const EGLint *attr_list) > +{ > + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); > + struct dri2_egl_image *dri2_img; > + xcb_dri3_buffers_from_pixmap_cookie_t bp_cookie; > + xcb_dri3_buffers_from_pixmap_reply_t *bp_reply; > + xcb_drawable_t drawable; > + unsigned int format; > + > + drawable = (xcb_drawable_t) (uintptr_t) buffer; > + bp_cookie = xcb_dri3_buffers_from_pixmap(dri2_dpy->conn, drawable); > + bp_reply = xcb_dri3_buffers_from_pixmap_reply(dri2_dpy->conn, > + bp_cookie, NULL); > + > + if (!bp_reply) { > + _eglError(EGL_BAD_ATTRIBUTE, "dri3_create_image_khr"); > + return EGL_NO_IMAGE_KHR; > + } > + > + format = dri3_format_for_depth(bp_reply->depth); > + if (format == __DRI_IMAGE_FORMAT_NONE) { > + _eglError(EGL_BAD_PARAMETER, > + "dri3_create_image_khr: unsupported pixmap depth"); > + free(bp_reply); > + return EGL_NO_IMAGE_KHR; > + } > + > + dri2_img = malloc(sizeof *dri2_img); > + if (!dri2_img) { > + _eglError(EGL_BAD_ALLOC, "dri3_create_image_khr"); > + free(bp_reply); > + return EGL_NO_IMAGE_KHR; > + } > + > + _eglInitImage(&dri2_img->base, disp); > + > + dri2_img->dri_image = loader_dri3_create_image_from_ > buffers(dri2_dpy->conn, > + bp_reply, > + format, > + > dri2_dpy->dri_screen, > + > dri2_dpy->image, > + dri2_img); > + free(bp_reply); > + > + if (!dri2_img->dri_image) { > + _eglError(EGL_BAD_ATTRIBUTE, "dri3_create_image_khr"); > + free(dri2_img); > + return EGL_NO_IMAGE_KHR; > + } > + > + return &dri2_img->base; > +} > +#endif > + > static _EGLImage * > dri3_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, > _EGLContext *ctx, EGLenum target, > EGLClientBuffer buffer, const EGLint *attr_list) > { > + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); > + > switch (target) { > case EGL_NATIVE_PIXMAP_KHR: > +#if XCB_DRI3_MAJOR_VERSION > 1 || (XCB_DRI3_MAJOR_VERSION == 1 && > XCB_DRI3_MINOR_VERSION >= 1) > + if (dri2_dpy->multibuffers_available) > + return dri3_create_image_khr_pixmap_from_buffers(disp, ctx, > buffer, > + attr_list); > +#endif > return dri3_create_image_khr_pixmap(disp, ctx, buffer, attr_list); > default: > return dri2_create_image_khr(drv, disp, ctx, target, buffer, > attr_list); > @@ -471,6 +543,9 @@ dri3_x11_connect(struct dri2_egl_display *dri2_dpy) > free(error); > return EGL_FALSE; > } > + > + dri2_dpy->dri3_major_version = dri3_query->major_version; > + dri2_dpy->dri3_minor_version = dri3_query->minor_version; > free(dri3_query); > > present_query = > diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c > index f280a8cef77..931912f9430 100644 > --- a/src/glx/dri3_glx.c > +++ b/src/glx/dri3_glx.c > @@ -346,7 +346,10 @@ dri3_create_drawable(struct glx_screen *base, XID > xDrawable, > { > struct dri3_drawable *pdraw; > struct dri3_screen *psc = (struct dri3_screen *) base; > + const struct dri3_display *const pdp = (struct dri3_display *) > + base->display->dri3Display; > __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base; > + bool has_multibuffer = false; > > pdraw = calloc(1, sizeof(*pdraw)); > if (!pdraw) > @@ -357,11 +360,16 @@ dri3_create_drawable(struct glx_screen *base, XID > xDrawable, > pdraw->base.drawable = drawable; > pdraw->base.psc = &psc->base; > > + if ((psc->image && psc->image->base.version >= 15) && > + (pdp->dri3Major > 1 || (pdp->dri3Major == 1 && pdp->dri3Minor >= > 1))) > + has_multibuffer = true; > + > (void) __glXInitialize(psc->base.dpy); > > if (loader_dri3_drawable_init(XGetXCBConnection(base->dpy), > xDrawable, psc->driScreen, > - psc->is_different_gpu, config->driConfig, > + psc->is_different_gpu, has_multibuffer, > + config->driConfig, > &psc->loader_dri3_ext, &glx_dri3_vtable, > &pdraw->loader_drawable)) { > free(pdraw); > diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_ > helper.c > index 2912bb6749b..038216c2637 100644 > --- a/src/loader/loader_dri3_helper.c > +++ b/src/loader/loader_dri3_helper.c > @@ -24,6 +24,7 @@ > #include <fcntl.h> > #include <stdlib.h> > #include <unistd.h> > +#include <string.h> > > #include <X11/xshmfence.h> > #include <xcb/xcb.h> > @@ -256,6 +257,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn, > xcb_drawable_t drawable, > __DRIscreen *dri_screen, > bool is_different_gpu, > + bool multiplanes_available, > const __DRIconfig *dri_config, > struct loader_dri3_extensions *ext, > const struct loader_dri3_vtable *vtable, > @@ -273,6 +275,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn, > draw->drawable = drawable; > draw->dri_screen = dri_screen; > draw->is_different_gpu = is_different_gpu; > + draw->multiplanes_available = multiplanes_available; > > draw->have_back = 0; > draw->have_fake_front = 0; > @@ -1024,6 +1027,42 @@ image_format_to_fourcc(int format) > return 0; > } > > +static bool > +has_supported_modifier(struct loader_dri3_drawable *draw, unsigned int > format, > + uint64_t *modifiers, uint32_t count) > +{ > + uint64_t *supported_modifiers; > + int32_t supported_modifiers_count; > + int i, j; > + > + if (!draw->ext->image->queryDmaBufModifiers(draw->dri_screen, > + format, 0, NULL, NULL, > + > &supported_modifiers_count) || > + supported_modifiers_count == 0) > + return false; > + > + supported_modifiers = malloc(supported_modifiers_count * > sizeof(uint64_t)); > + if (!supported_modifiers) > + return false; > + > + draw->ext->image->queryDmaBufModifiers(draw->dri_screen, format, > + supported_modifiers_count, > + supported_modifiers, NULL, > + &supported_modifiers_count); > + > + for (i = 0; i < supported_modifiers_count; i++) { > + for (j = 0; j < count; j++) { > + if (supported_modifiers[i] == modifiers[j]) { > + free(supported_modifiers); > + return true; > + } > + } > + } > + > + free(supported_modifiers); > + return false; > We could make the cleanup path a bit nicer if we did something like this: bool found = false; for (...) { if (...) { found = true; break; } } free(...); return found; That would mean we only have one free. I don't really care all that much though as the current code is correct. > +} > + > /** loader_dri3_alloc_render_buffer > * > * Use the driver createImage function to construct a __DRIimage, then > @@ -1040,8 +1079,10 @@ dri3_alloc_render_buffer(struct > loader_dri3_drawable *draw, unsigned int format, > xcb_pixmap_t pixmap; > xcb_sync_fence_t sync_fence; > struct xshmfence *shm_fence; > - int buffer_fd, fence_fd; > - int stride; > + int buffer_fds[4], fence_fd; > + int num_planes = 0; > + int i, mod; > + int ret; > > /* Create an xshmfence object and > * prepare to send that to the X server > @@ -1066,13 +1107,81 @@ dri3_alloc_render_buffer(struct > loader_dri3_drawable *draw, unsigned int format, > goto no_image; > > if (!draw->is_different_gpu) { > - buffer->image = draw->ext->image->createImage(draw->dri_screen, > - width, height, > - format, > - __DRI_IMAGE_USE_SHARE > | > - > __DRI_IMAGE_USE_SCANOUT | > - > __DRI_IMAGE_USE_BACKBUFFER, > - buffer); > +#if XCB_DRI3_MAJOR_VERSION > 1 || (XCB_DRI3_MAJOR_VERSION == 1 && > XCB_DRI3_MINOR_VERSION >= 1) > + if (draw->multiplanes_available && > + draw->ext->image->base.version >= 15 && > + draw->ext->image->queryDmaBufModifiers && > + draw->ext->image->createImageWithModifiers) { > + xcb_dri3_get_supported_modifiers_cookie_t mod_cookie; > + xcb_dri3_get_supported_modifiers_reply_t *mod_reply; > + xcb_generic_error_t *error = NULL; > + uint64_t *modifiers = NULL; > + uint32_t count = 0; > + > + mod_cookie = xcb_dri3_get_supported_modifiers(draw->conn, > + draw->drawable, > + depth, buffer->cpp > * 8); > + mod_reply = xcb_dri3_get_supported_modifiers_reply(draw->conn, > + mod_cookie, > + &error); > + if (!mod_reply) > + goto no_image; > + > + if (mod_reply->num_drawable_modifiers) { > + count = mod_reply->num_drawable_modifiers; > + modifiers = malloc(count * sizeof(uint64_t)); > + if (!modifiers) { > + free(mod_reply); > + goto no_image; > + } > + > + memcpy(modifiers, > + xcb_dri3_get_supported_modifiers_drawable_modifiers( > mod_reply), > + count * sizeof(uint64_t)); > Dumb question, but why do we need to memcpy? Can't we just pass these directly into createImageWithModifiers so long as we don't free mod_reply until after it returns? > + > + if (!has_supported_modifier(draw, > image_format_to_fourcc(format), > + modifiers, count)) { > + free(modifiers); > + count = 0; > + modifiers = NULL; > + } > + } > + > + if (mod_reply->num_screen_modifiers && modifiers == NULL) { > + count = mod_reply->num_screen_modifiers; > + modifiers = malloc(count * sizeof(uint64_t)); > + if (!modifiers) { > + free(modifiers); > + free(mod_reply); > + goto no_image; > + } > + > + memcpy(modifiers, > + xcb_dri3_get_supported_modifiers_screen_modifiers( > mod_reply), > + count * sizeof(uint64_t)); > + } > + > + free(mod_reply); > + > + buffer->image = draw->ext->image->createImageWithModifiers(draw- > >dri_screen, > + > width, height, > + > format, > + > modifiers, > + count, > + > buffer); > + free(modifiers); > + } > +#endif > + > + if (!buffer->image) > + buffer->image = draw->ext->image->createImage(draw->dri_screen, > + width, height, > + format, > + > __DRI_IMAGE_USE_SHARE | > + > __DRI_IMAGE_USE_SCANOUT | > + > __DRI_IMAGE_USE_BACKBUFFER, > + buffer); > + > pixmap_buffer = buffer->image; > > if (!buffer->image) > @@ -1100,25 +1209,71 @@ dri3_alloc_render_buffer(struct > loader_dri3_drawable *draw, unsigned int format, > goto no_linear_buffer; > } > > - /* X wants the stride, so ask the image for it > + /* X want some information about the planes, so ask the image for it > */ > - if (!draw->ext->image->queryImage(pixmap_buffer, > __DRI_IMAGE_ATTRIB_STRIDE, > - &stride)) > - goto no_buffer_attrib; > + if (!draw->ext->image->queryImage(pixmap_buffer, > __DRI_IMAGE_ATTRIB_NUM_PLANES, > + &num_planes)) > + num_planes = 1; > > - buffer->pitch = stride; > + for (i = 0; i < num_planes; i++) { > + __DRIimage *image = draw->ext->image->fromPlanar(pixmap_buffer, i, > NULL); > > - if (!draw->ext->image->queryImage(pixmap_buffer, > __DRI_IMAGE_ATTRIB_FD, > - &buffer_fd)) > - goto no_buffer_attrib; > + if (!image) { > + assert(i == 0); > + image = pixmap_buffer; > + } > > - xcb_dri3_pixmap_from_buffer(draw->conn, > - (pixmap = xcb_generate_id(draw->conn)), > - draw->drawable, > - buffer->size, > - width, height, buffer->pitch, > - depth, buffer->cpp * 8, > - buffer_fd); > + ret = draw->ext->image->queryImage(image, __DRI_IMAGE_ATTRIB_FD, > + &buffer_fds[i]); > + ret &= draw->ext->image->queryImage(image, > __DRI_IMAGE_ATTRIB_STRIDE, > + &buffer->strides[i]); > + ret &= draw->ext->image->queryImage(image, > __DRI_IMAGE_ATTRIB_OFFSET, > + &buffer->offsets[i]); > + if (image != pixmap_buffer) > + draw->ext->image->destroyImage(image); > + > + if (!ret) > + goto no_buffer_attrib; > + } > + > + ret = draw->ext->image->queryImage(pixmap_buffer, > + __DRI_IMAGE_ATTRIB_MODIFIER_UPPER, > &mod); > + buffer->modifier = (uint64_t) mod << 32; > + ret &= draw->ext->image->queryImage(pixmap_buffer, > + __DRI_IMAGE_ATTRIB_MODIFIER_LOWER, > &mod); > + buffer->modifier |= (uint64_t)(mod & 0xffffffff); > + > + if (!ret) > + buffer->modifier = DRM_FORMAT_MOD_INVALID; > + > + pixmap = xcb_generate_id(draw->conn); > +#if XCB_DRI3_MAJOR_VERSION > 1 || (XCB_DRI3_MAJOR_VERSION == 1 && > XCB_DRI3_MINOR_VERSION >= 1) > + if (draw->multiplanes_available && > + buffer->modifier != DRM_FORMAT_MOD_INVALID) { > I made a similar comment on the Wayland one but buffer->modifier != INVALID should imply multiplanes_available. We should make multiplanes_available an assert. > + xcb_dri3_pixmap_from_buffers(draw->conn, > + pixmap, > + draw->drawable, > + num_planes, > + width, height, > + buffer->strides[0], buffer->offsets[0], > + buffer->strides[1], buffer->offsets[1], > + buffer->strides[2], buffer->offsets[2], > + buffer->strides[3], buffer->offsets[3], > + depth, buffer->cpp * 8, > + buffer->modifier, > + buffer_fds); > + } > + else > +#endif > + { > + xcb_dri3_pixmap_from_buffer(draw->conn, > + pixmap, > + draw->drawable, > + buffer->size, > + width, height, buffer->strides[0], > + depth, buffer->cpp * 8, > + buffer_fds[0]); > + } > > xcb_dri3_fence_from_fd(draw->conn, > pixmap, > @@ -1140,6 +1295,9 @@ dri3_alloc_render_buffer(struct > loader_dri3_drawable *draw, unsigned int format, > return buffer; > > no_buffer_attrib: > + do { > + close(buffer_fds[i]); > + } while (--i >= 0); > draw->ext->image->destroyImage(pixmap_buffer); > no_linear_buffer: > if (draw->is_different_gpu) > @@ -1296,6 +1454,50 @@ loader_dri3_create_image(xcb_connection_t *c, > return ret; > } > > +#if XCB_DRI3_MAJOR_VERSION > 1 || (XCB_DRI3_MAJOR_VERSION == 1 && > XCB_DRI3_MINOR_VERSION >= 1) > +__DRIimage * > +loader_dri3_create_image_from_buffers(xcb_connection_t *c, > + xcb_dri3_buffers_from_pixmap_reply_t > *bp_reply, > + unsigned int format, > + __DRIscreen *dri_screen, > + const __DRIimageExtension *image, > + void *loaderPrivate) > +{ > + __DRIimage *ret; > + int *fds; > + uint32_t *strides_in, *offsets_in; > + int strides[4], offsets[4]; > + unsigned error; > + int i; > + > + if (bp_reply->nfd > 4) > + return NULL; > + > + fds = xcb_dri3_buffers_from_pixmap_reply_fds(c, bp_reply); > + strides_in = xcb_dri3_buffers_from_pixmap_strides(bp_reply); > + offsets_in = xcb_dri3_buffers_from_pixmap_offsets(bp_reply); > + for (i = 0; i < bp_reply->nfd; i++) { > + strides[i] = strides_in[i]; > + offsets[i] = offsets_in[i]; > + } > + > + ret = image->createImageFromDmaBufs2(dri_screen, > + bp_reply->width, > + bp_reply->height, > + image_format_to_fourcc(format), > + bp_reply->modifier, > + fds, bp_reply->nfd, > + strides, offsets, > + 0, 0, 0, 0, /* UNDEFINED */ > + &error, loaderPrivate); > + > + for (i = 0; i < bp_reply->nfd; i++) > + close(fds[i]); > + > + return ret; > +} > +#endif > + > /** dri3_get_pixmap_buffer > * > * Get the DRM object for a pixmap from the X server and > @@ -1309,10 +1511,10 @@ dri3_get_pixmap_buffer(__DRIdrawable > *driDrawable, unsigned int format, > int buf_id = > loader_dri3_pixmap_buf_id(buffer_type); > struct loader_dri3_buffer *buffer = draw->buffers[buf_id]; > xcb_drawable_t pixmap; > - xcb_dri3_buffer_from_pixmap_cookie_t bp_cookie; > - xcb_dri3_buffer_from_pixmap_reply_t *bp_reply; > xcb_sync_fence_t sync_fence; > struct xshmfence *shm_fence; > + int width; > + int height; > int fence_fd; > > if (buffer) > @@ -1339,32 +1541,60 @@ dri3_get_pixmap_buffer(__DRIdrawable > *driDrawable, unsigned int format, > false, > fence_fd); > > - bp_cookie = xcb_dri3_buffer_from_pixmap(draw->conn, pixmap); > - bp_reply = xcb_dri3_buffer_from_pixmap_reply(draw->conn, bp_cookie, > NULL); > - if (!bp_reply) > - goto no_image; > +#if XCB_DRI3_MAJOR_VERSION > 1 || (XCB_DRI3_MAJOR_VERSION == 1 && > XCB_DRI3_MINOR_VERSION >= 1) > + if (draw->multiplanes_available && > + draw->ext->image->base.version >= 15 && > + draw->ext->image->createImageFromDmaBufs2) { > + xcb_dri3_buffers_from_pixmap_cookie_t bps_cookie; > + xcb_dri3_buffers_from_pixmap_reply_t *bps_reply; > + > + bps_cookie = xcb_dri3_buffers_from_pixmap(draw->conn, pixmap); > + bps_reply = xcb_dri3_buffers_from_pixmap_reply(draw->conn, > bps_cookie, > + NULL); > + if (!bps_reply) > + goto no_image; > + buffer->image = > + loader_dri3_create_image_from_buffers(draw->conn, bps_reply, > format, > + draw->dri_screen, > + draw->ext->image, > + buffer); > + width = bps_reply->width; > + height = bps_reply->height; > + free(bps_reply); > + } else > +#endif > I really don't like mising preprocessor and C control-flow like this. I made a suggestion on the previous version. If there's nothing better to do, then I can live with it. > + { > + xcb_dri3_buffer_from_pixmap_cookie_t bp_cookie; > + xcb_dri3_buffer_from_pixmap_reply_t *bp_reply; > + > + bp_cookie = xcb_dri3_buffer_from_pixmap(draw->conn, pixmap); > + bp_reply = xcb_dri3_buffer_from_pixmap_reply(draw->conn, > bp_cookie, NULL); > + if (!bp_reply) > + goto no_image; > + > + buffer->image = loader_dri3_create_image(draw->conn, bp_reply, > format, > + draw->dri_screen, > + draw->ext->image, buffer); > + width = bp_reply->width; > + height = bp_reply->height; > + free(bp_reply); > + } > > - buffer->image = loader_dri3_create_image(draw->conn, bp_reply, format, > - draw->dri_screen, > draw->ext->image, > - buffer); > if (!buffer->image) > goto no_image; > > buffer->pixmap = pixmap; > buffer->own_pixmap = false; > - buffer->width = bp_reply->width; > - buffer->height = bp_reply->height; > + buffer->width = width; > + buffer->height = height; > buffer->shm_fence = shm_fence; > buffer->sync_fence = sync_fence; > > draw->buffers[buf_id] = buffer; > > - free(bp_reply); > - > return buffer; > > no_image: > - free(bp_reply); > xcb_sync_destroy_fence(draw->conn, sync_fence); > xshmfence_unmap_shm(shm_fence); > no_fence: > diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_ > helper.h > index 4ce98b8c59f..5689e2707c5 100644 > --- a/src/loader/loader_dri3_helper.h > +++ b/src/loader/loader_dri3_helper.h > @@ -62,8 +62,11 @@ struct loader_dri3_buffer { > bool busy; /* Set on swap, cleared on IdleNotify */ > bool own_pixmap; /* We allocated the pixmap ID, free on > destroy */ > > + uint32_t num_planes; > uint32_t size; > - uint32_t pitch; > + int strides[4]; > + int offsets[4]; > + uint64_t modifier; > uint32_t cpp; > uint32_t flags; > uint32_t width, height; > @@ -120,6 +123,7 @@ struct loader_dri3_drawable { > /* Information about the GPU owning the buffer */ > __DRIscreen *dri_screen; > bool is_different_gpu; > + bool multiplanes_available; > > /* Present extension capabilities > */ > @@ -179,6 +183,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn, > xcb_drawable_t drawable, > __DRIscreen *dri_screen, > bool is_different_gpu, > + bool is_multiplanes_available, > const __DRIconfig *dri_config, > struct loader_dri3_extensions *ext, > const struct loader_dri3_vtable *vtable, > @@ -236,6 +241,16 @@ loader_dri3_create_image(xcb_connection_t *c, > const __DRIimageExtension *image, > void *loaderPrivate); > > +#if XCB_DRI3_MAJOR_VERSION > 1 || (XCB_DRI3_MAJOR_VERSION == 1 && > XCB_DRI3_MINOR_VERSION >= 1) > +__DRIimage * > +loader_dri3_create_image_from_buffers(xcb_connection_t *c, > + xcb_dri3_buffers_from_pixmap_reply_t > *bp_reply, > + unsigned int format, > + __DRIscreen *dri_screen, > + const __DRIimageExtension *image, > + void *loaderPrivate); > +#endif > + > int > loader_dri3_get_buffers(__DRIdrawable *driDrawable, > unsigned int format, > -- > 2.14.3 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev