[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