[Mesa-dev] [PATCH] r600/llvm: Store inputs in function arguments
Vincent Lejeune
vljn at ovi.com
Sun Nov 3 09:58:18 PST 2013
---
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(-)
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
+
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";
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
More information about the mesa-dev
mailing list