From: Dave Airlie <airl...@redhat.com> This adds the frontend support, however the llvm backend produces the wrong pattern, however we can conditionalise enabling ARB_gpu_shader5 on whatever version of llvm we fix this in.
Signed-off-by: Dave Airlie <airl...@redhat.com> --- docs/GL3.txt | 2 +- src/gallium/drivers/radeonsi/si_shader.c | 88 ++++++++++++++++++++++++++++---- 2 files changed, 79 insertions(+), 11 deletions(-) diff --git a/docs/GL3.txt b/docs/GL3.txt index d74ae63..ca3646c 100644 --- a/docs/GL3.txt +++ b/docs/GL3.txt @@ -98,7 +98,7 @@ GL 4.0, GLSL 4.00: GL_ARB_draw_indirect DONE (i965, nvc0, r600, radeonsi, llvmpipe, softpipe) GL_ARB_gpu_shader5 DONE (i965, nvc0) - 'precise' qualifier DONE - - Dynamically uniform sampler array indices DONE (r600, softpipe) + - Dynamically uniform sampler array indices DONE (r600, radeonsi, softpipe) - Dynamically uniform UBO array indices DONE (r600) - Implicit signed -> unsigned conversions DONE - Fused multiply-add DONE () diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 2705dcc..55357fa 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -1625,6 +1625,24 @@ static bool tgsi_is_shadow_sampler(unsigned target) static const struct lp_build_tgsi_action tex_action; +/** + * Return the value of tgsi_ind_register for indexing. + * This is the indirect index with the constant offset added to it. + */ +static LLVMValueRef get_indirect_index(struct si_shader_context *si_shader_ctx, + const struct tgsi_ind_register *ind, + int rel_index) +{ + struct gallivm_state *gallivm = si_shader_ctx->radeon_bld.soa.bld_base.base.gallivm; + LLVMValueRef result; + + result = si_shader_ctx->radeon_bld.soa.addr[ind->Index][ind->Swizzle]; + result = LLVMBuildLoad(gallivm->builder, result, ""); + result = LLVMBuildAdd(gallivm->builder, result, + lp_build_const_int32(gallivm, rel_index), ""); + return result; +} + static void tex_fetch_args( struct lp_build_tgsi_context * bld_base, struct lp_build_emit_data * emit_data) @@ -1640,10 +1658,36 @@ static void tex_fetch_args( unsigned num_coords = tgsi_util_get_texture_coord_dim(target, &ref_pos); unsigned count = 0; unsigned chan; - unsigned sampler_src = emit_data->inst->Instruction.NumSrcRegs - 1; - unsigned sampler_index = emit_data->inst->Src[sampler_src].Register.Index; + unsigned sampler_src; + unsigned sampler_index; bool has_offset = HAVE_LLVM >= 0x0305 ? inst->Texture.NumOffsets > 0 : false; + bool has_sampler_indirect = false; + LLVMValueRef res_ptr, samp_ptr; + + sampler_src = emit_data->inst->Instruction.NumSrcRegs - 1; + sampler_index = emit_data->inst->Src[sampler_src].Register.Index; + + if (emit_data->inst->Src[sampler_src].Register.Indirect) { + const struct tgsi_full_src_register *reg = &emit_data->inst->Src[sampler_src]; + unsigned first = reg->Register.Index; + LLVMValueRef ind_index; + ind_index = get_indirect_index(si_shader_ctx, ®->Indirect, + reg->Register.Index - first); + + res_ptr = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_RESOURCE); + res_ptr = build_indexed_load_const(si_shader_ctx, res_ptr, + ind_index); + + samp_ptr = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_SAMPLER); + samp_ptr = build_indexed_load_const(si_shader_ctx, samp_ptr, + ind_index); + has_sampler_indirect = true; + + } else { + res_ptr = si_shader_ctx->resources[sampler_index]; + samp_ptr = si_shader_ctx->samplers[sampler_index]; + } if (target == TGSI_TEXTURE_BUFFER) { LLVMTypeRef i128 = LLVMIntTypeInContext(gallivm->context, 128); LLVMTypeRef v2i128 = LLVMVectorType(i128, 2); @@ -1651,7 +1695,7 @@ static void tex_fetch_args( LLVMTypeRef v16i8 = LLVMVectorType(i8, 16); /* Bitcast and truncate v8i32 to v16i8. */ - LLVMValueRef res = si_shader_ctx->resources[sampler_index]; + LLVMValueRef res = res_ptr; res = LLVMBuildBitCast(gallivm->builder, res, v2i128, ""); res = LLVMBuildExtractElement(gallivm->builder, res, bld_base->uint_bld.one, ""); res = LLVMBuildBitCast(gallivm->builder, res, v16i8, ""); @@ -1877,7 +1921,7 @@ static void tex_fetch_args( } /* Resource */ - emit_data->args[1] = si_shader_ctx->resources[sampler_index]; + emit_data->args[1] = res_ptr; if (opcode == TGSI_OPCODE_TXF) { /* add tex offsets */ @@ -1923,7 +1967,7 @@ static void tex_fetch_args( 4); } else if (opcode == TGSI_OPCODE_TG4 || opcode == TGSI_OPCODE_LODQ || - has_offset) { + has_offset || has_sampler_indirect) { unsigned is_array = target == TGSI_TEXTURE_1D_ARRAY || target == TGSI_TEXTURE_SHADOW1D_ARRAY || target == TGSI_TEXTURE_2D_ARRAY || @@ -1960,7 +2004,7 @@ static void tex_fetch_args( dmask = 1 << gather_comp; } - emit_data->args[2] = si_shader_ctx->samplers[sampler_index]; + emit_data->args[2] = samp_ptr; emit_data->args[3] = lp_build_const_int32(gallivm, dmask); emit_data->args[4] = lp_build_const_int32(gallivm, is_rect); /* unorm */ emit_data->args[5] = lp_build_const_int32(gallivm, 0); /* r128 */ @@ -1976,7 +2020,7 @@ static void tex_fetch_args( LLVMFloatTypeInContext(gallivm->context), 4); } else { - emit_data->args[2] = si_shader_ctx->samplers[sampler_index]; + emit_data->args[2] = samp_ptr; emit_data->args[3] = lp_build_const_int32(gallivm, target); emit_data->arg_count = 4; @@ -2009,7 +2053,16 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action * action, char intr_name[127]; bool has_offset = HAVE_LLVM >= 0x0305 ? emit_data->inst->Texture.NumOffsets > 0 : false; + bool has_sampler_indirect = false; + unsigned sampler_src; + + if (emit_data->inst->Instruction.NumSrcRegs) { + sampler_src = emit_data->inst->Instruction.NumSrcRegs - 1; + if (emit_data->inst->Src[sampler_src].Register.Indirect) { + has_sampler_indirect = true; + } + } if (target == TGSI_TEXTURE_BUFFER) { emit_data->output[emit_data->chan] = build_intrinsic( base->gallivm->builder, @@ -2021,7 +2074,7 @@ static void build_tex_intrinsic(const struct lp_build_tgsi_action * action, if (opcode == TGSI_OPCODE_TG4 || opcode == TGSI_OPCODE_LODQ || - (opcode != TGSI_OPCODE_TXF && has_offset)) { + (opcode != TGSI_OPCODE_TXF && has_offset) || has_sampler_indirect) { bool is_shadow = tgsi_is_shadow_sampler(target); const char *name = "llvm.SI.image.sample"; const char *infix = ""; @@ -2122,13 +2175,28 @@ static void txq_fetch_args( const struct tgsi_full_instruction *inst = emit_data->inst; struct gallivm_state *gallivm = bld_base->base.gallivm; unsigned target = inst->Texture.Texture; + LLVMValueRef res_ptr; + + if (inst->Src[1].Register.Indirect) { + const struct tgsi_full_src_register *reg = &inst->Src[1]; + unsigned first = reg->Register.Index; + LLVMValueRef ind_index; + + ind_index = get_indirect_index(si_shader_ctx, ®->Indirect, + reg->Register.Index - first); + + res_ptr = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_RESOURCE); + res_ptr = build_indexed_load_const(si_shader_ctx, res_ptr, + ind_index); + } else + res_ptr = si_shader_ctx->resources[inst->Src[1].Register.Index]; if (target == TGSI_TEXTURE_BUFFER) { LLVMTypeRef i32 = LLVMInt32TypeInContext(gallivm->context); LLVMTypeRef v8i32 = LLVMVectorType(i32, 8); /* Read the size from the buffer descriptor directly. */ - LLVMValueRef size = si_shader_ctx->resources[inst->Src[1].Register.Index]; + LLVMValueRef size = res_ptr; size = LLVMBuildBitCast(gallivm->builder, size, v8i32, ""); size = LLVMBuildExtractElement(gallivm->builder, size, lp_build_const_int32(gallivm, 6), ""); @@ -2140,7 +2208,7 @@ static void txq_fetch_args( emit_data->args[0] = lp_build_emit_fetch(bld_base, inst, 0, TGSI_CHAN_X); /* Resource */ - emit_data->args[1] = si_shader_ctx->resources[inst->Src[1].Register.Index]; + emit_data->args[1] = res_ptr; /* Texture target */ if (target == TGSI_TEXTURE_CUBE_ARRAY || -- 2.4.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev