From 2716385afa281d874e83bf33df7204224b9bdfe1 Mon Sep 17 00:00:00 2001 From: Job Noorman Date: Wed, 22 Jan 2025 15:33:48 +0100 Subject: [PATCH] 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 Part-of: --- src/freedreno/ir3/ir3_shader.h | 1 + src/freedreno/vulkan/tu_shader.cc | 35 ++++++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/freedreno/ir3/ir3_shader.h b/src/freedreno/ir3/ir3_shader.h index 8e8a1cfd5f7..64ccc949185 100644 --- a/src/freedreno/ir3/ir3_shader.h +++ b/src/freedreno/ir3/ir3_shader.h @@ -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; }; diff --git a/src/freedreno/vulkan/tu_shader.cc b/src/freedreno/vulkan/tu_shader.cc index 5ec17133979..d52e53c83dc 100644 --- a/src/freedreno/vulkan/tu_shader.cc +++ b/src/freedreno/vulkan/tu_shader.cc @@ -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) |