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