[Mesa-dev] [PATCH 03/10] radeonsi: clamp indirect index to the number of declared shader resources

Marek Olšák maraeo at gmail.com
Wed May 17 19:38:45 UTC 2017


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

We'll do partial uploads of descriptor arrays, so we need to clamp
against what shaders declare.
---
 src/gallium/drivers/radeonsi/si_shader.c            | 2 +-
 src/gallium/drivers/radeonsi/si_shader_internal.h   | 6 ++++++
 src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c   | 6 +++---
 src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c | 5 +++++
 4 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index f847e46..61f1384 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -1756,21 +1756,21 @@ static LLVMValueRef fetch_constant(
 	}
 
 	buf = reg->Register.Dimension ? reg->Dimension.Index : 0;
 	idx = reg->Register.Index * 4 + swizzle;
 
 	if (reg->Register.Dimension && reg->Dimension.Indirect) {
 		LLVMValueRef ptr = LLVMGetParam(ctx->main_fn, ctx->param_const_and_shader_buffers);
 		LLVMValueRef index;
 		index = si_get_bounded_indirect_index(ctx, &reg->DimIndirect,
 						      reg->Dimension.Index,
-						      SI_NUM_CONST_BUFFERS);
+						      ctx->num_const_buffers);
 		index = LLVMBuildAdd(ctx->gallivm.builder, index,
 				     LLVMConstInt(ctx->i32, SI_NUM_SHADER_BUFFERS, 0), "");
 		bufp = ac_build_indexed_load_const(&ctx->ac, ptr, index);
 	} else
 		bufp = load_const_buffer_desc(ctx, buf);
 
 	if (reg->Register.Indirect) {
 		addr = ctx->addrs[ireg->Index][ireg->Swizzle];
 		addr = LLVMBuildLoad(base->gallivm->builder, addr, "load addr reg");
 		addr = lp_build_mul_imm(&bld_base->uint_bld, addr, 16);
diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h
index 5094023..5ccde71 100644
--- a/src/gallium/drivers/radeonsi/si_shader_internal.h
+++ b/src/gallium/drivers/radeonsi/si_shader_internal.h
@@ -50,20 +50,26 @@ struct si_llvm_flow;
 
 struct si_shader_context {
 	struct lp_build_tgsi_context bld_base;
 	struct gallivm_state gallivm;
 	struct ac_llvm_context ac;
 	struct si_shader *shader;
 	struct si_screen *screen;
 
 	unsigned type; /* PIPE_SHADER_* specifies the type of shader. */
 
+	/* For clamping the non-constant index in resource indexing: */
+	unsigned num_const_buffers;
+	unsigned num_shader_buffers;
+	unsigned num_images;
+	unsigned num_samplers;
+
 	/* Whether the prolog will be compiled separately. */
 	bool separate_prolog;
 
 	/** This function is responsible for initilizing the inputs array and will be
 	  * called once for each input declared in the TGSI shader.
 	  */
 	void (*load_input)(struct si_shader_context *,
 			   unsigned input_index,
 			   const struct tgsi_full_declaration *decl,
 			   LLVMValueRef out[4]);
diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
index 5fc3420..d710c16 100644
--- a/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
+++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c
@@ -85,21 +85,21 @@ shader_buffer_fetch_rsrc(struct si_shader_context *ctx,
 	LLVMValueRef index;
 	LLVMValueRef rsrc_ptr = LLVMGetParam(ctx->main_fn,
 					     ctx->param_const_and_shader_buffers);
 
 	if (!reg->Register.Indirect) {
 		index = LLVMConstInt(ctx->i32,
 				     si_get_shaderbuf_slot(reg->Register.Index), 0);
 	} else {
 		index = si_get_bounded_indirect_index(ctx, &reg->Indirect,
 						      reg->Register.Index,
-						      SI_NUM_SHADER_BUFFERS);
+						      ctx->num_shader_buffers);
 		index = LLVMBuildSub(ctx->gallivm.builder,
 				     LLVMConstInt(ctx->i32, SI_NUM_SHADER_BUFFERS - 1, 0),
 				     index, "");
 	}
 
 	return ac_build_indexed_load_const(&ctx->ac, rsrc_ptr, index);
 }
 
 static bool tgsi_is_array_sampler(unsigned target)
 {
@@ -201,21 +201,21 @@ image_fetch_rsrc(
 		 *
 		 *    If a shader performs an image load, store, or atomic
 		 *    operation using an image variable declared as an array,
 		 *    and if the index used to select an individual element is
 		 *    negative or greater than or equal to the size of the
 		 *    array, the results of the operation are undefined but may
 		 *    not lead to termination.
 		 */
 		index = si_get_bounded_indirect_index(ctx, &image->Indirect,
 						      image->Register.Index,
-						      SI_NUM_IMAGES);
+						      ctx->num_images);
 		index = LLVMBuildSub(ctx->gallivm.builder,
 				     LLVMConstInt(ctx->i32, SI_NUM_IMAGES - 1, 0),
 				     index, "");
 	}
 
 	*rsrc = load_image_desc(ctx, rsrc_ptr, index, target);
 	if (dcc_off && target != TGSI_TEXTURE_BUFFER)
 		*rsrc = force_dcc_off(ctx, *rsrc);
 }
 
