From ea4a0ce78e70a7dfdd8a098848fc27395b820f33 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Sat, 7 Dec 2024 13:10:04 +0100 Subject: [PATCH 1/3] dri: don't fetch X11 modifiers if we don't support them If we supply modifiers to dri_create_image_with_modifiers() and the driver doesn't support them, the function will fail. The X11 server always supports implicit modifiers so we can always fall back to that. Signed-off-by: Simon Ser Fixes: 4c065158927d ("dri: revert INVALID modifier special-casing") --- src/gallium/frontends/dri/loader_dri3_helper.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gallium/frontends/dri/loader_dri3_helper.c b/src/gallium/frontends/dri/loader_dri3_helper.c index 268ec3d86c8a3..e1f51619c5fa3 100644 --- a/src/gallium/frontends/dri/loader_dri3_helper.c +++ b/src/gallium/frontends/dri/loader_dri3_helper.c @@ -36,9 +36,11 @@ #include "loader_dri_helper.h" #include "loader_dri3_helper.h" +#include "pipe/p_screen.h" #include "util/macros.h" #include "util/simple_mtx.h" #include "drm-uapi/drm_fourcc.h" +#include "dri_screen.h" #include "dri_util.h" /** @@ -1401,7 +1403,7 @@ dri3_alloc_render_buffer(struct loader_dri3_drawable *draw, unsigned int fourcc, if (draw->dri_screen_render_gpu == draw->dri_screen_display_gpu) { #ifdef HAVE_X11_DRM - if (draw->multiplanes_available) { + if (draw->multiplanes_available && draw->dri_screen_render_gpu->base.screen->resource_create_with_modifiers) { xcb_dri3_get_supported_modifiers_cookie_t mod_cookie; xcb_dri3_get_supported_modifiers_reply_t *mod_reply; xcb_generic_error_t *error = NULL; -- GitLab From 314c930b541453d1e76cec8141e7315dd5be15cb Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Sat, 7 Dec 2024 13:12:40 +0100 Subject: [PATCH 2/3] egl/wayland: only supply LINEAR modifier when supported If we supply modifiers to dri_create_image_with_modifiers() and the driver doesn't support them, the function will fail. We pass __DRI_IMAGE_USE_LINEAR anyways so stripping the modifier is fine. Signed-off-by: Simon Ser Fixes: 4c065158927d ("dri: revert INVALID modifier special-casing") --- src/egl/drivers/dri2/platform_wayland.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index 513d2d0709b14..472665a36b0dd 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -45,11 +45,13 @@ #include "util/u_vector.h" #include "util/format/u_formats.h" #include "main/glconfig.h" +#include "pipe/p_screen.h" #include "egl_dri2.h" #include "eglglobals.h" #include "kopper_interface.h" #include "loader.h" #include "loader_dri_helper.h" +#include "dri_screen.h" #include "dri_util.h" #include @@ -1193,14 +1195,25 @@ get_back_bo(struct dri2_egl_surface *dri2_surf) if (dri2_dpy->fd_render_gpu != dri2_dpy->fd_display_gpu && dri2_surf->back->linear_copy == NULL) { uint64_t linear_mod = DRM_FORMAT_MOD_LINEAR; + const uint64_t *render_modifiers = NULL, *display_modifiers = NULL; + unsigned int render_num_modifiers = 0, display_num_modifiers = 0; struct dri_image *linear_copy_display_gpu_image = NULL; + if (dri2_dpy->dri_screen_render_gpu->base.screen->resource_create_with_modifiers) { + render_modifiers = &linear_mod; + render_num_modifiers = 1; + } + if (dri2_dpy->dri_screen_display_gpu->base.screen->resource_create_with_modifiers) { + display_modifiers = &linear_mod; + display_num_modifiers = 1; + } + if (dri2_dpy->dri_screen_display_gpu) { linear_copy_display_gpu_image = dri_create_image_with_modifiers( dri2_dpy->dri_screen_display_gpu, dri2_surf->base.Width, dri2_surf->base.Height, linear_pipe_format, use_flags | __DRI_IMAGE_USE_LINEAR, - &linear_mod, 1, NULL); + display_modifiers, display_num_modifiers, NULL); if (linear_copy_display_gpu_image) { int i, ret = 1; @@ -1285,7 +1298,7 @@ get_back_bo(struct dri2_egl_surface *dri2_surf) dri2_dpy->dri_screen_render_gpu, dri2_surf->base.Width, dri2_surf->base.Height, linear_pipe_format, use_flags | __DRI_IMAGE_USE_LINEAR, - &linear_mod, 1, NULL); + render_modifiers, render_num_modifiers, NULL); } if (dri2_surf->back->linear_copy == NULL) -- GitLab From 33873da6a2474bb2c44f582bcfcf7612f10546ba Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Sat, 7 Dec 2024 13:15:57 +0100 Subject: [PATCH 3/3] egl/wayland: fallback to implicit modifiers if advertised by compositor The Wayland protocol defines INVALID as a special marker indicating that implicit modifiers are supported. If the driver doesn't support explicit modifiers and the compositor advertises support for implicit modifiers, fallback to these. This effectively restores logic removed in 4c065158927d, but only for the specific case of Wayland instead of affecting all APIs. (Wayland is one of the few APIs defining a special meaning for INVALID.) Signed-off-by: Simon Ser Fixes: 4c065158927d ("dri: revert INVALID modifier special-casing") --- src/egl/drivers/dri2/platform_wayland.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index 472665a36b0dd..9c60a89e90243 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -1010,6 +1010,7 @@ create_dri_image(struct dri2_egl_surface *dri2_surf, uint64_t *modifiers; unsigned int num_modifiers; struct u_vector *modifiers_present; + bool implicit_mod_supported; assert(visual_idx != -1); @@ -1049,6 +1050,26 @@ create_dri_image(struct dri2_egl_surface *dri2_surf, num_modifiers = u_vector_length(modifiers_present); } + if (!dri2_dpy->dri_screen_render_gpu->base.screen->resource_create_with_modifiers && + dri2_dpy->wl_dmabuf) { + /* We don't support explicit modifiers, check if the compositor supports + * implicit modifiers. */ + implicit_mod_supported = false; + for (unsigned int i = 0; i < num_modifiers; i++) { + if (modifiers[i] == DRM_FORMAT_MOD_INVALID) { + implicit_mod_supported = true; + break; + } + } + + if (!implicit_mod_supported) { + return; + } + + num_modifiers = 0; + modifiers = NULL; + } + /* For the purposes of this function, an INVALID modifier on * its own means the modifiers aren't supported. */ if (num_modifiers == 0 || --