[Mesa-dev] [PATCH 2/8] radeonsi: Add DCC compression tracking machinery.

Bas Nieuwenhuizen bas at basnieuwenhuizen.nl
Fri Sep 4 12:47:09 PDT 2015


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 <bas at 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



More information about the mesa-dev mailing list