From 580ce1c911c9cd4ec2b8109fea9347bf311152df Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Tue, 26 Aug 2025 19:32:35 +0200 Subject: [PATCH] tu: Handle mismatch in mip layouts for reinterpreted compressed images If the threshold of the linear mipmap fallback for compressed format is reached at a different mipmap level than the size-compatible non-compressed formats the image can be viewed as, then we have to disable the fallback. Otherwise, for some levels, texels would be read from the wrong locations due to the tiling mismatch. NOTE: Prop driver falls back to LINEAR in this case. Signed-off-by: Danylo Piliaiev Part-of: --- src/freedreno/fdl/fd6_layout.c | 5 +++++ src/freedreno/fdl/freedreno_layout.h | 2 ++ src/freedreno/vulkan/tu_image.cc | 32 ++++++++++++++++++++++++++++ src/freedreno/vulkan/tu_image.h | 2 ++ 4 files changed, 41 insertions(+) diff --git a/src/freedreno/fdl/fd6_layout.c b/src/freedreno/fdl/fd6_layout.c index 9fb7a8cefd6..f55ea19d7ea 100644 --- a/src/freedreno/fdl/fd6_layout.c +++ b/src/freedreno/fdl/fd6_layout.c @@ -175,6 +175,11 @@ fdl6_layout_image(struct fdl_layout *layout, const struct fd_dev_info *info, if (layout->ubwc && !info->props.has_ubwc_linear_mipmap_fallback) layout->tile_all = true; + if (layout->tile_mode != TILE6_LINEAR && + params->force_disable_linear_fallback) { + layout->tile_all = true; + } + /* in layer_first layout, the level (slice) contains just one * layer (since in fact the layer contains the slices) */ diff --git a/src/freedreno/fdl/freedreno_layout.h b/src/freedreno/fdl/freedreno_layout.h index 1e1814890de..f436069e110 100644 --- a/src/freedreno/fdl/freedreno_layout.h +++ b/src/freedreno/fdl/freedreno_layout.h @@ -109,6 +109,8 @@ struct fdl_image_params { * standard sparse tiling. */ bool sparse; + + bool force_disable_linear_fallback; }; /** diff --git a/src/freedreno/vulkan/tu_image.cc b/src/freedreno/vulkan/tu_image.cc index dc6c3868fbf..168b0eea455 100644 --- a/src/freedreno/vulkan/tu_image.cc +++ b/src/freedreno/vulkan/tu_image.cc @@ -475,6 +475,20 @@ format_list_has_swaps(const VkImageFormatListCreateInfo *fmt_list) return false; } +static bool +format_list_has_uncompressed_format( + const VkImageFormatListCreateInfo *fmt_list) +{ + if (!fmt_list || !fmt_list->viewFormatCount) + return true; + + for (uint32_t i = 0; i < fmt_list->viewFormatCount; i++) { + if (!vk_format_is_compressed(fmt_list->pViewFormats[i])) + return true; + } + return false; +} + template VkResult tu_image_update_layout(struct tu_device *device, struct tu_image *image, @@ -564,6 +578,7 @@ tu_image_update_layout(struct tu_device *device, struct tu_image *image, .is_mutable = image->is_mutable, .sparse = image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, + .force_disable_linear_fallback = image->force_disable_linear_fallback, }; if (!fdl6_layout_image(layout, &device->physical_device->dev_info, @@ -780,6 +795,23 @@ tu_image_init(struct tu_device *device, struct tu_image *image, if (!format_list_ubwc_possible(device, fmt_list, pCreateInfo)) image->ubwc_enabled = false; } + + /* If the threshold of the linear mipmap fallback for compressed + * format is reached at a different mipmap level than the + * size-compatible non-compressed formats the image can be viewed as, + * then we have to disable the fallback. Otherwise, for some levels, + * texels would be read from the wrong locations due to the tiling + * mismatch. + * NOTE: Prop driver falls back to LINEAR in this case. + */ + if (!device->physical_device->info->props + .supports_linear_mipmap_threshold_in_blocks && + vk_format_is_compressed(image->vk.format) && + pCreateInfo->usage & + VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT && + format_list_has_uncompressed_format(fmt_list)) { + image->force_disable_linear_fallback = true; + } } } diff --git a/src/freedreno/vulkan/tu_image.h b/src/freedreno/vulkan/tu_image.h index ed47b89aca4..df4ce5b6088 100644 --- a/src/freedreno/vulkan/tu_image.h +++ b/src/freedreno/vulkan/tu_image.h @@ -58,6 +58,8 @@ struct tu_image bool ubwc_enabled; bool force_linear_tile; bool is_mutable; + /* Force to either use tiled layout or linear for all mip layers. */ + bool force_disable_linear_fallback; }; VK_DEFINE_NONDISP_HANDLE_CASTS(tu_image, vk.base, VkImage, VK_OBJECT_TYPE_IMAGE)