[Mesa-dev] [PATCH 04/61] radeonsi/gfx9: add a workaround for viewing a slice of 3D as a 2D image

Nicolai Hähnle nhaehnle at gmail.com
Tue Apr 25 18:14:42 UTC 2017


On 24.04.2017 10:45, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> Cc: 17.1 <mesa-stable at lists.freedesktop.org>
> ---
>  src/gallium/drivers/radeonsi/si_shader.c | 28 +++++++++++++++++++++-------
>  1 file changed, 21 insertions(+), 7 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
> index c5c994d..840742c 100644
> --- a/src/gallium/drivers/radeonsi/si_shader.c
> +++ b/src/gallium/drivers/radeonsi/si_shader.c
> @@ -3393,21 +3393,21 @@ image_fetch_rsrc(
>  	}
>
>  	*rsrc = load_image_desc(ctx, rsrc_ptr, index, target);
>  	if (dcc_off && target != TGSI_TEXTURE_BUFFER)
>  		*rsrc = force_dcc_off(ctx, *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;
>  	LLVMBuilderRef builder = gallivm->builder;
>  	unsigned target = inst->Memory.Texture;
>  	unsigned num_coords = tgsi_util_get_texture_coord_dim(target);
>  	LLVMValueRef coords[4];
>  	LLVMValueRef tmp;
>  	int chan;
>
> @@ -3419,20 +3419,35 @@ static LLVMValueRef image_fetch_coords(
>
>  	/* 1D textures are allocated and used as 2D on GFX9. */

Maybe move this comment down a bit?

Either way, patches 1-4:

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>


>  	if (ctx->screen->b.chip_class >= GFX9) {
>  		if (target == TGSI_TEXTURE_1D) {
>  			coords[1] = ctx->i32_0;
>  			num_coords++;
>  		} else if (target == TGSI_TEXTURE_1D_ARRAY) {
>  			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++;
>  		}
>  	}
>
>  	if (num_coords == 1)
>  		return coords[0];
>
>  	if (num_coords == 3) {
>  		/* LLVM has difficulties lowering 3-element vectors. */
>  		coords[3] = bld_base->uint_bld.undef;
>  		num_coords = 4;
> @@ -3533,21 +3548,21 @@ static void load_fetch_args(
>
>  		tmp = lp_build_emit_fetch(bld_base, inst, 1, 0);
>  		offset = LLVMBuildBitCast(builder, tmp, ctx->i32, "");
>
>  		buffer_append_args(ctx, emit_data, rsrc, ctx->i32_0,
>  				   offset, false, false);
>  	} else if (inst->Src[0].Register.File == TGSI_FILE_IMAGE) {
>  		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,
>  					   ctx->i32_0, false, false);
>  		} else {
>  			emit_data->args[0] = coords;
>  			emit_data->args[1] = rsrc;
>  			emit_data->args[2] = LLVMConstInt(ctx->i32, 15, 0); /* dmask */
>  			emit_data->arg_count = 3;
>
> @@ -3808,30 +3823,29 @@ static void store_fetch_args(
>  		LLVMValueRef coords;
>
>  		/* 8bit/16bit TC L1 write corruption bug on SI.
>  		 * All store opcodes not aligned to a dword are affected.
>  		 *
>  		 * The only way to get unaligned stores in radeonsi is through
>  		 * shader images.
>  		 */
>  		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;
>
>  			image_append_args(ctx, emit_data, target, false, force_glc);
>  		}
>  	}
>  }
>
>  static void store_emit_buffer(
>  		struct si_shader_context *ctx,
> @@ -4021,21 +4035,21 @@ static void atomic_fetch_args(
>  		tmp = lp_build_emit_fetch(bld_base, inst, 1, 0);
>  		offset = LLVMBuildBitCast(builder, tmp, ctx->i32, "");
>
>  		buffer_append_args(ctx, emit_data, rsrc, ctx->i32_0,
>  				   offset, true, false);
>  	} else if (inst->Src[0].Register.File == TGSI_FILE_IMAGE) {
>  		unsigned target = inst->Memory.Texture;
>  		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,
>  					   ctx->i32_0, true, false);
>  		} else {
>  			emit_data->args[emit_data->arg_count++] = coords;
>  			emit_data->args[emit_data->arg_count++] = rsrc;
>
>  			image_append_args(ctx, emit_data, target, true, false);
>  		}
>


-- 
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.


More information about the mesa-dev mailing list