@@ -1192,21 +1192,21 @@ static void tex_fetch_ptrs(
 	unsigned sampler_src;
 	LLVMValueRef index;
 
 	sampler_src = emit_data->inst->Instruction.NumSrcRegs - 1;
 	reg = &emit_data->inst->Src[sampler_src];
 
 	if (reg->Register.Indirect) {
 		index = si_get_bounded_indirect_index(ctx,
 						      &reg->Indirect,
 						      reg->Register.Index,
-						      SI_NUM_SAMPLERS);
+						      ctx->num_samplers);
 		index = LLVMBuildAdd(ctx->gallivm.builder, index,
 				     LLVMConstInt(ctx->i32, SI_NUM_IMAGES / 2, 0), "");
 	} else {
 		index = LLVMConstInt(ctx->i32,
 				     si_get_sampler_slot(reg->Register.Index), 0);
 	}
 
 	if (target == TGSI_TEXTURE_BUFFER)
 		*res_ptr = load_sampler_desc(ctx, list, index, DESC_BUFFER);
 	else
diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
index ad586c3..1f8e913 100644
--- a/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
+++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
@@ -1347,20 +1347,25 @@ void si_llvm_context_set_tgsi(struct si_shader_context *ctx,
 	ctx->bld_base.num_instructions = 0;
 	ctx->bld_base.pc = 0;
 	memset(ctx->outputs, 0, sizeof(ctx->outputs));
 
 	ctx->bld_base.emit_store = si_llvm_emit_store;
 	ctx->bld_base.emit_fetch_funcs[TGSI_FILE_IMMEDIATE] = si_llvm_emit_fetch;
 	ctx->bld_base.emit_fetch_funcs[TGSI_FILE_INPUT] = si_llvm_emit_fetch;
 	ctx->bld_base.emit_fetch_funcs[TGSI_FILE_TEMPORARY] = si_llvm_emit_fetch;
 	ctx->bld_base.emit_fetch_funcs[TGSI_FILE_OUTPUT] = si_llvm_emit_fetch;
 	ctx->bld_base.emit_fetch_funcs[TGSI_FILE_SYSTEM_VALUE] = fetch_system_value;
+
+	ctx->num_const_buffers = util_last_bit(info->const_buffers_declared);
+	ctx->num_shader_buffers = util_last_bit(info->shader_buffers_declared);
+	ctx->num_samplers = util_last_bit(info->samplers_declared);
+	ctx->num_images = util_last_bit(info->images_declared);
 }
 
 void si_llvm_create_func(struct si_shader_context *ctx,
 			 const char *name,
 			 LLVMTypeRef *return_types, unsigned num_return_elems,
 			 LLVMTypeRef *ParamTypes, unsigned ParamCount)
 {
 	LLVMTypeRef main_fn_type, ret_type;
 	LLVMBasicBlockRef main_fn_body;
 	enum si_llvm_calling_convention call_conv;
-- 
2.7.4



More information about the mesa-dev mailing list