From 82a313a14c1896a7fd4f6613bc5df1831298e1d8 Mon Sep 17 00:00:00 2001
From: FernandoS27 <fsahmkow27@gmail.com>
Date: Fri, 7 Sep 2018 19:02:33 -0400
Subject: [PATCH 1/2] Change name of TEXQ to TXQ, in order to match NVIDIA's
 naming

---
 src/video_core/engines/shader_bytecode.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index d2388673e..9bfeff5b6 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -670,7 +670,7 @@ public:
         LDG, // Load from global memory
         STG, // Store in global memory
         TEX,
-        TEXQ,  // Texture Query
+        TXQ,  // Texture Query
         TEXS,  // Texture Fetch with scalar/non-vec4 source/destinations
         TLDS,  // Texture Load with scalar/non-vec4 source/destinations
         TLD4,  // Texture Load 4
@@ -894,7 +894,7 @@ private:
             INST("1110111011010---", Id::LDG, Type::Memory, "LDG"),
             INST("1110111011011---", Id::STG, Type::Memory, "STG"),
             INST("110000----111---", Id::TEX, Type::Memory, "TEX"),
-            INST("1101111101001---", Id::TEXQ, Type::Memory, "TEXQ"),
+            INST("1101111101001---", Id::TXQ, Type::Memory, "TXQ"),
             INST("1101100---------", Id::TEXS, Type::Memory, "TEXS"),
             INST("1101101---------", Id::TLDS, Type::Memory, "TLDS"),
             INST("110010----111---", Id::TLD4, Type::Memory, "TLD4"),

From 073a21ac0b9af6871af02aa0096677abb4af117b Mon Sep 17 00:00:00 2001
From: FernandoS27 <fsahmkow27@gmail.com>
Date: Fri, 7 Sep 2018 19:53:06 -0400
Subject: [PATCH 2/2] Implemented TXQ dimension query type, used by SMO.

---
 src/video_core/engines/shader_bytecode.h      | 17 +++++++++++++++-
 .../renderer_opengl/gl_shader_decompiler.cpp  | 20 +++++++++++++++++++
 2 files changed, 36 insertions(+), 1 deletion(-)

diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 9bfeff5b6..6cfdb6e27 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -244,6 +244,16 @@ enum class TextureType : u64 {
     TextureCube = 3,
 };
 
+enum class TextureQueryType : u64 {
+    Dimension = 1,
+    TextureType = 2,
+    SamplePosition = 5,
+    Filter = 16,
+    LevelOfDetail = 18,
+    Wrap = 20,
+    BorderColor = 22,
+};
+
 enum class IpaInterpMode : u64 { Linear = 0, Perspective = 1, Flat = 2, Sc = 3 };
 enum class IpaSampleMode : u64 { Default = 0, Centroid = 1, Offset = 2 };
 
@@ -518,6 +528,11 @@ union Instruction {
         }
     } tex;
 
+    union {
+        BitField<22, 6, TextureQueryType> query_type;
+        BitField<31, 4, u64> component_mask;
+    } txq;
+
     union {
         BitField<28, 1, u64> array;
         BitField<29, 2, TextureType> texture_type;
@@ -670,7 +685,7 @@ public:
         LDG, // Load from global memory
         STG, // Store in global memory
         TEX,
-        TXQ,  // Texture Query
+        TXQ,   // Texture Query
         TEXS,  // Texture Fetch with scalar/non-vec4 source/destinations
         TLDS,  // Texture Load with scalar/non-vec4 source/destinations
         TLD4,  // Texture Load 4
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 172ba8335..6d895bbb6 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1920,6 +1920,26 @@ private:
                 WriteTexsInstruction(instr, coord, texture);
                 break;
             }
+            case OpCode::Id::TXQ: {
+                // TODO: the new commits on the texture refactor, change the way samplers work.
+                // Sadly, not all texture instructions specify the type of texture their sampler
+                // uses. This must be fixed at a later instance.
+                const std::string sampler =
+                    GetSampler(instr.sampler, Tegra::Shader::TextureType::Texture2D, false);
+                switch (instr.txq.query_type) {
+                case Tegra::Shader::TextureQueryType::Dimension: {
+                    const std::string texture = "textureQueryLevels(" + sampler + ')';
+                    regs.SetRegisterToInteger(instr.gpr0, true, 0, texture, 1, 1);
+                    break;
+                }
+                default: {
+                    LOG_CRITICAL(HW_GPU, "Unhandled texture query type: {}",
+                                 static_cast<u32>(instr.txq.query_type.Value()));
+                    UNREACHABLE();
+                }
+                }
+                break;
+            }
             default: {
                 LOG_CRITICAL(HW_GPU, "Unhandled memory instruction: {}", opcode->GetName());
                 UNREACHABLE();