mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 07:28:11 +02:00
tu: Enable UBWC for SNORM formats on a740+
The fast-clear value is now the same for SNORM and UNORM, so our trick of reinterpreting SNORM as UNORM when copying now works with UBWC. We can also freely reinterpret UNORM, SNORM, and UINT formats, as tested by dEQP-VK.image.mutable.*. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27506>
This commit is contained in:
parent
4529b2ea54
commit
b9e04f8293
5 changed files with 53 additions and 11 deletions
|
|
@ -220,6 +220,13 @@ struct fd_dev_info {
|
|||
/* Size of buffer in gmem for VPC attributes */
|
||||
uint32_t sysmem_vpc_attr_buf_size;
|
||||
uint32_t gmem_vpc_attr_buf_size;
|
||||
|
||||
/* Whether the UBWC fast-clear values for snorn, unorm, and int formats
|
||||
* are the same. This is the case from a740 onwards. These formats were
|
||||
* already otherwise UBWC-compatible, so this means that they are now
|
||||
* fully compatible.
|
||||
*/
|
||||
bool ubwc_unorm_snorm_int_compatible;
|
||||
} a7xx;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -790,6 +790,7 @@ a7xx_730 = A7XXProps()
|
|||
a7xx_740 = A7XXProps(
|
||||
stsc_duplication_quirk = True,
|
||||
has_event_write_sample_count = True,
|
||||
ubwc_unorm_snorm_int_compatible = True,
|
||||
)
|
||||
|
||||
a7xx_750 = A7XXProps(
|
||||
|
|
@ -799,6 +800,7 @@ a7xx_750 = A7XXProps(
|
|||
has_gmem_vpc_attr_buf = True,
|
||||
sysmem_vpc_attr_buf_size = 0x20000,
|
||||
gmem_vpc_attr_buf_size = 0xc000,
|
||||
ubwc_unorm_snorm_int_compatible = True,
|
||||
)
|
||||
|
||||
a730_magic_regs = dict(
|
||||
|
|
|
|||
|
|
@ -101,7 +101,9 @@ enum tu6_ubwc_compat_type {
|
|||
TU6_UBWC_R8G8B8A8_UNORM,
|
||||
TU6_UBWC_R8G8B8A8_INT,
|
||||
TU6_UBWC_B8G8R8A8_UNORM,
|
||||
TU6_UBWC_R16G16_UNORM,
|
||||
TU6_UBWC_R16G16_INT,
|
||||
TU6_UBWC_R16G16B16A16_UNORM,
|
||||
TU6_UBWC_R16G16B16A16_INT,
|
||||
TU6_UBWC_R32_INT,
|
||||
TU6_UBWC_R32G32_INT,
|
||||
|
|
@ -110,12 +112,17 @@ enum tu6_ubwc_compat_type {
|
|||
};
|
||||
|
||||
static enum tu6_ubwc_compat_type
|
||||
tu6_ubwc_compat_mode(VkFormat format)
|
||||
tu6_ubwc_compat_mode(const struct fd_dev_info *info, VkFormat format)
|
||||
{
|
||||
switch (format) {
|
||||
case VK_FORMAT_R8G8_UNORM:
|
||||
case VK_FORMAT_R8G8_SRGB:
|
||||
return TU6_UBWC_R8G8_UNORM;
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
TU6_UBWC_R8G8_INT : TU6_UBWC_R8G8_UNORM;
|
||||
|
||||
case VK_FORMAT_R8G8_SNORM:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
TU6_UBWC_R8G8_INT : TU6_UBWC_UNKNOWN_COMPAT;
|
||||
|
||||
case VK_FORMAT_R8G8_UINT:
|
||||
case VK_FORMAT_R8G8_SINT:
|
||||
|
|
@ -125,7 +132,12 @@ tu6_ubwc_compat_mode(VkFormat format)
|
|||
case VK_FORMAT_R8G8B8A8_SRGB:
|
||||
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
|
||||
case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
|
||||
return TU6_UBWC_R8G8B8A8_UNORM;
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
TU6_UBWC_R8G8B8A8_INT : TU6_UBWC_R8G8B8A8_UNORM;
|
||||
|
||||
case VK_FORMAT_R8G8B8A8_SNORM:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
TU6_UBWC_R8G8B8A8_INT : TU6_UBWC_UNKNOWN_COMPAT;
|
||||
|
||||
case VK_FORMAT_R8G8B8A8_UINT:
|
||||
case VK_FORMAT_R8G8B8A8_SINT:
|
||||
|
|
@ -133,10 +145,26 @@ tu6_ubwc_compat_mode(VkFormat format)
|
|||
case VK_FORMAT_A8B8G8R8_SINT_PACK32:
|
||||
return TU6_UBWC_R8G8B8A8_INT;
|
||||
|
||||
case VK_FORMAT_R16G16_UNORM:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
TU6_UBWC_R16G16_INT : TU6_UBWC_R16G16_UNORM;
|
||||
|
||||
case VK_FORMAT_R16G16_SNORM:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
TU6_UBWC_R16G16_INT : TU6_UBWC_UNKNOWN_COMPAT;
|
||||
|
||||
case VK_FORMAT_R16G16_UINT:
|
||||
case VK_FORMAT_R16G16_SINT:
|
||||
return TU6_UBWC_R16G16_INT;
|
||||
|
||||
case VK_FORMAT_R16G16B16A16_UNORM:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
TU6_UBWC_R16G16B16A16_INT : TU6_UBWC_R16G16B16A16_UNORM;
|
||||
|
||||
case VK_FORMAT_R16G16B16A16_SNORM:
|
||||
return info->a7xx.ubwc_unorm_snorm_int_compatible ?
|
||||
TU6_UBWC_R16G16B16A16_INT : TU6_UBWC_UNKNOWN_COMPAT;
|
||||
|
||||
case VK_FORMAT_R16G16B16A16_UINT:
|
||||
case VK_FORMAT_R16G16B16A16_SINT:
|
||||
return TU6_UBWC_R16G16B16A16_INT;
|
||||
|
|
@ -172,7 +200,8 @@ tu6_ubwc_compat_mode(VkFormat format)
|
|||
}
|
||||
|
||||
bool
|
||||
tu6_mutable_format_list_ubwc_compatible(const VkImageFormatListCreateInfo *fmt_list)
|
||||
tu6_mutable_format_list_ubwc_compatible(const struct fd_dev_info *info,
|
||||
const VkImageFormatListCreateInfo *fmt_list)
|
||||
{
|
||||
if (!fmt_list || !fmt_list->viewFormatCount)
|
||||
return false;
|
||||
|
|
@ -184,12 +213,12 @@ tu6_mutable_format_list_ubwc_compatible(const VkImageFormatListCreateInfo *fmt_l
|
|||
return true;
|
||||
|
||||
enum tu6_ubwc_compat_type type =
|
||||
tu6_ubwc_compat_mode(fmt_list->pViewFormats[0]);
|
||||
tu6_ubwc_compat_mode(info, fmt_list->pViewFormats[0]);
|
||||
if (type == TU6_UBWC_UNKNOWN_COMPAT)
|
||||
return false;
|
||||
|
||||
for (uint32_t i = 1; i < fmt_list->viewFormatCount; i++) {
|
||||
if (tu6_ubwc_compat_mode(fmt_list->pViewFormats[i]) != type)
|
||||
if (tu6_ubwc_compat_mode(info, fmt_list->pViewFormats[i]) != type)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -484,7 +513,8 @@ tu_get_image_format_properties(
|
|||
const VkImageFormatListCreateInfo *format_list =
|
||||
vk_find_struct_const(info->pNext,
|
||||
IMAGE_FORMAT_LIST_CREATE_INFO);
|
||||
if (!tu6_mutable_format_list_ubwc_compatible(format_list))
|
||||
if (!tu6_mutable_format_list_ubwc_compatible(physical_device->info,
|
||||
format_list))
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ struct tu_native_format tu6_format_vtx(enum pipe_format format);
|
|||
struct tu_native_format tu6_format_color(enum pipe_format format, enum a6xx_tile_mode tile_mode);
|
||||
struct tu_native_format tu6_format_texture(enum pipe_format format, enum a6xx_tile_mode tile_mode);
|
||||
|
||||
bool tu6_mutable_format_list_ubwc_compatible(const VkImageFormatListCreateInfo *fmt_list);
|
||||
bool tu6_mutable_format_list_ubwc_compatible(const struct fd_dev_info *info,
|
||||
const VkImageFormatListCreateInfo *fmt_list);
|
||||
|
||||
#endif /* TU_FORMATS_H */
|
||||
|
|
|
|||
|
|
@ -310,9 +310,10 @@ ubwc_possible(struct tu_device *device,
|
|||
|
||||
/* In copy_format, we treat snorm as unorm to avoid clamping. But snorm
|
||||
* and unorm are UBWC incompatible for special values such as all 0's or
|
||||
* all 1's. Disable UBWC for snorm.
|
||||
* all 1's prior to a740. Disable UBWC for snorm.
|
||||
*/
|
||||
if (vk_format_is_snorm(format))
|
||||
if (vk_format_is_snorm(format) &&
|
||||
!info->a7xx.ubwc_unorm_snorm_int_compatible)
|
||||
return false;
|
||||
|
||||
if (!info->a6xx.has_8bpp_ubwc &&
|
||||
|
|
@ -498,7 +499,8 @@ tu_image_init(struct tu_device *device, struct tu_image *image,
|
|||
!vk_format_is_depth_or_stencil(image->vk.format)) {
|
||||
const VkImageFormatListCreateInfo *fmt_list =
|
||||
vk_find_struct_const(pCreateInfo->pNext, IMAGE_FORMAT_LIST_CREATE_INFO);
|
||||
if (!tu6_mutable_format_list_ubwc_compatible(fmt_list)) {
|
||||
if (!tu6_mutable_format_list_ubwc_compatible(device->physical_device->info,
|
||||
fmt_list)) {
|
||||
if (ubwc_enabled) {
|
||||
if (fmt_list && fmt_list->viewFormatCount == 2) {
|
||||
perf_debug(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue