[Mesa-dev] [PATCH 2/3] radeonsi: only do depth-only or stencil-only in-place decompression

Marek Olšák maraeo at gmail.com
Sun Sep 6 15:17:18 PDT 2015


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

instead of always doing both.
Usually, only depth is needed, so stencil decompression is useless.
---
 src/gallium/drivers/radeonsi/si_blit.c  | 26 ++++++++++++++++++++------
 src/gallium/drivers/radeonsi/si_pipe.h  |  4 +++-
 src/gallium/drivers/radeonsi/si_state.c | 12 +++++++++---
 3 files changed, 32 insertions(+), 10 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c
index 93fa67a..a8a271e 100644
--- a/src/gallium/drivers/radeonsi/si_blit.c
+++ b/src/gallium/drivers/radeonsi/si_blit.c
@@ -180,19 +180,27 @@ static void si_blit_decompress_depth(struct pipe_context *ctx,
 
 static void si_blit_decompress_depth_in_place(struct si_context *sctx,
                                               struct r600_texture *texture,
+					      bool is_stencil_sampler,
                                               unsigned first_level, unsigned last_level,
                                               unsigned first_layer, unsigned last_layer)
 {
 	struct pipe_surface *zsurf, surf_tmpl = {{0}};
 	unsigned layer, max_layer, checked_last_layer, level;
-
-	sctx->db_inplace_flush_enabled = true;
+	unsigned *dirty_level_mask;
+
+	if (is_stencil_sampler) {
+		sctx->db_flush_stencil_inplace = true;
+		dirty_level_mask = &texture->stencil_dirty_level_mask;
+	} else {
+		sctx->db_flush_depth_inplace = true;
+		dirty_level_mask = &texture->dirty_level_mask;
+	}
 	si_mark_atom_dirty(sctx, &sctx->db_render_state);
 
 	surf_tmpl.format = texture->resource.b.b.format;
 
 	for (level = first_level; level <= last_level; level++) {
-		if (!(texture->dirty_level_mask & (1 << level)))
+		if (!(*dirty_level_mask & (1 << level)))
 			continue;
 
 		surf_tmpl.u.tex.level = level;
@@ -220,11 +228,12 @@ static void si_blit_decompress_depth_in_place(struct si_context *sctx,
 		/* The texture will always be dirty if some layers aren't flushed.
 		 * I don't think this case occurs often though. */
 		if (first_layer == 0 && last_layer == max_layer) {
-			texture->dirty_level_mask &= ~(1 << level);
+			*dirty_level_mask &= ~(1 << level);
 		}
 	}
 
-	sctx->db_inplace_flush_enabled = false;
+	sctx->db_flush_depth_inplace = false;
+	sctx->db_flush_stencil_inplace = false;
 	si_mark_atom_dirty(sctx, &sctx->db_render_state);
 }
 
@@ -247,6 +256,7 @@ void si_flush_depth_textures(struct si_context *sctx,
 		assert(tex->is_depth && !tex->is_flushing_texture);
 
 		si_blit_decompress_depth_in_place(sctx, tex,
+						  ((struct si_sampler_view*)view)->is_stencil_sampler,
 						  view->u.tex.first_level, view->u.tex.last_level,
 						  0, util_max_layer(&tex->resource.b.b, view->u.tex.first_level));
 	}
@@ -436,9 +446,13 @@ static void si_decompress_subresource(struct pipe_context *ctx,
 	struct r600_texture *rtex = (struct r600_texture*)tex;
 
 	if (rtex->is_depth && !rtex->is_flushing_texture) {
-		si_blit_decompress_depth_in_place(sctx, rtex,
+		si_blit_decompress_depth_in_place(sctx, rtex, false,
 						  level, level,
 						  first_layer, last_layer);
+		if (rtex->surface.flags & RADEON_SURF_SBUFFER)
+			si_blit_decompress_depth_in_place(sctx, rtex, true,
+							  level, level,
+							  first_layer, last_layer);
 	} else if (rtex->fmask.size || rtex->cmask.size) {
 		si_blit_decompress_color(ctx, rtex, level, level,
 					 first_layer, last_layer);
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 847853e..9143c77 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -100,6 +100,7 @@ struct si_sampler_view {
          * [4..7] = buffer descriptor */
 	uint32_t			state[8];
 	uint32_t			fmask_state[8];
+	bool is_stencil_sampler;
 };
 
 struct si_sampler_state {
@@ -237,7 +238,8 @@ struct si_context {
 	bool			dbcb_depth_copy_enabled;
 	bool			dbcb_stencil_copy_enabled;
 	unsigned		dbcb_copy_sample;
-	bool			db_inplace_flush_enabled;
+	bool			db_flush_depth_inplace;
+	bool			db_flush_stencil_inplace;
 	bool			db_depth_clear;
 	bool			db_depth_disable_expclear;
 	unsigned		ps_db_shader_control;
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index d74f6e8..3b22038 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -998,10 +998,10 @@ static void si_emit_db_render_state(struct si_context *sctx, struct r600_atom *s
 			    S_028000_STENCIL_COPY(sctx->dbcb_stencil_copy_enabled) |
 			    S_028000_COPY_CENTROID(1) |
 			    S_028000_COPY_SAMPLE(sctx->dbcb_copy_sample));
-	} else if (sctx->db_inplace_flush_enabled) {
+	} else if (sctx->db_flush_depth_inplace || sctx->db_flush_stencil_inplace) {
 		radeon_emit(cs,
-			    S_028000_DEPTH_COMPRESS_DISABLE(1) |
-			    S_028000_STENCIL_COMPRESS_DISABLE(1));
+			    S_028000_DEPTH_COMPRESS_DISABLE(sctx->db_flush_depth_inplace) |
+			    S_028000_STENCIL_COMPRESS_DISABLE(sctx->db_flush_stencil_inplace));
 	} else if (sctx->db_depth_clear) {
 		radeon_emit(cs, S_028000_DEPTH_CLEAR_ENABLE(1));
 	} else {
@@ -2411,6 +2411,12 @@ si_create_sampler_view_custom(struct pipe_context *ctx,
 	pipe_resource_reference(&view->base.texture, texture);
 	view->resource = &tmp->resource;
 
+	if (state->format == PIPE_FORMAT_X24S8_UINT ||
+	    state->format == PIPE_FORMAT_S8X24_UINT ||
+	    state->format == PIPE_FORMAT_X32_S8X24_UINT ||
+	    state->format == PIPE_FORMAT_S8_UINT)
+		view->is_stencil_sampler = true;
+
 	/* Buffer resource. */
 	if (texture->target == PIPE_BUFFER) {
 		unsigned stride, num_records;
-- 
2.1.4



More information about the mesa-dev mailing list