aco,radeonsi: use enums for color barycentrics instead of input VGPR indices

The VGPR indices will be dynamic. This replaces hardcoded VGPR indices
with enums in the PS prolog key.
This commit is contained in:
Marek Olšák 2026-04-25 16:46:14 -04:00
parent 190aabdf71
commit ae610a411b
8 changed files with 81 additions and 27 deletions

View file

@ -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;
}

View file

@ -10,6 +10,10 @@
#include <stdbool.h>
#include <stdint.h>
#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

View file

@ -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;

View file

@ -205,7 +205,7 @@ passthrough_all_args(isel_context* ctx, std::vector<Operand>& 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++}));
}

View file

@ -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:

View file

@ -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;

View file

@ -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,

View file

@ -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] = {