Mesa (main): vulkan/wsi/wayland: generalize modifier handling

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Aug 16 08:56:09 UTC 2021


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

Author: Simon Ser <contact at emersion.fr>
Date:   Wed Jul 28 17:44:14 2021 -0300

vulkan/wsi/wayland: generalize modifier handling

Instead of having hard-coded lists of modifiers for argb8888 and
xrgb8888, store a list of modifiers alongside each VkFormat. To
achieve this goal, introduce a new struct wsi_wl_format that holds
both a VkFormat and a modifier list, and use it for the items in
the formats list.

This commit unlocks non-{A,X}RGB8888 formats, which were previously
always disabled for linux-dmabuf.

Signed-off-by: Simon Ser <contact at emersion.fr>
Signed-off-by: Leandro Ribeiro <leandro.ribeiro at collabora.com>
Acked-by: Daniel Stone <daniels at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12117>

---

 src/vulkan/wsi/wsi_common_wayland.c | 220 +++++++++++++++++++-----------------
 1 file changed, 116 insertions(+), 104 deletions(-)

diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c
index 9000c70b4d2..3ab7b5f4624 100644
--- a/src/vulkan/wsi/wsi_common_wayland.c
+++ b/src/vulkan/wsi/wsi_common_wayland.c
@@ -48,6 +48,11 @@
 
 struct wsi_wayland;
 
