[Mesa-dev] [PATCH 05/18] radeonsi: add get_dw_address_from_generic_indices() helper

Timothy Arceri tarceri at itsqueeze.com
Mon Dec 11 02:43:15 UTC 2017


This will be used by both the tgsi and nir backends.
---
 src/gallium/drivers/radeonsi/si_shader.c | 76 +++++++++++++++++++-------------
 1 file changed, 46 insertions(+), 30 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 96488ca4e29..ba8301b3deb 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -819,108 +819,124 @@ LLVMValueRef si_get_indirect_index(struct si_shader_context *ctx,
  */
 LLVMValueRef si_get_bounded_indirect_index(struct si_shader_context *ctx,
 					   const struct tgsi_ind_register *ind,
 					   int rel_index, unsigned num)
 {
 	LLVMValueRef result = si_get_indirect_index(ctx, ind, 1, rel_index);
 
 	return si_llvm_bound_index(ctx, result, num);
 }
 
+static LLVMValueRef get_dw_address_from_generic_indices(struct si_shader_context *ctx,
+							LLVMValueRef vertex_dw_stride,
+							LLVMValueRef base_addr,
+							LLVMValueRef vertex_index,
+							LLVMValueRef param_index,
+							unsigned input_index,
+							ubyte *name,
+							ubyte *index,
+							bool is_patch)
+{
+	if (vertex_dw_stride) {
+		base_addr = LLVMBuildAdd(ctx->ac.builder, base_addr,
+					 LLVMBuildMul(ctx->ac.builder, vertex_index,
+						      vertex_dw_stride, ""), "");
+	}
+
+	if (param_index) {
+		base_addr = LLVMBuildAdd(ctx->ac.builder, base_addr,
+					 LLVMBuildMul(ctx->ac.builder, param_index,
+						      LLVMConstInt(ctx->i32, 4, 0), ""), "");
+	}
+
+	int param = is_patch ?
+		si_shader_io_get_unique_index_patch(name[input_index],
+						    index[input_index]) :
+		si_shader_io_get_unique_index(name[input_index],
+					      index[input_index]);
+
+	/* Add the base address of the element. */
+	return LLVMBuildAdd(ctx->ac.builder, base_addr,
+			    LLVMConstInt(ctx->i32, param * 4, 0), "");
+}
 
 /**
  * Calculate a dword address given an input or output register and a stride.
  */
 static LLVMValueRef get_dw_address(struct si_shader_context *ctx,
 				   const struct tgsi_full_dst_register *dst,
 				   const struct tgsi_full_src_register *src,
 				   LLVMValueRef vertex_dw_stride,
 				   LLVMValueRef base_addr)
 {
 	struct tgsi_shader_info *info = &ctx->shader->selector->info;
 	ubyte *name, *index, *array_first;
-	int first, param;
+	int input_index;
 	struct tgsi_full_dst_register reg;
+	LLVMValueRef vertex_index = NULL;
+	LLVMValueRef ind_index = NULL;
 
 	/* Set the register description. The address computation is the same
 	 * for sources and destinations. */
 	if (src) {
 		reg.Register.File = src->Register.File;
 		reg.Register.Index = src->Register.Index;
 		reg.Register.Indirect = src->Register.Indirect;
 		reg.Register.Dimension = src->Register.Dimension;
 		reg.Indirect = src->Indirect;
 		reg.Dimension = src->Dimension;
 		reg.DimIndirect = src->DimIndirect;
 	} else
 		reg = *dst;
 
 	/* If the register is 2-dimensional (e.g. an array of vertices
 	 * in a primitive), calculate the base address of the vertex. */
 	if (reg.Register.Dimension) {
-		LLVMValueRef index;
-
 		if (reg.Dimension.Indirect)
-			index = si_get_indirect_index(ctx, &reg.DimIndirect,
+			vertex_index = si_get_indirect_index(ctx, &reg.DimIndirect,
 						      1, reg.Dimension.Index);
 		else
-			index = LLVMConstInt(ctx->i32, reg.Dimension.Index, 0);
-
-		base_addr = LLVMBuildAdd(ctx->ac.builder, base_addr,
-					 LLVMBuildMul(ctx->ac.builder, index,
-						      vertex_dw_stride, ""), "");
+			vertex_index = LLVMConstInt(ctx->i32, reg.Dimension.Index, 0);
 	}
 
 	/* Get information about the register. */
 	if (reg.Register.File == TGSI_FILE_INPUT) {
 		name = info->input_semantic_name;
 		index = info->input_semantic_index;
 		array_first = info->input_array_first;
 	} else if (reg.Register.File == TGSI_FILE_OUTPUT) {
 		name = info->output_semantic_name;
 		index = info->output_semantic_index;
 		array_first = info->output_array_first;
 	} else {
 		assert(0);
 		return NULL;
 	}
 
 	if (reg.Register.Indirect) {
 		/* Add the relative address of the element. */
-		LLVMValueRef ind_index;
-
 		if (reg.Indirect.ArrayID)
-			first = array_first[reg.Indirect.ArrayID];
+			input_index = array_first[reg.Indirect.ArrayID];
 		else
-			first = reg.Register.Index;
+			input_index = reg.Register.Index;
 
 		ind_index = si_get_indirect_index(ctx, &reg.Indirect,
-						  1, reg.Register.Index - first);
-
-		base_addr = LLVMBuildAdd(ctx->ac.builder, base_addr,
-				    LLVMBuildMul(ctx->ac.builder, ind_index,
-						 LLVMConstInt(ctx->i32, 4, 0), ""), "");
-
-		param = reg.Register.Dimension ?
-			si_shader_io_get_unique_index(name[first], index[first]) :
-			si_shader_io_get_unique_index_patch(name[first], index[first]);
+						  1, reg.Register.Index - input_index);
 	} else {
-		param = reg.Register.Dimension ?
-			si_shader_io_get_unique_index(name[reg.Register.Index],
-						      index[reg.Register.Index]) :
-			si_shader_io_get_unique_index_patch(name[reg.Register.Index],
-							    index[reg.Register.Index]);
+		input_index = reg.Register.Index;
 	}
 
-	/* Add the base address of the element. */
-	return LLVMBuildAdd(ctx->ac.builder, base_addr,
-			    LLVMConstInt(ctx->i32, param * 4, 0), "");
+	return get_dw_address_from_generic_indices(ctx, vertex_dw_stride,
+						   base_addr, vertex_index,
+						   ind_index, input_index,
+						   name, index,
+						   !reg.Register.Dimension);
 }
 
 /* The offchip buffer layout for TCS->TES is
  *
  * - attribute 0 of patch 0 vertex 0
  * - attribute 0 of patch 0 vertex 1
  * - attribute 0 of patch 0 vertex 2
  *   ...
  * - attribute 0 of patch 1 vertex 0
  * - attribute 0 of patch 1 vertex 1
-- 
2.14.3



More information about the mesa-dev mailing list