radeonsi/gfx10: add a workaround for stencil HTILE with mipmapping
authorMarek Olšák <marek.olsak@amd.com>
Wed, 5 Jun 2019 05:54:46 +0000 (01:54 -0400)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 3 Jul 2019 19:51:13 +0000 (15:51 -0400)
Acked-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
src/gallium/drivers/radeonsi/si_blit.c
src/gallium/drivers/radeonsi/si_clear.c
src/gallium/drivers/radeonsi/si_descriptors.c
src/gallium/drivers/radeonsi/si_pipe.h
src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_texture.c

index 9c6e3bc2c5465a3a1019ea71b5d195b86516a040..ff189f1274d62d1623d4108a21134c406dfd8870 100644 (file)
@@ -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. */
index 9a32977243c0051b510adb5e726684e5b08bb326..00884b438d1820d9f120e653d3af47ab2d01c686 100644 (file)
@@ -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;
 
index 006656ddc2eb50f71abe599624a7ad1593ada974..591986c30a605f0ae2b7414f5ad04b56f4c87cbf 100644 (file)
@@ -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;
                }
 
index 06508beb9f2a9f5b13bc4bbc3887303b7235093b..a9080c93505f9f87a4d1b973a062583bcb0e94c0 100644 (file)
@@ -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)
index 40de130a34f45f5fa669dda21a8afe76f6e8b0e0..3b3ee913c799a3cfeecfe90bbfc3bb8fce1c1ec3 100644 (file)
@@ -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);
index 7bbffe359b350b3d510306451c84807a1624a845..477ea2fa0bc52541a2a1810df1ddd6ef2fd9d0d6 100644 (file)
@@ -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;