+struct wsi_wl_format {
+   VkFormat vk_format;
+   struct u_vector modifiers;
+};
+
 struct wsi_wl_display {
    /* The real wl_display */
    struct wl_display *                          wl_display;
@@ -62,10 +67,6 @@ struct wsi_wl_display {
 
    /* Formats populated by zwp_linux_dmabuf_v1 or wl_shm interfaces */
    struct u_vector                              formats;
-   struct {
-      struct u_vector                           argb8888;
-      struct u_vector                           xrgb8888;
-   } modifiers;
 
    /* Only used for displays created by wsi_wl_display_create */
    uint32_t                                     refcount;
@@ -82,15 +83,15 @@ struct wsi_wayland {
    VkPhysicalDevice physical_device;
 };
 
-static void
+static struct wsi_wl_format *
 wsi_wl_display_add_vk_format(struct wsi_wl_display *display,
                              struct u_vector *formats, VkFormat format)
 {
    /* Don't add a format that's already in the list */
-   VkFormat *f;
+   struct wsi_wl_format *f;
    u_vector_foreach(f, formats)
-      if (*f == format)
-         return;
+      if (f->vk_format == format)
+         return f;
 
    /* Don't add formats that aren't renderable. */
    VkFormatProperties props;
@@ -98,30 +99,61 @@ wsi_wl_display_add_vk_format(struct wsi_wl_display *display,
    display->wsi_wl->wsi->GetPhysicalDeviceFormatProperties(display->wsi_wl->physical_device,
                                                            format, &props);
    if (!(props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
-      return;
+      return NULL;
+
+   struct u_vector modifiers;
+   if (!u_vector_init(&modifiers, sizeof(uint64_t), 32))
+      return NULL;
 
    f = u_vector_add(formats);
-   if (f)
-      *f = format;
+   if (!f) {
+      u_vector_finish(&modifiers);
+      return NULL;
+   }
+
+   f->vk_format = format;
+   f->modifiers = modifiers;
+
+   return f;
 }
 
 static void
-wsi_wl_display_add_drm_format(struct wsi_wl_display *display,
-                              struct u_vector *formats, uint32_t drm_format)
+wsi_wl_format_add_modifier(struct wsi_wl_format *format, uint64_t modifier)
 {
+   uint64_t *mod;
+
+   if (modifier == DRM_FORMAT_MOD_INVALID)
+      return;
+
+   u_vector_foreach(mod, &format->modifiers)
+      if (*mod == modifier)
+         return;
+
+   mod = u_vector_add(&format->modifiers);
+   if (mod)
+      *mod = modifier;
+}
+
+static void
+wsi_wl_display_add_drm_format_modifier(struct wsi_wl_display *display,
+                                       struct u_vector *formats,
+                                       uint32_t drm_format, uint64_t modifier)
+{
+   struct wsi_wl_format *format = NULL, *srgb_format = NULL;
+
    switch (drm_format) {
 #if 0
    /* TODO: These are only available when VK_EXT_4444_formats is enabled, so
     * we probably need to make their use conditional on this extension. */
    case DRM_FORMAT_ARGB4444:
    case DRM_FORMAT_XRGB4444:
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT);
+      format = wsi_wl_display_add_vk_format(display, formats,
+                                            VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT);
       break;
    case DRM_FORMAT_ABGR4444:
    case DRM_FORMAT_XBGR4444:
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT);
+      format = wsi_wl_display_add_vk_format(display, formats,
+                                            VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT);
       break;
 #endif
 
@@ -130,46 +162,46 @@ wsi_wl_display_add_drm_format(struct wsi_wl_display *display,
 #if MESA_LITTLE_ENDIAN
    case DRM_FORMAT_RGBA4444:
    case DRM_FORMAT_RGBX4444:
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_R4G4B4A4_UNORM_PACK16);
+      format = wsi_wl_display_add_vk_format(display, formats,
+                                            VK_FORMAT_R4G4B4A4_UNORM_PACK16);
       break;
    case DRM_FORMAT_BGRA4444:
    case DRM_FORMAT_BGRX4444:
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_B4G4R4A4_UNORM_PACK16);
+      format = wsi_wl_display_add_vk_format(display, formats,
+                                            VK_FORMAT_B4G4R4A4_UNORM_PACK16);
       break;
    case DRM_FORMAT_RGB565:
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_R5G6B5_UNORM_PACK16);
+      format = wsi_wl_display_add_vk_format(display, formats,
+                                            VK_FORMAT_R5G6B5_UNORM_PACK16);
       break;
    case DRM_FORMAT_BGR565:
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_B5G6R5_UNORM_PACK16);
+      format = wsi_wl_display_add_vk_format(display, formats,
+                                            VK_FORMAT_B5G6R5_UNORM_PACK16);
       break;
    case DRM_FORMAT_ARGB1555:
    case DRM_FORMAT_XRGB1555:
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_A1R5G5B5_UNORM_PACK16);
+      format = wsi_wl_display_add_vk_format(display, formats,
+                                            VK_FORMAT_A1R5G5B5_UNORM_PACK16);
       break;
    case DRM_FORMAT_RGBA5551:
    case DRM_FORMAT_RGBX5551:
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_R5G5B5A1_UNORM_PACK16);
+      format = wsi_wl_display_add_vk_format(display, formats,
+                                            VK_FORMAT_R5G5B5A1_UNORM_PACK16);
       break;
    case DRM_FORMAT_BGRA5551:
    case DRM_FORMAT_BGRX5551:
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_B5G5R5A1_UNORM_PACK16);
+      format = wsi_wl_display_add_vk_format(display, formats,
+                                            VK_FORMAT_B5G5R5A1_UNORM_PACK16);
       break;
    case DRM_FORMAT_ARGB2101010:
    case DRM_FORMAT_XRGB2101010:
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_A2R10G10B10_UNORM_PACK32);
+      format = wsi_wl_display_add_vk_format(display, formats,
+                                            VK_FORMAT_A2R10G10B10_UNORM_PACK32);
       break;
    case DRM_FORMAT_ABGR2101010:
    case DRM_FORMAT_XBGR2101010:
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_A2B10G10R10_UNORM_PACK32);
+      format = wsi_wl_display_add_vk_format(display, formats,
+                                            VK_FORMAT_A2B10G10R10_UNORM_PACK32);
       break;
 #endif
 
