gallivm: fix small_unorm -> unorm8 fetch path on big-endian
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

Two bugs in lp_build_fetch_rgba_aos's small_unorm fast path:

- vector_justify=true shifted the loaded value into the MSB of the wider
  type on big-endian. The format_desc already carries
  big-endian-corrected channel shifts, so the extra shift broke channel
  extraction for sub-32-bit formats (e.g. R8G8B8, B5G5R5).

- The output OR-loop packed channels assuming little-endian byte order
  (shift = j * width), so after bitcast to vec4-u8 on big-endian the
  alpha channel landed at byte[0] instead of byte[3].

The fix is simple: gather with vector_justify=false so format_desc
shifts apply directly; use (3-j)*width on UTIL_ARCH_BIG_ENDIAN to match
the memory layout that big-endian bitcast produces.

This fixes the lp_test_format test on big-endian platforms.

Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/42228>
This commit is contained in:
Matt Turner 2026-06-12 18:36:26 -04:00 committed by Marge Bot
parent a9d70225ec
commit 5bb025f953

View file

@ -35,6 +35,7 @@
#include "util/format/u_format.h"
#include "util/bitscan.h"
#include "util/u_endian.h"
#include "util/u_pointer.h"
#include "lp_bld_arit.h"
@ -546,7 +547,7 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
packed = lp_build_gather(gallivm, type.length/4,
format_desc->block.bits, fetch_type,
aligned, base_ptr, offset, true);
aligned, base_ptr, offset, false);
assert(format_desc->block.bits * type.length / 4 <=
type.width * type.length);
@ -585,12 +586,18 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm,
} else {
rgba[j] = lp_build_swizzle_soa_channel(&bld_conv, chans, swizzle);
}
#if UTIL_ARCH_BIG_ENDIAN
unsigned shift = (3 - j) * type.width;
#else
unsigned shift = j * type.width;
#endif
if (shift != 0) {
rgba[j] = LLVMBuildShl(builder, rgba[j],
lp_build_const_int_vec(gallivm, conv_type, shift), "");
}
if (j == 0) {
res = rgba[j];
} else {
rgba[j] = LLVMBuildShl(builder, rgba[j],
lp_build_const_int_vec(gallivm, conv_type,
j * type.width), "");
res = LLVMBuildOr(builder, res, rgba[j], "");
}
}