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. - - + + +