@@ -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. */ |
@@ -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) { |
@@ -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; |
@@ -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) | |||
*/ |
@@ -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; | |||
@@ -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); |