radeonsi: dcc dirty flag
authorPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Fri, 22 Nov 2019 14:42:46 +0000 (15:42 +0100)
committerPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Tue, 10 Dec 2019 08:25:28 +0000 (09:25 +0100)
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/gallium/drivers/radeonsi/si_blit.c
src/gallium/drivers/radeonsi/si_clear.c
src/gallium/drivers/radeonsi/si_pipe.h
src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_state_draw.c
src/gallium/drivers/radeonsi/si_texture.c

index 0afed60ae5ba358dc6c03f960141f74e2ba18f93..6f7cbc22dc77639fd444c2035ee8240a5a42aa7d 100644 (file)
@@ -1302,8 +1302,10 @@ static void si_flush_resource(struct pipe_context *ctx,
                                         0, util_max_layer(res, 0),
                                         tex->dcc_separate_buffer != NULL, false);
 
-               if (tex->surface.display_dcc_offset)
+               if (tex->surface.display_dcc_offset && tex->displayable_dcc_dirty) {
                        si_retile_dcc(sctx, tex);
+                       tex->displayable_dcc_dirty = false;
+               }
        }
 
        /* Always do the analysis even if DCC is disabled at the moment. */
index aab208c5ed6db7de1893d4c3a322423affbe811b..c0aceea66c4fd4d0e68768146c2314344ee1496d 100644 (file)
@@ -510,6 +510,7 @@ static void si_do_fast_color_clear(struct si_context *sctx,
                                continue;
 
                        tex->separate_dcc_dirty = true;
+                       tex->displayable_dcc_dirty = true;
 
                        /* DCC fast clear with MSAA should clear CMASK to 0xC. */
                        if (tex->buffer.b.b.nr_samples >= 2 && tex->cmask_buffer) {
index b4e066095820a8a3ed8a59be148cf82cb682f282..bd0c777c148be08a0fe0976849fc68ef91e6cb81 100644 (file)
@@ -332,6 +332,8 @@ struct si_texture {
         * for a possible future enablement.
         */
        bool                            separate_dcc_dirty:1;
+       bool                            displayable_dcc_dirty:1;
+
        /* Statistics gathering for the DCC enablement heuristic. */
        bool                            dcc_gather_statistics:1;
        /* Counter that should be non-zero if the texture is bound to a
@@ -670,6 +672,7 @@ struct si_framebuffer {
        ubyte                           nr_color_samples; /* at most 8xAA */
        ubyte                           compressed_cb_mask;
        ubyte                           uncompressed_cb_mask;
+       ubyte                           displayable_dcc_cb_mask;
        ubyte                           color_is_int8;
        ubyte                           color_is_int10;
        ubyte                           dirty_cbufs;
index 1339383610f560f8d2a07b1512a478995e740176..26518244c5427137981b844c4ef47dc662c83bc2 100644 (file)
@@ -2984,6 +2984,7 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
 
        sctx->framebuffer.compressed_cb_mask = 0;
        sctx->framebuffer.uncompressed_cb_mask = 0;
+       sctx->framebuffer.displayable_dcc_cb_mask = 0;
        sctx->framebuffer.nr_samples = util_framebuffer_get_num_samples(state);
        sctx->framebuffer.nr_color_samples = sctx->framebuffer.nr_samples;
        sctx->framebuffer.log_samples = util_logbase2(sctx->framebuffer.nr_samples);
@@ -3024,6 +3025,9 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
                else
                        sctx->framebuffer.uncompressed_cb_mask |= 1 << i;
 
+               if (tex->surface.dcc_offset)
+                       sctx->framebuffer.displayable_dcc_cb_mask |= 1 << i;
+
                /* Don't update nr_color_samples for non-AA buffers.
                 * (e.g. destination of MSAA resolve)
                 */
index 74610d600cf845e30950094a1e03ede89d6735ee..9aacc9e176d7feef6aab8eb6351a449d0a627af9 100644 (file)
@@ -2142,6 +2142,20 @@ static void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *i
                        cik_emit_prefetch_L2(sctx, false);
        }
 
+       /* Mark the displayable dcc buffer as dirty in order to update
+        * it on the next call to si_flush_resource. */
+       if (sctx->screen->info.use_display_dcc_with_retile_blit) {
+               /* Don't use si_update_fb_dirtiness_after_rendering because it'll
+                * cause unnecessary texture decompressions on each draw. */
+               unsigned displayable_dcc_cb_mask = sctx->framebuffer.displayable_dcc_cb_mask;
+               while (displayable_dcc_cb_mask) {
+                       unsigned i = u_bit_scan(&displayable_dcc_cb_mask);
+                       struct pipe_surface *surf = sctx->framebuffer.state.cbufs[i];
+                       struct si_texture *tex = (struct si_texture*) surf->texture;
+                       tex->displayable_dcc_dirty = true;
+               }
+       }
+
        /* Clear the context roll flag after the draw call. */
        sctx->context_roll = false;
 
index 474bc00f8c4f18181db5757cfc554475caaa1619..161d0db7d4f03656a8e9450beb05954bc552bcc8 100644 (file)
@@ -620,6 +620,7 @@ static void si_reallocate_texture_inplace(struct si_context *sctx,
        tex->can_sample_s = new_tex->can_sample_s;
 
        tex->separate_dcc_dirty = new_tex->separate_dcc_dirty;
+       tex->displayable_dcc_dirty = new_tex->displayable_dcc_dirty;
        tex->dcc_gather_statistics = new_tex->dcc_gather_statistics;
        si_resource_reference(&tex->dcc_separate_buffer,
                                new_tex->dcc_separate_buffer);