Mesa (master): radeonsi/gfx9: add a workaround for viewing a slice of 3D as a 2D image

Marek Olšák mareko at kemper.freedesktop.org
Wed Apr 26 11:23:40 UTC 2017


Module: Mesa
Branch: master
Commit: 8e8570a9e8bae7f4d3ad623475dfadc715a828d7
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=8e8570a9e8bae7f4d3ad623475dfadc715a828d7

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Mon Apr 24 00:01:06 2017 +0200

radeonsi/gfx9: add a workaround for viewing a slice of 3D as a 2D image

Cc: 17.1 <mesa-stable at lists.freedesktop.org>
Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>

---

 src/gallium/drivers/radeonsi/si_shader.c | 30 ++++++++++++++++++++++--------
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index c5c994d607..bbb1c13cf2 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -3400,7 +3400,7 @@ image_fetch_rsrc(
 static LLVMValueRef image_fetch_coords(
 		struct lp_build_tgsi_context *bld_base,
 		const struct tgsi_full_instruction *inst,
-		unsigned src)
+		unsigned src, LLVMValueRef desc)
 {
 	struct si_shader_context *ctx = si_shader_context(bld_base);
 	struct gallivm_state *gallivm = &ctx->gallivm;
@@ -3417,8 +3417,8 @@ static LLVMValueRef image_fetch_coords(
 		coords[chan] = tmp;
 	}
 
-	/* 1D textures are allocated and used as 2D on GFX9. */
 	if (ctx->screen->b.chip_class >= GFX9) {
+		/* 1D textures are allocated and used as 2D on GFX9. */
 		if (target == TGSI_TEXTURE_1D) {
 			coords[1] = ctx->i32_0;
 			num_coords++;
@@ -3426,6 +3426,21 @@ static LLVMValueRef image_fetch_coords(
 			coords[2] = coords[1];
 			coords[1] = ctx->i32_0;
 			num_coords++;
+		} else if (target == TGSI_TEXTURE_2D) {
+			/* The hw can't bind a slice of a 3D image as a 2D
+			 * image, because it ignores BASE_ARRAY if the target
+			 * is 3D. The workaround is to read BASE_ARRAY and set
+			 * it as the 3rd address operand for all 2D images.
+			 */
+			LLVMValueRef first_layer, const5, mask;
+
+			const5 = LLVMConstInt(ctx->i32, 5, 0);
+			mask = LLVMConstInt(ctx->i32, S_008F24_BASE_ARRAY(~0), 0);
+			first_layer = LLVMBuildExtractElement(builder, desc, const5, "");
+			first_layer = LLVMBuildAnd(builder, first_layer, mask, "");
+
+			coords[2] = first_layer;
+			num_coords++;
 		}
 	}
 
@@ -3540,7 +3555,7 @@ static void load_fetch_args(
 		LLVMValueRef coords;
 
 		image_fetch_rsrc(bld_base, &inst->Src[0], false, target, &rsrc);
-		coords = image_fetch_coords(bld_base, inst, 1);
+		coords = image_fetch_coords(bld_base, inst, 1, rsrc);
 
 		if (target == TGSI_TEXTURE_BUFFER) {
 			buffer_append_args(ctx, emit_data, rsrc, coords,
@@ -3815,16 +3830,15 @@ static void store_fetch_args(
 		 */
 		bool force_glc = ctx->screen->b.chip_class == SI;
 
-		coords = image_fetch_coords(bld_base, inst, 0);
+		image_fetch_rsrc(bld_base, &memory, true, target, &rsrc);
+		coords = image_fetch_coords(bld_base, inst, 0, rsrc);
 
 		if (target == TGSI_TEXTURE_BUFFER) {
-			image_fetch_rsrc(bld_base, &memory, true, target, &rsrc);
 			buffer_append_args(ctx, emit_data, rsrc, coords,
 					   ctx->i32_0, false, force_glc);
 		} else {
 			emit_data->args[1] = coords;
-			image_fetch_rsrc(bld_base, &memory, true, target,
-					 &emit_data->args[2]);
+			emit_data->args[2] = rsrc;
 			emit_data->args[3] = LLVMConstInt(ctx->i32, 15, 0); /* dmask */
 			emit_data->arg_count = 4;
 
@@ -4028,7 +4042,7 @@ static void atomic_fetch_args(
 		LLVMValueRef coords;
 
 		image_fetch_rsrc(bld_base, &inst->Src[0], true, target, &rsrc);
-		coords = image_fetch_coords(bld_base, inst, 1);
+		coords = image_fetch_coords(bld_base, inst, 1, rsrc);
 
 		if (target == TGSI_TEXTURE_BUFFER) {
 			buffer_append_args(ctx, emit_data, rsrc, coords,




More information about the mesa-commit mailing list