X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Famd%2Fvulkan%2Fradv_formats.c;h=c008c1bae67a2a58df0642fe339687856451c68c;hb=2ce11ac11fee594ca01608c4006b38c0c8ea37ff;hp=57bde9e7cdc072ace2e04b19e3b0618fd0416378;hpb=486472a98db8dc8bd87f498970ead1cf6f5dfd02;p=mesa.git diff --git a/src/amd/vulkan/radv_formats.c b/src/amd/vulkan/radv_formats.c index 57bde9e7cdc..c008c1bae67 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" @@ -578,6 +577,10 @@ 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; + + /* GFX9 doesn't support linear depth surfaces */ + if (physical_device->rad_info.chip_class >= GFX9) + linear = 0; } } else { bool linear_sampling; @@ -763,7 +766,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 +774,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 +961,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; @@ -1173,7 +1182,8 @@ get_external_image_format_properties(const VkPhysicalDeviceImageFormatInfo2KHR * 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; + 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; @@ -1232,6 +1242,7 @@ VkResult radv_GetPhysicalDeviceImageFormatProperties2KHR( if (external_info && external_info->handleType != 0) { switch (external_info->handleType) { case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: + case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: get_external_image_format_properties(base_info, &external_props->externalMemoryProperties); break; default: @@ -1300,9 +1311,11 @@ void radv_GetPhysicalDeviceExternalBufferPropertiesKHR( VkExternalMemoryHandleTypeFlagsKHR compat_flags = 0; switch(pExternalBufferInfo->handleType) { 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; + 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; @@ -1313,3 +1326,88 @@ void radv_GetPhysicalDeviceExternalBufferPropertiesKHR( .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; +} +