As textures can be sampled without decompression and the fastclear bits can be erased without decompressing, so add a new set of flags.
Signed-off-by: Bas Nieuwenhuizen <b...@basnieuwenhuizen.nl> --- src/gallium/drivers/radeon/r600_pipe_common.h | 2 ++ src/gallium/drivers/radeonsi/cik_sdma.c | 6 ++++-- src/gallium/drivers/radeonsi/si_blit.c | 9 +++++---- src/gallium/drivers/radeonsi/si_descriptors.c | 2 +- src/gallium/drivers/radeonsi/si_dma.c | 6 ++++-- src/gallium/drivers/radeonsi/si_pipe.h | 1 + src/gallium/drivers/radeonsi/si_state.c | 5 +++++ src/gallium/drivers/radeonsi/si_state_draw.c | 14 ++++++++++++++ 8 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index 4bbecca..f05318f 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -204,6 +204,8 @@ struct r600_texture { unsigned pitch_override; bool is_depth; unsigned 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/radeonsi/cik_sdma.c b/src/gallium/drivers/radeonsi/cik_sdma.c index 8b0ce9f..421dc15 100644 --- a/src/gallium/drivers/radeonsi/cik_sdma.c +++ b/src/gallium/drivers/radeonsi/cik_sdma.c @@ -242,11 +242,13 @@ void cik_sdma_copy(struct pipe_context *ctx, if (src->format != dst->format || rdst->surface.nsamples > 1 || rsrc->surface.nsamples > 1 || - rdst->dirty_level_mask & (1 << dst_level)) { + rdst->dirty_level_mask & (1 << dst_level) || + rdst->dcc_compressed_level_mask & (1 << dst_level)) { goto fallback; } - if (rsrc->dirty_level_mask & (1 << src_level)) { + if (rsrc->dirty_level_mask & (1 << src_level) || + rsrc->dcc_compressed_level_mask & (1 << src_level)) { if (rsrc->htile_buffer) goto fallback; diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c index 93fa67a..13bb457 100644 --- a/src/gallium/drivers/radeonsi/si_blit.c +++ b/src/gallium/drivers/radeonsi/si_blit.c @@ -260,7 +260,7 @@ 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) + if (!rtex->dirty_level_mask && !rtex->dcc_compressed_level_mask) return; for (level = first_level; level <= last_level; level++) { @@ -294,6 +294,7 @@ 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); + rtex->dcc_compressed_level_mask &= ~(1 << level); } } } @@ -314,7 +315,7 @@ void si_decompress_color_textures(struct si_context *sctx, assert(view); tex = (struct r600_texture *)view->texture; - assert(tex->cmask.size || tex->fmask.size); + assert(tex->cmask.size || tex->fmask.size || tex->dcc_buffer); si_blit_decompress_color(&sctx->b.b, tex, view->u.tex.first_level, view->u.tex.last_level, @@ -439,7 +440,7 @@ static void si_decompress_subresource(struct pipe_context *ctx, si_blit_decompress_depth_in_place(sctx, rtex, level, level, first_layer, last_layer); - } else if (rtex->fmask.size || rtex->cmask.size) { + } else if (rtex->fmask.size || rtex->cmask.size || rtex->dcc_buffer) { si_blit_decompress_color(ctx, rtex, level, level, first_layer, last_layer); } @@ -708,7 +709,7 @@ static void si_flush_resource(struct pipe_context *ctx, assert(res->target != PIPE_BUFFER); - if (!rtex->is_depth && rtex->cmask.size) { + if (!rtex->is_depth && (rtex->cmask.size || rtex->dcc_buffer)) { si_blit_decompress_color(ctx, rtex, 0, res->last_level, 0, util_max_layer(res, 0)); } diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index 92a7068..d7cad23 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -240,7 +240,7 @@ static void si_set_sampler_views(struct pipe_context *ctx, } else { samplers->depth_texture_mask &= ~(1 << slot); } - if (rtex->cmask.size || rtex->fmask.size) { + if (rtex->cmask.size || rtex->fmask.size || rtex->dcc_buffer) { samplers->compressed_colortex_mask |= 1 << slot; } else { samplers->compressed_colortex_mask &= ~(1 << slot); diff --git a/src/gallium/drivers/radeonsi/si_dma.c b/src/gallium/drivers/radeonsi/si_dma.c index 309ae04..03ce4ba 100644 --- a/src/gallium/drivers/radeonsi/si_dma.c +++ b/src/gallium/drivers/radeonsi/si_dma.c @@ -247,12 +247,14 @@ void si_dma_copy(struct pipe_context *ctx, if (src->format != dst->format || src_box->depth > 1 || rdst->dirty_level_mask != 0 || + rdst->dcc_compressed_level_mask != 0 || rdst->cmask.size || rdst->fmask.size || - rsrc->cmask.size || rsrc->fmask.size) { + rsrc->cmask.size || rsrc->fmask.size || + rsrc->dcc_buffer || rdst->dcc_buffer) { goto fallback; } - if (rsrc->dirty_level_mask) { + if (rsrc->dirty_level_mask || rsrc->dcc_compressed_level_mask) { ctx->flush_resource(ctx, src); } diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 847853e..d9c7871 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -124,6 +124,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 1e2f32a..faef2ee 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -2116,6 +2116,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] && @@ -2142,6 +2143,10 @@ 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->dcc_buffer) { + 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 8cb98d7..60fc408 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -866,6 +866,20 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) rtex->dirty_level_mask |= 1 << surf->u.tex.level; } 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.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev