tu: add support for aliased render target components

a7xx introduced support for aliasing render target components using
alias.rt. This allows components to be bound to uniform (const or
immediate) values in the preamble:

alias.rt.f32.0 rt0.y, c0.x
alias.rt.f32.0 rt1.z, (1.000000)

This aliases the 2nd component of RT0 to c0.x and the 3rd component of
RT1 to the immediate 1.0. All components of all 8 render targets can be
aliased.

In addition to using alias.rt, the hardware needs to be informed about
which render target components are being aliased using the
SP_PS_ALIASED_COMPONENTS{_CONTROL} registers. This commit implements
those registers.

Signed-off-by: Job Noorman <jnoorman@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31222>
This commit is contained in:
Job Noorman 2025-01-22 15:33:48 +01:00 committed by Marge Bot
parent 3290a3dcf3
commit 2716385afa
2 changed files with 33 additions and 3 deletions

View file

@ -618,6 +618,7 @@ struct ir3_shader_output {
uint8_t slot;
uint8_t regid;
uint8_t view;
uint8_t aliased_components : 4;
bool half : 1;
};

View file

@ -1821,12 +1821,30 @@ tu6_emit_fs_outputs(struct tu_cs *cs,
int output_reg_count = 0;
uint32_t fragdata_regid[8];
uint32_t fragdata_aliased_components = 0;
assert(!fs->color0_mrt);
for (uint32_t i = 0; i < ARRAY_SIZE(fragdata_regid); i++) {
fragdata_regid[i] = ir3_find_output_regid(fs, FRAG_RESULT_DATA0 + i);
if (VALIDREG(fragdata_regid[i]))
int output_idx =
ir3_find_output(fs, (gl_varying_slot) (FRAG_RESULT_DATA0 + i));
if (output_idx < 0) {
fragdata_regid[i] = INVALID_REG;
continue;
}
const struct ir3_shader_output *fragdata = &fs->outputs[output_idx];
fragdata_regid[i] = ir3_get_output_regid(fragdata);
if (VALIDREG(fragdata_regid[i]) || fragdata->aliased_components) {
/* An invalid reg is only allowed if all components are aliased. */
assert(VALIDREG(fragdata_regid[i] ||
fragdata->aliased_components == 0xf));
output_reg_count = i + 1;
fragdata_aliased_components |= fragdata->aliased_components
<< (i * 4);
}
}
tu_cs_emit_pkt4(cs, REG_A6XX_SP_FS_OUTPUT_CNTL0, 1);
@ -1847,7 +1865,8 @@ tu6_emit_fs_outputs(struct tu_cs *cs,
(COND(fragdata_regid[i] & HALF_REG_ID,
A6XX_SP_FS_OUTPUT_REG_HALF_PRECISION)));
if (VALIDREG(fragdata_regid[i])) {
if (VALIDREG(fragdata_regid[i]) ||
(fragdata_aliased_components & (0xf << (i * 4)))) {
fs_render_components |= 0xf << (i * 4);
}
}
@ -1855,6 +1874,16 @@ tu6_emit_fs_outputs(struct tu_cs *cs,
tu_cs_emit_regs(cs,
A6XX_SP_FS_RENDER_COMPONENTS(.dword = fs_render_components));
if (CHIP >= A7XX) {
tu_cs_emit_regs(
cs,
A7XX_SP_PS_ALIASED_COMPONENTS_CONTROL(
.enabled = fragdata_aliased_components != 0),
A7XX_SP_PS_ALIASED_COMPONENTS(.dword = fragdata_aliased_components));
} else {
assert(fragdata_aliased_components == 0);
}
tu_cs_emit_pkt4(cs, REG_A6XX_RB_FS_OUTPUT_CNTL0, 1);
tu_cs_emit(cs, COND(fs->writes_pos, A6XX_RB_FS_OUTPUT_CNTL0_FRAG_WRITES_Z) |
COND(fs->writes_smask, A6XX_RB_FS_OUTPUT_CNTL0_FRAG_WRITES_SAMPMASK) |