[Mesa-dev] [PATCH 12/16] radeonsi: don't update clear color registers if they don't change

Marek Olšák maraeo at gmail.com
Wed May 2 04:00:36 UTC 2018


From: Marek Olšák <marek.olsak at amd.com>

---
 src/gallium/drivers/radeonsi/si_clear.c | 32 ++++++++++++++++---------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_clear.c b/src/gallium/drivers/radeonsi/si_clear.c
index 8ecd47fea9b..0f3546b02da 100644
--- a/src/gallium/drivers/radeonsi/si_clear.c
+++ b/src/gallium/drivers/radeonsi/si_clear.c
@@ -58,21 +58,21 @@ static void si_alloc_separate_cmask(struct si_screen *sscreen,
 	}
 
 	/* update colorbuffer state bits */
 	rtex->cmask.base_address_reg = rtex->cmask_buffer->gpu_address >> 8;
 
 	rtex->cb_color_info |= S_028C70_FAST_CLEAR(1);
 
 	p_atomic_inc(&sscreen->compressed_colortex_counter);
 }
 
-static void si_set_clear_color(struct r600_texture *rtex,
+static bool si_set_clear_color(struct r600_texture *rtex,
 			       enum pipe_format surface_format,
 			       const union pipe_color_union *color)
 {
 	union util_color uc;
 
 	memset(&uc, 0, sizeof(uc));
 
 	if (rtex->surface.bpe == 16) {
 		/* DCC fast clear only:
 		 *   CLEAR_WORD0 = R = G = B
@@ -83,21 +83,25 @@ static void si_set_clear_color(struct r600_texture *rtex,
 		uc.ui[0] = color->ui[0];
 		uc.ui[1] = color->ui[3];
 	} else if (util_format_is_pure_uint(surface_format)) {
 		util_format_write_4ui(surface_format, color->ui, 0, &uc, 0, 0, 0, 1, 1);
 	} else if (util_format_is_pure_sint(surface_format)) {
 		util_format_write_4i(surface_format, color->i, 0, &uc, 0, 0, 0, 1, 1);
 	} else {
 		util_pack_color(color->f, surface_format, &uc);
 	}
 
+	if (memcmp(rtex->color_clear_value, &uc, 2 * sizeof(uint32_t)) == 0)
+		return false;
+
 	memcpy(rtex->color_clear_value, &uc, 2 * sizeof(uint32_t));
+	return true;
 }
 
 /** Linearize and convert luminace/intensity to red. */
 enum pipe_format si_simplify_cb_format(enum pipe_format format)
 {
 	format = util_format_linear(format);
 	format = util_format_luminance_to_red(format);
 	return util_format_intensity_to_red(format);
 }
 
@@ -538,24 +542,24 @@ static void si_do_fast_color_clear(struct si_context *sctx,
 
 		if (need_decompress_pass &&
 		    !(tex->dirty_level_mask & (1 << level))) {
 			tex->dirty_level_mask |= 1 << level;
 			p_atomic_inc(&sctx->screen->compressed_colortex_counter);
 		}
 
 		/* We can change the micro tile mode before a full clear. */
 		si_set_optimal_micro_tile_mode(sctx->screen, tex);
 
-		si_set_clear_color(tex, fb->cbufs[i]->format, color);
-
-		sctx->framebuffer.dirty_cbufs |= 1 << i;
-		si_mark_atom_dirty(sctx, &sctx->atoms.s.framebuffer);
+		if (si_set_clear_color(tex, fb->cbufs[i]->format, color)) {
+			sctx->framebuffer.dirty_cbufs |= 1 << i;
+			si_mark_atom_dirty(sctx, &sctx->atoms.s.framebuffer);
+		}
 		*buffers &= ~clear_bit;
 	}
 }
 
 static void si_clear(struct pipe_context *ctx, unsigned buffers,
 		     const union pipe_color_union *color,
 		     double depth, unsigned stencil)
 {
 	struct si_context *sctx = (struct si_context *)ctx;
 	struct pipe_framebuffer_state *fb = &sctx->framebuffer.state;
@@ -589,41 +593,47 @@ static void si_clear(struct pipe_context *ctx, unsigned buffers,
 		/* TC-compatible HTILE only supports depth clears to 0 or 1. */
 		if (buffers & PIPE_CLEAR_DEPTH &&
 		    (!zstex->tc_compatible_htile ||
 		     depth == 0 || depth == 1)) {
 			/* Need to disable EXPCLEAR temporarily if clearing
 			 * to a new value. */
 			if (!zstex->depth_cleared || zstex->depth_clear_value != depth) {
 				sctx->db_depth_disable_expclear = true;
 			}
 
-			zstex->depth_clear_value = depth;
-			sctx->framebuffer.dirty_zsbuf = true;
-			si_mark_atom_dirty(sctx, &sctx->atoms.s.framebuffer); /* updates DB_DEPTH_CLEAR */
+			if (zstex->depth_clear_value != (float)depth) {
+				/* Update DB_DEPTH_CLEAR. */
+				zstex->depth_clear_value = depth;
+				sctx->framebuffer.dirty_zsbuf = true;
+				si_mark_atom_dirty(sctx, &sctx->atoms.s.framebuffer);
+			}
 			sctx->db_depth_clear = true;
 			si_mark_atom_dirty(sctx, &sctx->atoms.s.db_render_state);
 		}
 
 		/* TC-compatible HTILE only supports stencil clears to 0. */
 		if (buffers & PIPE_CLEAR_STENCIL &&
 		    (!zstex->tc_compatible_htile || stencil == 0)) {
 			stencil &= 0xff;
 
 			/* Need to disable EXPCLEAR temporarily if clearing
 			 * to a new value. */
 			if (!zstex->stencil_cleared || zstex->stencil_clear_value != stencil) {
 				sctx->db_stencil_disable_expclear = true;
 			}
 
-			zstex->stencil_clear_value = stencil;
-			sctx->framebuffer.dirty_zsbuf = true;
-			si_mark_atom_dirty(sctx, &sctx->atoms.s.framebuffer); /* updates DB_STENCIL_CLEAR */
+			if (zstex->stencil_clear_value != (uint8_t)stencil) {
+				/* Update DB_STENCIL_CLEAR. */
+				zstex->stencil_clear_value = stencil;
+				sctx->framebuffer.dirty_zsbuf = true;
+				si_mark_atom_dirty(sctx, &sctx->atoms.s.framebuffer);
+			}
 			sctx->db_stencil_clear = true;
 			si_mark_atom_dirty(sctx, &sctx->atoms.s.db_render_state);
 		}
 
 		/* TODO: Find out what's wrong here. Fast depth clear leads to
 		 * corruption in ARK: Survival Evolved, but that may just be
 		 * a coincidence and the root cause is elsewhere.
 		 *
 		 * The corruption can be fixed by putting the DB flush before
 		 * or after the depth clear. (surprisingly)
-- 
2.17.0



More information about the mesa-dev mailing list