[vk] change UInt32->Int32 being used as texture gather offsets (#3404)

"So, found another macOS crash while testing Luigi's mansion 2. It looks like Metal is pretty picky about types and was crashing because the texture gather offsets were being passed as unsigned integers instead of signed ones.
I made a small tweak to the shader recompiler to force them to be signed, and the game boots fine now. Most other drivers usually handle signed offsets anyway, so it should be a safe fix for everyone." - rayman

Authored-by: rayman
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3404
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
lizzie 2026-01-29 17:24:11 +01:00 committed by crueter
parent 54af7abac4
commit 025bc799f7
No known key found for this signature in database
GPG Key ID: 425ACD2D4830EBC6
1 changed files with 5 additions and 8 deletions

View File

@ -40,10 +40,7 @@ public:
explicit ImageOperands(EmitContext& ctx, const IR::Value& offset, const IR::Value& offset2) {
if (offset2.IsEmpty()) {
if (offset.IsEmpty()) {
return;
}
Add(spv::ImageOperandsMask::Offset, ctx.Def(offset));
AddOffset(ctx, offset, ImageGatherOffsetAllowed);
return;
}
const std::array values{offset.InstRecursive(), offset2.InstRecursive()};
@ -55,12 +52,12 @@ public:
if (opcode != values[1]->GetOpcode() || opcode != IR::Opcode::CompositeConstructU32x4) {
throw LogicError("Invalid PTP arguments");
}
auto read{[&](unsigned int a, unsigned int b) { return values[a]->Arg(b).U32(); }};
auto read{[&](unsigned int a, unsigned int b) { return static_cast<s32>(values[a]->Arg(b).U32()); }};
const Id offsets{ctx.ConstantComposite(
ctx.TypeArray(ctx.U32[2], ctx.Const(4U)), ctx.Const(read(0, 0), read(0, 1)),
ctx.Const(read(0, 2), read(0, 3)), ctx.Const(read(1, 0), read(1, 1)),
ctx.Const(read(1, 2), read(1, 3)))};
ctx.TypeArray(ctx.S32[2], ctx.Const(4U)), ctx.SConst(read(0, 0), read(0, 1)),
ctx.SConst(read(0, 2), read(0, 3)), ctx.SConst(read(1, 0), read(1, 1)),
ctx.SConst(read(1, 2), read(1, 3)))};
Add(spv::ImageOperandsMask::ConstOffsets, offsets);
}