ac/nir: fix unaligned single component load/stores

This fixes two problems:
1. we need to lower the bit_size according to the alignment.
2. num_components could end up being 0, so we need to round up instead.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/13102
Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34976>
This commit is contained in:
Karol Herbst
2025-06-03 14:22:15 +02:00
committed by Marge Bot
parent d30a6f8102
commit 4f5ce2d5aa
@@ -67,6 +67,8 @@ lower_mem_access_cb(nir_intrinsic_op intrin, uint8_t bytes, uint8_t bit_size, ui
if (is_load && bit_size == 8 && combined_align >= 2 && bytes % 2 == 0)
bit_size = 16;
bit_size = MIN2(bit_size, combined_align == 4 ? 64 : combined_align * 8ull);
unsigned max_components = 4;
if (cb_data->use_llvm && access & (ACCESS_COHERENT | ACCESS_VOLATILE) &&
(intrin == nir_intrinsic_load_global || intrin == nir_intrinsic_store_global))
@@ -75,7 +77,7 @@ lower_mem_access_cb(nir_intrinsic_op intrin, uint8_t bytes, uint8_t bit_size, ui
max_components = MIN2(512 / bit_size, 16);
nir_mem_access_size_align res;
res.num_components = MIN2(bytes / (bit_size / 8), max_components);
res.num_components = MIN2(DIV_ROUND_UP(bytes, bit_size / 8), max_components);
res.bit_size = bit_size;
res.align = MIN2(bit_size / 8, 4); /* 64-bit access only requires 4 byte alignment. */
res.shift = nir_mem_access_shift_method_shift64;