From 4ccbc924b58c36bb98bf37a7b128febd1ab4a0ae Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Fri, 11 Oct 2024 14:41:46 +0200 Subject: [PATCH] tu: Enable UBWC for 3D images without mipmaps Many D3D11 games use 3D images writing to them from compute shaders. Most of such 3D images don't use mipmaps, and in such case enabling UBWC is trivial. Signed-off-by: Danylo Piliaiev Part-of: --- src/freedreno/fdl/fd6_layout.c | 13 ++++-- src/freedreno/fdl/fd6_layout_test.c | 61 ++++++++++++++++++++++++++++- src/freedreno/vulkan/tu_formats.cc | 6 +-- src/freedreno/vulkan/tu_image.cc | 14 ++++--- src/freedreno/vulkan/tu_image.h | 1 + 5 files changed, 82 insertions(+), 13 deletions(-) diff --git a/src/freedreno/fdl/fd6_layout.c b/src/freedreno/fdl/fd6_layout.c index acf19c3925e..f7b61d3d4c7 100644 --- a/src/freedreno/fdl/fd6_layout.c +++ b/src/freedreno/fdl/fd6_layout.c @@ -125,7 +125,13 @@ fdl6_layout(struct fdl_layout *layout, enum pipe_format format, fdl6_get_ubwc_blockwidth(layout, &ubwc_blockwidth, &ubwc_blockheight); - if (depth0 > 1 || ubwc_blockwidth == 0) + /* For simplicity support UBWC only for 3D images without mipmaps, + * most d3d11 games don't use mipmaps for 3D images. + */ + if (depth0 > 1 && mip_levels > 1) + layout->ubwc = false; + + if (ubwc_blockwidth == 0) layout->ubwc = false; if (layout->ubwc || util_format_is_depth_or_stencil(format)) @@ -279,9 +285,10 @@ fdl6_layout(struct fdl_layout *layout, enum pipe_format format, * independently. */ if (layout->ubwc) { + assert(!(depth0 > 1 && mip_levels > 1)); for (uint32_t level = 0; level < mip_levels; level++) - layout->slices[level].offset += layout->ubwc_layer_size * array_size; - layout->size += layout->ubwc_layer_size * array_size; + layout->slices[level].offset += layout->ubwc_layer_size * array_size * depth0; + layout->size += layout->ubwc_layer_size * array_size * depth0; } /* include explicit offset in size */ diff --git a/src/freedreno/fdl/fd6_layout_test.c b/src/freedreno/fdl/fd6_layout_test.c index 2cdabb675bb..35b00918215 100644 --- a/src/freedreno/fdl/fd6_layout_test.c +++ b/src/freedreno/fdl/fd6_layout_test.c @@ -901,7 +901,66 @@ static const struct testcase }, }, }, - + { + .format = PIPE_FORMAT_R16G16B16A16_UINT, + .is_3d = true, + .layout = + { + .tile_mode = TILE6_3, + .ubwc = true, + .width0 = 56, + .height0 = 32, + .depth0 = 18, + .slices = + { + {.offset = 0, .pitch = 512, .size0 = 16384}, + }, + .ubwc_slices = + { + {.offset = 0, .pitch = 64}, + }, + }, + }, + { + .format = PIPE_FORMAT_R32_UINT, + .is_3d = true, + .layout = + { + .tile_mode = TILE6_3, + .ubwc = true, + .width0 = 56, + .height0 = 32, + .depth0 = 16, + .slices = + { + {.offset = 0, .pitch = 256, .size0 = 8192}, + }, + .ubwc_slices = + { + {.offset = 0, .pitch = 64}, + }, + }, + }, + { + .format = PIPE_FORMAT_R8G8B8A8_UINT, + .is_3d = true, + .layout = + { + .tile_mode = TILE6_3, + .ubwc = true, + .width0 = 56, + .height0 = 32, + .depth0 = 16, + .slices = + { + {.offset = 0, .pitch = 256, .size0 = 8192}, + }, + .ubwc_slices = + { + {.offset = 0, .pitch = 64}, + }, + }, + }, }; int diff --git a/src/freedreno/vulkan/tu_formats.cc b/src/freedreno/vulkan/tu_formats.cc index 8b710dd7d8c..468892ede6e 100644 --- a/src/freedreno/vulkan/tu_formats.cc +++ b/src/freedreno/vulkan/tu_formats.cc @@ -320,7 +320,7 @@ tu_GetPhysicalDeviceFormatProperties2( if (pFormatProperties->formatProperties.optimalTilingFeatures && tiling_possible(format) && ubwc_possible(NULL, format, VK_IMAGE_TYPE_2D, 0, 0, - physical_device->info, VK_SAMPLE_COUNT_1_BIT, + physical_device->info, VK_SAMPLE_COUNT_1_BIT, 1, false)) { vk_outarray_append_typed(VkDrmFormatModifierPropertiesEXT, &out, mod_props) { mod_props->drmFormatModifier = DRM_FORMAT_MOD_QCOM_COMPRESSED; @@ -398,7 +398,7 @@ tu_get_image_format_properties( if (!ubwc_possible(NULL, info->format, info->type, info->usage, info->usage, physical_device->info, sampleCounts, - false)) { + 1, false)) { return VK_ERROR_FORMAT_NOT_SUPPORTED; } @@ -768,7 +768,7 @@ tu_GetPhysicalDeviceImageFormatProperties2( !ubwc_possible(NULL, base_info->format, base_info->type, (base_info->usage & ~VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT), (base_info->usage & ~VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT), - physical_device->info, VK_SAMPLE_COUNT_1_BIT, + physical_device->info, VK_SAMPLE_COUNT_1_BIT, 1, physical_device->info->a6xx.has_z24uint_s8uint)); } diff --git a/src/freedreno/vulkan/tu_image.cc b/src/freedreno/vulkan/tu_image.cc index fe759d949b4..103e5b2d048 100644 --- a/src/freedreno/vulkan/tu_image.cc +++ b/src/freedreno/vulkan/tu_image.cc @@ -339,6 +339,7 @@ ubwc_possible(struct tu_device *device, VkImageUsageFlags stencil_usage, const struct fd_dev_info *info, VkSampleCountFlagBits samples, + uint32_t mip_levels, bool use_z24uint_s8uint) { /* no UBWC with compressed formats, E5B9G9R9, S8_UINT @@ -362,12 +363,13 @@ ubwc_possible(struct tu_device *device, vk_format_get_plane_count(format) == 1) return false; - if (type == VK_IMAGE_TYPE_3D) { + if (type == VK_IMAGE_TYPE_3D && mip_levels > 1) { if (device) { - perf_debug(device, - "Disabling UBWC for %s 3D image, but it should be " - "possible to support.", - util_format_name(vk_format_to_pipe_format(format))); + perf_debug( + device, + "Disabling UBWC for %s 3D image with mipmaps, but it should be " + "possible to support.", + util_format_name(vk_format_to_pipe_format(format))); } return false; } @@ -673,7 +675,7 @@ tu_image_init(struct tu_device *device, struct tu_image *image, !ubwc_possible(device, image->vk.format, pCreateInfo->imageType, pCreateInfo->usage, image->vk.stencil_usage, device->physical_device->info, pCreateInfo->samples, - device->use_z24uint_s8uint)) + pCreateInfo->mipLevels, device->use_z24uint_s8uint)) image->ubwc_enabled = false; bool fmt_list_has_swaps = false; diff --git a/src/freedreno/vulkan/tu_image.h b/src/freedreno/vulkan/tu_image.h index 1dd5d5e78ae..bb26b77cd6c 100644 --- a/src/freedreno/vulkan/tu_image.h +++ b/src/freedreno/vulkan/tu_image.h @@ -122,6 +122,7 @@ ubwc_possible(struct tu_device *device, VkImageUsageFlags stencil_usage, const struct fd_dev_info *info, VkSampleCountFlagBits samples, + uint32_t mip_levels, bool use_z24uint_s8uint); struct tu_frag_area {