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 <dpiliaiev@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38655>
This commit is contained in:
Danylo Piliaiev 2025-08-19 15:20:06 +02:00 committed by Marge Bot
parent 654b0dd548
commit e347f82aeb
14 changed files with 70 additions and 18 deletions

View file

@ -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.
*/

View file

@ -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,

View file

@ -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

View file

@ -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))

View file

@ -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;

View file

@ -4373,8 +4373,9 @@ by a particular renderpass/blit.
<reg32 offset="0xab21" name="SP_WINDOW_OFFSET" type="a6xx_reg_xy" variants="A7XX" usage="rp_blit"/>
<reg32 offset="0xab07" name="SP_WINDOW_OFFSET" type="a6xx_reg_xy" variants="A8XX-" usage="rp_blit"/>
<!-- always 0x100000 or 0x1000000? -->
<reg32 offset="0xb600" name="TPL1_DBG_ECO_CNTL" low="0" high="25" usage="init"/>
<reg32 offset="0xb600" name="TPL1_DBG_ECO_CNTL" usage="init">
<bitfield name="LINEAR_MIPMAP_FALLBACK_IN_BLOCKS" pos="25" type="boolean" variants="A6XX-A7XX"/>
</reg32>
<reg32 offset="0xb601" name="TPL1_ADDR_MODE_CNTL" type="a5xx_address_mode" variants="A6XX"/>
<reg32 offset="0xb602" name="TPL1_DBG_ECO_CNTL1" usage="init">
<!-- Affects UBWC in some way, if BLIT_OP_SCALE is done with this bit set

View file

@ -1635,7 +1635,7 @@ registers:
deadbeef 0xae50: deadbeef
deadbeef 0xae51: deadbeef
deadbeef SP_CONTEXT_SWITCH_GFX_PREEMPTION_SAFE_MODE: 0xdeadbeef
00000000 TPL1_DBG_ECO_CNTL: 0
00000000 TPL1_DBG_ECO_CNTL: { 0 }
00000001 TPL1_ADDR_MODE_CNTL: ADDR_64B
00000004 TPL1_NC_MODE_CNTL: { LOWER_BIT = 2 | UPPER_BIT = 0 }
00000000 TPL1_UNKNOWN_B605: 0

View file

@ -1848,7 +1848,7 @@ registers:
deadbeef 0xae50: deadbeef
deadbeef 0xae51: deadbeef
deadbeef SP_CONTEXT_SWITCH_GFX_PREEMPTION_SAFE_MODE: 0xdeadbeef
00108000 TPL1_DBG_ECO_CNTL: 0x108000
00108000 TPL1_DBG_ECO_CNTL: { 0x108000 }
00000001 TPL1_ADDR_MODE_CNTL: ADDR_64B
00000002 TPL1_NC_MODE_CNTL: { LOWER_BIT = 1 | UPPER_BIT = 0 }
00000044 TPL1_UNKNOWN_B605: 68
@ -1986,7 +1986,7 @@ got cmdszdw=38
+ 00000000 TPL1_PS_SWIZZLE_CNTL: 0
!+ 100001100 TPL1_GFX_BORDER_COLOR_BASE: 0x100001100 base=100000000, offset=4352, size=532480
!+ 000000a2 TPL1_MODE_CNTL: { ISAMMODE = ISAMMODE_GL | TEXCOORDROUNDMODE = COORD_TRUNCATE | NEARESTMIPSNAP = CLAMP_ROUND_TRUNCATE | DESTDATATYPEOVERRIDE }
!+ 00108000 TPL1_DBG_ECO_CNTL: 0x108000
!+ 00108000 TPL1_DBG_ECO_CNTL: { 0x108000 }
!+ 00000044 TPL1_UNKNOWN_B605: 68
!+ 000000fc SP_REG_PROG_ID_3: { LINELENGTHREGID = r63.x | FOVEATIONQUALITYREGID = r0.x }
!+ 000fffff SP_UPDATE_CNTL: { VS_STATE | HS_STATE | DS_STATE | GS_STATE | FS_STATE | CS_STATE | CS_UAV | GFX_UAV | CS_SHARED_CONST | GFX_SHARED_CONST | CS_BINDLESS = 0x1f | GFX_BINDLESS = 0x1f }
@ -2296,7 +2296,7 @@ got cmdszdw=38
+ 00000000 TPL1_WINDOW_OFFSET: { X = 0 | Y = 0 }
+ 000000a2 TPL1_MODE_CNTL: { ISAMMODE = ISAMMODE_GL | TEXCOORDROUNDMODE = COORD_TRUNCATE | NEARESTMIPSNAP = CLAMP_ROUND_TRUNCATE | DESTDATATYPEOVERRIDE }
+ 00000000 SP_WINDOW_OFFSET: { X = 0 | Y = 0 }
+ 00108000 TPL1_DBG_ECO_CNTL: 0x108000
+ 00108000 TPL1_DBG_ECO_CNTL: { 0x108000 }
+ 00000044 TPL1_UNKNOWN_B605: 68
+ 000000fc SP_REG_PROG_ID_3: { LINELENGTHREGID = r63.x | FOVEATIONQUALITYREGID = r0.x }
+ 000fffff SP_UPDATE_CNTL: { VS_STATE | HS_STATE | DS_STATE | GS_STATE | FS_STATE | CS_STATE | CS_UAV | GFX_UAV | CS_SHARED_CONST | GFX_SHARED_CONST | CS_BINDLESS = 0x1f | GFX_BINDLESS = 0x1f }
@ -5059,7 +5059,7 @@ ESTIMATED CRASH LOCATION!
!+ 00001000 TPL1_A2D_SRC_TEXTURE_PITCH: { PITCH = 512 }
!+ 100082000 TPL1_A2D_SRC_TEXTURE_FLAG_BASE: 0x100082000
+ 00000000 TPL1_A2D_SRC_TEXTURE_FLAG_PITCH: 0
+ 00108000 TPL1_DBG_ECO_CNTL: 0x108000
+ 00108000 TPL1_DBG_ECO_CNTL: { 0x108000 }
+ 00000044 TPL1_UNKNOWN_B605: 68
!+ 000000fc SP_REG_PROG_ID_3: { LINELENGTHREGID = r63.x | FOVEATIONQUALITYREGID = r0.x }
!+ 000fffff SP_UPDATE_CNTL: { VS_STATE | HS_STATE | DS_STATE | GS_STATE | FS_STATE | CS_STATE | CS_UAV | GFX_UAV | CS_SHARED_CONST | GFX_SHARED_CONST | CS_BINDLESS = 0x1f | GFX_BINDLESS = 0x1f }

