From fbe4d7ccf49ccfeed08531680232dcaa28a66479 Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Thu, 13 Jan 2022 09:00:10 +0100 Subject: [PATCH] v3dv: implement VK_EXT_4444_formats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Because these formats are introduced trough an extension, their enum values are exceedingly large and we cannot use them to index directly into the format table we had for core formats. Instead, we put these in a separate table and we always use the VK_ENUM_OFFSET helper to index into these tables. Reviewed-by: Alejandro PiƱeiro Part-of: --- docs/features.txt | 2 +- src/broadcom/vulkan/v3dv_device.c | 9 +++++++ src/broadcom/vulkan/v3dvx_formats.c | 37 +++++++++++++++++++++++++++-- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/docs/features.txt b/docs/features.txt index 6e519e6c393..93d1f90f63d 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -510,7 +510,7 @@ Khronos extensions that are not part of any Vulkan version: VK_KHR_xcb_surface DONE (anv, lvp, radv, tu, v3dv, vn) VK_KHR_xlib_surface DONE (anv, lvp, radv, tu, v3dv, vn) VK_KHR_zero_initialize_workgroup_memory DONE (anv, radv) - VK_EXT_4444_formats DONE (anv, lvp, radv, tu) + VK_EXT_4444_formats DONE (anv, lvp, radv, tu, v3dv) VK_EXT_buffer_device_address DONE (radv) VK_EXT_calibrated_timestamps DONE (anv, lvp, radv) VK_EXT_color_write_enable DONE (anv, lvp, radv, v3dv) diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c index b02a232b155..4d07ffe904c 100644 --- a/src/broadcom/vulkan/v3dv_device.c +++ b/src/broadcom/vulkan/v3dv_device.c @@ -144,6 +144,7 @@ get_device_extensions(const struct v3dv_physical_device *device, .KHR_incremental_present = true, #endif .KHR_variable_pointers = true, + .EXT_4444_formats = true, .EXT_color_write_enable = true, .EXT_custom_border_color = true, .EXT_external_memory_dma_buf = true, @@ -1093,6 +1094,14 @@ v3dv_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice, vk_foreach_struct(ext, pFeatures->pNext) { switch (ext->sType) { + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT: { + VkPhysicalDevice4444FormatsFeaturesEXT *features = + (VkPhysicalDevice4444FormatsFeaturesEXT *)ext; + features->formatA4R4G4B4 = true; + features->formatA4B4G4R4 = true; + break; + } + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: { VkPhysicalDeviceCustomBorderColorFeaturesEXT *features = (VkPhysicalDeviceCustomBorderColorFeaturesEXT *)ext; diff --git a/src/broadcom/vulkan/v3dvx_formats.c b/src/broadcom/vulkan/v3dvx_formats.c index 4b75da7b537..85505b66f61 100644 --- a/src/broadcom/vulkan/v3dvx_formats.c +++ b/src/broadcom/vulkan/v3dvx_formats.c @@ -26,6 +26,7 @@ #include "broadcom/cle/v3dx_pack.h" #include "util/format/u_format.h" +#include "vulkan/util/vk_util.h" #define SWIZ(x,y,z,w) { \ PIPE_SWIZZLE_##x, \ @@ -35,7 +36,7 @@ } #define FORMAT(vk, rt, tex, swiz, return_size, supports_filtering) \ - [VK_FORMAT_##vk] = { \ + [VK_ENUM_OFFSET(VK_FORMAT_##vk)] = { \ true, \ V3D_OUTPUT_IMAGE_FORMAT_##rt, \ TEXTURE_DATA_FORMAT_##tex, \ @@ -57,6 +58,7 @@ #define SWIZ_XXXX SWIZ(X, X, X, X) #define SWIZ_000X SWIZ(0, 0, 0, X) #define SWIZ_WXYZ SWIZ(W, X, Y, Z) +#define SWIZ_WZYX SWIZ(W, Z, Y, X) /* FIXME: expand format table to describe whether the format is supported * for buffer surfaces (texel buffers, vertex buffers, etc). @@ -196,13 +198,44 @@ static const struct v3dv_format format_table[] = { FORMAT(ASTC_12x12_SRGB_BLOCK, NO, ASTC_12X12, SWIZ_XYZW, 16, true), }; +/** + * Vulkan layout for 4444 formats is defined like this: + * + * Vulkan ABGR4: (LSB) R | G | B | A (MSB) + * Vulkan ARGB4: (LSB) B | G | R | A (MSB) + * + * We map this to the V3D RGB4 texture format, which really, is ABGR4 with + * R in the MSB, so: + * + * V3D ABGR4 : (LSB) A | B | G | R (MSB) + * + * Which is reversed from Vulkan's ABGR4 layout. So in order to match Vulkan + * semantics we need to apply the following swizzles: + * + * ABGR4: WZYX (reverse) + * ARGB4: YZWX (reverse + swap R/B) + */ +static const struct v3dv_format format_table_4444[] = { + FORMAT(A4B4G4R4_UNORM_PACK16_EXT, ABGR4444, RGBA4, SWIZ_WZYX, 16, true), /* Reverse */ + FORMAT(A4R4G4B4_UNORM_PACK16_EXT, ABGR4444, RGBA4, SWIZ_YZWX, 16, true), /* Reverse + RB swap */ +}; + const struct v3dv_format * v3dX(get_format)(VkFormat format) { + /* Core formats */ if (format < ARRAY_SIZE(format_table) && format_table[format].supported) return &format_table[format]; - else + + switch (format) { + /* VK_EXT_4444_formats */ + case VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT: + case VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT: + return &format_table_4444[VK_ENUM_OFFSET(format)]; + + default: return NULL; + } } void