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 <pendingchaos02@gmail.com>
Reviewed-by: Georg Lehmann <dadschoorse@gmail.com>
Fixes: c3d27906d8 ("radv: vectorize lowered shader IO")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33531>
This commit is contained in:
Rhys Perry
2025-02-13 15:38:21 +00:00
committed by Marge Bot
parent ebd8893710
commit 8fd862499a
+11 -1
View File
@@ -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;