summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2019-06-05 01:54:46 -0400
committerMarek Olšák <[email protected]>2019-07-03 15:51:13 -0400
commit07aacdbfd5826ccb1281814610030c346e2c4cfc (patch)
treeacfac26b4f4f2772938d49ac5907e50a682dfd83
parent51db950419b810243468b6aa626b154b3fdc94f0 (diff)
radeonsi/gfx10: add a workaround for stencil HTILE with mipmapping
Acked-by: Bas Nieuwenhuizen <[email protected]>
-rw-r--r--src/gallium/drivers/radeonsi/si_blit.c5
-rw-r--r--src/gallium/drivers/radeonsi/si_clear.c3
-rw-r--r--src/gallium/drivers/radeonsi/si_descriptors.c3
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.h10
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c11
-rw-r--r--src/gallium/drivers/radeonsi/si_texture.c8
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;