From 069fdd5f9facbd72fb6a289696c7b74e3237e70f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Louis-Francis=20Ratt=C3=A9-Boulianne?= Date: Fri, 7 Jul 2017 02:54:26 -0400 Subject: [PATCH] egl/x11: Support DRI3 v1.1 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Eric Engestrom Reviewed-by: Emil Velikov Reviewed-by: Daniel Stone --- src/egl/drivers/dri2/egl_dri2.c | 7 + src/egl/drivers/dri2/egl_dri2.h | 3 + src/egl/drivers/dri2/platform_x11_dri3.c | 101 ++++++-- src/glx/dri3_glx.c | 10 +- src/loader/loader_dri3_helper.c | 308 +++++++++++++++++++---- src/loader/loader_dri3_helper.h | 15 +- src/loader/meson.build | 2 +- 7 files changed, 383 insertions(+), 63 deletions(-) diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index c06a0ca0995..1bd57c9ea31 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 >= 2)) && + (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 2073c592dc9..c1efa930159 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); @@ -168,7 +185,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)) { @@ -274,20 +293,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); @@ -315,13 +322,74 @@ dri3_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx, return &dri2_img->base; } +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; +} + 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 (dri2_dpy->multibuffers_available) + return dri3_create_image_khr_pixmap_from_buffers(disp, ctx, buffer, + attr_list); return dri3_create_image_khr_pixmap(disp, ctx, buffer, attr_list); default: return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list); @@ -483,6 +551,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 adfc3499688..71ecebbc16c 100644 --- a/src/glx/dri3_glx.c +++ b/src/glx/dri3_glx.c @@ -357,7 +357,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) @@ -368,11 +371,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 >= 2))) + 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 426966a786a..6587281c4ab 100644 --- a/src/loader/loader_dri3_helper.c +++ b/src/loader/loader_dri3_helper.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -34,6 +35,7 @@ #include "loader_dri3_helper.h" #include "util/macros.h" +#include "drm_fourcc.h" /* From xmlpool/options.h, user exposed so should be stable */ #define DRI_CONF_VBLANK_NEVER 0 @@ -257,6 +259,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, @@ -274,6 +277,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; @@ -1023,6 +1027,41 @@ 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; + bool found = false; + 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; !found && i < supported_modifiers_count; i++) { + for (j = 0; !found && j < count; j++) { + if (supported_modifiers[i] == modifiers[j]) + found = true; + } + } + + free(supported_modifiers); + return found; +} + /** loader_dri3_alloc_render_buffer * * Use the driver createImage function to construct a __DRIimage, then @@ -1039,8 +1078,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 @@ -1065,13 +1106,79 @@ 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 (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_window_modifiers) { + count = mod_reply->num_window_modifiers; + modifiers = malloc(count * sizeof(uint64_t)); + if (!modifiers) { + free(mod_reply); + goto no_image; + } + + memcpy(modifiers, + xcb_dri3_get_supported_modifiers_window_modifiers(mod_reply), + count * sizeof(uint64_t)); + + 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); + } + + 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) @@ -1099,25 +1206,67 @@ 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; + + for (i = 0; i < num_planes; i++) { + __DRIimage *image = draw->ext->image->fromPlanar(pixmap_buffer, i, NULL); - buffer->pitch = stride; + if (!image) { + assert(i == 0); + image = pixmap_buffer; + } - if (!draw->ext->image->queryImage(pixmap_buffer, __DRI_IMAGE_ATTRIB_FD, - &buffer_fd)) - goto no_buffer_attrib; + 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; + } - 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(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 (draw->multiplanes_available && + buffer->modifier != DRM_FORMAT_MOD_INVALID) { + 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 { + 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, @@ -1139,6 +1288,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) @@ -1295,6 +1447,48 @@ loader_dri3_create_image(xcb_connection_t *c, return ret; } +__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; +} + /** dri3_get_pixmap_buffer * * Get the DRM object for a pixmap from the X server and @@ -1308,10 +1502,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; __DRIscreen *cur_screen; @@ -1333,17 +1527,6 @@ dri3_get_pixmap_buffer(__DRIdrawable *driDrawable, unsigned int format, goto no_fence; } - xcb_dri3_fence_from_fd(draw->conn, - pixmap, - (sync_fence = xcb_generate_id(draw->conn)), - 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; - /* Get the currently-bound screen or revert to using the drawable's screen if * no contexts are currently bound. The latter case is at least necessary for * obs-studio, when using Window Capture (Xcomposite) as a Source. @@ -1353,27 +1536,62 @@ dri3_get_pixmap_buffer(__DRIdrawable *driDrawable, unsigned int format, cur_screen = draw->dri_screen; } - buffer->image = loader_dri3_create_image(draw->conn, bp_reply, format, - cur_screen, draw->ext->image, - buffer); + xcb_dri3_fence_from_fd(draw->conn, + pixmap, + (sync_fence = xcb_generate_id(draw->conn)), + false, + fence_fd); + + 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, + cur_screen, draw->ext->image, + buffer); + width = bps_reply->width; + height = bps_reply->height; + free(bps_reply); + } else { + 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, + cur_screen, draw->ext->image, + buffer); + width = bp_reply->width; + height = bp_reply->height; + free(bp_reply); + } + 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 5caf214b372..c54c668032e 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 */ @@ -180,6 +184,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, @@ -237,6 +242,14 @@ loader_dri3_create_image(xcb_connection_t *c, const __DRIimageExtension *image, void *loaderPrivate); +__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); + int loader_dri3_get_buffers(__DRIdrawable *driDrawable, unsigned int format, diff --git a/src/loader/meson.build b/src/loader/meson.build index 2693970182f..76fcae2cb44 100644 --- a/src/loader/meson.build +++ b/src/loader/meson.build @@ -25,7 +25,7 @@ if with_platform_x11 and with_dri3 'loader_dri3_helper', ['loader_dri3_helper.c', 'loader_dri3_helper.h'], c_args : c_vis_args, - include_directories : [inc_include, inc_src], + include_directories : [inc_include, inc_src, inc_drm_uapi], dependencies : [ dep_libdrm, dep_xcb_dri3, dep_xcb_present, dep_xcb_sync, dep_xshmfence, ], -- 2.30.2