@@ -184,30 +216,35 @@ wsi_wl_display_add_drm_format(struct wsi_wl_display *display,
     * From Wayland's perspective nothing changes, the difference is just how
     * Vulkan interprets the pixel data. */
    case DRM_FORMAT_XBGR8888:
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_R8G8B8_SRGB);
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_R8G8B8_UNORM);
+      srgb_format = wsi_wl_display_add_vk_format(display, formats,
+                                                 VK_FORMAT_R8G8B8_SRGB);
+      format = wsi_wl_display_add_vk_format(display, formats,
+                                            VK_FORMAT_R8G8B8_UNORM);
       FALLTHROUGH;
    case DRM_FORMAT_ABGR8888:
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_R8G8B8A8_SRGB);
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_R8G8B8A8_UNORM);
+      srgb_format = wsi_wl_display_add_vk_format(display, formats,
+                                                 VK_FORMAT_R8G8B8A8_SRGB);
+      format = wsi_wl_display_add_vk_format(display, formats,
+                                            VK_FORMAT_R8G8B8A8_UNORM);
       break;
    case DRM_FORMAT_XRGB8888:
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_B8G8R8_SRGB);
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_B8G8R8_UNORM);
+      srgb_format = wsi_wl_display_add_vk_format(display, formats,
+                                                 VK_FORMAT_B8G8R8_SRGB);
+      format = wsi_wl_display_add_vk_format(display, formats,
+                                            VK_FORMAT_B8G8R8_UNORM);
       FALLTHROUGH;
    case DRM_FORMAT_ARGB8888:
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_B8G8R8A8_SRGB);
-      wsi_wl_display_add_vk_format(display, formats,
-                                   VK_FORMAT_B8G8R8A8_UNORM);
+      srgb_format = wsi_wl_display_add_vk_format(display, formats,
+                                                 VK_FORMAT_B8G8R8A8_SRGB);
+      format = wsi_wl_display_add_vk_format(display, formats,
+                                            VK_FORMAT_B8G8R8A8_UNORM);
       break;
    }
+
+   if (format)
+      wsi_wl_format_add_modifier(format, modifier);
+   if (srgb_format)
+      wsi_wl_format_add_modifier(srgb_format, modifier);
 }
 
 static void
