[Mesa-dev] [PATCH v2 6/6] vulkan/wsi/wayland: Use vk and wl_drm format descriptions to automate format matching

alexandros.frantzis at collabora.com alexandros.frantzis at collabora.com
Wed Jul 12 10:16:06 UTC 2017


From: Alexandros Frantzis <alexandros.frantzis at collabora.com>

Use the descriptions of Vulkan and wl_drm formats, as provided by the
related utilities, to automate finding Vulkan formats compatible with
wl_drm formats and vice versa.
---
 src/vulkan/wsi/wsi_common_wayland.c | 188 +++++++++++++++++++-----------------
 1 file changed, 102 insertions(+), 86 deletions(-)

diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c
index dd283a1211..118d01efa1 100644
--- a/src/vulkan/wsi/wsi_common_wayland.c
+++ b/src/vulkan/wsi/wsi_common_wayland.c
@@ -32,6 +32,8 @@
 #include <pthread.h>
 
 #include "vk_util.h"
+#include "vk_format.h"
+#include "wl_drm_format.h"
 #include "wsi_common_wayland.h"
 #include "wayland-drm-client-protocol.h"
 
@@ -101,48 +103,97 @@ drm_handle_device(void *data, struct wl_drm *drm, const char *name)
    fprintf(stderr, "wl_drm.device(%s)\n", name);
 }
 
