From 9b36d8c23ac405be98a0e83ace1bea4d7a95df82 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Timur=20Krist=C3=B3f?= Date: Sat, 7 Mar 2020 01:51:39 +0100 Subject: [PATCH] aco: Only write TCS outputs to LDS when they are read by the TCS. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Note that tess factors are always read at the end of the shader, so those are still always saved to LDS. Totals from affected shaders: VGPRS: 25244 -> 25164 (-0.32 %) Code Size: 1768268 -> 1690804 (-4.38 %) bytes Max Waves: 4947 -> 4953 (0.12 %) Signed-off-by: Timur Kristóf Reviewed-by: Rhys Perry Part-of: --- .../compiler/aco_instruction_selection.cpp | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/amd/compiler/aco_instruction_selection.cpp b/src/amd/compiler/aco_instruction_selection.cpp index c363edb602d..386616f52ef 100644 --- a/src/amd/compiler/aco_instruction_selection.cpp +++ b/src/amd/compiler/aco_instruction_selection.cpp @@ -3334,6 +3334,29 @@ bool should_write_tcs_patch_output_to_vmem(isel_context *ctx, nir_intrinsic_inst (off != (tess_index_outer * 16u)); } +bool should_write_tcs_patch_output_to_lds(isel_context *ctx, nir_intrinsic_instr *instr, bool per_vertex) +{ + unsigned off = nir_intrinsic_base(instr) * 4u; + nir_src *off_src = nir_get_io_offset_src(instr); + + /* Indirect offset, we can't be sure if this is read or not, always write to LDS */ + if (!nir_src_is_const(*off_src)) + return true; + + off += nir_src_as_uint(*off_src) * 16u; + + uint64_t out_rd = per_vertex + ? ctx->shader->info.outputs_read + : ctx->shader->info.patch_outputs_read; + while (out_rd) { + unsigned slot = u_bit_scan64(&out_rd) + (per_vertex ? 0 : VARYING_SLOT_PATCH0); + if (off == shader_io_get_unique_index((gl_varying_slot) slot) * 16u) + return true; + } + + return false; +} + void visit_store_tcs_output(isel_context *ctx, nir_intrinsic_instr *instr, bool per_vertex) { assert(ctx->stage == tess_control_hs || ctx->stage == vertex_tess_control_hs); @@ -3347,8 +3370,8 @@ void visit_store_tcs_output(isel_context *ctx, nir_intrinsic_instr *instr, bool /* Only write to VMEM if the output is per-vertex or it's per-patch non tess factor */ bool write_to_vmem = per_vertex || should_write_tcs_patch_output_to_vmem(ctx, instr); - /* TODO: Only write to LDS if the output is read by the shader, or it's per-patch tess factor */ - bool write_to_lds = true; + /* Only write to LDS if the output is read by the shader, or it's per-patch tess factor */ + bool write_to_lds = !write_to_vmem || should_write_tcs_patch_output_to_lds(ctx, instr, per_vertex); if (write_to_vmem) { std::pair vmem_offs = per_vertex -- 2.30.2