[Mesa-dev] [PATCH v3 7/7] radeonsi: Add DCC compression tracking machinery.

Bas Nieuwenhuizen bas at basnieuwenhuizen.nl
Tue Oct 20 15:10:42 PDT 2015


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 <bas at 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 4391665..6ef0108 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -1374,6 +1374,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 f43965a..2328468 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 (rtex->surface.dcc_enabled && need_dcc_decompress) {
+		if ((rtex->dcc_compressed_level_mask & (1 << level)) && need_dcc_decompress) {
 			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 c9b33a1..445fd06 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -126,6 +126,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 52e9ee5..985c927 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -2142,6 +2142,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] &&
@@ -2168,6 +2169,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 29c40d2..eed5e52 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -887,6 +887,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.6.1



More information about the mesa-dev mailing list