[Mesa-dev] [PATCH 4/7] radeonsi: make use of LOAD for UBOs

Timothy Arceri tarceri at itsqueeze.com
Tue Aug 22 12:14:20 UTC 2017


v2: always set can_speculate and allow_smem to true
---
 src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c | 31 +++++++++++++++--------
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
index f8c99ff7e7..83cd8cd938 100644
--- a/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
+++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
@@ -66,32 +66,36 @@ static LLVMValueRef get_buffer_size(
 				      LLVMConstInt(ctx->i32, 0x3FFF, 0), "");
 
 		size = LLVMBuildUDiv(builder, size, stride, "");
 	}
 
 	return size;
 }
 
 static LLVMValueRef
 shader_buffer_fetch_rsrc(struct si_shader_context *ctx,
-			 const struct tgsi_full_src_register *reg)
+			 const struct tgsi_full_src_register *reg,
+			 bool ubo)
 {
 	LLVMValueRef index;
 
 	if (!reg->Register.Indirect) {
 		index = LLVMConstInt(ctx->i32, reg->Register.Index, false);
 	} else {
 		index = si_get_indirect_index(ctx, &reg->Indirect,
 					      reg->Register.Index);
 	}
 
-	return ctx->abi.load_ssbo(&ctx->abi, index, false);
+	if (ubo)
+		return ctx->abi.load_ubo(&ctx->abi, index);
+	else
+		return ctx->abi.load_ssbo(&ctx->abi, index, false);
 }
 
 static bool tgsi_is_array_sampler(unsigned target)
 {
 	return target == TGSI_TEXTURE_1D_ARRAY ||
 	       target == TGSI_TEXTURE_SHADOW1D_ARRAY ||
 	       target == TGSI_TEXTURE_2D_ARRAY ||
 	       target == TGSI_TEXTURE_SHADOW2D_ARRAY ||
 	       target == TGSI_TEXTURE_CUBE_ARRAY ||
 	       target == TGSI_TEXTURE_SHADOWCUBE_ARRAY ||
@@ -356,26 +360,28 @@ static void load_fetch_args(
 		struct lp_build_emit_data * emit_data)
 {
 	struct si_shader_context *ctx = si_shader_context(bld_base);
 	struct gallivm_state *gallivm = &ctx->gallivm;
 	const struct tgsi_full_instruction * inst = emit_data->inst;
 	unsigned target = inst->Memory.Texture;
 	LLVMValueRef rsrc;
 
 	emit_data->dst_type = ctx->v4f32;
 
-	if (inst->Src[0].Register.File == TGSI_FILE_BUFFER) {
+	if (inst->Src[0].Register.File == TGSI_FILE_BUFFER ||
+		   inst->Src[0].Register.File == TGSI_FILE_CONSTBUF) {
 		LLVMBuilderRef builder = gallivm->builder;
 		LLVMValueRef offset;
 		LLVMValueRef tmp;
 
-		rsrc = shader_buffer_fetch_rsrc(ctx, &inst->Src[0]);
+		bool ubo = inst->Src[0].Register.File == TGSI_FILE_CONSTBUF;
+		rsrc = shader_buffer_fetch_rsrc(ctx, &inst->Src[0], ubo);
 
 		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 ||
 		   tgsi_is_bindless_image_file(inst->Src[0].Register.File)) {
 		LLVMValueRef coords;
 
@@ -407,21 +413,21 @@ static unsigned get_load_intr_attribs(bool can_speculate)
 
 static unsigned get_store_intr_attribs(bool writeonly_memory)
 {
 	return writeonly_memory && HAVE_LLVM >= 0x0400 ?
 				  LP_FUNC_ATTR_INACCESSIBLE_MEM_ONLY :
 				  LP_FUNC_ATTR_WRITEONLY;
 }
 
 static void load_emit_buffer(struct si_shader_context *ctx,
 			     struct lp_build_emit_data *emit_data,
-			     bool can_speculate)
+			     bool can_speculate, bool allow_smem)
 {
 	const struct tgsi_full_instruction *inst = emit_data->inst;
 	uint writemask = inst->Dst[0].Register.WriteMask;
 	uint count = util_last_bit(writemask);
 	LLVMValueRef *args = emit_data->args;
 
 	/* Don't use SMEM for shader buffer loads, because LLVM doesn't
 	 * select SMEM for SI.load.const with a non-constant offset, and
 	 * constant offsets practically don't exist with shader buffers.
 	 *
@@ -434,21 +440,21 @@ static void load_emit_buffer(struct si_shader_context *ctx,
 	 *       After that, si_memory_barrier should invalidate sL1 for shader
 	 *       buffers.
 	 */
 
 	assert(LLVMConstIntGetZExtValue(args[1]) == 0); /* vindex */
 	emit_data->output[emit_data->chan] =
 		ac_build_buffer_load(&ctx->ac, args[0], count, NULL,
 				     args[2], NULL, 0,
 				     LLVMConstIntGetZExtValue(args[3]),
 				     LLVMConstIntGetZExtValue(args[4]),
-				     can_speculate, false);
+				     can_speculate, allow_smem);
 }
 
 static LLVMValueRef get_memory_ptr(struct si_shader_context *ctx,
                                    const struct tgsi_full_instruction *inst,
                                    LLVMTypeRef type, int arg)
 {
 	struct gallivm_state *gallivm = &ctx->gallivm;
 	LLVMBuilderRef builder = gallivm->builder;
 	LLVMValueRef offset, ptr;
 	int addr_space;
@@ -564,32 +570,37 @@ static void load_emit(
 	const struct tgsi_full_instruction * inst = emit_data->inst;
 	const struct tgsi_shader_info *info = &ctx->shader->selector->info;
 	char intrinsic_name[64];
 	bool can_speculate = false;
 
 	if (inst->Src[0].Register.File == TGSI_FILE_MEMORY) {
 		load_emit_memory(ctx, emit_data);
 		return;
 	}
 
+	if (inst->Src[0].Register.File == TGSI_FILE_CONSTBUF) {
+		load_emit_buffer(ctx, emit_data, true, true);
+		return;
+	}
+
 	if (inst->Memory.Qualifier & TGSI_MEMORY_VOLATILE)
 		si_emit_waitcnt(ctx, VM_CNT);
 
 	can_speculate = !(inst->Memory.Qualifier & TGSI_MEMORY_VOLATILE) &&
 			  is_oneway_access_only(inst, info,
 						info->shader_buffers_store |
 						info->shader_buffers_atomic,
 						info->images_store |
 						info->images_atomic);
 
 	if (inst->Src[0].Register.File == TGSI_FILE_BUFFER) {
-		load_emit_buffer(ctx, emit_data, can_speculate);
+		load_emit_buffer(ctx, emit_data, can_speculate, false);
 		return;
 	}
 
 	if (inst->Memory.Texture == TGSI_TEXTURE_BUFFER) {
 		emit_data->output[emit_data->chan] =
 			lp_build_intrinsic(
 				builder, "llvm.amdgcn.buffer.load.format.v4f32", emit_data->dst_type,
 				emit_data->args, emit_data->arg_count,
 				get_load_intr_attribs(can_speculate));
 	} else {
@@ -629,21 +640,21 @@ static void store_fetch_args(
 	data = lp_build_gather_values(gallivm, chans, 4);
 
 	emit_data->args[emit_data->arg_count++] = data;
 
 	memory = tgsi_full_src_register_from_dst(&inst->Dst[0]);
 
 	if (inst->Dst[0].Register.File == TGSI_FILE_BUFFER) {
 		LLVMValueRef offset;
 		LLVMValueRef tmp;
 
-		rsrc = shader_buffer_fetch_rsrc(ctx, &memory);
+		rsrc = shader_buffer_fetch_rsrc(ctx, &memory, false);
 
 		tmp = lp_build_emit_fetch(bld_base, inst, 0, 0);
 		offset = LLVMBuildBitCast(builder, tmp, ctx->i32, "");
 
 		buffer_append_args(ctx, emit_data, rsrc, ctx->i32_0,
 				   offset, false, false);
 	} else if (inst->Dst[0].Register.File == TGSI_FILE_IMAGE ||
 		   tgsi_is_bindless_image_file(inst->Dst[0].Register.File)) {
 		unsigned target = inst->Memory.Texture;
 		LLVMValueRef coords;
@@ -849,21 +860,21 @@ static void atomic_fetch_args(
 	/* llvm.amdgcn.image/buffer.atomic.cmpswap reflect the hardware order
 	 * of arguments, which is reversed relative to TGSI (and GLSL)
 	 */
 	if (inst->Instruction.Opcode == TGSI_OPCODE_ATOMCAS)
 		emit_data->args[emit_data->arg_count++] = data2;
 	emit_data->args[emit_data->arg_count++] = data1;
 
 	if (inst->Src[0].Register.File == TGSI_FILE_BUFFER) {
 		LLVMValueRef offset;
 
-		rsrc = shader_buffer_fetch_rsrc(ctx, &inst->Src[0]);
+		rsrc = shader_buffer_fetch_rsrc(ctx, &inst->Src[0], false);
 
 		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 ||
 		   tgsi_is_bindless_image_file(inst->Src[0].Register.File)) {
 		unsigned target = inst->Memory.Texture;
 		LLVMValueRef coords;
@@ -1057,21 +1068,21 @@ static void resq_fetch_args(
 		struct lp_build_tgsi_context * bld_base,
 		struct lp_build_emit_data * emit_data)
 {
 	struct si_shader_context *ctx = si_shader_context(bld_base);
 	const struct tgsi_full_instruction *inst = emit_data->inst;
 	const struct tgsi_full_src_register *reg = &inst->Src[0];
 
 	emit_data->dst_type = ctx->v4i32;
 
 	if (reg->Register.File == TGSI_FILE_BUFFER) {
-		emit_data->args[0] = shader_buffer_fetch_rsrc(ctx, reg);
+		emit_data->args[0] = shader_buffer_fetch_rsrc(ctx, reg, false);
 		emit_data->arg_count = 1;
 	} else if (inst->Memory.Texture == TGSI_TEXTURE_BUFFER) {
 		image_fetch_rsrc(bld_base, reg, false, inst->Memory.Texture,
 				 &emit_data->args[0]);
 		emit_data->arg_count = 1;
 	} else {
 		LLVMValueRef res_ptr;
 		unsigned image_target;
 
 		if (inst->Memory.Texture == TGSI_TEXTURE_3D)
-- 
2.13.4



More information about the mesa-dev mailing list