r600/llvm: Store inputs in function arguments
This commit is contained in:
parent
23afe71f44
commit
88c8f19729
|
@ -77,6 +77,11 @@ static void llvm_load_system_value(
|
||||||
default: assert(!"unknown system value");
|
default: assert(!"unknown system value");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HAVE_LLVM >= 0x0304
|
||||||
|
ctx->system_values[index] = LLVMBuildExtractElement(ctx->gallivm.builder,
|
||||||
|
LLVMGetParam(ctx->main_fn, 0), lp_build_const_int32(&(ctx->gallivm), chan),
|
||||||
|
"");
|
||||||
|
#else
|
||||||
LLVMValueRef reg = lp_build_const_int32(
|
LLVMValueRef reg = lp_build_const_int32(
|
||||||
ctx->soa.bld_base.base.gallivm, chan);
|
ctx->soa.bld_base.base.gallivm, chan);
|
||||||
ctx->system_values[index] = build_intrinsic(
|
ctx->system_values[index] = build_intrinsic(
|
||||||
|
@ -84,8 +89,49 @@ static void llvm_load_system_value(
|
||||||
"llvm.R600.load.input",
|
"llvm.R600.load.input",
|
||||||
ctx->soa.bld_base.base.elem_type, ®, 1,
|
ctx->soa.bld_base.base.elem_type, ®, 1,
|
||||||
LLVMReadNoneAttribute);
|
LLVMReadNoneAttribute);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HAVE_LLVM >= 0x0304
|
||||||
|
static LLVMValueRef
|
||||||
|
llvm_load_input_vector(
|
||||||
|
struct radeon_llvm_context * ctx, unsigned location, unsigned ijregs,
|
||||||
|
boolean interp)
|
||||||
|
{
|
||||||
|
LLVMTypeRef VecType;
|
||||||
|
LLVMValueRef Args[3] = {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
static LLVMValueRef
|
static LLVMValueRef
|
||||||
llvm_load_input_helper(
|
llvm_load_input_helper(
|
||||||
struct radeon_llvm_context * ctx,
|
struct radeon_llvm_context * ctx,
|
||||||
|
@ -110,7 +156,22 @@ llvm_load_input_helper(
|
||||||
return build_intrinsic(bb->gallivm->builder, intrinsic,
|
return build_intrinsic(bb->gallivm->builder, intrinsic,
|
||||||
bb->elem_type, &arg[0], arg_count, LLVMReadNoneAttribute);
|
bb->elem_type, &arg[0], arg_count, LLVMReadNoneAttribute);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_LLVM >= 0x0304
|
||||||
|
static LLVMValueRef
|
||||||
|
llvm_face_select_helper(
|
||||||
|
struct radeon_llvm_context * ctx,
|
||||||
|
LLVMValueRef face, LLVMValueRef front_color, LLVMValueRef back_color)
|
||||||
|
{
|
||||||
|
const struct lp_build_context * bb = &ctx->soa.bld_base.base;
|
||||||
|
LLVMValueRef is_front = LLVMBuildFCmp(
|
||||||
|
bb->gallivm->builder, LLVMRealUGT, face,
|
||||||
|
lp_build_const_float(bb->gallivm, 0.0f), "");
|
||||||
|
return LLVMBuildSelect(bb->gallivm->builder, is_front,
|
||||||
|
front_color, back_color, "");
|
||||||
|
}
|
||||||
|
#else
|
||||||
static LLVMValueRef
|
static LLVMValueRef
|
||||||
llvm_face_select_helper(
|
llvm_face_select_helper(
|
||||||
struct radeon_llvm_context * ctx,
|
struct radeon_llvm_context * ctx,
|
||||||
|
@ -124,6 +185,7 @@ llvm_face_select_helper(
|
||||||
return LLVMBuildSelect(bb->gallivm->builder, is_front,
|
return LLVMBuildSelect(bb->gallivm->builder, is_front,
|
||||||
front_color, back_color, "");
|
front_color, back_color, "");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void llvm_load_input(
|
static void llvm_load_input(
|
||||||
struct radeon_llvm_context * ctx,
|
struct radeon_llvm_context * ctx,
|
||||||
|
@ -132,11 +194,55 @@ static void llvm_load_input(
|
||||||
{
|
{
|
||||||
const struct r600_shader_io * input = &ctx->r600_inputs[input_index];
|
const struct r600_shader_io * input = &ctx->r600_inputs[input_index];
|
||||||
unsigned chan;
|
unsigned chan;
|
||||||
|
#if HAVE_LLVM < 0x0304
|
||||||
unsigned interp = 0;
|
unsigned interp = 0;
|
||||||
int ij_index;
|
int ij_index;
|
||||||
|
#endif
|
||||||
int two_side = (ctx->two_side && input->name == TGSI_SEMANTIC_COLOR);
|
int two_side = (ctx->two_side && input->name == TGSI_SEMANTIC_COLOR);
|
||||||
LLVMValueRef v;
|
LLVMValueRef v;
|
||||||
|
#if HAVE_LLVM >= 0x0304
|
||||||
|
boolean require_interp_intrinsic = ctx->chip_class >= EVERGREEN &&
|
||||||
|
ctx->type == TGSI_PROCESSOR_FRAGMENT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_LLVM >= 0x0304
|
||||||
|
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);
|
||||||
|
|
||||||
|
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 (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
|
||||||
|
v2 = LLVMGetParam(ctx->main_fn, back_input->gpr);
|
||||||
|
v = llvm_face_select_helper(ctx, face, v, v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (chan = 0; chan < 4; chan++) {
|
||||||
|
unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan);
|
||||||
|
|
||||||
|
ctx->inputs[soa_index] = LLVMBuildExtractElement(ctx->gallivm.builder, v,
|
||||||
|
lp_build_const_int32(&(ctx->gallivm), chan), "");
|
||||||
|
|
||||||
|
if (input->name == TGSI_SEMANTIC_POSITION &&
|
||||||
|
ctx->type == TGSI_PROCESSOR_FRAGMENT && chan == 3) {
|
||||||
|
/* RCP for fragcoord.w */
|
||||||
|
ctx->inputs[soa_index] = LLVMBuildFDiv(ctx->gallivm.builder,
|
||||||
|
lp_build_const_float(&(ctx->gallivm), 1.0f),
|
||||||
|
ctx->inputs[soa_index], "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (ctx->chip_class >= EVERGREEN && ctx->type == TGSI_PROCESSOR_FRAGMENT &&
|
if (ctx->chip_class >= EVERGREEN && ctx->type == TGSI_PROCESSOR_FRAGMENT &&
|
||||||
input->spi_sid) {
|
input->spi_sid) {
|
||||||
interp = 1;
|
interp = 1;
|
||||||
|
@ -177,6 +283,7 @@ static void llvm_load_input(
|
||||||
|
|
||||||
ctx->inputs[soa_index] = v;
|
ctx->inputs[soa_index] = v;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void llvm_emit_prologue(struct lp_build_tgsi_context * bld_base)
|
static void llvm_emit_prologue(struct lp_build_tgsi_context * bld_base)
|
||||||
|
@ -657,7 +764,19 @@ LLVMModuleRef r600_tgsi_llvm(
|
||||||
struct tgsi_shader_info shader_info;
|
struct tgsi_shader_info shader_info;
|
||||||
struct lp_build_tgsi_context * bld_base = &ctx->soa.bld_base;
|
struct lp_build_tgsi_context * bld_base = &ctx->soa.bld_base;
|
||||||
radeon_llvm_context_init(ctx);
|
radeon_llvm_context_init(ctx);
|
||||||
|
#if HAVE_LLVM >= 0x0304
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
#else
|
||||||
radeon_llvm_create_func(ctx, NULL, 0);
|
radeon_llvm_create_func(ctx, NULL, 0);
|
||||||
|
#endif
|
||||||
tgsi_scan_shader(tokens, &shader_info);
|
tgsi_scan_shader(tokens, &shader_info);
|
||||||
|
|
||||||
bld_base->info = &shader_info;
|
bld_base->info = &shader_info;
|
||||||
|
|
|
@ -1102,6 +1102,7 @@ static int r600_shader_from_tgsi(struct r600_screen *rscreen,
|
||||||
radeon_llvm_ctx.type = ctx.type;
|
radeon_llvm_ctx.type = ctx.type;
|
||||||
radeon_llvm_ctx.two_side = shader->two_side;
|
radeon_llvm_ctx.two_side = shader->two_side;
|
||||||
radeon_llvm_ctx.face_gpr = ctx.face_gpr;
|
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_inputs = ctx.shader->input;
|
||||||
radeon_llvm_ctx.r600_outputs = ctx.shader->output;
|
radeon_llvm_ctx.r600_outputs = ctx.shader->output;
|
||||||
radeon_llvm_ctx.color_buffer_count = max_color_exports;
|
radeon_llvm_ctx.color_buffer_count = max_color_exports;
|
||||||
|
|
|
@ -60,6 +60,7 @@ struct radeon_llvm_context {
|
||||||
unsigned face_gpr;
|
unsigned face_gpr;
|
||||||
unsigned two_side;
|
unsigned two_side;
|
||||||
unsigned clip_vertex;
|
unsigned clip_vertex;
|
||||||
|
unsigned inputs_count;
|
||||||
struct r600_shader_io * r600_inputs;
|
struct r600_shader_io * r600_inputs;
|
||||||
struct r600_shader_io * r600_outputs;
|
struct r600_shader_io * r600_outputs;
|
||||||
struct pipe_stream_output_info *stream_outputs;
|
struct pipe_stream_output_info *stream_outputs;
|
||||||
|
|
Loading…
Reference in New Issue