From e347f82aeb166f896701dfd92461320e804ddcc2 Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Tue, 19 Aug 2025 15:20:06 +0200 Subject: [PATCH] freedreno/layout: Use blocks for linear mipmap fallback where possible Starting from at least A6XX gen3 there is an option for compressed formats to have linear fallback threshold in compressed blocks, instead of threshold in raw texels. However, proprietary driver doesn't enable it on A6XX, so to be safe we also enable it only on A7XX. Additionaly, clarify what the linear fallback threshold is really about. It's about tiling, not strictly about UBWC. Signed-off-by: Danylo Piliaiev Part-of: --- src/freedreno/common/freedreno_dev_info.h | 5 ++++ src/freedreno/common/freedreno_devices.py | 7 ++++++ src/freedreno/fdl/fd5_layout.c | 1 + src/freedreno/fdl/fd6_layout.c | 6 ++++- src/freedreno/fdl/freedreno_layout.h | 24 ++++++++++++++++--- src/freedreno/registers/adreno/a6xx.xml | 5 ++-- src/freedreno/tests/reference/crash.log | 2 +- .../tests/reference/crash_prefetch.log | 8 +++---- ...exed.indirect_draw_count.triangle_list.log | 4 ++-- src/freedreno/tests/reference/fd-clouds.log | 4 ++-- .../tests/reference/prefetch-test.log | 4 ++-- src/freedreno/vulkan/tu_cmd_buffer.cc | 6 +++++ .../drivers/freedreno/a6xx/fd6_emit.cc | 6 +++++ .../drivers/freedreno/freedreno_resource.c | 6 ++++- 14 files changed, 70 insertions(+), 18 deletions(-) diff --git a/src/freedreno/common/freedreno_dev_info.h b/src/freedreno/common/freedreno_dev_info.h index b6b36070c44..477c52288e6 100644 --- a/src/freedreno/common/freedreno_dev_info.h +++ b/src/freedreno/common/freedreno_dev_info.h @@ -224,6 +224,11 @@ struct fd_dev_info { */ bool has_ubwc_linear_mipmap_fallback; + /* Whether threshold for linear mipmaps for compressed textures is in + * blocks, if false then threshold is in texels. + */ + bool supports_linear_mipmap_threshold_in_blocks; + /* Whether 4 nops are needed after the second pred[tf] of a * pred[tf]/pred[ft] pair to work around a hardware issue. */ diff --git a/src/freedreno/common/freedreno_devices.py b/src/freedreno/common/freedreno_devices.py index 84dd35ce627..2b0a6a15f21 100644 --- a/src/freedreno/common/freedreno_devices.py +++ b/src/freedreno/common/freedreno_devices.py @@ -399,6 +399,9 @@ a6xx_gen3 = GPUProps( prede_nop_quirk = True, has_pred_bit = True, has_pc_dgen_so_cntl = True, + # HW seem to support this, but prop driver doesn't enable it, + # Be safe and don't enable it either. + # supports_linear_mipmap_threshold_in_blocks = True, ) a6xx_gen4 = GPUProps( @@ -437,6 +440,9 @@ a6xx_gen4 = GPUProps( has_sel_b_fneg = True, has_pred_bit = True, has_pc_dgen_so_cntl = True, + # HW seem to support this, but prop driver doesn't enable it, + # Be safe and don't enable it either. + # supports_linear_mipmap_threshold_in_blocks = True, ) add_gpus([ @@ -949,6 +955,7 @@ a7xx_base = GPUProps( has_early_preamble = True, has_attachment_shading_rate = True, has_ubwc_linear_mipmap_fallback = True, + supports_linear_mipmap_threshold_in_blocks = True, prede_nop_quirk = True, predtf_nop_quirk = True, has_sad = True, diff --git a/src/freedreno/fdl/fd5_layout.c b/src/freedreno/fdl/fd5_layout.c index d1ac960c306..aaf4a1c4b8c 100644 --- a/src/freedreno/fdl/fd5_layout.c +++ b/src/freedreno/fdl/fd5_layout.c @@ -32,6 +32,7 @@ fdl5_layout_image(struct fdl_layout *layout, const struct fdl_image_params *para layout->layer_first = !params->is_3d; layout->tile_mode = params->tile_mode; + layout->linear_fallback_threshold_texels = FDL_LINEAR_FALLBACK_THRESHOLD; uint32_t heightalign = layout->cpp == 1 ? 32 : 16; /* in layer_first layout, the level (slice) contains just one diff --git a/src/freedreno/fdl/fd6_layout.c b/src/freedreno/fdl/fd6_layout.c index 9b104537b86..9fb7a8cefd6 100644 --- a/src/freedreno/fdl/fd6_layout.c +++ b/src/freedreno/fdl/fd6_layout.c @@ -157,7 +157,11 @@ fdl6_layout_image(struct fdl_layout *layout, const struct fd_dev_info *info, assert(!params->force_ubwc || layout->ubwc); - if (!params->force_ubwc && params->width0 < FDL_MIN_UBWC_WIDTH) { + layout->linear_fallback_threshold_texels = + fdl_linear_fallback_threshold_texels(layout, info); + + if (!params->force_ubwc && + layout->width0 < layout->linear_fallback_threshold_texels) { layout->ubwc = false; /* Linear D/S is not supported by HW. */ if (!util_format_is_depth_or_stencil(params->format)) diff --git a/src/freedreno/fdl/freedreno_layout.h b/src/freedreno/fdl/freedreno_layout.h index 7613095fc5b..1e1814890de 100644 --- a/src/freedreno/fdl/freedreno_layout.h +++ b/src/freedreno/fdl/freedreno_layout.h @@ -158,6 +158,11 @@ struct fdl_layout { */ uint8_t cpp_shift; + /* In texels the threshold for linear fallback can be different between + * compressed and uncompressed formats. + */ + uint32_t linear_fallback_threshold_texels; + uint32_t width0, height0, depth0; uint32_t mip_levels; uint32_t nr_samples; @@ -234,8 +239,21 @@ fdl_ubwc_offset(const struct fdl_layout *layout, unsigned level, unsigned layer) return slice->offset + layer * layout->ubwc_layer_size; } -/* Minimum layout width to enable UBWC. */ -#define FDL_MIN_UBWC_WIDTH 16 +/* Minimum layout width to enable tiling/UBWC, and width below which + * mipmaps can use LINEAR layout even if previous mipmaps are tiled. + * Can be in texel or blocks, depending on HW support. + */ +#define FDL_LINEAR_FALLBACK_THRESHOLD 16 + +static inline uint32_t +fdl_linear_fallback_threshold_texels(struct fdl_layout *layout, + const struct fd_dev_info *info) +{ + return info->props.supports_linear_mipmap_threshold_in_blocks + ? FDL_LINEAR_FALLBACK_THRESHOLD * + util_format_get_blockwidth(layout->format) + : FDL_LINEAR_FALLBACK_THRESHOLD; +} static inline bool fdl_level_linear(const struct fdl_layout *layout, int level) @@ -244,7 +262,7 @@ fdl_level_linear(const struct fdl_layout *layout, int level) return false; unsigned w = u_minify(layout->width0, level); - if (w < FDL_MIN_UBWC_WIDTH) + if (w < layout->linear_fallback_threshold_texels) return true; return false; diff --git a/src/freedreno/registers/adreno/a6xx.xml b/src/freedreno/registers/adreno/a6xx.xml index 7004cec0a37..0e708554b0f 100644 --- a/src/freedreno/registers/adreno/a6xx.xml +++ b/src/freedreno/registers/adreno/a6xx.xml @@ -4373,8 +4373,9 @@ by a particular renderpass/blit. - - + + +