From 90b512c4efc2064adeffe2d13cb204735eae84a0 Mon Sep 17 00:00:00 2001 From: Job Noorman Date: Wed, 22 Jan 2025 15:33:48 +0100 Subject: [PATCH] freedreno: 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 Part-of: --- .../drivers/freedreno/a6xx/fd6_program.cc | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_program.cc b/src/gallium/drivers/freedreno/a6xx/fd6_program.cc index 9c26e135fb2..ba9419607ea 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_program.cc +++ b/src/gallium/drivers/freedreno/a6xx/fd6_program.cc @@ -1130,12 +1130,28 @@ emit_fs_outputs(struct fd_ringbuffer *ring, const struct program_builder *b) int output_reg_count = 0; uint32_t fragdata_regid[8]; + uint32_t fragdata_aliased_components = 0; for (uint32_t i = 0; i < ARRAY_SIZE(fragdata_regid); i++) { unsigned slot = fs->color0_mrt ? FRAG_RESULT_COLOR : FRAG_RESULT_DATA0 + i; - fragdata_regid[i] = ir3_find_output_regid(fs, slot); - if (VALIDREG(fragdata_regid[i])) + int output_idx = ir3_find_output(fs, (gl_varying_slot)slot); + + 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); + } } OUT_PKT4(ring, REG_A6XX_SP_FS_OUTPUT_CNTL0, 1); @@ -1150,10 +1166,21 @@ emit_fs_outputs(struct fd_ringbuffer *ring, const struct program_builder *b) 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)))) { b->state->mrt_components |= 0xf << (i * 4); } } + + if (CHIP >= A7XX) { + OUT_REG( + ring, + 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); + } } template