X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Famd%2Fvulkan%2Fradv_formats.c;h=1ac07b41a611acf473daad3c02e7f337686e9342;hb=de06dfa9ea05ab5d06efb20223a858eb42d02683;hp=b13adb9abdcb40b80fc4fe25b53eca88b75bc968;hpb=621b3410f5f88e2a3743bc025b100717cac26e63;p=mesa.git diff --git a/src/amd/vulkan/radv_formats.c b/src/amd/vulkan/radv_formats.c index b13adb9abdc..1ac07b41a61 100644 --- a/src/amd/vulkan/radv_formats.c +++ b/src/amd/vulkan/radv_formats.c @@ -26,7 +26,6 @@ #include "vk_format.h" #include "sid.h" -#include "r600d_common.h" #include "vk_util.h" @@ -322,10 +321,8 @@ uint32_t radv_translate_tex_dataformat(VkFormat format, return V_008F14_IMG_DATA_FORMAT_32; case 2: return V_008F14_IMG_DATA_FORMAT_32_32; -#if 0 /* Not supported for render targets */ case 3: return V_008F14_IMG_DATA_FORMAT_32_32_32; -#endif case 4: return V_008F14_IMG_DATA_FORMAT_32_32_32_32; } @@ -542,6 +539,35 @@ static bool radv_is_zs_format_supported(VkFormat format) return radv_translate_dbformat(format) != V_028040_Z_INVALID || format == VK_FORMAT_S8_UINT; } +static bool radv_is_filter_minmax_format_supported(VkFormat format) +{ + /* From the Vulkan spec 1.1.71: + * + * "The following formats must support the + * VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT feature with + * VK_IMAGE_TILING_OPTIMAL, if they support + * VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT." + */ + /* TODO: enable more formats. */ + switch (format) { + case VK_FORMAT_R8_UNORM: + case VK_FORMAT_R8_SNORM: + case VK_FORMAT_R16_UNORM: + case VK_FORMAT_R16_SNORM: + case VK_FORMAT_R16_SFLOAT: + case VK_FORMAT_R32_SFLOAT: + case VK_FORMAT_D16_UNORM: + case VK_FORMAT_X8_D24_UNORM_PACK32: + case VK_FORMAT_D32_SFLOAT: + case VK_FORMAT_D16_UNORM_S8_UINT: + case VK_FORMAT_D24_UNORM_S8_UINT: + case VK_FORMAT_D32_SFLOAT_S8_UINT: + return true; + default: + return false; + } +} + static void radv_physical_device_get_format_properties(struct radv_physical_device *physical_device, VkFormat format, @@ -578,6 +604,13 @@ radv_physical_device_get_format_properties(struct radv_physical_device *physical VK_FORMAT_FEATURE_BLIT_DST_BIT; tiled |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR | VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR; + + if (radv_is_filter_minmax_format_supported(format)) + tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT; + + /* GFX9 doesn't support linear depth surfaces */ + if (physical_device->rad_info.chip_class >= GFX9) + linear = 0; } } else { bool linear_sampling; @@ -586,6 +619,10 @@ radv_physical_device_get_format_properties(struct radv_physical_device *physical VK_FORMAT_FEATURE_BLIT_SRC_BIT; tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT; + + if (radv_is_filter_minmax_format_supported(format)) + tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT; + if (linear_sampling) { linear |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; @@ -599,13 +636,17 @@ radv_physical_device_get_format_properties(struct radv_physical_device *physical tiled |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT; } } - if (tiled && util_is_power_of_two(vk_format_get_blocksize(format)) && !scaled) { + if (tiled && !scaled) { tiled |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR | VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR; } + + /* Tiled formatting does not support NPOT pixel sizes */ + if (!util_is_power_of_two_or_zero(vk_format_get_blocksize(format))) + tiled = 0; } - if (linear && util_is_power_of_two(vk_format_get_blocksize(format)) && !scaled) { + if (linear && !scaled) { linear |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR | VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR; } @@ -616,6 +657,25 @@ radv_physical_device_get_format_properties(struct radv_physical_device *physical tiled |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT; } + switch(format) { + case VK_FORMAT_A2R10G10B10_SNORM_PACK32: + case VK_FORMAT_A2B10G10R10_SNORM_PACK32: + case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: + case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: + case VK_FORMAT_A2R10G10B10_SINT_PACK32: + case VK_FORMAT_A2B10G10R10_SINT_PACK32: + if (physical_device->rad_info.chip_class <= VI && + physical_device->rad_info.family != CHIP_STONEY) { + buffer &= ~(VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | + VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT); + linear = 0; + tiled = 0; + } + break; + default: + break; + } + out_properties->linearTilingFeatures = linear; out_properties->optimalTilingFeatures = tiled; out_properties->bufferFeatures = buffer; @@ -763,7 +823,7 @@ unsigned radv_translate_colorswap(VkFormat format, bool do_endian_swap) #define HAS_SWIZZLE(chan,swz) (desc->swizzle[chan] == VK_SWIZZLE_##swz) if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) - return V_0280A0_SWAP_STD; + return V_028C70_SWAP_STD; if (desc->layout != VK_FORMAT_LAYOUT_PLAIN) return ~0U; @@ -771,45 +831,45 @@ unsigned radv_translate_colorswap(VkFormat format, bool do_endian_swap) switch (desc->nr_channels) { case 1: if (HAS_SWIZZLE(0,X)) - return V_0280A0_SWAP_STD; /* X___ */ + return V_028C70_SWAP_STD; /* X___ */ else if (HAS_SWIZZLE(3,X)) - return V_0280A0_SWAP_ALT_REV; /* ___X */ + return V_028C70_SWAP_ALT_REV; /* ___X */ break; case 2: if ((HAS_SWIZZLE(0,X) && HAS_SWIZZLE(1,Y)) || (HAS_SWIZZLE(0,X) && HAS_SWIZZLE(1,NONE)) || (HAS_SWIZZLE(0,NONE) && HAS_SWIZZLE(1,Y))) - return V_0280A0_SWAP_STD; /* XY__ */ + return V_028C70_SWAP_STD; /* XY__ */ else if ((HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(1,X)) || (HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(1,NONE)) || (HAS_SWIZZLE(0,NONE) && HAS_SWIZZLE(1,X))) /* YX__ */ - return (do_endian_swap ? V_0280A0_SWAP_STD : V_0280A0_SWAP_STD_REV); + return (do_endian_swap ? V_028C70_SWAP_STD : V_028C70_SWAP_STD_REV); else if (HAS_SWIZZLE(0,X) && HAS_SWIZZLE(3,Y)) - return V_0280A0_SWAP_ALT; /* X__Y */ + return V_028C70_SWAP_ALT; /* X__Y */ else if (HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(3,X)) - return V_0280A0_SWAP_ALT_REV; /* Y__X */ + return V_028C70_SWAP_ALT_REV; /* Y__X */ break; case 3: if (HAS_SWIZZLE(0,X)) - return (do_endian_swap ? V_0280A0_SWAP_STD_REV : V_0280A0_SWAP_STD); + return (do_endian_swap ? V_028C70_SWAP_STD_REV : V_028C70_SWAP_STD); else if (HAS_SWIZZLE(0,Z)) - return V_0280A0_SWAP_STD_REV; /* ZYX */ + return V_028C70_SWAP_STD_REV; /* ZYX */ break; case 4: /* check the middle channels, the 1st and 4th channel can be NONE */ if (HAS_SWIZZLE(1,Y) && HAS_SWIZZLE(2,Z)) { - return V_0280A0_SWAP_STD; /* XYZW */ + return V_028C70_SWAP_STD; /* XYZW */ } else if (HAS_SWIZZLE(1,Z) && HAS_SWIZZLE(2,Y)) { - return V_0280A0_SWAP_STD_REV; /* WZYX */ + return V_028C70_SWAP_STD_REV; /* WZYX */ } else if (HAS_SWIZZLE(1,Y) && HAS_SWIZZLE(2,X)) { - return V_0280A0_SWAP_ALT; /* ZYXW */ + return V_028C70_SWAP_ALT; /* ZYXW */ } else if (HAS_SWIZZLE(1,Z) && HAS_SWIZZLE(2,W)) { /* YZWX */ if (desc->is_array) - return V_0280A0_SWAP_ALT_REV; + return V_028C70_SWAP_ALT_REV; else - return (do_endian_swap ? V_0280A0_SWAP_ALT : V_0280A0_SWAP_ALT_REV); + return (do_endian_swap ? V_028C70_SWAP_ALT : V_028C70_SWAP_ALT_REV); } break; } @@ -958,6 +1018,12 @@ bool radv_format_pack_clear_color(VkFormat format, clear_vals[1] = ((uint16_t)util_iround(CLAMP(value->float32[2], 0.0f, 1.0f) * 0xffff)) & 0xffff; clear_vals[1] |= ((uint16_t)util_iround(CLAMP(value->float32[3], 0.0f, 1.0f) * 0xffff)) << 16; break; + case VK_FORMAT_R16G16B16A16_SNORM: + clear_vals[0] = ((uint16_t)util_iround(CLAMP(value->float32[0], -1.0f, 1.0f) * 0x7fff)) & 0xffff; + clear_vals[0] |= ((uint16_t)util_iround(CLAMP(value->float32[1], -1.0f, 1.0f) * 0x7fff)) << 16; + clear_vals[1] = ((uint16_t)util_iround(CLAMP(value->float32[2], -1.0f, 1.0f) * 0x7fff)) & 0xffff; + clear_vals[1] |= ((uint16_t)util_iround(CLAMP(value->float32[3], -1.0f, 1.0f) * 0x7fff)) << 16; + break; case VK_FORMAT_A2B10G10R10_UNORM_PACK32: clear_vals[0] = ((uint16_t)util_iround(CLAMP(value->float32[0], 0.0f, 1.0f) * 0x3ff)) & 0x3ff; clear_vals[0] |= (((uint16_t)util_iround(CLAMP(value->float32[1], 0.0f, 1.0f) * 0x3ff)) & 0x3ff) << 10; @@ -977,6 +1043,27 @@ bool radv_format_pack_clear_color(VkFormat format, clear_vals[0] = float3_to_r11g11b10f(value->float32); clear_vals[1] = 0; break; + case VK_FORMAT_R32G32B32A32_SFLOAT: + if (value->float32[0] != value->float32[1] || + value->float32[0] != value->float32[2]) + return false; + clear_vals[0] = fui(value->float32[0]); + clear_vals[1] = fui(value->float32[3]); + break; + case VK_FORMAT_R32G32B32A32_UINT: + if (value->uint32[0] != value->uint32[1] || + value->uint32[0] != value->uint32[2]) + return false; + clear_vals[0] = value->uint32[0]; + clear_vals[1] = value->uint32[3]; + break; + case VK_FORMAT_R32G32B32A32_SINT: + if (value->int32[0] != value->int32[1] || + value->int32[0] != value->int32[2]) + return false; + clear_vals[0] = value->int32[0]; + clear_vals[1] = value->int32[3]; + break; default: fprintf(stderr, "failed to fast clear %d\n", format); return false; @@ -996,7 +1083,7 @@ void radv_GetPhysicalDeviceFormatProperties( pFormatProperties); } -void radv_GetPhysicalDeviceFormatProperties2KHR( +void radv_GetPhysicalDeviceFormatProperties2( VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2KHR* pFormatProperties) @@ -1033,6 +1120,9 @@ static VkResult radv_get_image_format_properties(struct radv_physical_device *ph if (format_feature_flags == 0) goto unsupported; + if (info->type != VK_IMAGE_TYPE_2D && vk_format_is_depth_or_stencil(info->format)) + goto unsupported; + switch (info->type) { default: unreachable("bad vkimage type\n"); @@ -1144,35 +1234,48 @@ VkResult radv_GetPhysicalDeviceImageFormatProperties( static void get_external_image_format_properties(const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo, - VkExternalMemoryPropertiesKHX *external_properties) + VkExternalMemoryHandleTypeFlagBitsKHR handleType, + VkExternalMemoryPropertiesKHR *external_properties) { - VkExternalMemoryFeatureFlagBitsKHX flags = 0; - VkExternalMemoryHandleTypeFlagsKHX export_flags = 0; - VkExternalMemoryHandleTypeFlagsKHX compat_flags = 0; - switch (pImageFormatInfo->type) { - case VK_IMAGE_TYPE_2D: - flags = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHX|VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHX|VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHX; - compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX; + VkExternalMemoryFeatureFlagBitsKHR flags = 0; + VkExternalMemoryHandleTypeFlagsKHR export_flags = 0; + VkExternalMemoryHandleTypeFlagsKHR compat_flags = 0; + switch (handleType) { + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: + switch (pImageFormatInfo->type) { + case VK_IMAGE_TYPE_2D: + flags = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR|VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR|VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR; + compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR | + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; + break; + default: + break; + } + break; + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: + flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR; + compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT; break; default: break; } - *external_properties = (VkExternalMemoryPropertiesKHX) { + *external_properties = (VkExternalMemoryPropertiesKHR) { .externalMemoryFeatures = flags, .exportFromImportedHandleTypes = export_flags, .compatibleHandleTypes = compat_flags, }; } -VkResult radv_GetPhysicalDeviceImageFormatProperties2KHR( +VkResult radv_GetPhysicalDeviceImageFormatProperties2( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2KHR *base_info, VkImageFormatProperties2KHR *base_props) { RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice); - const VkPhysicalDeviceExternalImageFormatInfoKHX *external_info = NULL; - VkExternalImageFormatPropertiesKHX *external_props = NULL; + const VkPhysicalDeviceExternalImageFormatInfoKHR *external_info = NULL; + VkExternalImageFormatPropertiesKHR *external_props = NULL; VkResult result; result = radv_get_image_format_properties(physical_device, base_info, @@ -1183,7 +1286,7 @@ VkResult radv_GetPhysicalDeviceImageFormatProperties2KHR( /* Extract input structs */ vk_foreach_struct_const(s, base_info->pNext) { switch (s->sType) { - case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHX: + case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR: external_info = (const void *) s; break; default: @@ -1194,7 +1297,7 @@ VkResult radv_GetPhysicalDeviceImageFormatProperties2KHR( /* Extract output structs */ vk_foreach_struct(s, base_props->pNext) { switch (s->sType) { - case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHX: + case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR: external_props = (void *) s; break; default: @@ -1205,13 +1308,16 @@ VkResult radv_GetPhysicalDeviceImageFormatProperties2KHR( /* From the Vulkan 1.0.42 spec: * * If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2KHR will - * behave as if VkPhysicalDeviceExternalImageFormatInfoKHX was not - * present and VkExternalImageFormatPropertiesKHX will be ignored. + * behave as if VkPhysicalDeviceExternalImageFormatInfoKHR was not + * present and VkExternalImageFormatPropertiesKHR will be ignored. */ if (external_info && external_info->handleType != 0) { switch (external_info->handleType) { - case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX: - get_external_image_format_properties(base_info, &external_props->externalMemoryProperties); + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: + get_external_image_format_properties(base_info, external_info->handleType, + &external_props->externalMemoryProperties); break; default: /* From the Vulkan 1.0.42 spec: @@ -1222,7 +1328,7 @@ VkResult radv_GetPhysicalDeviceImageFormatProperties2KHR( * VK_ERROR_FORMAT_NOT_SUPPORTED. */ result = vk_errorf(VK_ERROR_FORMAT_NOT_SUPPORTED, - "unsupported VkExternalMemoryTypeFlagBitsKHX 0x%x", + "unsupported VkExternalMemoryTypeFlagBitsKHR 0x%x", external_info->handleType); goto fail; } @@ -1259,7 +1365,7 @@ void radv_GetPhysicalDeviceSparseImageFormatProperties( *pNumProperties = 0; } -void radv_GetPhysicalDeviceSparseImageFormatProperties2KHR( +void radv_GetPhysicalDeviceSparseImageFormatProperties2( VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2KHR* pFormatInfo, uint32_t *pPropertyCount, @@ -1269,27 +1375,117 @@ void radv_GetPhysicalDeviceSparseImageFormatProperties2KHR( *pPropertyCount = 0; } -void radv_GetPhysicalDeviceExternalBufferPropertiesKHX( +void radv_GetPhysicalDeviceExternalBufferProperties( VkPhysicalDevice physicalDevice, - const VkPhysicalDeviceExternalBufferInfoKHX *pExternalBufferInfo, - VkExternalBufferPropertiesKHX *pExternalBufferProperties) + const VkPhysicalDeviceExternalBufferInfoKHR *pExternalBufferInfo, + VkExternalBufferPropertiesKHR *pExternalBufferProperties) { - VkExternalMemoryFeatureFlagBitsKHX flags = 0; - VkExternalMemoryHandleTypeFlagsKHX export_flags = 0; - VkExternalMemoryHandleTypeFlagsKHX compat_flags = 0; + VkExternalMemoryFeatureFlagBitsKHR flags = 0; + VkExternalMemoryHandleTypeFlagsKHR export_flags = 0; + VkExternalMemoryHandleTypeFlagsKHR compat_flags = 0; switch(pExternalBufferInfo->handleType) { - case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX: - flags = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHX | - VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHX | - VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHX; - compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX; + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: + flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR | + VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR; + compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR | + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; + break; + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: + flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR; + compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT; break; default: break; } - pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryPropertiesKHX) { + pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryPropertiesKHR) { .externalMemoryFeatures = flags, .exportFromImportedHandleTypes = export_flags, .compatibleHandleTypes = compat_flags, }; } + +/* DCC channel type categories within which formats can be reinterpreted + * while keeping the same DCC encoding. The swizzle must also match. */ +enum dcc_channel_type { + dcc_channel_float32, + dcc_channel_uint32, + dcc_channel_sint32, + dcc_channel_float16, + dcc_channel_uint16, + dcc_channel_sint16, + dcc_channel_uint_10_10_10_2, + dcc_channel_uint8, + dcc_channel_sint8, + dcc_channel_incompatible, +}; + +/* Return the type of DCC encoding. */ +static enum dcc_channel_type +radv_get_dcc_channel_type(const struct vk_format_description *desc) +{ + int i; + + /* Find the first non-void channel. */ + for (i = 0; i < desc->nr_channels; i++) + if (desc->channel[i].type != VK_FORMAT_TYPE_VOID) + break; + if (i == desc->nr_channels) + return dcc_channel_incompatible; + + switch (desc->channel[i].size) { + case 32: + if (desc->channel[i].type == VK_FORMAT_TYPE_FLOAT) + return dcc_channel_float32; + if (desc->channel[i].type == VK_FORMAT_TYPE_UNSIGNED) + return dcc_channel_uint32; + return dcc_channel_sint32; + case 16: + if (desc->channel[i].type == VK_FORMAT_TYPE_FLOAT) + return dcc_channel_float16; + if (desc->channel[i].type == VK_FORMAT_TYPE_UNSIGNED) + return dcc_channel_uint16; + return dcc_channel_sint16; + case 10: + return dcc_channel_uint_10_10_10_2; + case 8: + if (desc->channel[i].type == VK_FORMAT_TYPE_UNSIGNED) + return dcc_channel_uint8; + return dcc_channel_sint8; + default: + return dcc_channel_incompatible; + } +} + +/* Return if it's allowed to reinterpret one format as another with DCC enabled. */ +bool radv_dcc_formats_compatible(VkFormat format1, + VkFormat format2) +{ + const struct vk_format_description *desc1, *desc2; + enum dcc_channel_type type1, type2; + int i; + + if (format1 == format2) + return true; + + desc1 = vk_format_description(format1); + desc2 = vk_format_description(format2); + + if (desc1->nr_channels != desc2->nr_channels) + return false; + + /* Swizzles must be the same. */ + for (i = 0; i < desc1->nr_channels; i++) + if (desc1->swizzle[i] <= VK_SWIZZLE_W && + desc2->swizzle[i] <= VK_SWIZZLE_W && + desc1->swizzle[i] != desc2->swizzle[i]) + return false; + + type1 = radv_get_dcc_channel_type(desc1); + type2 = radv_get_dcc_channel_type(desc2); + + return type1 != dcc_channel_incompatible && + type2 != dcc_channel_incompatible && + type1 == type2; +} +