This will be used by both the tgsi and nir backends.

Reviewed-by: Nicolai Hähnle <nicolai.haeh...@amd.com>
---
 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 9e16b92a5a1..5ef95589c2a 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

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to