From f5c1cb23835d79faafc1819069c28b82cfcb5fc2 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Fri, 22 Nov 2019 15:42:46 +0100 Subject: [PATCH] radeonsi: dcc dirty flag MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Reviewed-by: Marek Olšák --- src/gallium/drivers/radeonsi/si_blit.c | 4 +++- src/gallium/drivers/radeonsi/si_clear.c | 1 + src/gallium/drivers/radeonsi/si_pipe.h | 3 +++ src/gallium/drivers/radeonsi/si_state.c | 4 ++++ src/gallium/drivers/radeonsi/si_state_draw.c | 14 ++++++++++++++ src/gallium/drivers/radeonsi/si_texture.c | 1 + 6 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c index 0afed60..6f7cbc2 100644 --- a/src/gallium/drivers/radeonsi/si_blit.c +++ b/src/gallium/drivers/radeonsi/si_blit.c @@ -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. */ diff --git a/src/gallium/drivers/radeonsi/si_clear.c b/src/gallium/drivers/radeonsi/si_clear.c index aab208c..c0aceea 100644 --- a/src/gallium/drivers/radeonsi/si_clear.c +++ b/src/gallium/drivers/radeonsi/si_clear.c @@ -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) { diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index b4e0660..bd0c777 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -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; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 1339383..2651824 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -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) */ diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index 74610d6..9aacc9e 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -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; diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c index 474bc00..161d0db 100644 --- a/src/gallium/drivers/radeonsi/si_texture.c +++ b/src/gallium/drivers/radeonsi/si_texture.c @@ -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); -- 2.7.4