diff --git a/src/amd/compiler/aco_instruction_selection.cpp b/src/amd/compiler/aco_instruction_selection.cpp index f698cc63c37..660e259dbbb 100644 --- a/src/amd/compiler/aco_instruction_selection.cpp +++ b/src/amd/compiler/aco_instruction_selection.cpp @@ -7803,12 +7803,11 @@ emit_reduction_instr(isel_context* ctx, aco_opcode aco_op, ReduceOp op, unsigned } void -emit_interp_center(isel_context* ctx, Temp dst, Temp pos1, Temp pos2) +emit_interp_center(isel_context* ctx, Temp dst, Temp bary, Temp pos1, Temp pos2) { Builder bld(ctx->program, ctx->block); - Temp persp_center = get_arg(ctx, ctx->args->ac.persp_center); - Temp p1 = emit_extract_vector(ctx, persp_center, 0, v1); - Temp p2 = emit_extract_vector(ctx, persp_center, 1, v1); + Temp p1 = emit_extract_vector(ctx, bary, 0, v1); + Temp p2 = emit_extract_vector(ctx, bary, 1, v1); Temp ddx_1, ddx_2, ddy_1, ddy_2; uint32_t dpp_ctrl0 = dpp_quad_perm(0, 0, 0, 0); @@ -7855,6 +7854,23 @@ Temp merged_wave_info_to_mask(isel_context* ctx, unsigned i); void ngg_emit_sendmsg_gs_alloc_req(isel_context* ctx, Temp vtx_cnt, Temp prm_cnt); static void create_vs_exports(isel_context* ctx); +Temp +get_interp_param(isel_context* ctx, nir_intrinsic_op intrin, + enum glsl_interp_mode interp) +{ + bool linear = interp == INTERP_MODE_NOPERSPECTIVE; + if (intrin == nir_intrinsic_load_barycentric_pixel || + intrin == nir_intrinsic_load_barycentric_at_sample || + intrin == nir_intrinsic_load_barycentric_at_offset) { + return get_arg(ctx, linear ? ctx->args->ac.linear_center : ctx->args->ac.persp_center); + } else if (intrin == nir_intrinsic_load_barycentric_centroid) { + return linear ? ctx->linear_centroid : ctx->persp_centroid; + } else { + assert(intrin == nir_intrinsic_load_barycentric_sample); + return get_arg(ctx, linear ? ctx->args->ac.linear_sample : ctx->args->ac.persp_sample); + } +} + void visit_intrinsic(isel_context* ctx, nir_intrinsic_instr* instr) { @@ -7864,27 +7880,7 @@ visit_intrinsic(isel_context* ctx, nir_intrinsic_instr* instr) case nir_intrinsic_load_barycentric_pixel: case nir_intrinsic_load_barycentric_centroid: { glsl_interp_mode mode = (glsl_interp_mode)nir_intrinsic_interp_mode(instr); - Temp bary = Temp(0, s2); - switch (mode) { - case INTERP_MODE_SMOOTH: - case INTERP_MODE_NONE: - if (instr->intrinsic == nir_intrinsic_load_barycentric_pixel) - bary = get_arg(ctx, ctx->args->ac.persp_center); - else if (instr->intrinsic == nir_intrinsic_load_barycentric_centroid) - bary = ctx->persp_centroid; - else if (instr->intrinsic == nir_intrinsic_load_barycentric_sample) - bary = get_arg(ctx, ctx->args->ac.persp_sample); - break; - case INTERP_MODE_NOPERSPECTIVE: - if (instr->intrinsic == nir_intrinsic_load_barycentric_pixel) - bary = get_arg(ctx, ctx->args->ac.linear_center); - else if (instr->intrinsic == nir_intrinsic_load_barycentric_centroid) - bary = ctx->linear_centroid; - else if (instr->intrinsic == nir_intrinsic_load_barycentric_sample) - bary = get_arg(ctx, ctx->args->ac.linear_sample); - break; - default: break; - } + Temp bary = get_interp_param(ctx, instr->intrinsic, mode); Temp dst = get_ssa_temp(ctx, &instr->dest.ssa); Temp p1 = emit_extract_vector(ctx, bary, 0, v1); Temp p2 = emit_extract_vector(ctx, bary, 1, v1); @@ -7996,7 +7992,8 @@ visit_intrinsic(isel_context* ctx, nir_intrinsic_instr* instr) pos1 = bld.vop2_e64(aco_opcode::v_sub_f32, bld.def(v1), pos1, Operand::c32(0x3f000000u)); pos2 = bld.vop2_e64(aco_opcode::v_sub_f32, bld.def(v1), pos2, Operand::c32(0x3f000000u)); - emit_interp_center(ctx, get_ssa_temp(ctx, &instr->dest.ssa), pos1, pos2); + Temp bary = get_interp_param(ctx, instr->intrinsic, (glsl_interp_mode)nir_intrinsic_interp_mode(instr)); + emit_interp_center(ctx, get_ssa_temp(ctx, &instr->dest.ssa), bary, pos1, pos2); break; } case nir_intrinsic_load_barycentric_at_offset: { @@ -8004,7 +8001,8 @@ visit_intrinsic(isel_context* ctx, nir_intrinsic_instr* instr) RegClass rc = RegClass(offset.type(), 1); Temp pos1 = bld.tmp(rc), pos2 = bld.tmp(rc); bld.pseudo(aco_opcode::p_split_vector, Definition(pos1), Definition(pos2), offset); - emit_interp_center(ctx, get_ssa_temp(ctx, &instr->dest.ssa), pos1, pos2); + Temp bary = get_interp_param(ctx, instr->intrinsic, (glsl_interp_mode)nir_intrinsic_interp_mode(instr)); + emit_interp_center(ctx, get_ssa_temp(ctx, &instr->dest.ssa), bary, pos1, pos2); break; } case nir_intrinsic_load_front_face: { diff --git a/src/amd/compiler/aco_instruction_selection_setup.cpp b/src/amd/compiler/aco_instruction_selection_setup.cpp index b3aaad3ce1a..27d174e4671 100644 --- a/src/amd/compiler/aco_instruction_selection_setup.cpp +++ b/src/amd/compiler/aco_instruction_selection_setup.cpp @@ -52,7 +52,9 @@ get_interp_input(nir_intrinsic_op intrin, enum glsl_interp_mode interp) return S_0286CC_PERSP_SAMPLE_ENA(1); break; case INTERP_MODE_NOPERSPECTIVE: - if (intrin == nir_intrinsic_load_barycentric_pixel) + if (intrin == nir_intrinsic_load_barycentric_pixel || + intrin == nir_intrinsic_load_barycentric_at_sample || + intrin == nir_intrinsic_load_barycentric_at_offset) return S_0286CC_LINEAR_CENTER_ENA(1); else if (intrin == nir_intrinsic_load_barycentric_centroid) return S_0286CC_LINEAR_CENTROID_ENA(1);