+static bool
+are_blocks_compatible(const struct vk_format_block *block1,
+                      const struct vk_format_block *block2)
+{
+   return block1->width == block2->width &&
+          block1->height == block2->height &&
+          block1->bits == block2->bits;
+}
+
+static bool
+are_channels_compatible(const struct vk_format_channel_description *desc1,
+                        const struct vk_format_channel_description *desc2)
+{
+   /* If either channel is ignored, then it is enough to check whether the
+    * channel sizes and shifts match.
+    */
+   if (desc1->type == VK_FORMAT_TYPE_VOID ||
+       desc2->type == VK_FORMAT_TYPE_VOID) {
+      return desc1->size == desc2->size &&
+             desc1->shift == desc2->shift;
+   }
+
+   return desc1->type == desc2->type &&
+          desc1->normalized == desc2->normalized &&
+          desc1->pure_integer == desc2->pure_integer &&
+          desc1->scaled == desc2->scaled &&
+          desc1->size == desc2->size &&
+          desc1->shift == desc2->shift;
+}
+
+static bool
+are_colorspaces_compatible(enum vk_format_colorspace cs1,
+                           enum vk_format_colorspace cs2)
+{
+   /* We treat RGB and SRGB as compatible */
+   return cs1 == cs2 ||
+          (cs1 == VK_FORMAT_COLORSPACE_RGB && cs2 == VK_FORMAT_COLORSPACE_SRGB) ||
+          (cs1 == VK_FORMAT_COLORSPACE_SRGB && cs2 == VK_FORMAT_COLORSPACE_RGB);
+}
+
+static bool
+are_alpha_swizzles_compatible(unsigned char swizzle1,
+                              unsigned char swizzle2)
+{
+   /* If either alpha swizzle is 1, we match to allow mappings between formats
+    * with ignored (e.g. XRGB) and proper (e.g., ARGB) alpha channels.
+    */
+   return swizzle1 == swizzle2 ||
+          swizzle1 == VK_SWIZZLE_1 ||
+          swizzle2 == VK_SWIZZLE_1;
+}
+
+static bool
+are_formats_compatible(const struct vk_format_description *vformat,
+                       const struct wl_drm_format_description *wformat)
+{
+   return vformat->layout == wformat->layout &&
+          are_blocks_compatible(&vformat->block, &wformat->block) &&
+          vformat->nr_channels == wformat->nr_channels &&
+          are_channels_compatible(&vformat->channel[0], &wformat->channel[0]) &&
+          are_channels_compatible(&vformat->channel[1], &wformat->channel[1]) &&
+          are_channels_compatible(&vformat->channel[2], &wformat->channel[2]) &&
+          are_channels_compatible(&vformat->channel[3], &wformat->channel[3]) &&
+          vformat->swizzle[0] == wformat->swizzle[0] &&
+          vformat->swizzle[1] == wformat->swizzle[1] &&
+          vformat->swizzle[2] == wformat->swizzle[2] &&
+          are_alpha_swizzles_compatible(vformat->swizzle[3], wformat->swizzle[3]) &&
+          are_colorspaces_compatible(vformat->colorspace, wformat->colorspace);
+}
+
 static uint32_t
 wl_drm_format_for_vk_format(VkFormat vk_format, bool alpha)
 {
-   switch (vk_format) {
-   /* TODO: Figure out what all the formats mean and make this table
-    * correct.
-    */
-#if 0
-   case VK_FORMAT_R4G4B4A4_UNORM:
-      return alpha ? WL_DRM_FORMAT_ABGR4444 : WL_DRM_FORMAT_XBGR4444;
-   case VK_FORMAT_R5G6B5_UNORM:
-      return WL_DRM_FORMAT_BGR565;
-   case VK_FORMAT_R5G5B5A1_UNORM:
-      return alpha ? WL_DRM_FORMAT_ABGR1555 : WL_DRM_FORMAT_XBGR1555;
-   case VK_FORMAT_R8G8B8_UNORM:
-      return WL_DRM_FORMAT_XBGR8888;
-   case VK_FORMAT_R8G8B8A8_UNORM:
-      return alpha ? WL_DRM_FORMAT_ABGR8888 : WL_DRM_FORMAT_XBGR8888;
-   case VK_FORMAT_R10G10B10A2_UNORM:
-      return alpha ? WL_DRM_FORMAT_ABGR2101010 : WL_DRM_FORMAT_XBGR2101010;
-   case VK_FORMAT_B4G4R4A4_UNORM:
-      return alpha ? WL_DRM_FORMAT_ARGB4444 : WL_DRM_FORMAT_XRGB4444;
-   case VK_FORMAT_B5G6R5_UNORM:
-      return WL_DRM_FORMAT_RGB565;
-   case VK_FORMAT_B5G5R5A1_UNORM:
-      return alpha ? WL_DRM_FORMAT_XRGB1555 : WL_DRM_FORMAT_XRGB1555;
-#endif
-   case VK_FORMAT_B8G8R8_UNORM:
-   case VK_FORMAT_B8G8R8_SRGB:
-      return WL_DRM_FORMAT_BGRX8888;
-   case VK_FORMAT_B8G8R8A8_UNORM:
-   case VK_FORMAT_B8G8R8A8_SRGB:
-      return alpha ? WL_DRM_FORMAT_ARGB8888 : WL_DRM_FORMAT_XRGB8888;
-#if 0
-   case VK_FORMAT_B10G10R10A2_UNORM:
-      return alpha ? WL_DRM_FORMAT_ARGB2101010 : WL_DRM_FORMAT_XRGB2101010;
-#endif
-
-   default:
-      assert(!"Unsupported Vulkan format");
+   const struct vk_format_description *vformat =
+      vk_format_description(vk_format);
+
+   const struct wl_drm_format_description **wformat =
+      wl_drm_format_description_table;
+
+   if (!vformat)
       return 0;
+
+   while (*wformat != NULL) {
+      if (are_formats_compatible(vformat, *wformat) &&
+          wl_drm_format_has_alpha(*wformat) == alpha) {
+         return (*wformat)->format;
+      }
+      wformat++;
    }
+
+   return 0;
 }
 
 static void
@@ -150,55 +201,20 @@ drm_handle_format(void *data, struct wl_drm *drm, uint32_t wl_format)
 {
    struct wsi_wl_display *display = data;
 
-   switch (wl_format) {
-#if 0
-   case WL_DRM_FORMAT_ABGR4444:
-   case WL_DRM_FORMAT_XBGR4444:
-      wsi_wl_display_add_vk_format(display, VK_FORMAT_R4G4B4A4_UNORM);
-      break;
-   case WL_DRM_FORMAT_BGR565:
-      wsi_wl_display_add_vk_format(display, VK_FORMAT_R5G6B5_UNORM);
-      break;
-   case WL_DRM_FORMAT_ABGR1555:
-   case WL_DRM_FORMAT_XBGR1555:
-      wsi_wl_display_add_vk_format(display, VK_FORMAT_R5G5B5A1_UNORM);
-      break;
-   case WL_DRM_FORMAT_XBGR8888:
-      wsi_wl_display_add_vk_format(display, VK_FORMAT_R8G8B8_UNORM);
-      /* fallthrough */
-   case WL_DRM_FORMAT_ABGR8888:
-      wsi_wl_display_add_vk_format(display, VK_FORMAT_R8G8B8A8_UNORM);
-      break;
-   case WL_DRM_FORMAT_ABGR2101010:
-   case WL_DRM_FORMAT_XBGR2101010:
-      wsi_wl_display_add_vk_format(display, VK_FORMAT_R10G10B10A2_UNORM);
-      break;
-   case WL_DRM_FORMAT_ARGB4444:
-   case WL_DRM_FORMAT_XRGB4444:
-      wsi_wl_display_add_vk_format(display, VK_FORMAT_B4G4R4A4_UNORM);
-      break;
-   case WL_DRM_FORMAT_RGB565:
-      wsi_wl_display_add_vk_format(display, VK_FORMAT_B5G6R5_UNORM);
-      break;
-   case WL_DRM_FORMAT_ARGB1555:
-   case WL_DRM_FORMAT_XRGB1555:
-      wsi_wl_display_add_vk_format(display, VK_FORMAT_B5G5R5A1_UNORM);
-      break;
-#endif
-   case WL_DRM_FORMAT_XRGB8888:
-      wsi_wl_display_add_vk_format(display, VK_FORMAT_B8G8R8_SRGB);
-      wsi_wl_display_add_vk_format(display, VK_FORMAT_B8G8R8_UNORM);
-      /* fallthrough */
-   case WL_DRM_FORMAT_ARGB8888:
-      wsi_wl_display_add_vk_format(display, VK_FORMAT_B8G8R8A8_SRGB);
-      wsi_wl_display_add_vk_format(display, VK_FORMAT_B8G8R8A8_UNORM);
-      break;
-#if 0
-   case WL_DRM_FORMAT_ARGB2101010:
-   case WL_DRM_FORMAT_XRGB2101010:
-      wsi_wl_display_add_vk_format(display, VK_FORMAT_B10G10R10A2_UNORM);
-      break;
-#endif
+   const struct wl_drm_format_description *wformat =
+      wl_drm_format_description(wl_format);
+
+   const struct vk_format_description **vformat =
+      vk_format_description_table;
+
+   if (!wformat)
+       return;
+
+   while (*vformat != NULL) {
+      if (are_formats_compatible(*vformat, wformat)) {
+         wsi_wl_display_add_vk_format(display, (*vformat)->format);
+      }
+      vformat++;
    }
 }
 
-- 
2.13.2



More information about the mesa-dev mailing list