aco,radeonsi: declare prolog CENTROID VGPRs only if used

Small PS have their VGPR usage equal to the number of input VGPRs,
and this reduces it.

4 input VGPRs removed in most cases.
This commit is contained in:
Marek Olšák 2026-04-25 17:26:46 -04:00
parent 57e465a3e4
commit 7fea12b686
8 changed files with 66 additions and 16 deletions

View file

@ -91,6 +91,8 @@ struct aco_ps_prolog_info {
bool force_linear_sample_interp;
bool force_persp_center_interp;
bool force_linear_center_interp;
bool uses_persp_centroid;
bool uses_linear_centroid;
unsigned samplemask_log_ps_iter;
bool force_samplemask_to_helper_invocation;

View file

@ -64,6 +64,8 @@ overwrite_interp_args(isel_context* ctx, const struct aco_ps_prolog_info* finfo)
cond = bool_to_vector_condition(ctx, cond);
if (finfo->bc_optimize_for_persp) {
assert(finfo->uses_persp_centroid);
Temp center = get_arg(ctx, ctx->args->persp_center);
Temp centroid = get_arg(ctx, ctx->args->persp_centroid);
@ -73,6 +75,8 @@ overwrite_interp_args(isel_context* ctx, const struct aco_ps_prolog_info* finfo)
}
if (finfo->bc_optimize_for_linear) {
assert(finfo->uses_linear_centroid);
Temp center = get_arg(ctx, ctx->args->linear_center);
Temp centroid = get_arg(ctx, ctx->args->linear_centroid);
@ -85,25 +89,29 @@ overwrite_interp_args(isel_context* ctx, const struct aco_ps_prolog_info* finfo)
if (finfo->force_persp_sample_interp) {
Temp persp_sample = get_arg(ctx, ctx->args->persp_sample);
ctx->arg_temps[ctx->args->persp_center.arg_index] = persp_sample;
ctx->arg_temps[ctx->args->persp_centroid.arg_index] = persp_sample;
if (finfo->uses_persp_centroid)
ctx->arg_temps[ctx->args->persp_centroid.arg_index] = persp_sample;
}
if (finfo->force_linear_sample_interp) {
Temp linear_sample = get_arg(ctx, ctx->args->linear_sample);
ctx->arg_temps[ctx->args->linear_center.arg_index] = linear_sample;
ctx->arg_temps[ctx->args->linear_centroid.arg_index] = linear_sample;
if (finfo->uses_linear_centroid)
ctx->arg_temps[ctx->args->linear_centroid.arg_index] = linear_sample;
}
if (finfo->force_persp_center_interp) {
Temp persp_center = get_arg(ctx, ctx->args->persp_center);
ctx->arg_temps[ctx->args->persp_sample.arg_index] = persp_center;
ctx->arg_temps[ctx->args->persp_centroid.arg_index] = persp_center;
if (finfo->uses_persp_centroid)
ctx->arg_temps[ctx->args->persp_centroid.arg_index] = persp_center;
}
if (finfo->force_linear_center_interp) {
Temp linear_center = get_arg(ctx, ctx->args->linear_center);
ctx->arg_temps[ctx->args->linear_sample.arg_index] = linear_center;
ctx->arg_temps[ctx->args->linear_centroid.arg_index] = linear_center;
if (finfo->uses_linear_centroid)
ctx->arg_temps[ctx->args->linear_centroid.arg_index] = linear_center;
}
}

View file

@ -1744,6 +1744,10 @@ static void si_get_ps_prolog_key(struct si_shader *shader, union si_shader_part_
key->ps_prolog.states.bc_optimize_for_persp || key->ps_prolog.states.bc_optimize_for_linear ||
key->ps_prolog.states.samplemask_log_ps_iter ||
key->ps_prolog.states.force_samplemask_to_helper_invocation);
key->ps_prolog.uses_persp_centroid =
G_0286CC_PERSP_CENTROID_ENA(shader->config.spi_ps_input_addr); /* addr because the PS prolog may use it */
key->ps_prolog.uses_linear_centroid =
G_0286CC_LINEAR_CENTROID_ENA(shader->config.spi_ps_input_addr); /* addr because the PS prolog may use it */
key->ps_prolog.fragcoord_usage_mask =
G_0286CC_POS_X_FLOAT_ENA(shader->config.spi_ps_input_ena) |
(G_0286CC_POS_Y_FLOAT_ENA(shader->config.spi_ps_input_ena) << 1) |

View file

@ -564,6 +564,8 @@ union si_shader_part_key {
/* Color interpolation and two-side color selection. */
unsigned colors_read : 8; /* color input components read */
unsigned num_interp_inputs : 5; /* BCOLOR is at this location */
unsigned uses_persp_centroid : 1;
unsigned uses_linear_centroid : 1;
unsigned fragcoord_usage_mask : 4;
unsigned wqm : 1;
uint8_t color_attr_index[2];

View file

@ -253,6 +253,8 @@ si_aco_build_ps_prolog(struct aco_compiler_options *options,
.force_linear_sample_interp = key->ps_prolog.states.force_linear_sample_interp,
.force_persp_center_interp = key->ps_prolog.states.force_persp_center_interp,
.force_linear_center_interp = key->ps_prolog.states.force_linear_center_interp,
.uses_persp_centroid = key->ps_prolog.uses_persp_centroid,
.uses_linear_centroid = key->ps_prolog.uses_linear_centroid,
.samplemask_log_ps_iter = key->ps_prolog.states.samplemask_log_ps_iter,
.force_samplemask_to_helper_invocation = key->ps_prolog.states.force_samplemask_to_helper_invocation,

View file

@ -673,11 +673,17 @@ void si_get_ps_prolog_args(struct si_shader_args *args,
ac_add_arg(&args->ac, AC_ARG_VGPR, 2, AC_ARG_VALUE, &args->ac.persp_sample);
ac_add_arg(&args->ac, AC_ARG_VGPR, 2, AC_ARG_VALUE, &args->ac.persp_center);
ac_add_arg(&args->ac, AC_ARG_VGPR, 2, AC_ARG_VALUE, &args->ac.persp_centroid);
if (key->ps_prolog.uses_persp_centroid)
ac_add_arg(&args->ac, AC_ARG_VGPR, 2, AC_ARG_VALUE, &args->ac.persp_centroid);
/* skip PERSP_PULL_MODEL */
ac_add_arg(&args->ac, AC_ARG_VGPR, 2, AC_ARG_VALUE, &args->ac.linear_sample);
ac_add_arg(&args->ac, AC_ARG_VGPR, 2, AC_ARG_VALUE, &args->ac.linear_center);
ac_add_arg(&args->ac, AC_ARG_VGPR, 2, AC_ARG_VALUE, &args->ac.linear_centroid);
if (key->ps_prolog.uses_linear_centroid)
ac_add_arg(&args->ac, AC_ARG_VGPR, 2, AC_ARG_VALUE, &args->ac.linear_centroid);
ac_add_arg(&args->ac, AC_ARG_VGPR, 1, AC_ARG_VALUE, &args->ac.line_stipple_tex_ena);
/* POS_X|Y|Z|W_FLOAT */

View file

@ -550,15 +550,22 @@ void si_llvm_build_ps_prolog(struct si_shader_context *ctx, union si_shader_part
bc_optimize = LLVMBuildTrunc(ctx->ac.builder, bc_optimize, ctx->ac.i1, "");
if (key->ps_prolog.states.bc_optimize_for_persp) {
assert(key->ps_prolog.uses_persp_centroid);
center = ac_to_float(&ctx->ac, ac_get_arg(&ctx->ac, args->ac.persp_center));
centroid = ac_to_float(&ctx->ac, ac_get_arg(&ctx->ac, args->ac.persp_centroid));
/* Select PERSP_CENTROID. */
tmp = LLVMBuildSelect(ctx->ac.builder, bc_optimize, center, centroid, "");
ret = insert_ret_of_arg(ctx, ret, tmp, args->ac.persp_centroid.arg_index);
}
if (key->ps_prolog.states.bc_optimize_for_linear) {
assert(key->ps_prolog.uses_linear_centroid);
center = ac_to_float(&ctx->ac, ac_get_arg(&ctx->ac, args->ac.linear_center));
centroid = ac_to_float(&ctx->ac, ac_get_arg(&ctx->ac, args->ac.linear_centroid));
/* Select PERSP_CENTROID. */
tmp = LLVMBuildSelect(ctx->ac.builder, bc_optimize, center, centroid, "");
ret = insert_ret_of_arg(ctx, ret, tmp, args->ac.linear_centroid.arg_index);
@ -570,15 +577,21 @@ void si_llvm_build_ps_prolog(struct si_shader_context *ctx, union si_shader_part
LLVMValueRef persp_sample = ac_to_float(&ctx->ac, ac_get_arg(&ctx->ac, args->ac.persp_sample));
/* Overwrite PERSP_CENTER. */
ret = insert_ret_of_arg(ctx, ret, persp_sample, args->ac.persp_center.arg_index);
/* Overwrite PERSP_CENTROID. */
ret = insert_ret_of_arg(ctx, ret, persp_sample, args->ac.persp_centroid.arg_index);
if (key->ps_prolog.uses_persp_centroid) {
/* Overwrite PERSP_CENTROID. */
ret = insert_ret_of_arg(ctx, ret, persp_sample, args->ac.persp_centroid.arg_index);
}
}
if (key->ps_prolog.states.force_linear_sample_interp) {
LLVMValueRef linear_sample = ac_to_float(&ctx->ac, ac_get_arg(&ctx->ac, args->ac.linear_sample));
/* Overwrite LINEAR_CENTER. */
ret = insert_ret_of_arg(ctx, ret, linear_sample, args->ac.linear_center.arg_index);
/* Overwrite LINEAR_CENTROID. */
ret = insert_ret_of_arg(ctx, ret, linear_sample, args->ac.linear_centroid.arg_index);
if (key->ps_prolog.uses_linear_centroid) {
/* Overwrite LINEAR_CENTROID. */
ret = insert_ret_of_arg(ctx, ret, linear_sample, args->ac.linear_centroid.arg_index);
}
}
/* Force center interpolation. */
@ -586,15 +599,21 @@ void si_llvm_build_ps_prolog(struct si_shader_context *ctx, union si_shader_part
LLVMValueRef persp_center = ac_to_float(&ctx->ac, ac_get_arg(&ctx->ac, args->ac.persp_center));
/* Overwrite PERSP_SAMPLE. */
ret = insert_ret_of_arg(ctx, ret, persp_center, args->ac.persp_sample.arg_index);
/* Overwrite PERSP_CENTROID. */
ret = insert_ret_of_arg(ctx, ret, persp_center, args->ac.persp_centroid.arg_index);
if (key->ps_prolog.uses_persp_centroid) {
/* Overwrite PERSP_CENTROID. */
ret = insert_ret_of_arg(ctx, ret, persp_center, args->ac.persp_centroid.arg_index);
}
}
if (key->ps_prolog.states.force_linear_center_interp) {
LLVMValueRef linear_center = ac_to_float(&ctx->ac, ac_get_arg(&ctx->ac, args->ac.linear_center));
/* Overwrite LINEAR_SAMPLE. */
ret = insert_ret_of_arg(ctx, ret, linear_center, args->ac.linear_sample.arg_index);
/* Overwrite LINEAR_CENTROID. */
ret = insert_ret_of_arg(ctx, ret, linear_center, args->ac.linear_centroid.arg_index);
if (key->ps_prolog.uses_linear_centroid) {
/* Overwrite LINEAR_CENTROID. */
ret = insert_ret_of_arg(ctx, ret, linear_center, args->ac.linear_centroid.arg_index);
}
}
/* Interpolate colors. */

View file

@ -612,15 +612,22 @@ unsigned si_get_spi_ps_input_addr_for_prolog(struct si_shader_selector *sel)
{
unsigned spi_ps_input_addr = S_0286D0_PERSP_SAMPLE_ENA(1) |
S_0286D0_PERSP_CENTER_ENA(1) |
S_0286D0_PERSP_CENTROID_ENA(1) |
S_0286D0_LINEAR_SAMPLE_ENA(1) |
S_0286D0_LINEAR_CENTER_ENA(1) |
S_0286D0_LINEAR_CENTROID_ENA(1) |
S_0286D0_LINE_STIPPLE_TEX_ENA(1) |
S_0286D0_FRONT_FACE_ENA(1) |
S_0286D0_ANCILLARY_ENA(1) |
S_0286D0_SAMPLE_COVERAGE_ENA(1) |
S_0286D0_POS_FIXED_PT_ENA(1);
/* This includes color interpolation at centroid even if the main shader part doesn't
* use the barycentrics. The PS prolog can still use them.
*/
if (sel->info.uses_sysval_persp_centroid)
spi_ps_input_addr |= S_0286D0_PERSP_CENTROID_ENA(1);
if (sel->info.uses_sysval_linear_centroid)
spi_ps_input_addr |= S_0286D0_LINEAR_CENTROID_ENA(1);
return spi_ps_input_addr;
}