From 025bc799f782be40544d2718bdcbb8f4d0d033d2 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 29 Jan 2026 17:24:11 +0100 Subject: [PATCH] [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 Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3404 Reviewed-by: MaranBr Reviewed-by: crueter Co-authored-by: lizzie Co-committed-by: lizzie --- .../backend/spirv/emit_spirv_image.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index 9010e8e3e3..c07a778958 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp @@ -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(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); }