On Sun, Nov 03, 2013 at 06:58:18PM +0100, Vincent Lejeune wrote: > --- > src/gallium/drivers/r600/r600_llvm.c | 125 > ++++++++++++--------- > src/gallium/drivers/r600/r600_shader.c | 2 + > src/gallium/drivers/radeon/radeon_llvm.h | 1 + > .../drivers/radeon/radeon_setup_tgsi_llvm.c | 2 +- > 4 files changed, 75 insertions(+), 55 deletions(-)
As discussed on IRC, I think this will need some ifdefs to remain compatible with older LLVM. Plus, I have two comments below: > > diff --git a/src/gallium/drivers/r600/r600_llvm.c > b/src/gallium/drivers/r600/r600_llvm.c > index 5afe3cb..8dcda1a 100644 > --- a/src/gallium/drivers/r600/r600_llvm.c > +++ b/src/gallium/drivers/r600/r600_llvm.c > @@ -87,37 +87,50 @@ static void llvm_load_system_value( > } > > static LLVMValueRef > -llvm_load_input_helper( > - struct radeon_llvm_context * ctx, > - unsigned idx, int interp, int ij_index) > +llvm_load_input_vector( > + struct radeon_llvm_context * ctx, unsigned location, unsigned ijregs, > + boolean interp) > { > - const struct lp_build_context * bb = &ctx->soa.bld_base.base; > - LLVMValueRef arg[2]; > - int arg_count; > - const char * intrinsic; > - > - arg[0] = lp_build_const_int32(bb->gallivm, idx); > - > - if (interp) { > - intrinsic = "llvm.R600.interp.input"; > - arg[1] = lp_build_const_int32(bb->gallivm, ij_index); > - arg_count = 2; > - } else { > - intrinsic = "llvm.R600.load.input"; > - arg_count = 1; > - } > - > - return build_intrinsic(bb->gallivm->builder, intrinsic, > - bb->elem_type, &arg[0], arg_count, LLVMReadNoneAttribute); > + LLVMTypeRef VecType; > + LLVMValueRef Args[2] = { > + lp_build_const_int32(&(ctx->gallivm), location) > + }; > + unsigned ArgCount = 1; > + if (interp) { > + VecType = > LLVMVectorType(ctx->soa.bld_base.base.elem_type, 2); > + LLVMValueRef IJIndex = LLVMGetParam(ctx->main_fn, > ijregs / 2); > + Args[ArgCount++] = > LLVMBuildExtractElement(ctx->gallivm.builder, IJIndex, > + lp_build_const_int32(&(ctx->gallivm), 2 * (ijregs % > 2)), ""); > + Args[ArgCount++] = > LLVMBuildExtractElement(ctx->gallivm.builder, IJIndex, > + lp_build_const_int32(&(ctx->gallivm), 2 * (ijregs % 2) > + 1), ""); > + LLVMValueRef HalfVec[2] = { > + build_intrinsic(ctx->gallivm.builder, > "llvm.R600.interp.xy", > + VecType, Args, ArgCount, > LLVMReadNoneAttribute), > + build_intrinsic(ctx->gallivm.builder, > "llvm.R600.interp.zw", > + VecType, Args, ArgCount, > LLVMReadNoneAttribute) > + }; > + LLVMValueRef MaskInputs[4] = { > + lp_build_const_int32(&(ctx->gallivm), 0), > + lp_build_const_int32(&(ctx->gallivm), 1), > + lp_build_const_int32(&(ctx->gallivm), 2), > + lp_build_const_int32(&(ctx->gallivm), 3) > + }; > + LLVMValueRef Mask = LLVMConstVector(MaskInputs, 4); > + return LLVMBuildShuffleVector(ctx->gallivm.builder, > HalfVec[0], HalfVec[1], > + Mask, ""); > + } else { > + VecType = > LLVMVectorType(ctx->soa.bld_base.base.elem_type, 4); > + return build_intrinsic(ctx->gallivm.builder, > "llvm.R600.interp.const", > + VecType, Args, ArgCount, LLVMReadNoneAttribute); > + } > } > > static LLVMValueRef > llvm_face_select_helper( > struct radeon_llvm_context * ctx, > - unsigned face_loc, LLVMValueRef front_color, LLVMValueRef back_color) > + LLVMValueRef face, LLVMValueRef front_color, LLVMValueRef back_color) > { > const struct lp_build_context * bb = &ctx->soa.bld_base.base; > - LLVMValueRef face = llvm_load_input_helper(ctx, face_loc, 0, 0); > LLVMValueRef is_front = LLVMBuildFCmp( > bb->gallivm->builder, LLVMRealUGT, face, > lp_build_const_float(bb->gallivm, 0.0f), ""); > @@ -132,50 +145,46 @@ static void llvm_load_input( > { > const struct r600_shader_io * input = &ctx->r600_inputs[input_index]; > unsigned chan; > - unsigned interp = 0; > - int ij_index; > int two_side = (ctx->two_side && input->name == TGSI_SEMANTIC_COLOR); > LLVMValueRef v; > + boolean require_interp_intrinsic = ctx->chip_class >= EVERGREEN && > + ctx->type == TGSI_PROCESSOR_FRAGMENT; > > - if (ctx->chip_class >= EVERGREEN && ctx->type == > TGSI_PROCESSOR_FRAGMENT && > - input->spi_sid) { > - interp = 1; > - ij_index = (input->interpolate > 0) ? input->ij_index : -1; > - } > + if (require_interp_intrinsic && input->spi_sid) { > + v = llvm_load_input_vector(ctx, input->lds_pos, input->ij_index, > + (input->interpolate > 0)); > + } else > + v = LLVMGetParam(ctx->main_fn, input->gpr); > > - for (chan = 0; chan < 4; chan++) { > - unsigned soa_index = radeon_llvm_reg_index_soa(input_index, > chan); > - int loc; > + if (two_side) { > + struct r600_shader_io * back_input = > + &ctx->r600_inputs[input->back_color_input]; > + LLVMValueRef v2; > + LLVMValueRef face = LLVMGetParam(ctx->main_fn, > ctx->face_gpr); > + face = LLVMBuildExtractElement(ctx->gallivm.builder, > face, > + lp_build_const_int32(&(ctx->gallivm), 0), ""); > > - if (interp) { > - loc = 4 * input->lds_pos + chan; > - } else { > - if (input->name == TGSI_SEMANTIC_FACE) > - loc = 4 * ctx->face_gpr; > + if (require_interp_intrinsic && back_input->spi_sid) > + v2 = llvm_load_input_vector(ctx, > back_input->lds_pos, > + back_input->ij_index, > (back_input->interpolate > 0)); > else > - loc = 4 * input->gpr + chan; > + v2 = LLVMGetParam(ctx->main_fn, > back_input->gpr); > + v = llvm_face_select_helper(ctx, face, v, v2); > } > > - v = llvm_load_input_helper(ctx, loc, interp, ij_index); > + for (chan = 0; chan < 4; chan++) { > + unsigned soa_index = radeon_llvm_reg_index_soa(input_index, > chan); > > - if (two_side) { > - struct r600_shader_io * back_input = > - > &ctx->r600_inputs[input->back_color_input]; > - int back_loc = interp ? back_input->lds_pos : > back_input->gpr; > - LLVMValueRef v2; > + ctx->inputs[soa_index] = > LLVMBuildExtractElement(ctx->gallivm.builder, v, > + lp_build_const_int32(&(ctx->gallivm), chan), ""); > > - back_loc = 4 * back_loc + chan; > - v2 = llvm_load_input_helper(ctx, back_loc, interp, > ij_index); > - v = llvm_face_select_helper(ctx, 4 * ctx->face_gpr, v, > v2); > - } else if (input->name == TGSI_SEMANTIC_POSITION && > + if (input->name == TGSI_SEMANTIC_POSITION && > ctx->type == TGSI_PROCESSOR_FRAGMENT && chan == > 3) { > /* RCP for fragcoord.w */ > - v = LLVMBuildFDiv(ctx->gallivm.builder, > + ctx->inputs[soa_index] = > LLVMBuildFDiv(ctx->gallivm.builder, > lp_build_const_float(&(ctx->gallivm), > 1.0f), > - v, ""); > + ctx->inputs[soa_index], ""); > } > - > - ctx->inputs[soa_index] = v; > } > } > > @@ -657,7 +666,15 @@ LLVMModuleRef r600_tgsi_llvm( > struct tgsi_shader_info shader_info; > struct lp_build_tgsi_context * bld_base = &ctx->soa.bld_base; > radeon_llvm_context_init(ctx); > - radeon_llvm_create_func(ctx, NULL, 0); > + LLVMTypeRef Arguments[32]; > + unsigned ArgumentsCount = 0; > + for (unsigned i = 0; i < ctx->inputs_count; i++) > + Arguments[ArgumentsCount++] = > LLVMVectorType(bld_base->base.elem_type, 4); > + radeon_llvm_create_func(ctx, Arguments, ArgumentsCount); > + for (unsigned i = 0; i < ctx->inputs_count; i++) { > + LLVMValueRef P = LLVMGetParam(ctx->main_fn, i); > + LLVMAddAttribute(P, LLVMInRegAttribute); > + } > tgsi_scan_shader(tokens, &shader_info); > > bld_base->info = &shader_info; > diff --git a/src/gallium/drivers/r600/r600_shader.c > b/src/gallium/drivers/r600/r600_shader.c > index aed2100..ae134d1 100644 > --- a/src/gallium/drivers/r600/r600_shader.c > +++ b/src/gallium/drivers/r600/r600_shader.c > @@ -899,6 +899,7 @@ static int r600_shader_from_tgsi(struct r600_screen > *rscreen, > #ifdef R600_USE_LLVM > use_llvm = !(rscreen->b.debug_flags & DBG_NO_LLVM); > #endif > + Extra whitespace here. > ctx.bc = &shader->bc; > ctx.shader = shader; > ctx.native_integers = true; > @@ -1102,6 +1103,7 @@ static int r600_shader_from_tgsi(struct r600_screen > *rscreen, > radeon_llvm_ctx.type = ctx.type; > radeon_llvm_ctx.two_side = shader->two_side; > radeon_llvm_ctx.face_gpr = ctx.face_gpr; > + radeon_llvm_ctx.inputs_count = ctx.shader->ninput + 1; > radeon_llvm_ctx.r600_inputs = ctx.shader->input; > radeon_llvm_ctx.r600_outputs = ctx.shader->output; > radeon_llvm_ctx.color_buffer_count = max_color_exports; > diff --git a/src/gallium/drivers/radeon/radeon_llvm.h > b/src/gallium/drivers/radeon/radeon_llvm.h > index ef09dc8..2cab6b0 100644 > --- a/src/gallium/drivers/radeon/radeon_llvm.h > +++ b/src/gallium/drivers/radeon/radeon_llvm.h > @@ -60,6 +60,7 @@ struct radeon_llvm_context { > unsigned face_gpr; > unsigned two_side; > unsigned clip_vertex; > + unsigned inputs_count; > struct r600_shader_io * r600_inputs; > struct r600_shader_io * r600_outputs; > struct pipe_stream_output_info *stream_outputs; > diff --git a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c > b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c > index 43ebe7f..9ed671c 100644 > --- a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c > +++ b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c > @@ -1252,7 +1252,7 @@ void radeon_llvm_context_init(struct > radeon_llvm_context * ctx) > bld_base->op_actions[TGSI_OPCODE_ENDIF].emit = endif_emit; > bld_base->op_actions[TGSI_OPCODE_ENDLOOP].emit = endloop_emit; > bld_base->op_actions[TGSI_OPCODE_EX2].emit = build_tgsi_intrinsic_nomem; > - bld_base->op_actions[TGSI_OPCODE_EX2].intr_name = "llvm.AMDIL.exp."; > + bld_base->op_actions[TGSI_OPCODE_EX2].intr_name = "llvm.exp2.f32"; This change seems unrelated. > bld_base->op_actions[TGSI_OPCODE_FLR].emit = > build_tgsi_intrinsic_readonly; > bld_base->op_actions[TGSI_OPCODE_FLR].intr_name = "floor"; > bld_base->op_actions[TGSI_OPCODE_FRC].emit = build_tgsi_intrinsic_nomem; > -- > 1.8.3.1 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev