[Mesa-dev] [PATCH] r600/llvm: Store inputs in function arguments
Tom Stellard
tom at stellard.net
Mon Nov 11 06:53:59 PST 2013
On Mon, Nov 11, 2013 at 03:45:53PM +0100, Vincent Lejeune wrote:
Reviewed-by: Tom Stellard <thomas.stellard at amd.com>
> ---
> src/gallium/drivers/r600/r600_llvm.c | 119 +++++++++++++++++++++++++++++++
> src/gallium/drivers/r600/r600_shader.c | 1 +
> src/gallium/drivers/radeon/radeon_llvm.h | 1 +
> 3 files changed, 121 insertions(+)
>
> diff --git a/src/gallium/drivers/r600/r600_llvm.c b/src/gallium/drivers/r600/r600_llvm.c
> index 5afe3cb..a2ff0ec 100644
> --- a/src/gallium/drivers/r600/r600_llvm.c
> +++ b/src/gallium/drivers/r600/r600_llvm.c
> @@ -77,6 +77,11 @@ static void llvm_load_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(
> ctx->soa.bld_base.base.gallivm, chan);
> ctx->system_values[index] = build_intrinsic(
> @@ -84,8 +89,49 @@ static void llvm_load_system_value(
> "llvm.R600.load.input",
> ctx->soa.bld_base.base.elem_type, ®, 1,
> 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
> llvm_load_input_helper(
> struct radeon_llvm_context * ctx,
> @@ -110,7 +156,22 @@ llvm_load_input_helper(
> return build_intrinsic(bb->gallivm->builder, intrinsic,
> 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
> llvm_face_select_helper(
> struct radeon_llvm_context * ctx,
> @@ -124,6 +185,7 @@ llvm_face_select_helper(
> return LLVMBuildSelect(bb->gallivm->builder, is_front,
> front_color, back_color, "");
> }
> +#endif
>
> static void llvm_load_input(
> 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];
> unsigned chan;
> +#if HAVE_LLVM < 0x0304
> unsigned interp = 0;
> int ij_index;
> +#endif
> int two_side = (ctx->two_side && input->name == TGSI_SEMANTIC_COLOR);
> 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 &&
> input->spi_sid) {
> interp = 1;
> @@ -177,6 +283,7 @@ static void llvm_load_input(
>
> ctx->inputs[soa_index] = v;
> }
> +#endif
> }
>
> 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 lp_build_tgsi_context * bld_base = &ctx->soa.bld_base;
> 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);
> +#endif
> 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..1ea4ae6 100644
> --- a/src/gallium/drivers/r600/r600_shader.c
> +++ b/src/gallium/drivers/r600/r600_shader.c
> @@ -1102,6 +1102,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;
> --
> 1.8.3.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list