diff options
author | Timothy Arceri <tarceri@itsqueeze.com> | 2018-01-14 20:54:20 +1100 |
---|---|---|
committer | Timothy Arceri <tarceri@itsqueeze.com> | 2018-01-31 09:14:07 +1100 |
commit | d185190222cea1def252b15c1fca3676b50d76b4 (patch) | |
tree | ff37e983d0ab2132faf3672421c727c520afe4b1 /src | |
parent | 97058168a4bcf7d0dddbb13af02972a0edbcefd4 (diff) |
ac/radeonsi: add lookup_interp_param and load_sample_position to the abi
This will enable the interpolateAt builtins to work on the radeonsi
nir backend.
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/amd/common/ac_nir_to_llvm.c | 64 | ||||
-rw-r--r-- | src/amd/common/ac_shader_abi.h | 7 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.c | 2 |
3 files changed, 44 insertions, 29 deletions
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c index e4963dc359..fd5989389b 100644 --- a/src/amd/common/ac_nir_to_llvm.c +++ b/src/amd/common/ac_nir_to_llvm.c @@ -3975,9 +3975,11 @@ static LLVMValueRef visit_var_atomic(struct nir_to_llvm_context *ctx, return result; } -static LLVMValueRef lookup_interp_param(struct nir_to_llvm_context *ctx, +static LLVMValueRef lookup_interp_param(struct ac_shader_abi *abi, enum glsl_interp_mode interp, unsigned location) { + struct nir_to_llvm_context *ctx = nir_to_llvm_context_from_abi(abi); + switch (interp) { case INTERP_MODE_FLAT: default: @@ -4003,9 +4005,11 @@ static LLVMValueRef lookup_interp_param(struct nir_to_llvm_context *ctx, return NULL; } -static LLVMValueRef load_sample_position(struct nir_to_llvm_context *ctx, +static LLVMValueRef load_sample_position(struct ac_shader_abi *abi, LLVMValueRef sample_id) { + struct nir_to_llvm_context *ctx = nir_to_llvm_context_from_abi(abi); + LLVMValueRef result; LLVMValueRef ptr = ac_build_gep0(&ctx->ac, ctx->ring_offsets, LLVMConstInt(ctx->ac.i32, RING_PS_SAMPLE_POSITIONS, false)); @@ -4051,7 +4055,7 @@ static LLVMValueRef load_sample_mask_in(struct ac_nir_context *ctx) return result; } -static LLVMValueRef visit_interp(struct nir_to_llvm_context *ctx, +static LLVMValueRef visit_interp(struct ac_nir_context *ctx, const nir_intrinsic_instr *instr) { LLVMValueRef result[4]; @@ -4069,33 +4073,33 @@ static LLVMValueRef visit_interp(struct nir_to_llvm_context *ctx, case nir_intrinsic_interp_var_at_sample: case nir_intrinsic_interp_var_at_offset: location = INTERP_CENTER; - src0 = get_src(ctx->nir, instr->src[0]); + src0 = get_src(ctx, instr->src[0]); break; default: break; } if (instr->intrinsic == nir_intrinsic_interp_var_at_offset) { - src_c0 = ac_to_float(&ctx->ac, LLVMBuildExtractElement(ctx->builder, src0, ctx->ac.i32_0, "")); - src_c1 = ac_to_float(&ctx->ac, LLVMBuildExtractElement(ctx->builder, src0, ctx->ac.i32_1, "")); + src_c0 = ac_to_float(&ctx->ac, LLVMBuildExtractElement(ctx->ac.builder, src0, ctx->ac.i32_0, "")); + src_c1 = ac_to_float(&ctx->ac, LLVMBuildExtractElement(ctx->ac.builder, src0, ctx->ac.i32_1, "")); } else if (instr->intrinsic == nir_intrinsic_interp_var_at_sample) { LLVMValueRef sample_position; LLVMValueRef halfval = LLVMConstReal(ctx->ac.f32, 0.5f); /* fetch sample ID */ - sample_position = load_sample_position(ctx, src0); + sample_position = ctx->abi->load_sample_position(ctx->abi, src0); - src_c0 = LLVMBuildExtractElement(ctx->builder, sample_position, ctx->ac.i32_0, ""); - src_c0 = LLVMBuildFSub(ctx->builder, src_c0, halfval, ""); - src_c1 = LLVMBuildExtractElement(ctx->builder, sample_position, ctx->ac.i32_1, ""); - src_c1 = LLVMBuildFSub(ctx->builder, src_c1, halfval, ""); + src_c0 = LLVMBuildExtractElement(ctx->ac.builder, sample_position, ctx->ac.i32_0, ""); + src_c0 = LLVMBuildFSub(ctx->ac.builder, src_c0, halfval, ""); + src_c1 = LLVMBuildExtractElement(ctx->ac.builder, sample_position, ctx->ac.i32_1, ""); + src_c1 = LLVMBuildFSub(ctx->ac.builder, src_c1, halfval, ""); } - interp_param = lookup_interp_param(ctx, instr->variables[0]->var->data.interpolation, location); + interp_param = ctx->abi->lookup_interp_param(ctx->abi, instr->variables[0]->var->data.interpolation, location); attr_number = LLVMConstInt(ctx->ac.i32, input_index, false); if (location == INTERP_CENTER) { LLVMValueRef ij_out[2]; - LLVMValueRef ddxy_out = emit_ddxy_interp(ctx->nir, interp_param); + LLVMValueRef ddxy_out = emit_ddxy_interp(ctx, interp_param); /* * take the I then J parameters, and the DDX/Y for it, and @@ -4108,24 +4112,24 @@ static LLVMValueRef visit_interp(struct nir_to_llvm_context *ctx, for (unsigned i = 0; i < 2; i++) { LLVMValueRef ix_ll = LLVMConstInt(ctx->ac.i32, i, false); LLVMValueRef iy_ll = LLVMConstInt(ctx->ac.i32, i + 2, false); - LLVMValueRef ddx_el = LLVMBuildExtractElement(ctx->builder, + LLVMValueRef ddx_el = LLVMBuildExtractElement(ctx->ac.builder, ddxy_out, ix_ll, ""); - LLVMValueRef ddy_el = LLVMBuildExtractElement(ctx->builder, + LLVMValueRef ddy_el = LLVMBuildExtractElement(ctx->ac.builder, ddxy_out, iy_ll, ""); - LLVMValueRef interp_el = LLVMBuildExtractElement(ctx->builder, + LLVMValueRef interp_el = LLVMBuildExtractElement(ctx->ac.builder, interp_param, ix_ll, ""); LLVMValueRef temp1, temp2; - interp_el = LLVMBuildBitCast(ctx->builder, interp_el, + interp_el = LLVMBuildBitCast(ctx->ac.builder, interp_el, ctx->ac.f32, ""); - temp1 = LLVMBuildFMul(ctx->builder, ddx_el, src_c0, ""); - temp1 = LLVMBuildFAdd(ctx->builder, temp1, interp_el, ""); + temp1 = LLVMBuildFMul(ctx->ac.builder, ddx_el, src_c0, ""); + temp1 = LLVMBuildFAdd(ctx->ac.builder, temp1, interp_el, ""); - temp2 = LLVMBuildFMul(ctx->builder, ddy_el, src_c1, ""); - temp2 = LLVMBuildFAdd(ctx->builder, temp2, temp1, ""); + temp2 = LLVMBuildFMul(ctx->ac.builder, ddy_el, src_c1, ""); + temp2 = LLVMBuildFAdd(ctx->ac.builder, temp2, temp1, ""); - ij_out[i] = LLVMBuildBitCast(ctx->builder, + ij_out[i] = LLVMBuildBitCast(ctx->ac.builder, temp2, ctx->ac.i32, ""); } interp_param = ac_build_gather_values(&ctx->ac, ij_out, 2); @@ -4136,21 +4140,21 @@ static LLVMValueRef visit_interp(struct nir_to_llvm_context *ctx, LLVMValueRef llvm_chan = LLVMConstInt(ctx->ac.i32, chan, false); if (interp_param) { - interp_param = LLVMBuildBitCast(ctx->builder, + interp_param = LLVMBuildBitCast(ctx->ac.builder, interp_param, ctx->ac.v2f32, ""); LLVMValueRef i = LLVMBuildExtractElement( - ctx->builder, interp_param, ctx->ac.i32_0, ""); + ctx->ac.builder, interp_param, ctx->ac.i32_0, ""); LLVMValueRef j = LLVMBuildExtractElement( - ctx->builder, interp_param, ctx->ac.i32_1, ""); + ctx->ac.builder, interp_param, ctx->ac.i32_1, ""); result[chan] = ac_build_fs_interp(&ctx->ac, llvm_chan, attr_number, - ctx->abi.prim_mask, i, j); + ctx->abi->prim_mask, i, j); } else { result[chan] = ac_build_fs_interp_mov(&ctx->ac, LLVMConstInt(ctx->ac.i32, 2, false), llvm_chan, attr_number, - ctx->abi.prim_mask); + ctx->abi->prim_mask); } } return ac_build_varying_gather_values(&ctx->ac, result, instr->num_components, @@ -4473,7 +4477,7 @@ static void visit_intrinsic(struct ac_nir_context *ctx, case nir_intrinsic_interp_var_at_centroid: case nir_intrinsic_interp_var_at_sample: case nir_intrinsic_interp_var_at_offset: - result = visit_interp(ctx->nctx, instr); + result = visit_interp(ctx, instr); break; case nir_intrinsic_emit_vertex: ctx->abi->emit_vertex(ctx->abi, nir_intrinsic_stream_id(instr), ctx->outputs); @@ -5426,7 +5430,7 @@ handle_fs_input_decl(struct nir_to_llvm_context *ctx, else interp_type = INTERP_CENTER; - interp = lookup_interp_param(ctx, variable->data.interpolation, interp_type); + interp = lookup_interp_param(&ctx->abi, variable->data.interpolation, interp_type); } else interp = NULL; @@ -6870,6 +6874,8 @@ LLVMModuleRef ac_translate_nir_to_llvm(LLVMTargetMachineRef tm, } } else if (shaders[i]->info.stage == MESA_SHADER_FRAGMENT) { shader_info->fs.can_discard = shaders[i]->info.fs.uses_discard; + ctx.abi.lookup_interp_param = lookup_interp_param; + ctx.abi.load_sample_position = load_sample_position; } if (i) diff --git a/src/amd/common/ac_shader_abi.h b/src/amd/common/ac_shader_abi.h index 9cdfd9d1df..d9bb5a1e32 100644 --- a/src/amd/common/ac_shader_abi.h +++ b/src/amd/common/ac_shader_abi.h @@ -147,6 +147,13 @@ struct ac_shader_abi { enum ac_descriptor_type desc_type, bool image, bool write); + LLVMValueRef (*lookup_interp_param)(struct ac_shader_abi *abi, + enum glsl_interp_mode interp, + unsigned location); + + LLVMValueRef (*load_sample_position)(struct ac_shader_abi *abi, + LLVMValueRef sample_id); + /* Whether to clamp the shadow reference value to [0,1]on VI. Radeonsi currently * uses it due to promoting D16 to D32, but radv needs it off. */ bool clamp_shadow_reference; diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index dfec070d33..76215b318a 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -6028,6 +6028,8 @@ static bool si_compile_tgsi_main(struct si_shader_context *ctx, ctx->load_input = declare_input_fs; ctx->abi.emit_outputs = si_llvm_return_fs_outputs; bld_base->emit_epilogue = si_tgsi_emit_epilogue; + ctx->abi.lookup_interp_param = si_nir_lookup_interp_param; + ctx->abi.load_sample_position = load_sample_position; break; case PIPE_SHADER_COMPUTE: break; |