ac/llvm,radeonsi: lower nir_load_barycentric_at_sample in abi

RADV already did this in radv_lower_fs_intrinsics().

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21436>
This commit is contained in:
Qiang Yu
2023-02-10 11:15:46 +08:00
parent 0c8e7ad47e
commit 5c44404b5f
5 changed files with 19 additions and 52 deletions

View File

@@ -3235,27 +3235,6 @@ static LLVMValueRef barycentric_centroid(struct ac_nir_context *ctx, unsigned mo
return LLVMBuildBitCast(ctx->ac.builder, interp_param, ctx->ac.v2i32, "");
}
static LLVMValueRef barycentric_at_sample(struct ac_nir_context *ctx, unsigned mode,
LLVMValueRef sample_id)
{
if (ctx->abi->interp_at_sample_force_center)
return barycentric_center(ctx, mode);
LLVMValueRef halfval = LLVMConstReal(ctx->ac.f32, 0.5f);
/* fetch sample ID */
LLVMValueRef sample_pos = ctx->abi->load_sample_position(ctx->abi, sample_id);
LLVMValueRef src_c0 = LLVMBuildExtractElement(ctx->ac.builder, sample_pos, ctx->ac.i32_0, "");
src_c0 = LLVMBuildFSub(ctx->ac.builder, src_c0, halfval, "");
LLVMValueRef src_c1 = LLVMBuildExtractElement(ctx->ac.builder, sample_pos, ctx->ac.i32_1, "");
src_c1 = LLVMBuildFSub(ctx->ac.builder, src_c1, halfval, "");
LLVMValueRef coords[] = {src_c0, src_c1};
LLVMValueRef offset = ac_build_gather_values(&ctx->ac, coords, 2);
return barycentric_offset(ctx, mode, offset);
}
static LLVMValueRef barycentric_sample(struct ac_nir_context *ctx, unsigned mode)
{
LLVMValueRef interp_param = lookup_interp_param(ctx, mode, INTERP_SAMPLE);
@@ -3826,11 +3805,6 @@ static bool visit_intrinsic(struct ac_nir_context *ctx, nir_intrinsic_instr *ins
result = barycentric_offset(ctx, nir_intrinsic_interp_mode(instr), offset);
break;
}
case nir_intrinsic_load_barycentric_at_sample: {
LLVMValueRef sample_id = get_src(ctx, instr->src[0]);
result = barycentric_at_sample(ctx, nir_intrinsic_interp_mode(instr), sample_id);
break;
}
case nir_intrinsic_load_interpolated_input: {
/* We assume any indirect loads have been lowered away */
ASSERTED nir_const_value *offset = nir_src_as_const_value(instr->src[1]);

View File

@@ -96,8 +96,6 @@ struct ac_shader_abi {
LLVMValueRef (*load_sampler_desc)(struct ac_shader_abi *abi, LLVMValueRef index,
enum ac_descriptor_type desc_type);
LLVMValueRef (*load_sample_position)(struct ac_shader_abi *abi, LLVMValueRef sample_id);
LLVMValueRef (*emit_fbfetch)(struct ac_shader_abi *abi);
LLVMValueRef (*intrinsic_load)(struct ac_shader_abi *abi, nir_intrinsic_instr *intrin);
@@ -105,7 +103,6 @@ struct ac_shader_abi {
/* Whether to clamp the shadow reference value to [0,1]on GFX8. Radeonsi currently
* uses it due to promoting D16 to D32, but radv needs it off. */
bool clamp_shadow_reference;
bool interp_at_sample_force_center;
/* Whether bounds checks are required */
bool robust_buffer_access;

View File

@@ -336,6 +336,25 @@ static bool lower_abi_instr(nir_builder *b, nir_instr *instr, struct lower_abi_s
replacement = nir_imm_int(b, (1 << 2) | (1 << 4));
}
break;
case nir_intrinsic_load_barycentric_at_sample: {
unsigned mode = nir_intrinsic_interp_mode(intrin);
if (key->ps.mono.interpolate_at_sample_force_center) {
replacement = nir_load_barycentric_pixel(b, 32, .interp_mode = mode);
} else {
nir_ssa_def *sample_id = intrin->src[0].ssa;
/* offset = sample_id * 8 (8 = 2 floats containing samplepos.xy) */
nir_ssa_def *offset = nir_ishl_imm(b, sample_id, 3);
nir_ssa_def *buf = load_internal_binding(b, args, SI_PS_CONST_SAMPLE_POSITIONS);
nir_ssa_def *sample_pos = nir_load_smem_buffer_amd(b, 2, buf, offset);
sample_pos = nir_fsub(b, sample_pos, nir_imm_float(b, 0.5));
replacement = nir_load_barycentric_at_offset(b, 32, sample_pos, .interp_mode = mode);
}
break;
}
default:
return false;
}

View File

@@ -859,8 +859,6 @@ static bool si_llvm_translate_nir(struct si_shader_context *ctx, struct si_shade
}
ctx->abi.num_interp = si_get_ps_num_interp(shader);
ctx->abi.interp_at_sample_force_center =
ctx->shader->key.ps.mono.interpolate_at_sample_force_center;
ctx->abi.kill_ps_if_inf_interp =
ctx->screen->options.no_infinite_interp &&

View File

@@ -31,26 +31,6 @@ static LLVMValueRef si_get_sample_id(struct si_shader_context *ctx)
return si_unpack_param(ctx, ctx->args->ac.ancillary, 8, 4);
}
static LLVMValueRef load_sample_position(struct ac_shader_abi *abi, LLVMValueRef sample_id)
{
struct si_shader_context *ctx = si_shader_context_from_abi(abi);
LLVMValueRef buf_index = LLVMConstInt(ctx->ac.i32, SI_PS_CONST_SAMPLE_POSITIONS, 0);
LLVMValueRef resource = ac_build_load_to_sgpr(
&ctx->ac, ac_get_ptr_arg(&ctx->ac, &ctx->args->ac, ctx->args->internal_bindings), buf_index);
/* offset = sample_id * 8 (8 = 2 floats containing samplepos.xy) */
LLVMValueRef offset0 =
LLVMBuildMul(ctx->ac.builder, sample_id, LLVMConstInt(ctx->ac.i32, 8, 0), "");
LLVMValueRef offset1 =
LLVMBuildAdd(ctx->ac.builder, offset0, LLVMConstInt(ctx->ac.i32, 4, 0), "");
LLVMValueRef pos[4] = {si_buffer_load_const(ctx, resource, offset0),
si_buffer_load_const(ctx, resource, offset1),
LLVMConstReal(ctx->ac.f32, 0), LLVMConstReal(ctx->ac.f32, 0)};
return ac_build_gather_values(&ctx->ac, pos, 4);
}
static LLVMValueRef si_nir_emit_fbfetch(struct ac_shader_abi *abi)
{
struct si_shader_context *ctx = si_shader_context_from_abi(abi);
@@ -966,6 +946,5 @@ void si_llvm_build_monolithic_ps(struct si_shader_context *ctx, struct si_shader
void si_llvm_init_ps_callbacks(struct si_shader_context *ctx)
{
ctx->abi.load_sample_position = load_sample_position;
ctx->abi.emit_fbfetch = si_nir_emit_fbfetch;
}