View file

@ -30,7 +30,7 @@ cmdstream[0]: 265 dwords
TPL1_UNKNOWN_B605: 68
000000000105803c: 0000: 40b60501 00000044
write TPL1_DBG_ECO_CNTL (b600)
TPL1_DBG_ECO_CNTL: 0x100000
TPL1_DBG_ECO_CNTL: { 0x100000 }
0000000001058044: 0000: 40b60001 00100000
write HLSQ_UNKNOWN_BE00 (be00)
HLSQ_UNKNOWN_BE00: 0x80
@ -342,7 +342,7 @@ cmdstream[0]: 265 dwords
+ 00000000 TPL1_PS_SWIZZLE_CNTL: 0
!+ 01011000 TPL1_GFX_BORDER_COLOR_BASE: 0x1011000
!+ 000000a2 TPL1_MODE_CNTL: { ISAMMODE = ISAMMODE_GL | TEXCOORDROUNDMODE = COORD_TRUNCATE | NEARESTMIPSNAP = CLAMP_ROUND_TRUNCATE | DESTDATATYPEOVERRIDE }
!+ 00100000 TPL1_DBG_ECO_CNTL: 0x100000
!+ 00100000 TPL1_DBG_ECO_CNTL: { 0x100000 }
!+ 00000044 TPL1_UNKNOWN_B605: 68
!+ 000000fc SP_REG_PROG_ID_3: { LINELENGTHREGID = r63.x | FOVEATIONQUALITYREGID = r0.x }
!+ 000fffff SP_UPDATE_CNTL: { VS_STATE | HS_STATE | DS_STATE | GS_STATE | FS_STATE | CS_STATE | CS_UAV | GFX_UAV | CS_SHARED_CONST | GFX_SHARED_CONST | CS_BINDLESS = 0x1f | GFX_BINDLESS = 0x1f }

View file

@ -27,7 +27,7 @@ cmdstream[0]: 1023 dwords
TPL1_UNKNOWN_B605: 68
0000000001d91034: 0000: 40b60501 00000044
write TPL1_DBG_ECO_CNTL (b600)
TPL1_DBG_ECO_CNTL: 0x100000
TPL1_DBG_ECO_CNTL: { 0x100000 }
0000000001d9103c: 0000: 40b60001 00100000
write HLSQ_UNKNOWN_BE00 (be00)
HLSQ_UNKNOWN_BE00: 0x80
@ -1102,7 +1102,7 @@ cmdstream[0]: 1023 dwords
+ 00000000 TPL1_MSAA_SAMPLE_POS_CNTL: { 0 }
+ 00000000 TPL1_WINDOW_OFFSET: { X = 0 | Y = 0 }
!+ 000000a2 TPL1_MODE_CNTL: { ISAMMODE = ISAMMODE_GL | TEXCOORDROUNDMODE = COORD_TRUNCATE | NEARESTMIPSNAP = CLAMP_ROUND_TRUNCATE | DESTDATATYPEOVERRIDE }
!+ 00100000 TPL1_DBG_ECO_CNTL: 0x100000
!+ 00100000 TPL1_DBG_ECO_CNTL: { 0x100000 }
!+ 00000044 TPL1_UNKNOWN_B605: 68
!+ 00000100 SP_VS_CONST_CONFIG: { CONSTLEN = 0 | ENABLED }
+ 00000000 SP_HS_CONST_CONFIG: { CONSTLEN = 0 }

View file

