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

Marek Olšák maraeo at gmail.com
Sun Sep 6 15:17:19 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/r600/evergreen_state.c | 12 +++++++++---
 src/gallium/drivers/r600/r600_blit.c       | 25 ++++++++++++++++++++-----
 src/gallium/drivers/r600/r600_pipe.h       |  4 +++-
 src/gallium/drivers/r600/r600_state.c      | 12 +++++++++---
 4 files changed, 41 insertions(+), 12 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 8ecc498..5b478fd 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -783,6 +783,12 @@ evergreen_create_sampler_view_custom(struct pipe_context *ctx,
 
 	va = tmp->resource.gpu_address;
 
+	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;
+
 	view->tex_resource = &tmp->resource;
 	view->tex_resource_words[0] = (S_030000_DIM(r600_tex_dim(texture->target, texture->nr_samples)) |
 				       S_030000_PITCH((pitch / 8) - 1) |
@@ -1823,9 +1829,9 @@ static void evergreen_emit_db_misc_state(struct r600_context *rctx, struct r600_
 				     S_028000_STENCIL_COPY_ENABLE(a->copy_stencil) |
 				     S_028000_COPY_CENTROID(1) |
 				     S_028000_COPY_SAMPLE(a->copy_sample);
-	} else if (a->flush_depthstencil_in_place) {
-		db_render_control |= S_028000_DEPTH_COMPRESS_DISABLE(1) |
-				     S_028000_STENCIL_COMPRESS_DISABLE(1);
+	} else if (a->flush_depth_inplace || a->flush_stencil_inplace) {
+		db_render_control |= S_028000_DEPTH_COMPRESS_DISABLE(a->flush_depth_inplace) |
+				     S_028000_STENCIL_COMPRESS_DISABLE(a->flush_stencil_inplace);
 		db_render_override |= S_02800C_DISABLE_PIXEL_RATE_TILES(1);
 	}
 	if (a->htile_clear) {
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index d1370cd..6e6ee08 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -202,20 +202,28 @@ static void r600_blit_decompress_depth(struct pipe_context *ctx,
 
 static void r600_blit_decompress_depth_in_place(struct r600_context *rctx,
                                                 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;
+	unsigned *dirty_level_mask;
 
 	/* Enable decompression in DB_RENDER_CONTROL */
-	rctx->db_misc_state.flush_depthstencil_in_place = true;
+	if (is_stencil_sampler) {
+		rctx->db_misc_state.flush_stencil_inplace = true;
+		dirty_level_mask = &texture->stencil_dirty_level_mask;
+	} else {
+		rctx->db_misc_state.flush_depth_inplace = true;
+		dirty_level_mask = &texture->dirty_level_mask;
+	}
 	r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom);
 
 	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;
@@ -242,12 +250,13 @@ static void r600_blit_decompress_depth_in_place(struct r600_context *rctx,
 		/* The texture will always be dirty if some layers or samples 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);
 		}
 	}
 
 	/* Disable decompression in DB_RENDER_CONTROL */
-	rctx->db_misc_state.flush_depthstencil_in_place = false;
+	rctx->db_misc_state.flush_depth_inplace = false;
+	rctx->db_misc_state.flush_stencil_inplace = false;
 	r600_mark_atom_dirty(rctx, &rctx->db_misc_state.atom);
 }
 
@@ -272,6 +281,7 @@ void r600_decompress_depth_textures(struct r600_context *rctx,
 		if (rctx->b.chip_class >= EVERGREEN ||
 		    r600_can_read_depth(tex)) {
 			r600_blit_decompress_depth_in_place(rctx, tex,
+						   ((struct r600_pipe_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));
 		} else {
@@ -367,9 +377,14 @@ static bool r600_decompress_subresource(struct pipe_context *ctx,
 	if (rtex->is_depth && !rtex->is_flushing_texture) {
 		if (rctx->b.chip_class >= EVERGREEN ||
 		    r600_can_read_depth(rtex)) {
-			r600_blit_decompress_depth_in_place(rctx, rtex,
+			r600_blit_decompress_depth_in_place(rctx, rtex, false,
 						   level, level,
 						   first_layer, last_layer);
+			if (rtex->surface.flags & RADEON_SURF_SBUFFER) {
+				r600_blit_decompress_depth_in_place(rctx, rtex, true,
+							   level, level,
+							   first_layer, last_layer);
+			}
 		} else {
 			if (!r600_init_flushed_depth_texture(ctx, tex, NULL))
 				return false; /* error */
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 25df831..70ba6c7 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -109,7 +109,8 @@ struct r600_db_misc_state {
 	struct r600_atom		atom;
 	bool				occlusion_query_enabled;
 	bool				flush_depthstencil_through_cb;
-	bool				flush_depthstencil_in_place;
+	bool				flush_depth_inplace;
+	bool				flush_stencil_inplace;
 	bool				copy_depth, copy_stencil;
 	unsigned			copy_sample;
 	unsigned			log_samples;
@@ -253,6 +254,7 @@ struct r600_pipe_sampler_view {
 	struct r600_resource		*tex_resource;
 	uint32_t			tex_resource_words[8];
 	bool				skip_mip_address_reloc;
+	bool				is_stencil_sampler;
 };
 
 struct r600_rasterizer_state {
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 93a74f7..8d95464 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -710,6 +710,12 @@ r600_create_sampler_view_custom(struct pipe_context *ctx,
 		break;
 	}
 
+	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;
+
 	view->tex_resource = &tmp->resource;
 	view->tex_resource_words[0] = (S_038000_DIM(r600_tex_dim(texture->target, texture->nr_samples)) |
 				       S_038000_TILE_MODE(array_mode) |
@@ -1659,9 +1665,9 @@ static void r600_emit_db_misc_state(struct r600_context *rctx, struct r600_atom
 		if (rctx->b.family == CHIP_RV610 || rctx->b.family == CHIP_RV630 ||
 		    rctx->b.family == CHIP_RV620 || rctx->b.family == CHIP_RV635)
 			db_render_override |= S_028D10_FORCE_HIZ_ENABLE(V_028D10_FORCE_DISABLE);
-	} else if (a->flush_depthstencil_in_place) {
-		db_render_control |= S_028D0C_DEPTH_COMPRESS_DISABLE(1) |
-				     S_028D0C_STENCIL_COMPRESS_DISABLE(1);
+	} else if (a->flush_depth_inplace || a->flush_stencil_inplace) {
+		db_render_control |= S_028D0C_DEPTH_COMPRESS_DISABLE(a->flush_depth_inplace) |
+				     S_028D0C_STENCIL_COMPRESS_DISABLE(a->flush_stencil_inplace);
 		db_render_override |= S_028D10_NOOP_CULL_DISABLE(1);
 	}
 	if (a->htile_clear) {
-- 
2.1.4



More information about the mesa-dev mailing list