From 8fd862499ae84e1a79db7adf29f1e48f8f35bd27 Mon Sep 17 00:00:00 2001 From: Rhys Perry Date: Thu, 13 Feb 2025 15:38:21 +0000 Subject: [PATCH] ac/nir: don't cross swizzle elements when vectorizing buffer_amd intrinsic This can happen for mesh shader outputs. No fossil-db changes (navi31, navi21, polaris10). fossil-db (vega10): Totals from 37 (0.06% of 62962) affected shaders: MaxWaves: 183 -> 189 (+3.28%) Instrs: 45037 -> 45607 (+1.27%); split: -0.09%, +1.36% CodeSize: 231472 -> 241980 (+4.54%) VGPRs: 2656 -> 2524 (-4.97%) Latency: 151199 -> 152476 (+0.84%); split: -0.02%, +0.87% InvThroughput: 75148 -> 74441 (-0.94%); split: -1.44%, +0.50% VClause: 882 -> 902 (+2.27%); split: -4.31%, +6.58% Copies: 6465 -> 4989 (-22.83%) PreVGPRs: 2265 -> 2044 (-9.76%) VALU: 33109 -> 31634 (-4.45%) SALU: 2602 -> 2601 (-0.04%) VMEM: 3711 -> 5774 (+55.59%) Signed-off-by: Rhys Perry Reviewed-by: Georg Lehmann Fixes: c3d27906d8cb ("radv: vectorize lowered shader IO") Part-of: --- src/amd/common/nir/ac_nir.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/amd/common/nir/ac_nir.c b/src/amd/common/nir/ac_nir.c index 9ca5ce1b8c1..bb2a0675eda 100644 --- a/src/amd/common/nir/ac_nir.c +++ b/src/amd/common/nir/ac_nir.c @@ -470,6 +470,7 @@ ac_nir_mem_vectorize_callback(unsigned align_mul, unsigned align_offset, unsigne low->intrinsic == nir_intrinsic_store_shared || low->intrinsic == nir_intrinsic_load_deref || low->intrinsic == nir_intrinsic_store_deref; + unsigned swizzle_element_size = config->gfx_level <= GFX8 ? 4 : 16; assert(!is_store || hole_size <= 0); @@ -523,7 +524,7 @@ ac_nir_mem_vectorize_callback(unsigned align_mul, unsigned align_offset, unsigne return false; /* GFX6-8 only support 32-bit scratch loads/stores. */ - if (config->gfx_level <= GFX8 && swizzled && aligned_new_size > 32) + if (swizzled && aligned_new_size > (swizzle_element_size * 8)) return false; } @@ -588,6 +589,15 @@ ac_nir_mem_vectorize_callback(unsigned align_mul, unsigned align_offset, unsigne else align = align_mul; + /* Don't cross swizzle elements. stack/scratch intrinsics use scratch_* instructions, which + * seem to work fine. + */ + if ((low->intrinsic == nir_intrinsic_load_buffer_amd || + low->intrinsic == nir_intrinsic_store_buffer_amd) && swizzled && + (align_offset % swizzle_element_size + unaligned_new_size / 8u) > MIN2(align_mul, swizzle_element_size)) { + return false; + } + /* Validate the alignment and number of components. */ if (!is_shared) { unsigned max_components;