@ -2427,7 +2427,7 @@ registers:
deadbeef 0xae50: deadbeef
deadbeef 0xae51: deadbeef
deadbeef SP_CONTEXT_SWITCH_GFX_PREEMPTION_SAFE_MODE: 0xdeadbeef
00108000 TPL1_DBG_ECO_CNTL: 0x108000
00108000 TPL1_DBG_ECO_CNTL: { 0x108000 }
00000001 TPL1_ADDR_MODE_CNTL: ADDR_64B
00000002 TPL1_NC_MODE_CNTL: { LOWER_BIT = 1 | UPPER_BIT = 0 }
00000044 TPL1_UNKNOWN_B605: 68
@ -2607,7 +2607,7 @@ got cmdszdw=416
+ 00000000 TPL1_WINDOW_OFFSET: { X = 0 | Y = 0 }
!+ 000000a2 TPL1_MODE_CNTL: { ISAMMODE = ISAMMODE_GL | TEXCOORDROUNDMODE = COORD_TRUNCATE | NEARESTMIPSNAP = CLAMP_ROUND_TRUNCATE | DESTDATATYPEOVERRIDE }
+ 00000000 SP_WINDOW_OFFSET: { X = 0 | Y = 0 }
!+ 00108000 TPL1_DBG_ECO_CNTL: 0x108000
!+ 00108000 TPL1_DBG_ECO_CNTL: { 0x108000 }
!+ 00000044 TPL1_UNKNOWN_B605: 68
!+ 000000fc SP_REG_PROG_ID_3: { LINELENGTHREGID = r63.x | FOVEATIONQUALITYREGID = r0.x }
!+ 000fffff SP_UPDATE_CNTL: { VS_STATE | HS_STATE | DS_STATE | GS_STATE | FS_STATE | CS_STATE | CS_UAV | GFX_UAV | CS_SHARED_CONST | GFX_SHARED_CONST | CS_BINDLESS = 0x1f | GFX_BINDLESS = 0x1f }

View file

@ -1943,6 +1943,12 @@ tu6_init_static_regs(struct tu_device *dev, struct tu_cs *cs)
uint32_t value = magic_reg.value;
switch(magic_reg.reg) {
case REG_A6XX_TPL1_DBG_ECO_CNTL:
value = (value & ~A6XX_TPL1_DBG_ECO_CNTL_LINEAR_MIPMAP_FALLBACK_IN_BLOCKS) |
(phys_dev->info->props.supports_linear_mipmap_threshold_in_blocks
? A6XX_TPL1_DBG_ECO_CNTL_LINEAR_MIPMAP_FALLBACK_IN_BLOCKS
: 0);
break;
case REG_A6XX_TPL1_DBG_ECO_CNTL1:
value = (value & ~A6XX_TPL1_DBG_ECO_CNTL1_TP_UBWC_FLAG_HINT) |
(phys_dev->info->props.enable_tp_ubwc_flag_hint

View file

@ -854,6 +854,12 @@ fd6_emit_static_non_context_regs(struct fd_context *ctx, fd_cs &cs)
uint32_t value = magic_reg.value;
switch(magic_reg.reg) {
case REG_A6XX_TPL1_DBG_ECO_CNTL:
value = (value & ~A6XX_TPL1_DBG_ECO_CNTL_LINEAR_MIPMAP_FALLBACK_IN_BLOCKS) |
(screen->info->props.supports_linear_mipmap_threshold_in_blocks
? A6XX_TPL1_DBG_ECO_CNTL_LINEAR_MIPMAP_FALLBACK_IN_BLOCKS
: 0);
break;
case REG_A6XX_TPL1_DBG_ECO_CNTL1:
value = (value & ~A6XX_TPL1_DBG_ECO_CNTL1_TP_UBWC_FLAG_HINT) |
(screen->info->props.enable_tp_ubwc_flag_hint

View file

@ -1186,6 +1186,7 @@ fd_resource_resize(struct pipe_resource *prsc, uint32_t sz)
void
fd_resource_layout_init(struct pipe_resource *prsc)
{
const struct fd_dev_info *info = fd_screen(prsc->screen)->info;
struct fd_resource *rsc = fd_resource(prsc);
struct fdl_layout *layout = &rsc->layout;
@ -1198,6 +1199,9 @@ fd_resource_layout_init(struct pipe_resource *prsc)
layout->cpp = util_format_get_blocksize(prsc->format);
layout->cpp *= fd_resource_nr_samples(prsc);
layout->cpp_shift = ffs(util_next_power_of_two(layout->cpp)) - 1;
layout->linear_fallback_threshold_texels =
fdl_linear_fallback_threshold_texels(layout, info);
}
static struct fd_resource *
@ -1372,7 +1376,7 @@ fd_resource_allocate_and_resolve(struct pipe_screen *pscreen,
rsc->b.is_shared = true;
enum fd_layout_type layout =
get_best_layout(screen, tmpl, modifiers, count);
get_best_layout(screen, prsc, modifiers, count);
if (layout == FD_LAYOUT_ERROR) {
free(prsc);
return NULL;