Implement function added in DRI3 v1.1. A newest version of libepoxy (>= 1.4.4) is required as earlier versions use a problematic version of Khronos EXT_image_dma_buf_import_modifiers spec.
Signed-off-by: Louis-Francis Ratté-Boulianne <l...@collabora.com> --- configure.ac | 4 ++ glamor/glamor.h | 10 ++++ glamor/glamor_egl.c | 91 +++++++++++++++++++++++++++++ hw/xwayland/xwayland-glamor.c | 129 +++++++++++++++++++++++++++++++++++++----- hw/xwayland/xwayland.h | 9 ++- include/dix-config.h.in | 3 + 6 files changed, 232 insertions(+), 14 deletions(-) diff --git a/configure.ac b/configure.ac index 4604189ee..b1818477b 100644 --- a/configure.ac +++ b/configure.ac @@ -2087,6 +2087,10 @@ if test "x$GLAMOR" = xyes; then AC_DEFINE(GLAMOR, 1, [Build glamor]) PKG_CHECK_MODULES([GLAMOR], [epoxy]) + PKG_CHECK_EXISTS(epoxy >= 1.4.4, + [AC_DEFINE(GLAMOR_HAS_EGL_QUERY_DMABUF, 1, [Have GLAMOR_HAS_EGL_QUERY_DMABUF])], + []) + PKG_CHECK_MODULES(GBM, "$LIBGBM", [GBM=yes], [GBM=no]) if test "x$GBM" = xyes; then AC_DEFINE(GLAMOR_HAS_GBM, 1, diff --git a/glamor/glamor.h b/glamor/glamor.h index 8f8c31b45..ddf67fe20 100644 --- a/glamor/glamor.h +++ b/glamor/glamor.h @@ -272,6 +272,16 @@ extern _X_EXPORT Bool glamor_back_pixmap_from_fd(PixmapPtr pixmap, CARD16 stride, CARD8 depth, CARD8 bpp); + +extern _X_EXPORT Bool glamor_get_formats(ScreenPtr screen, + CARD32 *num_formats, + CARD32 **formats); + +extern _X_EXPORT Bool glamor_get_modifiers(ScreenPtr screen, + CARD32 format, + CARD32 *num_modifiers, + uint64_t **modifiers); + #ifdef GLAMOR_FOR_XORG #define GLAMOR_EGL_MODULE_NAME "glamoregl" diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c index 5708170a9..dc51337ad 100644 --- a/glamor/glamor_egl.c +++ b/glamor/glamor_egl.c @@ -486,6 +486,95 @@ glamor_pixmap_from_fds(ScreenPtr screen, return pixmap; } +_X_EXPORT Bool +glamor_get_formats(ScreenPtr screen, + CARD32 *num_formats, CARD32 **formats) +{ +#ifdef GLAMOR_HAS_EGL_QUERY_DMABUF + struct glamor_egl_screen_private *glamor_egl; + EGLint num; + + glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen)); + + if (!glamor_egl->dmabuf_capable) + return FALSE; + + if (!eglQueryDmaBufFormatsEXT(glamor_egl->display, 0, NULL, &num)) { + *num_formats = 0; + return FALSE; + } + + if (num == 0) { + *num_formats = 0; + return TRUE; + } + + *formats = calloc(num, sizeof(CARD32)); + if (*formats == NULL) { + *num_formats = 0; + return FALSE; + } + + if (!eglQueryDmaBufFormatsEXT(glamor_egl->display, num, + (EGLint *) *formats, &num)) { + *num_formats = 0; + free(*formats); + return FALSE; + } + + *num_formats = num; + return TRUE; +#else + *num_formats = 0; + return TRUE; +#endif +} + +_X_EXPORT Bool +glamor_get_modifiers(ScreenPtr screen, CARD32 format, + CARD32 *num_modifiers, uint64_t **modifiers) +{ +#ifdef GLAMOR_HAS_EGL_QUERY_DMABUF + struct glamor_egl_screen_private *glamor_egl; + EGLint num; + + glamor_egl = glamor_egl_get_screen_private(xf86ScreenToScrn(screen)); + + if (!glamor_egl->dmabuf_capable) + return FALSE; + + if (!eglQueryDmaBufModifiersEXT(glamor_egl->display, format, 0, NULL, + NULL, &num)) { + *num_modifiers = 0; + return FALSE; + } + + if (num == 0) { + *num_modifiers = 0; + return TRUE; + } + + *modifiers = calloc(num, sizeof(uint64_t)); + if (*modifiers == NULL) { + *num_modifiers = 0; + return FALSE; + } + + if (!eglQueryDmaBufModifiersEXT(glamor_egl->display, format, num, + (EGLuint64KHR *) *modifiers, NULL, &num)) { + *num_modifiers = 0; + free(*modifiers); + return FALSE; + } + + *num_modifiers = num; + return TRUE; +#else + *num_modifiers = 0; + return TRUE; +#endif +} + static Bool glamor_egl_destroy_pixmap(PixmapPtr pixmap) { @@ -607,6 +696,8 @@ static dri3_screen_info_rec glamor_dri3_info = { .open_client = glamor_dri3_open_client, .pixmap_from_fds = glamor_pixmap_from_fds, .fds_from_pixmap = glamor_egl_fds_from_pixmap, + .get_formats = glamor_get_formats, + .get_modifiers = glamor_get_modifiers, }; #endif /* DRI3 */ diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c index 5c0c408ab..ca3785ff5 100644 --- a/hw/xwayland/xwayland-glamor.c +++ b/hw/xwayland/xwayland-glamor.c @@ -409,19 +409,6 @@ xwl_drm_handle_device(void *data, struct wl_drm *drm, const char *device) static void xwl_drm_handle_format(void *data, struct wl_drm *drm, uint32_t format) { - struct xwl_screen *xwl_screen = data; - - switch (format) { - case WL_DRM_FORMAT_ARGB8888: - xwl_screen->formats |= XWL_FORMAT_ARGB8888; - break; - case WL_DRM_FORMAT_XRGB8888: - xwl_screen->formats |= XWL_FORMAT_XRGB8888; - break; - case WL_DRM_FORMAT_RGB565: - xwl_screen->formats |= XWL_FORMAT_RGB565; - break; - } } static void @@ -448,6 +435,54 @@ static const struct wl_drm_listener xwl_drm_listener = { xwl_drm_handle_capabilities }; +static void +xwl_dmabuf_handle_format(void *data, struct zwp_linux_dmabuf_v1 *dmabuf, + uint32_t format) +{ +} + +static void +xwl_dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf, + uint32_t format, uint32_t modifier_hi, + uint32_t modifier_lo) +{ + struct xwl_screen *xwl_screen = data; + struct xwl_format *xwl_format = NULL; + int i; + + for (i = 0; i < xwl_screen->num_formats; i++) { + if (xwl_screen->formats[i].format == format) { + xwl_format = &xwl_screen->formats[i]; + break; + } + } + + if (xwl_format == NULL) { + xwl_screen->num_formats++; + xwl_screen->formats = realloc(xwl_screen->formats, + xwl_screen->num_formats * sizeof(*xwl_format)); + if (!xwl_screen->formats) + return; + xwl_format = &xwl_screen->formats[xwl_screen->num_formats - 1]; + xwl_format->format = format; + xwl_format->num_modifiers = 0; + xwl_format->modifiers = NULL; + } + + xwl_format->num_modifiers++; + xwl_format->modifiers = realloc(xwl_format->modifiers, + xwl_format->num_modifiers * sizeof(uint64_t)); + if (!xwl_format->modifiers) + return; + xwl_format->modifiers[xwl_format->num_modifiers - 1] = (uint64_t) modifier_lo; + xwl_format->modifiers[xwl_format->num_modifiers - 1] |= (uint64_t) modifier_hi << 32; +} + +static const struct zwp_linux_dmabuf_v1_listener xwl_dmabuf_listener = { + .format = xwl_dmabuf_handle_format, + .modifier = xwl_dmabuf_handle_modifier +}; + Bool xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version) @@ -472,6 +507,7 @@ xwl_screen_set_dmabuf_interface(struct xwl_screen *xwl_screen, xwl_screen->dmabuf = wl_registry_bind(xwl_screen->registry, id, &zwp_linux_dmabuf_v1_interface, 2); + zwp_linux_dmabuf_v1_add_listener(xwl_screen->dmabuf, &xwl_dmabuf_listener, xwl_screen); return TRUE; } @@ -673,12 +709,79 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds, return xwl_pixmap->num_fds; } +_X_EXPORT Bool +glamor_get_formats(ScreenPtr screen, + CARD32 *num_formats, CARD32 **formats) +{ + struct xwl_screen *xwl_screen = xwl_screen_get(screen); + int i; + + if (!xwl_screen->dmabuf_capable || !xwl_screen->dmabuf) + return FALSE; + + if (xwl_screen->num_formats == 0) { + *num_formats = 0; + return TRUE; + } + + *formats = calloc(xwl_screen->num_formats, sizeof(CARD32)); + if (*formats == NULL) { + *num_formats = 0; + return FALSE; + } + + for (i = 0; i < xwl_screen->num_formats; i++) + (*formats)[i] = xwl_screen->formats[i].format; + *num_formats = xwl_screen->num_formats; + + return TRUE; +} + +_X_EXPORT Bool +glamor_get_modifiers(ScreenPtr screen, CARD32 format, + CARD32 *num_modifiers, uint64_t **modifiers) +{ + struct xwl_screen *xwl_screen = xwl_screen_get(screen); + struct xwl_format *xwl_format = NULL; + int i; + + if (!xwl_screen->dmabuf_capable || !xwl_screen->dmabuf) + return FALSE; + + if (xwl_screen->num_modifiers == 0) { + *num_modifiers = 0; + return TRUE; + } + + for (i = 0; i < xwl_screen->num_formats; i++) { + if (xwl_screen->formats[i].format == format) { + xwl_format = &xwl_screen->formats[i]; + break; + } + } + + *modifiers = calloc(xwl_format->num_modifiers, sizeof(uint64_t)); + if (*modifiers == NULL) { + *num_modifiers = 0; + return FALSE; + } + + for (i = 0; i < xwl_format->num_modifiers; i++) + (*modifiers)[i] = xwl_format->modifiers[i]; + *num_modifiers = xwl_format->num_modifiers; + + return TRUE; +} + + static dri3_screen_info_rec xwl_dri3_info = { .version = 2, .open = NULL, .pixmap_from_fds = glamor_pixmap_from_fds, .fds_from_pixmap = glamor_fds_from_pixmap, .open_client = xwl_dri3_open_client, + .get_formats = glamor_get_formats, + .get_modifiers = glamor_get_modifiers, }; Bool diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index ec77d10f9..fc24e1e74 100644 --- a/hw/xwayland/xwayland.h +++ b/hw/xwayland/xwayland.h @@ -48,6 +48,12 @@ #include "xwayland-keyboard-grab-unstable-v1-client-protocol.h" #include "linux-dmabuf-unstable-v1-client-protocol.h" +struct xwl_format { + uint32_t format; + int num_modifiers; + uint64_t *modifiers; +}; + struct xwl_screen { int width; int height; @@ -97,7 +103,8 @@ struct xwl_screen { int fd_render_node; struct wl_drm *drm; struct zwp_linux_dmabuf_v1 *dmabuf; - uint32_t formats; + uint32_t num_formats; + struct xwl_format *formats; uint32_t capabilities; void *egl_display, *egl_context; struct gbm_device *gbm; diff --git a/include/dix-config.h.in b/include/dix-config.h.in index 57aee61fd..8e9dcdfcc 100644 --- a/include/dix-config.h.in +++ b/include/dix-config.h.in @@ -503,6 +503,9 @@ /* Build glamor use new drmGetDeviceNameFromFD2 */ #undef GLAMOR_HAS_DRM_NAME_FROM_FD_2 +/* Glamor can use eglQueryDmaBuf* functions */ +#undef GLAMOR_HAS_EGL_QUERY_DMABUF + /* byte order */ #undef X_BYTE_ORDER -- 2.13.0 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel