r600g: only do depth-only or stencil-only in-place decompression
authorMarek Olšák <marek.olsak@amd.com>
Sun, 6 Sep 2015 15:37:38 +0000 (17:37 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Sat, 3 Oct 2015 20:06:08 +0000 (22:06 +0200)
instead of always doing both.
Usually, only depth is needed, so stencil decompression is useless.

Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/r600_blit.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_state.c

index 6169c5b719befd7bc24142c61589373d38f9f547..c6702a9ca3400fb1a49eb797df01853e0fe447bf 100644 (file)
@@ -783,6 +783,12 @@ evergreen_create_sampler_view_custom(struct pipe_context *ctx,
 
        va = tmp->resource.gpu_address;
 
+       if (state->format == PIPE_FORMAT_X24S8_UINT ||
+           state->format == PIPE_FORMAT_S8X24_UINT ||
+           state->format == PIPE_FORMAT_X32_S8X24_UINT ||
+           state->format == PIPE_FORMAT_S8_UINT)
+               view->is_stencil_sampler = true;
+
        view->tex_resource = &tmp->resource;
        view->tex_resource_words[0] = (S_030000_DIM(r600_tex_dim(texture->target, texture->nr_samples)) |
                                       S_030000_PITCH((pitch / 8) - 1) |
@@ -1823,9 +1829,9 @@ static void evergreen_emit_db_misc_state(struct r600_context *rctx, struct r600_
                                     S_028000_STENCIL_COPY_ENABLE(a->copy_stencil) |
                                     S_028000_COPY_CENTROID(1) |
                                     S_028000_COPY_SAMPLE(a->copy_sample);
-       } else if (a->flush_depthstencil_in_place) {
-               db_render_control |= S_028000_DEPTH_COMPRESS_DISABLE(1) |
-                                    S_028000_STENCIL_COMPRESS_DISABLE(1);
+       } else if (a->flush_depth_inplace || a->flush_stencil_inplace) {
+               db_render_control |= S_028000_DEPTH_COMPRESS_DISABLE(a->flush_depth_inplace) |
+                                    S_028000_STENCIL_COMPRESS_DISABLE(a->flush_stencil_inplace);
                db_render_override |= S_02800C_DISABLE_PIXEL_RATE_TILES(1);
        }
        if (a->htile_clear) {
index d1370cd8f26f07ceef0e19716e8e6110b60cfeb9..aede84084469af4e7150b2bbcacf750666bd1f56 100644 (file)
@@ -202,20 +202,28 @@ static void r600_blit_decompress_depth(struct pipe_context *ctx,
 
 static void r600_blit_decompress_depth_in_place(struct r600_context *rctx,
                                                 struct r600_texture *texture,
+                                               bool is_stencil_sampler,
                                                 unsigned first_level, unsigned last_level,
                                                 unsigned first_layer, unsigned last_layer)
 {
        struct pipe_surface *zsurf, surf_tmpl = {{0}};
        unsigned layer, max_layer, checked_last_layer, level;
+       unsigned *dirty_level_mask;
 
        /* Enable decompression in DB_RENDER_CONTROL */
-       rctx->db_misc_state.flush_depthstencil_in_place = true;
+       if (is_stencil_sampler) {
+               rctx->db_misc_state.flush_stencil_inplace = true;
+               dirty_level_mask = &texture->stencil_dirty_level_mask;
+       } else {
+               rctx->db_misc_state.flush_depth_inplace = true;
+               dirty_level_mask = &texture->dirty_level_mask;
+       }
        r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom);
 
        surf_tmpl.format = texture->resource.b.b.format;
 
        for (level = first_level; level <= last_level; level++) {
-               if (!(texture->dirty_level_mask & (1 << level)))
+               if (!(*dirty_level_mask & (1 << level)))
                        continue;
 
                surf_tmpl.u.tex.level = level;
@@ -242,12 +250,13 @@ static void r600_blit_decompress_depth_in_place(struct r600_context *rctx,
                /* The texture will always be dirty if some layers or samples aren't flushed.
                 * I don't think this case occurs often though. */
                if (first_layer == 0 && last_layer == max_layer) {
-                       texture->dirty_level_mask &= ~(1 << level);
+                       *dirty_level_mask &= ~(1 << level);
                }
        }
 
        /* Disable decompression in DB_RENDER_CONTROL */
-       rctx->db_misc_state.flush_depthstencil_in_place = false;
+       rctx->db_misc_state.flush_depth_inplace = false;
+       rctx->db_misc_state.flush_stencil_inplace = false;
        r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom);
 }
 
@@ -259,12 +268,14 @@ void r600_decompress_depth_textures(struct r600_context *rctx,
 
        while (depth_texture_mask) {
                struct pipe_sampler_view *view;
+               struct r600_pipe_sampler_view *rview;
                struct r600_texture *tex;
 
                i = u_bit_scan(&depth_texture_mask);
 
                view = &textures->views[i]->base;
                assert(view);
+               rview = (struct r600_pipe_sampler_view*)view;
 
                tex = (struct r600_texture *)view->texture;
                assert(tex->is_depth && !tex->is_flushing_texture);
@@ -272,6 +283,7 @@ void r600_decompress_depth_textures(struct r600_context *rctx,
                if (rctx->b.chip_class >= EVERGREEN ||
                    r600_can_read_depth(tex)) {
                        r600_blit_decompress_depth_in_place(rctx, tex,
+                                                  rview->is_stencil_sampler,
                                                   view->u.tex.first_level, view->u.tex.last_level,
                                                   0, util_max_layer(&tex->resource.b.b, view->u.tex.first_level));
                } else {
@@ -367,9 +379,14 @@ static bool r600_decompress_subresource(struct pipe_context *ctx,
        if (rtex->is_depth && !rtex->is_flushing_texture) {
                if (rctx->b.chip_class >= EVERGREEN ||
                    r600_can_read_depth(rtex)) {
-                       r600_blit_decompress_depth_in_place(rctx, rtex,
+                       r600_blit_decompress_depth_in_place(rctx, rtex, false,
                                                   level, level,
                                                   first_layer, last_layer);
+                       if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
+                               r600_blit_decompress_depth_in_place(rctx, rtex, true,
+                                                          level, level,
+                                                          first_layer, last_layer);
+                       }
                } else {
                        if (!r600_init_flushed_depth_texture(ctx, tex, NULL))
                                return false; /* error */
index d0774de857366c8509f55991424e1825f81c0aa5..520b03f605da83b17b0ace2b8a6fbfac5940e12c 100644 (file)
@@ -109,7 +109,8 @@ struct r600_db_misc_state {
        struct r600_atom                atom;
        bool                            occlusion_query_enabled;
        bool                            flush_depthstencil_through_cb;
-       bool                            flush_depthstencil_in_place;
+       bool                            flush_depth_inplace;
+       bool                            flush_stencil_inplace;
        bool                            copy_depth, copy_stencil;
        unsigned                        copy_sample;
        unsigned                        log_samples;
@@ -253,6 +254,7 @@ struct r600_pipe_sampler_view {
        struct r600_resource            *tex_resource;
        uint32_t                        tex_resource_words[8];
        bool                            skip_mip_address_reloc;
+       bool                            is_stencil_sampler;
 };
 
 struct r600_rasterizer_state {
index 4b171894f5c2c0ea87fb94576aabc453a03efa5a..1be3e1b4de50d888052a893d58dd76d2f3d2cb5e 100644 (file)
@@ -710,6 +710,12 @@ r600_create_sampler_view_custom(struct pipe_context *ctx,
                break;
        }
 
+       if (state->format == PIPE_FORMAT_X24S8_UINT ||
+           state->format == PIPE_FORMAT_S8X24_UINT ||
+           state->format == PIPE_FORMAT_X32_S8X24_UINT ||
+           state->format == PIPE_FORMAT_S8_UINT)
+               view->is_stencil_sampler = true;
+
        view->tex_resource = &tmp->resource;
        view->tex_resource_words[0] = (S_038000_DIM(r600_tex_dim(texture->target, texture->nr_samples)) |
                                       S_038000_TILE_MODE(array_mode) |
@@ -1659,9 +1665,9 @@ static void r600_emit_db_misc_state(struct r600_context *rctx, struct r600_atom
                if (rctx->b.family == CHIP_RV610 || rctx->b.family == CHIP_RV630 ||
                    rctx->b.family == CHIP_RV620 || rctx->b.family == CHIP_RV635)
                        db_render_override |= S_028D10_FORCE_HIZ_ENABLE(V_028D10_FORCE_DISABLE);
-       } else if (a->flush_depthstencil_in_place) {
-               db_render_control |= S_028D0C_DEPTH_COMPRESS_DISABLE(1) |
-                                    S_028D0C_STENCIL_COMPRESS_DISABLE(1);
+       } else if (a->flush_depth_inplace || a->flush_stencil_inplace) {
+               db_render_control |= S_028D0C_DEPTH_COMPRESS_DISABLE(a->flush_depth_inplace) |
+                                    S_028D0C_STENCIL_COMPRESS_DISABLE(a->flush_stencil_inplace);
                db_render_override |= S_028D10_NOOP_CULL_DISABLE(1);
        }
        if (a->htile_clear) {