diff --git a/src/amd/common/ac_shader_args.c b/src/amd/common/ac_shader_args.c index 6246347972e..5f4cb6ea3e4 100644 --- a/src/amd/common/ac_shader_args.c +++ b/src/amd/common/ac_shader_args.c @@ -82,3 +82,35 @@ void ac_compact_ps_vgpr_args(struct ac_shader_args *info, uint32_t spi_ps_input) info->num_vgprs_used = vgpr_reg; } + +unsigned +ac_get_color_interp_arg(const struct ac_shader_args *args, enum ac_color_interp interp) +{ + struct ac_arg arg; + + switch (interp) { + case AC_COLOR_INTERP_PERSP_SAMPLE: + arg = args->persp_sample; + break; + case AC_COLOR_INTERP_PERSP_CENTER: + arg = args->persp_center; + break; + case AC_COLOR_INTERP_PERSP_CENTROID: + arg = args->persp_centroid; + break; + case AC_COLOR_INTERP_LINEAR_SAMPLE: + arg = args->linear_sample; + break; + case AC_COLOR_INTERP_LINEAR_CENTER: + arg = args->linear_center; + break; + case AC_COLOR_INTERP_LINEAR_CENTROID: + arg = args->linear_centroid; + break; + default: + UNREACHABLE("unexpected interp mode"); + } + + assert(arg.used); + return arg.arg_index; +} diff --git a/src/amd/common/ac_shader_args.h b/src/amd/common/ac_shader_args.h index 64675c03854..fc47f92135f 100644 --- a/src/amd/common/ac_shader_args.h +++ b/src/amd/common/ac_shader_args.h @@ -10,6 +10,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /* Maximum dwords of inline push constants when the indirect path is still used */ #define AC_MAX_INLINE_PUSH_CONSTS_WITH_INDIRECT 8 /* Maximum dwords of inline push constants when the indirect path is not used */ @@ -27,6 +31,16 @@ enum ac_arg_type AC_ARG_CONST_ADDR, }; +enum ac_color_interp { + AC_COLOR_INTERP_FLAT, + AC_COLOR_INTERP_PERSP_SAMPLE, + AC_COLOR_INTERP_PERSP_CENTER, + AC_COLOR_INTERP_PERSP_CENTROID, + AC_COLOR_INTERP_LINEAR_SAMPLE, + AC_COLOR_INTERP_LINEAR_CENTER, + AC_COLOR_INTERP_LINEAR_CENTROID, +}; + struct ac_arg { uint16_t arg_index; bool used; @@ -204,5 +218,10 @@ void ac_add_arg(struct ac_shader_args *info, enum ac_arg_regfile regfile, unsign void ac_add_return(struct ac_shader_args *info, enum ac_arg_regfile regfile); void ac_add_preserved(struct ac_shader_args *info, const struct ac_arg *arg); void ac_compact_ps_vgpr_args(struct ac_shader_args *info, uint32_t spi_ps_input); +unsigned ac_get_color_interp_arg(const struct ac_shader_args *args, enum ac_color_interp interp); + +#ifdef __cplusplus +} +#endif #endif diff --git a/src/amd/compiler/aco_shader_info.h b/src/amd/compiler/aco_shader_info.h index 56f230b63b6..1b49f38134b 100644 --- a/src/amd/compiler/aco_shader_info.h +++ b/src/amd/compiler/aco_shader_info.h @@ -98,8 +98,8 @@ struct aco_ps_prolog_info { bool force_samplemask_to_helper_invocation; unsigned num_interp_inputs; unsigned colors_read; - int color_interp_vgpr_index[2]; - int color_attr_index[2]; + uint8_t color_attr_index[2]; + enum ac_color_interp color_interp[2]; bool color_two_side; bool needs_wqm; diff --git a/src/amd/compiler/instruction_selection/aco_select_ps_prolog.cpp b/src/amd/compiler/instruction_selection/aco_select_ps_prolog.cpp index 927df3c8eca..77808479a71 100644 --- a/src/amd/compiler/instruction_selection/aco_select_ps_prolog.cpp +++ b/src/amd/compiler/instruction_selection/aco_select_ps_prolog.cpp @@ -205,7 +205,7 @@ passthrough_all_args(isel_context* ctx, std::vector& regs) } Temp -get_interp_color(isel_context* ctx, int interp_vgpr, unsigned attr_index, unsigned comp) +get_interp_color(isel_context* ctx, int interp_arg, unsigned attr_index, unsigned comp) { Builder bld(ctx->program, ctx->block); @@ -213,10 +213,8 @@ get_interp_color(isel_context* ctx, int interp_vgpr, unsigned attr_index, unsign Temp prim_mask = get_arg(ctx, ctx->args->prim_mask); - if (interp_vgpr != -1) { - /* interp args are all 2 vgprs */ - int arg_index = ctx->args->persp_sample.arg_index + interp_vgpr / 2; - Temp interp_ij = ctx->arg_temps[arg_index]; + if (interp_arg != -1) { + Temp interp_ij = ctx->arg_temps[interp_arg]; emit_interp_instr(ctx, attr_index, comp, interp_ij, dst, prim_mask, false); } else { @@ -245,7 +243,9 @@ interpolate_color_args(isel_context* ctx, const struct aco_ps_prolog_info* finfo u_foreach_bit (i, finfo->colors_read) { unsigned color_index = i / 4; unsigned front_index = finfo->color_attr_index[color_index]; - int interp_vgpr = finfo->color_interp_vgpr_index[color_index]; + int interp_arg = finfo->color_interp[color_index] == AC_COLOR_INTERP_FLAT + ? -1 + : ac_get_color_interp_arg(ctx->args, finfo->color_interp[color_index]); /* If BCOLOR0 is used, BCOLOR1 is at offset "num_inputs + 1", * otherwise it's at offset "num_inputs". @@ -254,8 +254,8 @@ interpolate_color_args(isel_context* ctx, const struct aco_ps_prolog_info* finfo if (color_index == 1 && finfo->colors_read & 0xf) back_index++; - Temp front = get_interp_color(ctx, interp_vgpr, front_index, i % 4); - Temp back = get_interp_color(ctx, interp_vgpr, back_index, i % 4); + Temp front = get_interp_color(ctx, interp_arg, front_index, i % 4); + Temp back = get_interp_color(ctx, interp_arg, back_index, i % 4); Temp color = bld.vop2(aco_opcode::v_cndmask_b32, bld.def(v1), back, front, is_face_positive); @@ -266,8 +266,10 @@ interpolate_color_args(isel_context* ctx, const struct aco_ps_prolog_info* finfo u_foreach_bit (i, finfo->colors_read) { unsigned color_index = i / 4; unsigned attr_index = finfo->color_attr_index[color_index]; - int interp_vgpr = finfo->color_interp_vgpr_index[color_index]; - Temp color = get_interp_color(ctx, interp_vgpr, attr_index, i % 4); + int interp_arg = finfo->color_interp[color_index] == AC_COLOR_INTERP_FLAT + ? -1 + : ac_get_color_interp_arg(ctx->args, finfo->color_interp[color_index]); + Temp color = get_interp_color(ctx, interp_arg, attr_index, i % 4); regs.emplace_back(Operand(color, PhysReg{vgpr++})); } diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index f3e8e1ac95c..c9e3bee389d 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -1778,7 +1778,7 @@ static void si_get_ps_prolog_key(struct si_shader *shader, union si_shader_part_ switch (interp) { case INTERP_MODE_FLAT: - key->ps_prolog.color_interp_vgpr_index[i] = -1; + key->ps_prolog.color_interp[i] = AC_COLOR_INTERP_FLAT; break; case INTERP_MODE_SMOOTH: case INTERP_MODE_COLOR: @@ -1790,15 +1790,15 @@ static void si_get_ps_prolog_key(struct si_shader *shader, union si_shader_part_ switch (location) { case TGSI_INTERPOLATE_LOC_SAMPLE: - key->ps_prolog.color_interp_vgpr_index[i] = 0; + key->ps_prolog.color_interp[i] = AC_COLOR_INTERP_PERSP_SAMPLE; shader->config.spi_ps_input_ena |= S_0286CC_PERSP_SAMPLE_ENA(1); break; case TGSI_INTERPOLATE_LOC_CENTER: - key->ps_prolog.color_interp_vgpr_index[i] = 2; + key->ps_prolog.color_interp[i] = AC_COLOR_INTERP_PERSP_CENTER; shader->config.spi_ps_input_ena |= S_0286CC_PERSP_CENTER_ENA(1); break; case TGSI_INTERPOLATE_LOC_CENTROID: - key->ps_prolog.color_interp_vgpr_index[i] = 4; + key->ps_prolog.color_interp[i] = AC_COLOR_INTERP_PERSP_CENTROID; shader->config.spi_ps_input_ena |= S_0286CC_PERSP_CENTROID_ENA(1); break; default: @@ -1818,15 +1818,15 @@ static void si_get_ps_prolog_key(struct si_shader *shader, union si_shader_part_ */ switch (location) { case TGSI_INTERPOLATE_LOC_SAMPLE: - key->ps_prolog.color_interp_vgpr_index[i] = 6; + key->ps_prolog.color_interp[i] = AC_COLOR_INTERP_LINEAR_SAMPLE; shader->config.spi_ps_input_ena |= S_0286CC_LINEAR_SAMPLE_ENA(1); break; case TGSI_INTERPOLATE_LOC_CENTER: - key->ps_prolog.color_interp_vgpr_index[i] = 8; + key->ps_prolog.color_interp[i] = AC_COLOR_INTERP_LINEAR_CENTER; shader->config.spi_ps_input_ena |= S_0286CC_LINEAR_CENTER_ENA(1); break; case TGSI_INTERPOLATE_LOC_CENTROID: - key->ps_prolog.color_interp_vgpr_index[i] = 10; + key->ps_prolog.color_interp[i] = AC_COLOR_INTERP_LINEAR_CENTROID; shader->config.spi_ps_input_ena |= S_0286CC_LINEAR_CENTROID_ENA(1); break; default: diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index d1ce5850466..f1c4241b053 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -568,8 +568,8 @@ union si_shader_part_key { unsigned fragcoord_usage_mask : 4; unsigned pixel_center_integer : 1; unsigned wqm : 1; - char color_attr_index[2]; - signed char color_interp_vgpr_index[2]; /* -1 == constant */ + uint8_t color_attr_index[2]; + uint8_t color_interp[2]; /* AC_COLOR_INTERP_* */ } ps_prolog; struct { struct si_ps_epilog_bits states; diff --git a/src/gallium/drivers/radeonsi/si_shader_aco.c b/src/gallium/drivers/radeonsi/si_shader_aco.c index 942cd76a18d..bddc2d84cb6 100644 --- a/src/gallium/drivers/radeonsi/si_shader_aco.c +++ b/src/gallium/drivers/radeonsi/si_shader_aco.c @@ -260,8 +260,8 @@ si_aco_build_ps_prolog(struct aco_compiler_options *options, .force_samplemask_to_helper_invocation = key->ps_prolog.states.force_samplemask_to_helper_invocation, .num_interp_inputs = key->ps_prolog.num_interp_inputs, .colors_read = key->ps_prolog.colors_read, - .color_interp_vgpr_index[0] = key->ps_prolog.color_interp_vgpr_index[0], - .color_interp_vgpr_index[1] = key->ps_prolog.color_interp_vgpr_index[1], + .color_interp[0] = key->ps_prolog.color_interp[0], + .color_interp[1] = key->ps_prolog.color_interp[1], .color_attr_index[0] = key->ps_prolog.color_attr_index[0], .color_attr_index[1] = key->ps_prolog.color_attr_index[1], .color_two_side = key->ps_prolog.states.color_two_side, diff --git a/src/gallium/drivers/radeonsi/si_shader_llvm_ps.c b/src/gallium/drivers/radeonsi/si_shader_llvm_ps.c index 3d4625fda7a..3b992357df0 100644 --- a/src/gallium/drivers/radeonsi/si_shader_llvm_ps.c +++ b/src/gallium/drivers/radeonsi/si_shader_llvm_ps.c @@ -597,11 +597,12 @@ void si_llvm_build_ps_prolog(struct si_shader_context *ctx, union si_shader_part if (!writemask) continue; - /* If the interpolation qualifier is not CONSTANT (-1). */ LLVMValueRef interp_ij = NULL; - if (key->ps_prolog.color_interp_vgpr_index[i] != -1) { - unsigned index = - args->ac.num_sgprs_used + key->ps_prolog.color_interp_vgpr_index[i]; + + if (key->ps_prolog.color_interp[i] != AC_COLOR_INTERP_FLAT) { + unsigned index = ac_get_color_interp_arg(&args->ac, key->ps_prolog.color_interp[i]); + + index = args->ac.num_sgprs_used + args->ac.args[index].offset; /* Get the (i,j) updated by bc_optimize handling. */ LLVMValueRef interp[2] = {