[Mesa-dev] [PATCH 02/61] radeonsi/gfx9: fix most things wrong with shader images

Marek Olšák maraeo at gmail.com
Mon Apr 24 08:44:59 UTC 2017


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

There are 2 major hw changes:
- The address must always point to the address of level 0. GFX9 tiling
  modes don't allow binding to a non-0 level.
- 3D must always be bound as 3D, because 2D and 3D use entirely different
  tiling modes, and the texture target determines which set of modes is
  used.

Cc: 17.1 <mesa-stable at lists.freedesktop.org>
---
 src/gallium/drivers/radeonsi/si_descriptors.c | 33 ++++++++++++++++++---------
 src/gallium/drivers/radeonsi/si_state.c       |  3 ++-
 2 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index 971aa43..bd73fcc 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -758,21 +758,21 @@ static void si_set_shader_image(struct si_context *ctx,
 					  view->u.buf.offset,
 					  view->u.buf.size, desc);
 		si_set_buf_desc_address(res, view->u.buf.offset, desc + 4);
 
 		images->compressed_colortex_mask &= ~(1 << slot);
 		res->bind_history |= PIPE_BIND_SHADER_IMAGE;
 	} else {
 		static const unsigned char swizzle[4] = { 0, 1, 2, 3 };
 		struct r600_texture *tex = (struct r600_texture *)res;
 		unsigned level = view->u.tex.level;
-		unsigned width, height, depth;
+		unsigned width, height, depth, hw_level;
 		bool uses_dcc = vi_dcc_enabled(tex, level);
 
 		assert(!tex->is_depth);
 		assert(tex->fmask.size == 0);
 
 		if (uses_dcc && !skip_decompress &&
 		    (view->access & PIPE_IMAGE_ACCESS_WRITE ||
 		     !vi_dcc_formats_compatible(res->b.b.format, view->format))) {
 			/* If DCC can't be disabled, at least decompress it.
 			 * The decompression is relatively cheap if the surface
@@ -787,34 +787,45 @@ static void si_set_shader_image(struct si_context *ctx,
 		if (is_compressed_colortex(tex)) {
 			images->compressed_colortex_mask |= 1 << slot;
 		} else {
 			images->compressed_colortex_mask &= ~(1 << slot);
 		}
 
 		if (uses_dcc &&
 		    p_atomic_read(&tex->framebuffers_bound))
 			ctx->need_check_render_feedback = true;
 
-		/* Always force the base level to the selected level.
-		 *
-		 * This is required for 3D textures, where otherwise
-		 * selecting a single slice for non-layered bindings
-		 * fails. It doesn't hurt the other targets.
-		 */
-		width = u_minify(res->b.b.width0, level);
-		height = u_minify(res->b.b.height0, level);
-		depth = u_minify(res->b.b.depth0, level);
+		if (ctx->b.chip_class >= GFX9) {
+			/* Always set the base address. The swizzle modes don't
+			 * allow setting mipmap level offsets as the base.
+			 */
+			width = res->b.b.width0;
+			height = res->b.b.height0;
+			depth = res->b.b.depth0;
+			hw_level = level;
+		} else {
+			/* Always force the base level to the selected level.
+			 *
+			 * This is required for 3D textures, where otherwise
+			 * selecting a single slice for non-layered bindings
+			 * fails. It doesn't hurt the other targets.
+			 */
+			width = u_minify(res->b.b.width0, level);
+			height = u_minify(res->b.b.height0, level);
+			depth = u_minify(res->b.b.depth0, level);
+			hw_level = 0;
+		}
 
 		si_make_texture_descriptor(screen, tex,
 					   false, res->b.b.target,
 					   view->format, swizzle,
-					   0, 0,
+					   hw_level, hw_level,
 					   view->u.tex.first_layer,
 					   view->u.tex.last_layer,
 					   width, height, depth,
 					   desc, NULL);
 		si_set_mutable_tex_desc_fields(screen, tex,
 					       &tex->surface.u.legacy.level[level],
 					       level, level,
 					       util_format_get_blockwidth(view->format),
 					       false, desc);
 	}
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 8a8705f..ec99326 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -3182,21 +3182,22 @@ si_make_texture_descriptor(struct si_screen *screen,
 	    util_format_has_depth(desc) &&
 	    num_format == V_008F14_IMG_NUM_FORMAT_FLOAT &&
 	    util_get_depth_format_type(base_desc) != UTIL_FORMAT_TYPE_FLOAT) {
 		/* NUM_FORMAT=FLOAT and DATA_FORMAT=24_8 means "clamp to [0,1]". */
 		data_format = V_008F14_IMG_DATA_FORMAT_24_8;
 	}
 
 	if (!sampler &&
 	    (res->target == PIPE_TEXTURE_CUBE ||
 	     res->target == PIPE_TEXTURE_CUBE_ARRAY ||
-	     res->target == PIPE_TEXTURE_3D)) {
+	     (screen->b.chip_class <= VI &&
+	      res->target == PIPE_TEXTURE_3D))) {
 		/* For the purpose of shader images, treat cube maps and 3D
 		 * textures as 2D arrays. For 3D textures, the address
 		 * calculations for mipmaps are different, so we rely on the
 		 * caller to effectively disable mipmaps.
 		 */
 		type = V_008F1C_SQ_RSRC_IMG_2D_ARRAY;
 
 		assert(res->target != PIPE_TEXTURE_3D || (first_level == 0 && last_level == 0));
 	} else {
 		type = si_tex_dim(screen, tex, target, res->nr_samples);
-- 
2.7.4



More information about the mesa-dev mailing list