Mesa (main): vulkan/wsi: prefer the Wayland linux-dmabuf protocol

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jun 30 05:05:19 UTC 2021


Module: Mesa
Branch: main
Commit: fc667fdf3bf3956337ac474d308e09dede619518
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=fc667fdf3bf3956337ac474d308e09dede619518

Author: Simon Ser <contact at emersion.fr>
Date:   Thu May 28 19:59:35 2020 +0200

vulkan/wsi: prefer the Wayland linux-dmabuf protocol

When the linux-dmabuf protocol is available, prefer it over the old
wl_drm protocol. Previously wl_drm was used when modifiers aren't
supported, however linux-dmabuf supports formats without modifiers too.
In this case, linux-dmabuf will send a DRM_FORMAT_MOD_INVALID modifier
for each supported format [1].

All of this allows compositors to better handle these buffers, getting a
DMA-BUF and implementing features like direct scan-out.

A similar logic has been implemented for EGL [2].

In this patch, we bind to linux-dmabuf even if the driver doesn't support
modifiers. In this case the formats advertised by the compositor will
still be added to the display->dmabuf.formats list.

In wsi_wl_image_init, drop the assertions that display->drm_wrapper and
display->dmabuf.wl_dmabuf can't be both present. If the driver doesn't
support modifiers, the modifier is already set to DRM_FORMAT_MOD_INVALID.
If the parent compositor doesn't support modifiers, the modifiers list
passed to wsi_create_native_image will be empty, and the common code
will ensure that the image's modifier is set to DRM_FORMAT_MOD_INVALID.

In wsi_wl_surface_create_swapchain, create the wl_proxy proxy if we've
bound to it earlier. Don't decide to create the proxy depending on the
number of supported modifiers.

[1]: https://gitlab.freedesktop.org/wayland/wayland-protocols/commit/fb9b2a87317c77e26283da5f6c9559d709f6fdcd
[2]: https://gitlab.freedesktop.org/mesa/mesa/-/commit/c376865f5eeca535c4aa8e33bcf166052c1ce2f2

Signed-off-by: Simon Ser <contact at emersion.fr>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4942>

---

 src/vulkan/wsi/wsi_common_wayland.c | 37 ++++++++++++-------------------------
 1 file changed, 12 insertions(+), 25 deletions(-)

diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c
index d0cabf9514e..4294863b55e 100644
--- a/src/vulkan/wsi/wsi_common_wayland.c
+++ b/src/vulkan/wsi/wsi_common_wayland.c
@@ -310,10 +310,6 @@ dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
    if (display->dmabuf.formats.element_size == 0)
       return;
 
-   if (modifier_hi == (DRM_FORMAT_MOD_INVALID >> 32) &&
-       modifier_lo == (DRM_FORMAT_MOD_INVALID & 0xffffffff))
-      return;
-
    switch (format) {
    case WL_DRM_FORMAT_ARGB8888:
       modifiers = &display->dmabuf.modifiers.argb8888;
@@ -327,6 +323,10 @@ dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
 
    wsi_wl_display_add_wl_format(display, &display->dmabuf.formats, format);
 
+   if (modifier_hi == (DRM_FORMAT_MOD_INVALID >> 32) &&
+       modifier_lo == (DRM_FORMAT_MOD_INVALID & 0xffffffff))
+      return;
+
    mod = u_vector_add(modifiers);
    if (!mod)
       return;
@@ -353,8 +353,7 @@ registry_handle_global(void *data, struct wl_registry *registry,
       display->drm.wl_drm =
          wl_registry_bind(registry, name, &wl_drm_interface, 2);
       wl_drm_add_listener(display->drm.wl_drm, &drm_listener, display);
-   } else if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0 && version >= 3 &&
-              display->wsi_wl->wsi->supports_modifiers) {
+   } else if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0 && version >= 3) {
       display->dmabuf.wl_dmabuf =
          wl_registry_bind(registry, name, &zwp_linux_dmabuf_v1_interface, 3);
       zwp_linux_dmabuf_v1_add_listener(display->dmabuf.wl_dmabuf,
@@ -461,12 +460,13 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl,
       }
    }
 
-   /* We need prime support for wl_drm */
-   if (display->drm.wl_drm &&
+   /* Prefer the linux-dmabuf protocol if available */
+   if (display->dmabuf.wl_dmabuf) {
+      display->formats = &display->dmabuf.formats;
+   } else if (display->drm.wl_drm &&
        (display->drm.capabilities & WL_DRM_CAPABILITY_PRIME)) {
+      /* We need prime support for wl_drm */
       display->formats = &display->drm.formats;
-   } else if (display->dmabuf.wl_dmabuf) {
-      display->formats = &display->dmabuf.formats;
    }
 
    if (!display->formats) {
@@ -760,9 +760,6 @@ struct wsi_wl_swapchain {
 
    struct wl_surface *                          surface;
 
-   /* non-NULL when wl_drm should be used for wl_buffer creation; otherwise,
-    * zwp_linux_dmabuf_v1 should be used.
-    */
    struct wl_drm *                              drm_wrapper;
 
    struct wl_callback *                         frame;
@@ -956,11 +953,7 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain,
    if (result != VK_SUCCESS)
       return result;
 
-   if (!chain->drm_wrapper) {
-      /* Only request modifiers if we have dmabuf, else it must be implicit. */
-      assert(display->dmabuf.wl_dmabuf);
-      assert(image->base.drm_modifier != DRM_FORMAT_MOD_INVALID);
-
+   if (display->dmabuf.wl_dmabuf) {
       struct zwp_linux_buffer_params_v1 *params =
          zwp_linux_dmabuf_v1_create_params(display->dmabuf.wl_dmabuf);
       wl_proxy_set_queue((struct wl_proxy *) params, chain->display->queue);
@@ -1144,13 +1137,7 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
       }
    }
 
-   /* When there are explicit DRM format modifiers, we must use
-    * zwp_linux_dmabuf_v1 for wl_buffer creation.  Otherwise, we must use
-    * wl_drm.
-    */
-   if (!chain->num_drm_modifiers) {
-      assert(chain->display->drm.wl_drm);
-
+   if (chain->display->drm.wl_drm) {
       chain->drm_wrapper =
          wl_proxy_create_wrapper(chain->display->drm.wl_drm);
       if (!chain->drm_wrapper) {



More information about the mesa-commit mailing list