From d4df803b2b6bab96321ca69651e4132545b433eb Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Thu, 2 May 2019 21:45:53 -0300
Subject: [PATCH] shader_ir/other: Implement IPA.IDX

---
 src/video_core/engines/shader_bytecode.h |  1 +
 src/video_core/shader/decode/other.cpp   | 13 ++++++++-----
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index e4a9471b82..7bbc556da9 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -596,6 +596,7 @@ union Instruction {
     } alu;
 
     union {
+        BitField<38, 1, u64> idx;
         BitField<51, 1, u64> saturate;
         BitField<52, 2, IpaSampleMode> sample_mode;
         BitField<54, 2, IpaInterpMode> interp_mode;
diff --git a/src/video_core/shader/decode/other.cpp b/src/video_core/shader/decode/other.cpp
index 776bdb9310..fa17c45b50 100644
--- a/src/video_core/shader/decode/other.cpp
+++ b/src/video_core/shader/decode/other.cpp
@@ -130,15 +130,18 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
         break;
     }
     case OpCode::Id::IPA: {
-        const auto& attribute = instr.attribute.fmt28;
+        const bool is_physical = instr.ipa.idx && instr.gpr8.Value() != 0xff;
+
+        const auto attribute = instr.attribute.fmt28;
         const Tegra::Shader::IpaMode input_mode{instr.ipa.interp_mode.Value(),
                                                 instr.ipa.sample_mode.Value()};
 
-        const Node attr = GetInputAttribute(attribute.index, attribute.element);
-        Node value = attr;
+        Node value = is_physical ? GetPhysicalInputAttribute(instr.gpr8)
+                                 : GetInputAttribute(attribute.index, attribute.element);
         const Tegra::Shader::Attribute::Index index = attribute.index.Value();
-        if (index >= Tegra::Shader::Attribute::Index::Attribute_0 &&
-            index <= Tegra::Shader::Attribute::Index::Attribute_31) {
+        const bool is_generic = index >= Tegra::Shader::Attribute::Index::Attribute_0 &&
+                                index <= Tegra::Shader::Attribute::Index::Attribute_31;
+        if (is_generic || is_physical) {
             // TODO(Blinkhawk): There are cases where a perspective attribute use PASS.
             // In theory by setting them as perspective, OpenGL does the perspective correction.
             // A way must figured to reverse the last step of it.
-- 
GitLab