[Mesa-dev] [PATCH 6/6] radeonsi: implement EXPCLEAR optimization for depth

Marek Olšák maraeo at gmail.com
Sat Aug 23 12:23:55 PDT 2014


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

---
 src/gallium/drivers/radeon/r600_pipe_common.h |  1 +
 src/gallium/drivers/radeonsi/si_blit.c        | 12 +++++++++++-
 src/gallium/drivers/radeonsi/si_pipe.h        |  1 +
 src/gallium/drivers/radeonsi/si_state.c       |  3 ++-
 src/gallium/drivers/radeonsi/si_state_draw.c  |  8 ++++++++
 5 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index ed16e1a..a5a347b 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -191,6 +191,7 @@ struct r600_texture {
 
 	/* Depth buffer compression and fast clear. */
 	struct r600_resource		*htile_buffer;
+	bool				depth_cleared; /* if it was cleared at least once */
 	float				depth_clear_value;
 
 	bool				non_disp_tiling; /* R600-Cayman only */
diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c
index 4e77d74..96d27ec 100644
--- a/src/gallium/drivers/radeonsi/si_blit.c
+++ b/src/gallium/drivers/radeonsi/si_blit.c
@@ -362,6 +362,12 @@ static void si_clear(struct pipe_context *ctx, unsigned buffers,
 	    zsbuf->u.tex.level == 0 &&
 	    zsbuf->u.tex.first_layer == 0 &&
 	    zsbuf->u.tex.last_layer == util_max_layer(&zstex->resource.b.b, 0)) {
+		/* 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.atom.dirty = true; /* updates DB_DEPTH_CLEAR */
 		sctx->db_depth_clear = true;
@@ -373,7 +379,11 @@ static void si_clear(struct pipe_context *ctx, unsigned buffers,
 			   buffers, color, depth, stencil);
 	si_blitter_end(ctx);
 
-	sctx->db_depth_clear = false;
+	if (sctx->db_depth_clear) {
+		sctx->db_depth_clear = false;
+		sctx->db_depth_disable_expclear = false;
+		zstex->depth_cleared = true;
+	}
 }
 
 static void si_clear_render_target(struct pipe_context *ctx,
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 0a79983..55643d6 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -165,6 +165,7 @@ struct si_context {
 	unsigned dbcb_copy_sample;
 	bool db_inplace_flush_enabled;
 	bool db_depth_clear;
+	bool db_depth_disable_expclear;
 };
 
 /* si_blit.c */
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 3b429cf..f470b32 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -1823,7 +1823,8 @@ static void si_init_depth_surface(struct si_context *sctx,
 	/* HiZ aka depth buffer htile */
 	/* use htile only for first level */
 	if (rtex->htile_buffer && !level) {
-		z_info |= S_028040_TILE_SURFACE_ENABLE(1);
+		z_info |= S_028040_TILE_SURFACE_ENABLE(1) |
+			  S_028040_ALLOW_EXPCLEAR(1);
 
 		/* This is optimal for the clear value of 1.0 and using
 		 * the LESS and LEQUAL test functions. Set this to 0
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
index a66337a..dea7d76 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -758,6 +758,14 @@ static void si_state_draw(struct si_context *sctx,
 		si_pm4_set_reg(pm4, R_028000_DB_RENDER_CONTROL, 0);
 	}
 
+	/* DB_RENDER_OVERRIDE2 */
+	if (sctx->db_depth_disable_expclear) {
+		si_pm4_set_reg(pm4, R_028010_DB_RENDER_OVERRIDE2,
+			       S_028010_DISABLE_ZMASK_EXPCLEAR_OPTIMIZATION(1));
+	} else {
+		si_pm4_set_reg(pm4, R_028010_DB_RENDER_OVERRIDE2, 0);
+	}
+
 	if (info->count_from_stream_output) {
 		struct r600_so_target *t =
 			(struct r600_so_target*)info->count_from_stream_output;
-- 
1.9.1



More information about the mesa-dev mailing list