From 07aacdbfd5826ccb1281814610030c346e2c4cfc Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Wed, 5 Jun 2019 01:54:46 -0400 Subject: [PATCH] radeonsi/gfx10: add a workaround for stencil HTILE with mipmapping Acked-by: Bas Nieuwenhuizen --- src/gallium/drivers/radeonsi/si_blit.c | 5 +++-- src/gallium/drivers/radeonsi/si_clear.c | 3 ++- src/gallium/drivers/radeonsi/si_descriptors.c | 3 ++- src/gallium/drivers/radeonsi/si_pipe.h | 10 +++++++--- src/gallium/drivers/radeonsi/si_state.c | 11 ++++++----- src/gallium/drivers/radeonsi/si_texture.c | 8 ++++++++ 6 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c index 9c6e3bc2c54..ff189f1274d 100644 --- a/src/gallium/drivers/radeonsi/si_blit.c +++ b/src/gallium/drivers/radeonsi/si_blit.c @@ -361,8 +361,9 @@ si_decompress_depth(struct si_context *sctx, } if (inplace_planes) { - bool has_htile = si_htile_enabled(tex, first_level); - bool tc_compat_htile = vi_tc_compat_htile_enabled(tex, first_level); + bool has_htile = si_htile_enabled(tex, first_level, inplace_planes); + bool tc_compat_htile = vi_tc_compat_htile_enabled(tex, first_level, + inplace_planes); /* Don't decompress if there is no HTILE or when HTILE is * TC-compatible. */ diff --git a/src/gallium/drivers/radeonsi/si_clear.c b/src/gallium/drivers/radeonsi/si_clear.c index 9a32977243c..00884b438d1 100644 --- a/src/gallium/drivers/radeonsi/si_clear.c +++ b/src/gallium/drivers/radeonsi/si_clear.c @@ -593,11 +593,11 @@ static void si_clear(struct pipe_context *ctx, unsigned buffers, } if (zstex && - si_htile_enabled(zstex, zsbuf->u.tex.level) && zsbuf->u.tex.first_layer == 0 && zsbuf->u.tex.last_layer == util_max_layer(&zstex->buffer.b.b, 0)) { /* TC-compatible HTILE only supports depth clears to 0 or 1. */ if (buffers & PIPE_CLEAR_DEPTH && + si_htile_enabled(zstex, zsbuf->u.tex.level, PIPE_MASK_Z) && (!zstex->tc_compatible_htile || depth == 0 || depth == 1)) { /* Need to disable EXPCLEAR temporarily if clearing @@ -618,6 +618,7 @@ static void si_clear(struct pipe_context *ctx, unsigned buffers, /* TC-compatible HTILE only supports stencil clears to 0. */ if (buffers & PIPE_CLEAR_STENCIL && + si_htile_enabled(zstex, zsbuf->u.tex.level, PIPE_MASK_S) && (!zstex->tc_compatible_htile || stencil == 0)) { stencil &= 0xff; diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index 006656ddc2e..591986c30a6 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -354,7 +354,8 @@ void si_set_mutable_tex_desc_fields(struct si_screen *sscreen, unsigned dcc_tile_swizzle = tex->surface.tile_swizzle << 8; dcc_tile_swizzle &= tex->surface.dcc_alignment - 1; meta_va |= dcc_tile_swizzle; - } else if (vi_tc_compat_htile_enabled(tex, first_level)) { + } else if (vi_tc_compat_htile_enabled(tex, first_level, + is_stencil ? PIPE_MASK_S : PIPE_MASK_Z)) { meta_va = tex->buffer.gpu_address + tex->htile_offset; } diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 06508beb9f2..a9080c93505 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -313,6 +313,7 @@ struct si_texture { enum pipe_format db_render_format:16; uint8_t stencil_clear_value; bool tc_compatible_htile:1; + bool htile_stencil_disabled:1; bool depth_cleared:1; /* if it was cleared at least once */ bool stencil_cleared:1; /* if it was cleared at least once */ bool upgraded_depth:1; /* upgraded from unorm to Z32_FLOAT */ @@ -1725,16 +1726,19 @@ si_can_sample_zs(struct si_texture *tex, bool stencil_sampler) } static inline bool -si_htile_enabled(struct si_texture *tex, unsigned level) +si_htile_enabled(struct si_texture *tex, unsigned level, unsigned zs_mask) { + if (zs_mask == PIPE_MASK_S && tex->htile_stencil_disabled) + return false; + return tex->htile_offset && level == 0; } static inline bool -vi_tc_compat_htile_enabled(struct si_texture *tex, unsigned level) +vi_tc_compat_htile_enabled(struct si_texture *tex, unsigned level, unsigned zs_mask) { assert(!tex->tc_compatible_htile || tex->htile_offset); - return tex->tc_compatible_htile && level == 0; + return tex->tc_compatible_htile && si_htile_enabled(tex, level, zs_mask); } static inline unsigned si_get_ps_iter_samples(struct si_context *sctx) diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 40de130a34f..3b3ee913c79 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -2646,7 +2646,7 @@ static void si_init_depth_surface(struct si_context *sctx, surf->db_depth_size = S_02801C_X_MAX(tex->buffer.b.b.width0 - 1) | S_02801C_Y_MAX(tex->buffer.b.b.height0 - 1); - if (si_htile_enabled(tex, level)) { + if (si_htile_enabled(tex, level, PIPE_MASK_ZS)) { z_info |= S_028038_TILE_SURFACE_ENABLE(1) | S_028038_ALLOW_EXPCLEAR(1); @@ -2661,14 +2661,14 @@ static void si_init_depth_surface(struct si_context *sctx, if (sctx->chip_class >= GFX10) { z_info |= S_028040_ITERATE_FLUSH(1); - s_info |= S_028044_ITERATE_FLUSH(1); + s_info |= S_028044_ITERATE_FLUSH(!tex->htile_stencil_disabled); } else { z_info |= S_028038_ITERATE_FLUSH(1); s_info |= S_02803C_ITERATE_FLUSH(1); } } - if (tex->surface.has_stencil) { + if (tex->surface.has_stencil && !tex->htile_stencil_disabled) { /* Stencil buffer workaround ported from the GFX6-GFX8 code. * See that for explanation. */ @@ -2733,7 +2733,7 @@ static void si_init_depth_surface(struct si_context *sctx, surf->db_depth_slice = S_02805C_SLICE_TILE_MAX((levelinfo->nblk_x * levelinfo->nblk_y) / 64 - 1); - if (si_htile_enabled(tex, level)) { + if (si_htile_enabled(tex, level, PIPE_MASK_ZS)) { z_info |= S_028040_TILE_SURFACE_ENABLE(1) | S_028040_ALLOW_EXPCLEAR(1); @@ -3048,7 +3048,8 @@ static void si_set_framebuffer_state(struct pipe_context *ctx, si_init_depth_surface(sctx, surf); } - if (vi_tc_compat_htile_enabled(zstex, surf->base.u.tex.level)) + if (vi_tc_compat_htile_enabled(zstex, surf->base.u.tex.level, + PIPE_MASK_ZS)) sctx->framebuffer.DB_has_shader_readable_metadata = true; si_context_add_resource_size(sctx, surf->base.texture); diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c index 7bbffe359b3..477ea2fa0bc 100644 --- a/src/gallium/drivers/radeonsi/si_texture.c +++ b/src/gallium/drivers/radeonsi/si_texture.c @@ -1272,6 +1272,14 @@ si_texture_create_object(struct pipe_screen *screen, if (sscreen->info.chip_class >= GFX9) { tex->can_sample_z = true; tex->can_sample_s = true; + + /* Stencil texturing with HTILE doesn't work + * with mipmapping on Navi10-14. */ + if ((sscreen->info.family == CHIP_NAVI10 || + sscreen->info.family == CHIP_NAVI12 || + sscreen->info.family == CHIP_NAVI14) && + base->last_level > 0) + tex->htile_stencil_disabled = true; } else { tex->can_sample_z = !tex->surface.u.legacy.depth_adjusted; tex->can_sample_s = !tex->surface.u.legacy.stencil_adjusted; -- 2.30.2