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.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41226>
This commit is contained in:
Marek Olšák 2026-04-25 16:46:14 -04:00 committed by Marge Bot
parent 97660e91b5
commit c9c0dce948
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] = {