From 2c2e019a44e353921d5fdf3cc6ab4304502eb2bd Mon Sep 17 00:00:00 2001
From: ameerj <52414509+ameerj@users.noreply.github.com>
Date: Sat, 28 Jan 2023 16:09:58 -0500
Subject: shader_recompiler: TXQ: Skip QueryLevels when possible

---
 src/shader_recompiler/frontend/ir/ir_emitter.cpp                 | 9 +++++----
 src/shader_recompiler/frontend/ir/ir_emitter.h                   | 5 +++--
 src/shader_recompiler/frontend/ir/opcodes.inc                    | 6 +++---
 .../frontend/maxwell/translate/impl/texture_query.cpp            | 8 +++++---
 4 files changed, 16 insertions(+), 12 deletions(-)

(limited to 'src/shader_recompiler/frontend')

diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
index eb2e49a688..8b379c920a 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
@@ -1851,15 +1851,16 @@ Value IREmitter::ImageFetch(const Value& handle, const Value& coords, const Valu
     return Inst(op, Flags{info}, handle, coords, offset, lod, multisampling);
 }
 
-Value IREmitter::ImageQueryDimension(const Value& handle, const IR::U32& lod) {
+Value IREmitter::ImageQueryDimension(const Value& handle, const IR::U32& lod,
+                                     const IR::U1& skip_mips) {
     const Opcode op{handle.IsImmediate() ? Opcode::BoundImageQueryDimensions
                                          : Opcode::BindlessImageQueryDimensions};
-    return Inst(op, handle, lod);
+    return Inst(op, handle, lod, skip_mips);
 }
 
 Value IREmitter::ImageQueryDimension(const Value& handle, const IR::U32& lod,
-                                     TextureInstInfo info) {
-    return Inst(Opcode::ImageQueryDimensions, Flags{info}, handle, lod);
+                                     const IR::U1& skip_mips, TextureInstInfo info) {
+    return Inst(Opcode::ImageQueryDimensions, Flags{info}, handle, lod, skip_mips);
 }
 
 Value IREmitter::ImageQueryLod(const Value& handle, const Value& coords, TextureInstInfo info) {
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h
index 7aaaa4ab06..df158c928c 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.h
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.h
@@ -320,9 +320,10 @@ public:
     [[nodiscard]] F32 ImageSampleDrefExplicitLod(const Value& handle, const Value& coords,
                                                  const F32& dref, const F32& lod,
                                                  const Value& offset, TextureInstInfo info);
-    [[nodiscard]] Value ImageQueryDimension(const Value& handle, const IR::U32& lod);
     [[nodiscard]] Value ImageQueryDimension(const Value& handle, const IR::U32& lod,
-                                            TextureInstInfo info);
+                                            const IR::U1& skip_mips);
+    [[nodiscard]] Value ImageQueryDimension(const Value& handle, const IR::U32& lod,
+                                            const IR::U1& skip_mips, TextureInstInfo info);
 
     [[nodiscard]] Value ImageQueryLod(const Value& handle, const Value& coords,
                                       TextureInstInfo info);
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc
index 1fe3749cc9..4ba262b84f 100644
--- a/src/shader_recompiler/frontend/ir/opcodes.inc
+++ b/src/shader_recompiler/frontend/ir/opcodes.inc
@@ -483,7 +483,7 @@ OPCODE(BindlessImageSampleDrefExplicitLod,                  F32,            U32,
 OPCODE(BindlessImageGather,                                 F32x4,          U32,            Opaque,         Opaque,         Opaque,                         )
 OPCODE(BindlessImageGatherDref,                             F32x4,          U32,            Opaque,         Opaque,         Opaque,         F32,            )
 OPCODE(BindlessImageFetch,                                  F32x4,          U32,            Opaque,         Opaque,         U32,            Opaque,         )
-OPCODE(BindlessImageQueryDimensions,                        U32x4,          U32,            U32,                                                            )
+OPCODE(BindlessImageQueryDimensions,                        U32x4,          U32,            U32,            U1,                                             )
 OPCODE(BindlessImageQueryLod,                               F32x4,          U32,            Opaque,                                                         )
 OPCODE(BindlessImageGradient,                               F32x4,          U32,            Opaque,         Opaque,         Opaque,         Opaque,         )
 OPCODE(BindlessImageRead,                                   U32x4,          U32,            Opaque,                                                         )
@@ -496,7 +496,7 @@ OPCODE(BoundImageSampleDrefExplicitLod,                     F32,            U32,
 OPCODE(BoundImageGather,                                    F32x4,          U32,            Opaque,         Opaque,         Opaque,                         )
 OPCODE(BoundImageGatherDref,                                F32x4,          U32,            Opaque,         Opaque,         Opaque,         F32,            )
 OPCODE(BoundImageFetch,                                     F32x4,          U32,            Opaque,         Opaque,         U32,            Opaque,         )
-OPCODE(BoundImageQueryDimensions,                           U32x4,          U32,            U32,                                                            )
+OPCODE(BoundImageQueryDimensions,                           U32x4,          U32,            U32,            U1,                                             )
 OPCODE(BoundImageQueryLod,                                  F32x4,          U32,            Opaque,                                                         )
 OPCODE(BoundImageGradient,                                  F32x4,          U32,            Opaque,         Opaque,         Opaque,         Opaque,         )
 OPCODE(BoundImageRead,                                      U32x4,          U32,            Opaque,                                                         )
@@ -509,7 +509,7 @@ OPCODE(ImageSampleDrefExplicitLod,                          F32,            Opaq
 OPCODE(ImageGather,                                         F32x4,          Opaque,         Opaque,         Opaque,         Opaque,                         )
 OPCODE(ImageGatherDref,                                     F32x4,          Opaque,         Opaque,         Opaque,         Opaque,         F32,            )
 OPCODE(ImageFetch,                                          F32x4,          Opaque,         Opaque,         Opaque,         U32,            Opaque,         )
-OPCODE(ImageQueryDimensions,                                U32x4,          Opaque,         U32,                                                            )
+OPCODE(ImageQueryDimensions,                                U32x4,          Opaque,         U32,            U1,                                             )
 OPCODE(ImageQueryLod,                                       F32x4,          Opaque,         Opaque,                                                         )
 OPCODE(ImageGradient,                                       F32x4,          Opaque,         Opaque,         Opaque,         Opaque,         Opaque,         )
 OPCODE(ImageRead,                                           U32x4,          Opaque,         Opaque,                                                         )
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_query.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_query.cpp
index f8cfd4ab64..39af625596 100644
--- a/src/shader_recompiler/frontend/maxwell/translate/impl/texture_query.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate/impl/texture_query.cpp
@@ -15,11 +15,13 @@ enum class Mode : u64 {
     SamplePos = 5,
 };
 
-IR::Value Query(TranslatorVisitor& v, const IR::U32& handle, Mode mode, IR::Reg src_reg) {
+IR::Value Query(TranslatorVisitor& v, const IR::U32& handle, Mode mode, IR::Reg src_reg, u64 mask) {
     switch (mode) {
     case Mode::Dimension: {
+        const bool needs_num_mips{((mask >> 3) & 1) != 0};
+        const IR::U1 skip_mips{v.ir.Imm1(!needs_num_mips)};
         const IR::U32 lod{v.X(src_reg)};
-        return v.ir.ImageQueryDimension(handle, lod);
+        return v.ir.ImageQueryDimension(handle, lod, skip_mips);
     }
     case Mode::TextureType:
     case Mode::SamplePos:
@@ -46,7 +48,7 @@ void Impl(TranslatorVisitor& v, u64 insn, std::optional<u32> cbuf_offset) {
         handle = v.X(src_reg);
         ++src_reg;
     }
-    const IR::Value query{Query(v, handle, txq.mode, src_reg)};
+    const IR::Value query{Query(v, handle, txq.mode, src_reg, txq.mask)};
     IR::Reg dest_reg{txq.dest_reg};
     for (int element = 0; element < 4; ++element) {
         if (((txq.mask >> element) & 1) == 0) {
-- 
cgit v1.2.3-70-g09d2