Add a mask to track if a texture level is still in its decompressed state or that we would need to decompress again.
Signed-off-by: Bas Nieuwenhuizen <b...@basnieuwenhuizen.nl> --- src/gallium/drivers/radeon/r600_pipe_common.h | 1 + src/gallium/drivers/radeon/r600_texture.c | 1 + src/gallium/drivers/radeonsi/si_blit.c | 9 ++++++--- src/gallium/drivers/radeonsi/si_pipe.h | 1 + src/gallium/drivers/radeonsi/si_state.c | 6 ++++++ src/gallium/drivers/radeonsi/si_state_draw.c | 14 ++++++++++++++ 6 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index f21a0b3..6e82ba6 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -206,6 +206,7 @@ struct r600_texture { bool is_depth; unsigned dirty_level_mask; /* each bit says if that mipmap is compressed */ unsigned stencil_dirty_level_mask; /* each bit says if that mipmap is compressed */ + unsigned dcc_compressed_level_mask; struct r600_texture *flushed_depth_texture; boolean is_flushing_texture; struct radeon_surf surface; diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index 90e47ba..1d3bf32 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -1347,6 +1347,7 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx, rctx->clear_buffer(&rctx->b, &tex->dcc_buffer->b.b, 0, tex->surface.dcc_size, reset_value, true); + tex->dcc_compressed_level_mask |= 1 << fb->cbufs[i]->u.tex.level; if (clear_words_needed) tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level; } else { diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c index 82d323e..73adf43 100644 --- a/src/gallium/drivers/radeonsi/si_blit.c +++ b/src/gallium/drivers/radeonsi/si_blit.c @@ -273,16 +273,17 @@ static void si_blit_decompress_color(struct pipe_context *ctx, struct si_context *sctx = (struct si_context *)ctx; unsigned layer, level, checked_last_layer, max_layer; - if (!rtex->dirty_level_mask && !need_dcc_decompress) + if (!rtex->dirty_level_mask && (!need_dcc_decompress || !rtex->dcc_compressed_level_mask)) return; for (level = first_level; level <= last_level; level++) { void* custom_blend; - if (!(rtex->dirty_level_mask & (1 << level)) && !need_dcc_decompress) + if (!(rtex->dirty_level_mask & (1 << level)) && + (!need_dcc_decompress || !(rtex->dcc_compressed_level_mask & (1 << level)))) continue; - if(need_dcc_decompress) { + if(need_dcc_decompress && (rtex->dcc_compressed_level_mask & (1 << level))) { custom_blend = sctx->custom_blend_dcc_decompress; } else if(rtex->fmask.size) { custom_blend = sctx->custom_blend_decompress; @@ -315,6 +316,8 @@ static void si_blit_decompress_color(struct pipe_context *ctx, * I don't think this case occurs often though. */ if (first_layer == 0 && last_layer == max_layer) { rtex->dirty_level_mask &= ~(1 << level); + if(custom_blend == sctx->custom_blend_dcc_decompress) + rtex->dcc_compressed_level_mask &= ~(1 << level); } } } diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 8c751c6..45f9475 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -127,6 +127,7 @@ struct si_framebuffer { unsigned log_samples; unsigned cb0_is_integer; unsigned compressed_cb_mask; + unsigned dcc_compressed_cb_mask; unsigned export_16bpc; unsigned dirty_cbufs; bool dirty_zsbuf; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 46f7341..f8218ac 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -2132,6 +2132,7 @@ static void si_set_framebuffer_state(struct pipe_context *ctx, sctx->framebuffer.export_16bpc = 0; sctx->framebuffer.compressed_cb_mask = 0; + sctx->framebuffer.dcc_compressed_cb_mask = 0; sctx->framebuffer.nr_samples = util_framebuffer_get_num_samples(state); sctx->framebuffer.log_samples = util_logbase2(sctx->framebuffer.nr_samples); sctx->framebuffer.cb0_is_integer = state->nr_cbufs && state->cbufs[0] && @@ -2158,6 +2159,11 @@ static void si_set_framebuffer_state(struct pipe_context *ctx, if (rtex->fmask.size && rtex->cmask.size) { sctx->framebuffer.compressed_cb_mask |= 1 << i; } + + if (rtex->surface.dcc_enabled) { + sctx->framebuffer.dcc_compressed_cb_mask |= 1 << i; + } + r600_context_add_resource_size(ctx, surf->base.texture); } /* Set the 16BPC export for possible dual-src blending. */ diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index c42d7cd..4616962 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -879,6 +879,20 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) } while (mask); } + if (sctx->framebuffer.dcc_compressed_cb_mask) { + struct pipe_surface *surf; + struct r600_texture *rtex; + unsigned mask = sctx->framebuffer.dcc_compressed_cb_mask; + + do { + unsigned i = u_bit_scan(&mask); + surf = sctx->framebuffer.state.cbufs[i]; + rtex = (struct r600_texture*)surf->texture; + + rtex->dcc_compressed_level_mask |= 1 << surf->u.tex.level; + } while (mask); + } + pipe_resource_reference(&ib.buffer, NULL); sctx->b.num_draw_calls++; } -- 2.5.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev