From e5f5d7fa66db5fd822172894a8ae8fb65b8812ac Mon Sep 17 00:00:00 2001 From: Taekyun Kim Date: Thu, 9 Jun 2016 21:27:06 +0900 Subject: [PATCH] wsi: Support for various pixel formats Change-Id: If2250033603c4185833b5405a62d2c2929afee59 --- src/wsi/surface.c | 61 +++++++++++++++++++++++++++++++++++++++------ src/wsi/swapchain.c | 71 +++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 115 insertions(+), 17 deletions(-) diff --git a/src/wsi/surface.c b/src/wsi/surface.c index 9039b40..4a457e0 100644 --- a/src/wsi/surface.c +++ b/src/wsi/surface.c @@ -94,9 +94,37 @@ vk_GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice pdev, return VK_SUCCESS; } -static VkSurfaceFormatKHR surface_formats[] = { - { VK_FORMAT_R8G8B8_SRGB, VK_COLORSPACE_SRGB_NONLINEAR_KHR }, - { VK_FORMAT_R8G8B8A8_SRGB, VK_COLORSPACE_SRGB_NONLINEAR_KHR } +#define FORMAT_ENTRY(tbm, vk, cs) { TBM_FORMAT_##tbm, { VK_FORMAT_##vk, VK_COLORSPACE_##cs }} + +static const struct { + tbm_format tbm_format; + VkSurfaceFormatKHR surface_format; +} supported_formats[] = { + /* TODO: Workaround to make tri sample run correctly. */ + FORMAT_ENTRY(RGBA8888, B8G8R8A8_UNORM, SRGB_NONLINEAR_KHR), + + /* TODO: Correct map between tbm formats and vulkan formats. */ + FORMAT_ENTRY(XRGB8888, B8G8R8A8_UNORM, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(ARGB8888, B8G8R8A8_UNORM, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(XBGR8888, A8B8G8R8_UNORM_PACK32, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(ABGR8888, A8B8G8R8_UNORM_PACK32, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(RGB888, B8G8R8_UNORM, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(BGR888, R8G8B8_UNORM, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(RGB565, R5G6B5_UNORM_PACK16, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(BGR565, B5G6R5_UNORM_PACK16, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(RGBX4444, R4G4B4A4_UNORM_PACK16, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(RGBA4444, R4G4B4A4_UNORM_PACK16, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(BGRX4444, B4G4R4A4_UNORM_PACK16, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(BGRA4444, B4G4R4A4_UNORM_PACK16, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(ARGB1555, A1R5G5B5_UNORM_PACK16, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(XRGB1555, A1R5G5B5_UNORM_PACK16, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(RGBX5551, R5G5B5A1_UNORM_PACK16, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(RGBA5551, R5G5B5A1_UNORM_PACK16, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(BGRX5551, B5G5R5A1_UNORM_PACK16, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(BGRA5551, B5G5R5A1_UNORM_PACK16, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(XRGB2101010, A2R10G10B10_UNORM_PACK32, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(XBGR2101010, A2B10G10R10_UNORM_PACK32, SRGB_NONLINEAR_KHR), + FORMAT_ENTRY(ABGR2101010, A2B10G10R10_UNORM_PACK32, SRGB_NONLINEAR_KHR), }; VKAPI_ATTR VkResult VKAPI_CALL @@ -105,16 +133,35 @@ vk_GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice pdev, uint32_t *format_count, VkSurfaceFormatKHR *formats) { - /* TODO: */ + uint32_t tbm_format_count; + tbm_format *tbm_formats; + uint32_t surface_format_count = 0; + VkSurfaceFormatKHR surface_formats[ARRAY_LENGTH(supported_formats)]; + uint32_t i, j; + + if (tbm_surface_query_formats(&tbm_formats, &tbm_format_count) != TBM_SURFACE_ERROR_NONE) + return VK_ERROR_DEVICE_LOST; + + for (i = 0; i < ARRAY_LENGTH(supported_formats); i++) { + for (j = 0; j < tbm_format_count; j++) { + if (tbm_formats[j] == supported_formats[i].tbm_format) { + /* TODO Check if ICD support the format. */ + surface_formats[surface_format_count++] = supported_formats[i].surface_format; + break; + } + } + } + + free(tbm_formats); if (formats) { - *format_count = MIN(*format_count, ARRAY_LENGTH(surface_formats)); + *format_count = MIN(*format_count, surface_format_count); memcpy(formats, &surface_formats[0], sizeof(VkSurfaceFormatKHR) * (*format_count)); - if (*format_count < ARRAY_LENGTH(surface_formats)) + if (*format_count < surface_format_count) return VK_INCOMPLETE; } else { - *format_count = ARRAY_LENGTH(surface_formats); + *format_count = surface_format_count; } return VK_SUCCESS; diff --git a/src/wsi/swapchain.c b/src/wsi/swapchain.c index e5c4b6e..e777e64 100644 --- a/src/wsi/swapchain.c +++ b/src/wsi/swapchain.c @@ -25,6 +25,65 @@ #include "wsi.h" #include +#define TBM_FORMAT_0 0 + +#define RETURN_FORMAT(comp, opaque, pre, post, inherit) \ + do { \ + if (comp == VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) \ + return TBM_FORMAT_##opaque; \ + else if (comp == VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR) \ + return TBM_FORMAT_##pre; \ + else if (comp == VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR) \ + return TBM_FORMAT_##post; \ + else if (comp == VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) \ + return TBM_FORMAT_##inherit; \ + else \ + return 0; \ + } while (0) + +static inline tbm_format +get_tbm_format(VkFormat format, VkCompositeAlphaFlagBitsKHR comp) +{ + switch (format) { + /* 4 4 4 4 */ + case VK_FORMAT_R4G4B4A4_UNORM_PACK16: + RETURN_FORMAT(comp, RGBX4444, RGBA4444, 0, RGBA4444); + case VK_FORMAT_B4G4R4A4_UNORM_PACK16: + RETURN_FORMAT(comp, BGRX4444, BGRA4444, 0, BGRA4444); + /* 5 6 5 */ + case VK_FORMAT_R5G6B5_UNORM_PACK16: + RETURN_FORMAT(comp, RGB565, RGB565, RGB565, RGB565); + case VK_FORMAT_B5G6R5_UNORM_PACK16: + RETURN_FORMAT(comp, BGR565, BGR565, BGR565, BGR565); + /* 5 5 5 1 */ + case VK_FORMAT_R5G5B5A1_UNORM_PACK16: + RETURN_FORMAT(comp, RGBX5551, RGBA5551, 0, RGBA5551); + case VK_FORMAT_B5G5R5A1_UNORM_PACK16: + RETURN_FORMAT(comp, BGRX5551, BGRA5551, 0, BGRA5551); + case VK_FORMAT_A1R5G5B5_UNORM_PACK16: + RETURN_FORMAT(comp, XRGB1555, ARGB1555, 0, ARGB1555); + /* 8 8 8 */ + case VK_FORMAT_R8G8B8_UNORM: + RETURN_FORMAT(comp, BGR888, BGR888, BGR888, BGR888); + case VK_FORMAT_B8G8R8_UNORM: + RETURN_FORMAT(comp, RGB888, RGB888, RGB888, RGB888); + /* 8 8 8 8 */ + case VK_FORMAT_B8G8R8A8_UNORM: + RETURN_FORMAT(comp, XRGB8888, ARGB8888, 0, ARGB8888); + case VK_FORMAT_A8B8G8R8_UNORM_PACK32: + RETURN_FORMAT(comp, XBGR8888, ABGR8888, 0, ABGR8888); + /* 2 10 10 10 */ + case VK_FORMAT_A2R10G10B10_UNORM_PACK32: + RETURN_FORMAT(comp, XRGB2101010, ARGB2101010, 0, ARGB2101010); + case VK_FORMAT_A2B10G10R10_UNORM_PACK32: + RETURN_FORMAT(comp, XBGR2101010, ABGR2101010, 0, ABGR2101010); + default: + break; + } + + return 0; +} + VKAPI_ATTR VkResult VKAPI_CALL vk_CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *info, @@ -41,16 +100,8 @@ vk_CreateSwapchainKHR(VkDevice device, VK_ASSERT(surface->base.platform == VK_ICD_WSI_PLATFORM_WAYLAND); - switch (info->imageFormat) { - case VK_FORMAT_R8G8B8_SRGB: - format = TBM_FORMAT_XRGB8888; - break; - case VK_FORMAT_R8G8B8A8_SRGB: - format = TBM_FORMAT_ARGB8888; - break; - default: - return VK_ERROR_SURFACE_LOST_KHR; - } + format = get_tbm_format(info->imageFormat, info->compositeAlpha); + VK_CHECK(format, return VK_ERROR_SURFACE_LOST_KHR, "Not supported image format.\n"); allocator = vk_get_allocator(device, allocator); -- 2.7.4