From cb6fc03e55e9eff0826173a6bcacef3034322f7c Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Mon, 29 Mar 2021 01:08:25 -0300
Subject: [PATCH] shader: Always pass a lod for TexelFetch

---
 src/shader_recompiler/frontend/ir/opcodes.inc |  6 ++--
 .../maxwell/translate/impl/texture_load.cpp   |  2 ++
 .../translate/impl/texture_load_swizzled.cpp  | 34 +++++++------------
 3 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc
index 79baacd08f..e82db0cd2f 100644
--- a/src/shader_recompiler/frontend/ir/opcodes.inc
+++ b/src/shader_recompiler/frontend/ir/opcodes.inc
@@ -378,7 +378,7 @@ OPCODE(BindlessImageSampleDrefImplicitLod,                  F32,            U32,
 OPCODE(BindlessImageSampleDrefExplicitLod,                  F32,            U32,            Opaque,         F32,            Opaque,         Opaque,         )
 OPCODE(BindlessImageGather,                                 F32x4,          U32,            Opaque,         Opaque,         Opaque,                         )
 OPCODE(BindlessImageGatherDref,                             F32x4,          U32,            Opaque,         Opaque,         Opaque,         F32,            )
-OPCODE(BindlessImageFetch,                                  F32x4,          U32,            Opaque,         Opaque,         Opaque,         Opaque,         )
+OPCODE(BindlessImageFetch,                                  F32x4,          U32,            Opaque,         Opaque,         U32,            Opaque,         )
 OPCODE(BindlessImageQueryDimensions,                        U32x4,          U32,            U32,                                                            )
 OPCODE(BindlessImageQueryLod,                               F32x4,          U32,            Opaque,                                                         )
 OPCODE(BindlessImageGradient,                               F32x4,          U32,            Opaque,         Opaque,         Opaque,         Opaque,         )
@@ -389,7 +389,7 @@ OPCODE(BoundImageSampleDrefImplicitLod,                     F32,            U32,
 OPCODE(BoundImageSampleDrefExplicitLod,                     F32,            U32,            Opaque,         F32,            Opaque,         Opaque,         )
 OPCODE(BoundImageGather,                                    F32x4,          U32,            Opaque,         Opaque,         Opaque,                         )
 OPCODE(BoundImageGatherDref,                                F32x4,          U32,            Opaque,         Opaque,         Opaque,         F32,            )
-OPCODE(BoundImageFetch,                                     F32x4,          U32,            Opaque,         Opaque,         Opaque,         Opaque,         )
+OPCODE(BoundImageFetch,                                     F32x4,          U32,            Opaque,         Opaque,         U32,            Opaque,         )
 OPCODE(BoundImageQueryDimensions,                           U32x4,          U32,            U32,                                                            )
 OPCODE(BoundImageQueryLod,                                  F32x4,          U32,            Opaque,                                                         )
 OPCODE(BoundImageGradient,                                  F32x4,          U32,            Opaque,         Opaque,         Opaque,         Opaque,         )
@@ -400,7 +400,7 @@ OPCODE(ImageSampleDrefImplicitLod,                          F32,            U32,
 OPCODE(ImageSampleDrefExplicitLod,                          F32,            U32,            Opaque,         F32,            Opaque,         Opaque,         )
 OPCODE(ImageGather,                                         F32x4,          U32,            Opaque,         Opaque,         Opaque,                         )
 OPCODE(ImageGatherDref,                                     F32x4,          U32,            Opaque,         Opaque,         Opaque,         F32,            )
-OPCODE(ImageFetch,                                          F32x4,          U32,            Opaque,         Opaque,         Opaque,         Opaque,         )
+OPCODE(ImageFetch,                                          F32x4,          U32,            Opaque,         Opaque,         U32,            Opaque,         )
 OPCODE(ImageQueryDimensions,                                U32x4,          U32,            U32,                                                            )
 OPCODE(ImageQueryLod,                                       F32x4,          U32,            Opaque,                                                         )
 OPCODE(ImageGradient,                                       F32x4,          U32,            Opaque,         Opaque,         Opaque,         F32,            )
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load.cpp
index b4063fa6e1..df38f87a35 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load.cpp
@@ -124,6 +124,8 @@ void Impl(TranslatorVisitor& v, u64 insn, bool is_bindless) {
     }
     if (tld.lod != 0) {
         lod = v.X(meta_reg++);
+    } else {
+        lod = v.ir.Imm32(0U);
     }
     if (tld.aoffi != 0) {
         offset = MakeOffset(v, meta_reg, tld.type);
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load_swizzled.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load_swizzled.cpp
index 3e6ebd911d..623b8fc23b 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load_swizzled.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_load_swizzled.cpp
@@ -74,62 +74,55 @@ IR::Value Sample(TranslatorVisitor& v, u64 insn) {
     const IR::Reg reg_a{tlds.src_reg_a};
     const IR::Reg reg_b{tlds.src_reg_b};
     IR::Value coords;
-    IR::U32 lod;
+    IR::U32 lod{v.ir.Imm32(0U)};
     IR::Value offsets;
     IR::U32 multisample;
-    Shader::TextureType texture_type;
+    Shader::TextureType texture_type{};
     switch (tlds.encoding) {
-    case 0: {
+    case 0:
         texture_type = Shader::TextureType::Color1D;
         coords = v.X(reg_a);
         break;
-    }
-    case 1: {
+    case 1:
         texture_type = Shader::TextureType::Color1D;
         coords = v.X(reg_a);
         lod = v.X(reg_b);
         break;
-    }
-    case 2: {
+    case 2:
         texture_type = Shader::TextureType::Color2D;
         coords = v.ir.CompositeConstruct(v.X(reg_a), v.X(reg_b));
         break;
-    }
-    case 4: {
+    case 4:
         CheckAlignment(reg_a, 2);
         texture_type = Shader::TextureType::Color2D;
         coords = v.ir.CompositeConstruct(v.X(reg_a), v.X(reg_a + 1));
         offsets = MakeOffset(v, reg_b);
         break;
-    }
-    case 5: {
+    case 5:
         CheckAlignment(reg_a, 2);
         texture_type = Shader::TextureType::Color2D;
         coords = v.ir.CompositeConstruct(v.X(reg_a), v.X(reg_a + 1));
         lod = v.X(reg_b);
         break;
-    }
-    case 6: {
+    case 6:
         CheckAlignment(reg_a, 2);
         texture_type = Shader::TextureType::Color2D;
         coords = v.ir.CompositeConstruct(v.X(reg_a), v.X(reg_a + 1));
         multisample = v.X(reg_b);
         break;
-    }
-    case 7: {
+    case 7:
         CheckAlignment(reg_a, 2);
         texture_type = Shader::TextureType::Color3D;
         coords = v.ir.CompositeConstruct(v.X(reg_a), v.X(reg_a + 1), v.X(reg_b));
         break;
-    }
     case 8: {
         CheckAlignment(reg_b, 2);
+        const IR::U32 array{v.ir.BitFieldExtract(v.X(reg_a), v.ir.Imm32(0), v.ir.Imm32(16))};
         texture_type = Shader::TextureType::ColorArray2D;
-        IR::U32 array = v.ir.BitFieldExtract(v.X(reg_a), v.ir.Imm32(0), v.ir.Imm32(16));
         coords = v.ir.CompositeConstruct(v.X(reg_b), v.X(reg_b + 1), array);
         break;
     }
-    case 12: {
+    case 12:
         CheckAlignment(reg_a, 2);
         CheckAlignment(reg_b, 2);
         texture_type = Shader::TextureType::Color2D;
@@ -137,11 +130,8 @@ IR::Value Sample(TranslatorVisitor& v, u64 insn) {
         lod = v.X(reg_b);
         offsets = MakeOffset(v, reg_b + 1);
         break;
-    }
-    default: {
+    default:
         throw NotImplementedException("Illegal encoding {}", tlds.encoding.Value());
-        break;
-    }
     }
     IR::TextureInstInfo info{};
     if (tlds.precision == Precision::F16) {