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, ®.DimIndirect, + vertex_index = si_get_indirect_index(ctx, ®.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, ®.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