From d2e811db2edd3829b344e96ad56ae979bccd28d2 Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Sun, 23 May 2021 04:14:35 -0300
Subject: spirv: Workaround image unsigned offset bug

Workaround bug on Nvidia's OpenGL SPIR-V compiler when using unsigned
texture offsets.
---
 src/shader_recompiler/backend/spirv/emit_context.h | 25 ++++++++++++++++++----
 .../backend/spirv/emit_spirv_image.cpp             | 10 ++++-----
 2 files changed, 26 insertions(+), 9 deletions(-)

(limited to 'src')

diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h
index baf12c2170..823ed8525b 100644
--- a/src/shader_recompiler/backend/spirv/emit_context.h
+++ b/src/shader_recompiler/backend/spirv/emit_context.h
@@ -122,10 +122,6 @@ public:
         return Constant(U32[1], value);
     }
 
-    Id Const(f32 value) {
-        return Constant(F32[1], value);
-    }
-
     Id Const(u32 element_1, u32 element_2) {
         return ConstantComposite(U32[2], Const(element_1), Const(element_2));
     }
@@ -139,6 +135,27 @@ public:
                                  Const(element_4));
     }
 
+    Id SConst(s32 value) {
+        return Constant(S32[1], value);
+    }
+
+    Id SConst(s32 element_1, s32 element_2) {
+        return ConstantComposite(S32[2], SConst(element_1), SConst(element_2));
+    }
+
+    Id SConst(s32 element_1, s32 element_2, s32 element_3) {
+        return ConstantComposite(S32[3], SConst(element_1), SConst(element_2), SConst(element_3));
+    }
+
+    Id SConst(s32 element_1, s32 element_2, s32 element_3, s32 element_4) {
+        return ConstantComposite(S32[4], SConst(element_1), SConst(element_2), SConst(element_3),
+                                 SConst(element_4));
+    }
+
+    Id Const(f32 value) {
+        return Constant(F32[1], value);
+    }
+
     const Profile& profile;
     Stage stage{};
 
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
index 6008980afe..a6cb67b971 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
@@ -104,7 +104,7 @@ private:
             return;
         }
         if (offset.IsImmediate()) {
-            Add(spv::ImageOperandsMask::ConstOffset, ctx.Const(offset.U32()));
+            Add(spv::ImageOperandsMask::ConstOffset, ctx.SConst(offset.U32()));
             return;
         }
         IR::Inst* const inst{offset.InstRecursive()};
@@ -112,16 +112,16 @@ private:
             switch (inst->GetOpcode()) {
             case IR::Opcode::CompositeConstructU32x2:
                 Add(spv::ImageOperandsMask::ConstOffset,
-                    ctx.Const(inst->Arg(0).U32(), inst->Arg(1).U32()));
+                    ctx.SConst(inst->Arg(0).U32(), inst->Arg(1).U32()));
                 return;
             case IR::Opcode::CompositeConstructU32x3:
                 Add(spv::ImageOperandsMask::ConstOffset,
-                    ctx.Const(inst->Arg(0).U32(), inst->Arg(1).U32(), inst->Arg(2).U32()));
+                    ctx.SConst(inst->Arg(0).U32(), inst->Arg(1).U32(), inst->Arg(2).U32()));
                 return;
             case IR::Opcode::CompositeConstructU32x4:
                 Add(spv::ImageOperandsMask::ConstOffset,
-                    ctx.Const(inst->Arg(0).U32(), inst->Arg(1).U32(), inst->Arg(2).U32(),
-                              inst->Arg(3).U32()));
+                    ctx.SConst(inst->Arg(0).U32(), inst->Arg(1).U32(), inst->Arg(2).U32(),
+                               inst->Arg(3).U32()));
                 return;
             default:
                 break;
-- 
cgit v1.2.3-70-g09d2