@@ -323,32 +360,11 @@ dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
                        uint32_t modifier_lo)
 {
    struct wsi_wl_display *display = data;
-   struct u_vector *modifiers;
-   uint64_t *mod = NULL;
+   uint64_t modifier;
 
-   switch (format) {
-   case DRM_FORMAT_ARGB8888:
-      modifiers = &display->modifiers.argb8888;
-      break;
-   case DRM_FORMAT_XRGB8888:
-      modifiers = &display->modifiers.xrgb8888;
-      break;
-   default:
-      return; /* Unsupported format */
-   }
-
-   wsi_wl_display_add_drm_format(display, &display->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;
-
-   *mod = (uint64_t) modifier_hi << 32;
-   *mod |= (uint64_t) (modifier_lo & 0xffffffff);
+   modifier = ((uint64_t) modifier_hi << 32) | modifier_lo;
+   wsi_wl_display_add_drm_format_modifier(display, &display->formats,
+                                          format, modifier);
 }
 
 static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = {
@@ -405,9 +421,10 @@ wsi_wl_display_finish(struct wsi_wl_display *display)
 {
    assert(display->refcount == 0);
 
+   struct wsi_wl_format *f;
+   u_vector_foreach(f, &display->formats)
+      u_vector_finish(&f->modifiers);
    u_vector_finish(&display->formats);
-   u_vector_finish(&display->modifiers.argb8888);
-   u_vector_finish(&display->modifiers.xrgb8888);
    if (display->wl_shm)
       wl_shm_destroy(display->wl_shm);
    if (display->wl_dmabuf)
@@ -432,9 +449,8 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl,
    display->sw = sw;
 
    if (get_format_list) {
-      if (!u_vector_init(&display->formats, sizeof(VkFormat), 8) ||
-         !u_vector_init(&display->modifiers.argb8888, sizeof(uint64_t), 32) ||
-         !u_vector_init(&display->modifiers.xrgb8888, sizeof(uint64_t), 32)) {
+      if (!u_vector_init(&display->formats, sizeof(struct wsi_wl_format),
+                         8 * sizeof(struct wsi_wl_format))) {
          result = VK_ERROR_OUT_OF_HOST_MEMORY;
          goto fail;
       }
@@ -482,12 +498,13 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl,
       /* Find BGRA8_UNORM in the list and swap it to the first position if we
        * can find it.  Some apps get confused if SRGB is first in the list.
        */
-      VkFormat *first_fmt = u_vector_head(&display->formats);
-      VkFormat *iter_fmt;
+      struct wsi_wl_format *first_fmt = u_vector_head(&display->formats);
+      struct wsi_wl_format *iter_fmt, tmp_fmt;
       u_vector_foreach(iter_fmt, &display->formats) {
-         if (*iter_fmt == VK_FORMAT_B8G8R8A8_UNORM) {
+         if (iter_fmt->vk_format == VK_FORMAT_B8G8R8A8_UNORM) {
+            tmp_fmt = *iter_fmt;
             *iter_fmt = *first_fmt;
-            *first_fmt = VK_FORMAT_B8G8R8A8_UNORM;
+            *first_fmt = tmp_fmt;
             break;
          }
       }
@@ -670,10 +687,10 @@ wsi_wl_surface_get_formats(VkIcdSurfaceBase *icd_surface,
 
    VK_OUTARRAY_MAKE(out, pSurfaceFormats, pSurfaceFormatCount);
 
-   VkFormat *disp_fmt;
+   struct wsi_wl_format *disp_fmt;
    u_vector_foreach(disp_fmt, &display.formats) {
       vk_outarray_append(&out, out_fmt) {
-         out_fmt->format = *disp_fmt;
+         out_fmt->format = disp_fmt->vk_format;
          out_fmt->colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
       }
    }
@@ -701,10 +718,10 @@ wsi_wl_surface_get_formats2(VkIcdSurfaceBase *icd_surface,
 
    VK_OUTARRAY_MAKE(out, pSurfaceFormats, pSurfaceFormatCount);
 
-   VkFormat *disp_fmt;
+   struct wsi_wl_format *disp_fmt;
    u_vector_foreach(disp_fmt, &display.formats) {
       vk_outarray_append(&out, out_fmt) {
-         out_fmt->surfaceFormat.format = *disp_fmt;
+         out_fmt->surfaceFormat.format = disp_fmt->vk_format;
          out_fmt->surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
       }
    }
@@ -1177,22 +1194,17 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
     * support them.
     */
    if (chain->display->wl_dmabuf && chain->base.wsi->supports_modifiers) {
-      struct u_vector *modifiers;
-      switch (chain->drm_format) {
-      case DRM_FORMAT_ARGB8888:
-         modifiers = &chain->display->modifiers.argb8888;
-         break;
-      case DRM_FORMAT_XRGB8888:
-         modifiers = &chain->display->modifiers.xrgb8888;
-         break;
-      default:
-         modifiers = NULL;
-         break;
+      struct wsi_wl_format *f;
+      bool found = false;
+      u_vector_foreach(f, &chain->display->formats) {
+         if (f->vk_format == chain->vk_format) {
+            found = true;
+            break;
+         }
       }
-
-      if (modifiers) {
-         chain->drm_modifiers = u_vector_tail(modifiers);
-         chain->num_drm_modifiers = u_vector_length(modifiers);
+      if (found) {
+         chain->drm_modifiers = u_vector_tail(&f->modifiers);
+         chain->num_drm_modifiers = u_vector_length(&f->modifiers);
       }
    }
 



More information about the mesa-commit mailing list