tu: Use the format list to decide whether we can do UBWC with MUTABLE.
The goal here is to allow zink and ANGLE to switch sRGB on and off, but keep UBWC enabled for most textures. This doesn't quite work yet for zink on gbm, where zink asks the device if it supports a UBWC-modifier image with unorm+sRGB mutable formats (yes), but then doesn't pass the unorm+sRGB format list to vkImageCreate(), which then asserts because it couldn't make a general VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT UBWC image. The format list here comes from Danylo's testing in https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17278#note_1447812 Reduces frame times in Genshin Impact GLES AoV 2.02063% +/- 0.207575% (n=5) Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17900>
This commit is contained in:
@@ -132,6 +132,108 @@ tu6_format_texture_supported(enum pipe_format format)
|
||||
return tu6_format_texture_unchecked(format, TILE6_LINEAR).fmt != FMT6_NONE;
|
||||
}
|
||||
|
||||
enum tu6_ubwc_compat_type {
|
||||
TU6_UBWC_UNKNOWN_COMPAT,
|
||||
TU6_UBWC_R8G8_UNORM,
|
||||
TU6_UBWC_R8G8_INT,
|
||||
TU6_UBWC_R8G8B8A8_UNORM,
|
||||
TU6_UBWC_R8G8B8A8_INT,
|
||||
TU6_UBWC_B8G8R8A8_UNORM,
|
||||
TU6_UBWC_R16G16_INT,
|
||||
TU6_UBWC_R16G16B16A16_INT,
|
||||
TU6_UBWC_R32_INT,
|
||||
TU6_UBWC_R32G32_INT,
|
||||
TU6_UBWC_R32G32B32A32_INT,
|
||||
TU6_UBWC_R32_FLOAT,
|
||||
};
|
||||
|
||||
static enum tu6_ubwc_compat_type
|
||||
tu6_ubwc_compat_mode(VkFormat format)
|
||||
{
|
||||
switch (format) {
|
||||
case VK_FORMAT_R8G8_UNORM:
|
||||
case VK_FORMAT_R8G8_SRGB:
|
||||
return TU6_UBWC_R8G8_UNORM;
|
||||
|
||||
case VK_FORMAT_R8G8_UINT:
|
||||
case VK_FORMAT_R8G8_SINT:
|
||||
return TU6_UBWC_R8G8_INT;
|
||||
|
||||
case VK_FORMAT_R8G8B8A8_UNORM:
|
||||
case VK_FORMAT_R8G8B8A8_SRGB:
|
||||
case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
|
||||
case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
|
||||
return TU6_UBWC_R8G8B8A8_UNORM;
|
||||
|
||||
case VK_FORMAT_R8G8B8A8_UINT:
|
||||
case VK_FORMAT_R8G8B8A8_SINT:
|
||||
case VK_FORMAT_A8B8G8R8_UINT_PACK32:
|
||||
case VK_FORMAT_A8B8G8R8_SINT_PACK32:
|
||||
return TU6_UBWC_R8G8B8A8_INT;
|
||||
|
||||
case VK_FORMAT_R16G16_UINT:
|
||||
case VK_FORMAT_R16G16_SINT:
|
||||
return TU6_UBWC_R16G16_INT;
|
||||
|
||||
case VK_FORMAT_R16G16B16A16_UINT:
|
||||
case VK_FORMAT_R16G16B16A16_SINT:
|
||||
return TU6_UBWC_R16G16B16A16_INT;
|
||||
|
||||
case VK_FORMAT_R32_UINT:
|
||||
case VK_FORMAT_R32_SINT:
|
||||
return TU6_UBWC_R32_INT;
|
||||
|
||||
case VK_FORMAT_R32G32_UINT:
|
||||
case VK_FORMAT_R32G32_SINT:
|
||||
return TU6_UBWC_R32G32_INT;
|
||||
|
||||
case VK_FORMAT_R32G32B32A32_UINT:
|
||||
case VK_FORMAT_R32G32B32A32_SINT:
|
||||
return TU6_UBWC_R32G32B32A32_INT;
|
||||
|
||||
case VK_FORMAT_D32_SFLOAT:
|
||||
case VK_FORMAT_R32_SFLOAT:
|
||||
/* TODO: a630 blob allows these, but not a660. When is it legal? */
|
||||
return TU6_UBWC_UNKNOWN_COMPAT;
|
||||
|
||||
case VK_FORMAT_B8G8R8A8_UNORM:
|
||||
case VK_FORMAT_B8G8R8A8_SRGB:
|
||||
/* The blob doesn't list these as compatible, but they surely are.
|
||||
* freedreno's happy to cast between them, and zink would really like
|
||||
* to.
|
||||
*/
|
||||
return TU6_UBWC_B8G8R8A8_UNORM;
|
||||
|
||||
default:
|
||||
return TU6_UBWC_UNKNOWN_COMPAT;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
tu6_mutable_format_list_ubwc_compatible(const VkImageFormatListCreateInfo *fmt_list)
|
||||
{
|
||||
if (!fmt_list || !fmt_list->viewFormatCount)
|
||||
return false;
|
||||
|
||||
/* We're only looking at format list cross compatibility here, check
|
||||
* ubwc_possible() for the base "is the format UBWC-able at all?"
|
||||
*/
|
||||
if (fmt_list->viewFormatCount == 1)
|
||||
return true;
|
||||
|
||||
enum tu6_ubwc_compat_type type =
|
||||
tu6_ubwc_compat_mode(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)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
tu_physical_device_get_format_properties(
|
||||
struct tu_physical_device *physical_device,
|
||||
@@ -375,10 +477,13 @@ tu_get_image_format_properties(
|
||||
!tiling_possible(info->format))
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
|
||||
/* for mutable formats, its very unlikely to be possible to use UBWC */
|
||||
if (info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
|
||||
if (info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
|
||||
const VkImageFormatListCreateInfo *format_list =
|
||||
vk_find_struct_const(info->pNext,
|
||||
IMAGE_FORMAT_LIST_CREATE_INFO);
|
||||
if (!tu6_mutable_format_list_ubwc_compatible(format_list))
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (!ubwc_possible(info->format, info->type, info->usage, info->usage, physical_device->info, sampleCounts, false))
|
||||
return VK_ERROR_FORMAT_NOT_SUPPORTED;
|
||||
|
||||
@@ -34,4 +34,6 @@ tu6_base_format(enum pipe_format format)
|
||||
return tu6_format_color(format, TILE6_LINEAR).fmt;
|
||||
}
|
||||
|
||||
bool tu6_mutable_format_list_ubwc_compatible(const VkImageFormatListCreateInfo *fmt_list);
|
||||
|
||||
#endif /* TU_FORMATS_H */
|
||||
|
||||
@@ -437,12 +437,13 @@ 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)) {
|
||||
ubwc_enabled = false;
|
||||
|
||||
ubwc_enabled = false;
|
||||
|
||||
if (format_list_reinterprets_r8g8_r16(format, fmt_list) ||
|
||||
format_list_has_swaps(fmt_list)) {
|
||||
tile_mode = TILE6_LINEAR;
|
||||
if (format_list_reinterprets_r8g8_r16(format, fmt_list) ||
|
||||
format_list_has_swaps(fmt_list)) {
|
||||
tile_mode = TILE6_LINEAR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user