From d53b79ff5ca37d5110034e73e50b2fe35c3868ee Mon Sep 17 00:00:00 2001
From: Levi Behunin <l3ehunin@gmail.com>
Date: Thu, 24 Sep 2020 16:40:06 -0600
Subject: [PATCH 1/4] Start of Integer flags implementation

---
 src/video_core/shader/node.h        |  4 +++
 src/video_core/shader/shader_ir.cpp | 46 +++++++++++++++++++++++++++--
 src/video_core/shader/shader_ir.h   |  3 ++
 3 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h
index 8f230d57a..11a8a3f70 100644
--- a/src/video_core/shader/node.h
+++ b/src/video_core/shader/node.h
@@ -464,6 +464,10 @@ public:
         return operands.size();
     }
 
+    NodeBlock GetOperands() const {
+        return operands;
+    }
+
     const Node& operator[](std::size_t operand_index) const {
         return operands.at(operand_index);
     }
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index 29d794b34..14206d3ae 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -387,9 +387,49 @@ void ShaderIR::SetInternalFlagsFromInteger(NodeBlock& bb, Node value, bool sets_
     if (!sets_cc) {
         return;
     }
-    Node zerop = Operation(OperationCode::LogicalIEqual, std::move(value), Immediate(0));
-    SetInternalFlag(bb, InternalFlag::Zero, std::move(zerop));
-    LOG_WARNING(HW_GPU, "Condition codes implementation is incomplete");
+    switch (value->index()) {
+    case 0:
+        Iterop(bb, value);
+        break;
+    case 2:
+        if (const auto gpr = std::get_if<GprNode>(value.get())) {
+            LOG_WARNING(HW_GPU, "GprNode: index={}", gpr->GetIndex());
+            Node zerop = Operation(OperationCode::LogicalIEqual, std::move(value),
+                                   Immediate(gpr->GetIndex()));
+            SetInternalFlag(bb, InternalFlag::Zero, std::move(zerop));
+        }
+        break;
+
+    default:
+        Node zerop = Operation(OperationCode::LogicalIEqual, std::move(value), Immediate(0));
+        SetInternalFlag(bb, InternalFlag::Zero, std::move(zerop));
+        LOG_WARNING(HW_GPU, "Node Type: {}", value->index());
+        break;
+    }
+}
+
+void ShaderIR::Iterop(NodeBlock& nb, Node var) {
+    if (const auto op = std::get_if<OperationNode>(var.get())) {
+        if (op->GetOperandsCount() > 0) {
+            for (auto& opss : op->GetOperands()) {
+                switch (opss->index()) {
+                case 0:
+                    return Iterop(nb, opss);
+                case 2:
+                    if (const auto gpr = std::get_if<GprNode>(opss.get())) {
+                        LOG_WARNING(HW_GPU, "Child GprNode: index={}", gpr->GetIndex());
+                        Node zerop = Operation(OperationCode::LogicalIEqual, std::move(opss),
+                                               Immediate(gpr->GetIndex()));
+                        SetInternalFlag(nb, InternalFlag::Zero, std::move(zerop));
+                    }
+                    break;
+                default:
+                    LOG_WARNING(HW_GPU, "Child Node Type: {}", opss->index());
+                    break;
+                }
+            }
+        }
+    }
 }
 
 Node ShaderIR::BitfieldExtract(Node value, u32 offset, u32 bits) {
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 3a98b2104..2484b1c6a 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -346,6 +346,9 @@ private:
     /// Access a bindless image sampler.
     Image& GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type);
 
+    /// Recursive Iteration over the OperationNode operands
+    void Iterop(NodeBlock& nb, Node var);
+
     /// Extracts a sequence of bits from a node
     Node BitfieldExtract(Node value, u32 offset, u32 bits);
 

From a19dc3bf00bb031120805b1e40fe0a3a455648b7 Mon Sep 17 00:00:00 2001
From: Levi Behunin <l3ehunin@gmail.com>
Date: Thu, 24 Sep 2020 21:52:23 -0600
Subject: [PATCH 2/4] Address Comments

---
 src/video_core/shader/node.h        |  6 +++-
 src/video_core/shader/shader_ir.cpp | 49 ++++++++++++++++-------------
 src/video_core/shader/shader_ir.h   |  4 +--
 3 files changed, 34 insertions(+), 25 deletions(-)

diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h
index 11a8a3f70..1b19a0673 100644
--- a/src/video_core/shader/node.h
+++ b/src/video_core/shader/node.h
@@ -464,7 +464,11 @@ public:
         return operands.size();
     }
 
-    NodeBlock GetOperands() const {
+    NodeBlock& GetOperands() {
+        return operands;
+    }
+
+    const NodeBlock& GetOperands() const {
         return operands;
     }
 
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index 14206d3ae..521d0e47d 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -388,12 +388,12 @@ void ShaderIR::SetInternalFlagsFromInteger(NodeBlock& bb, Node value, bool sets_
         return;
     }
     switch (value->index()) {
-    case 0:
+    case 0: // Operation Node
         Iterop(bb, value);
         break;
-    case 2:
+    case 2: // Genral Purpose Node
         if (const auto gpr = std::get_if<GprNode>(value.get())) {
-            LOG_WARNING(HW_GPU, "GprNode: index={}", gpr->GetIndex());
+            LOG_DEBUG(HW_GPU, "GprNode: index={}", gpr->GetIndex());
             Node zerop = Operation(OperationCode::LogicalIEqual, std::move(value),
                                    Immediate(gpr->GetIndex()));
             SetInternalFlag(bb, InternalFlag::Zero, std::move(zerop));
@@ -408,26 +408,31 @@ void ShaderIR::SetInternalFlagsFromInteger(NodeBlock& bb, Node value, bool sets_
     }
 }
 
-void ShaderIR::Iterop(NodeBlock& nb, Node var) {
-    if (const auto op = std::get_if<OperationNode>(var.get())) {
-        if (op->GetOperandsCount() > 0) {
-            for (auto& opss : op->GetOperands()) {
-                switch (opss->index()) {
-                case 0:
-                    return Iterop(nb, opss);
-                case 2:
-                    if (const auto gpr = std::get_if<GprNode>(opss.get())) {
-                        LOG_WARNING(HW_GPU, "Child GprNode: index={}", gpr->GetIndex());
-                        Node zerop = Operation(OperationCode::LogicalIEqual, std::move(opss),
-                                               Immediate(gpr->GetIndex()));
-                        SetInternalFlag(nb, InternalFlag::Zero, std::move(zerop));
-                    }
-                    break;
-                default:
-                    LOG_WARNING(HW_GPU, "Child Node Type: {}", opss->index());
-                    break;
-                }
+void ShaderIR::SearchOperands(NodeBlock& nb, Node var) {
+    const auto* op = std::get_if<OperationNode>(var.get());
+    if (op == nullptr) {
+        return;
+    }
+
+    if (op->GetOperandsCount() == 0) {
+        return;
+    }
+
+    for (auto& operand : op->GetOperands()) {
+        switch (operand->index()) {
+        case 0: // Operation Node
+            return Iterop(nb, operand);
+        case 2: // General Purpose Node
+            if (const auto* gpr = std::get_if<GprNode>(operand.get())) {
+                LOG_DEBUG(HW_GPU, "Child GprNode: index={}", gpr->GetIndex());
+                Node zerop = Operation(OperationCode::LogicalIEqual, std::move(operand),
+                                       Immediate(gpr->GetIndex()));
+                SetInternalFlag(nb, InternalFlag::Zero, std::move(zerop));
             }
+            break;
+        default:
+            LOG_WARNING(HW_GPU, "Child Node Type: {}", operand->index());
+            break;
         }
     }
 }
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h
index 2484b1c6a..b450f3b8a 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -346,8 +346,8 @@ private:
     /// Access a bindless image sampler.
     Image& GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type);
 
-    /// Recursive Iteration over the OperationNode operands
-    void Iterop(NodeBlock& nb, Node var);
+    /// Recursive Iteration over the OperationNode operands, searching for GprNodes.
+    void SearchOperands(NodeBlock& nb, Node var);
 
     /// Extracts a sequence of bits from a node
     Node BitfieldExtract(Node value, u32 offset, u32 bits);

From 24c1bb3842324c681f2a718b7a004c7c6afe52a8 Mon Sep 17 00:00:00 2001
From: Levi Behunin <l3ehunin@gmail.com>
Date: Thu, 24 Sep 2020 21:58:51 -0600
Subject: [PATCH 3/4] Forgot to apply suggestion here as well

---
 src/video_core/shader/shader_ir.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index 521d0e47d..7d144b9cf 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -392,7 +392,7 @@ void ShaderIR::SetInternalFlagsFromInteger(NodeBlock& bb, Node value, bool sets_
         Iterop(bb, value);
         break;
     case 2: // Genral Purpose Node
-        if (const auto gpr = std::get_if<GprNode>(value.get())) {
+        if (const auto* gpr = std::get_if<GprNode>(value.get())) {
             LOG_DEBUG(HW_GPU, "GprNode: index={}", gpr->GetIndex());
             Node zerop = Operation(OperationCode::LogicalIEqual, std::move(value),
                                    Immediate(gpr->GetIndex()));

From bc69cc151192326f9b8e18bbda831f1589ba27e0 Mon Sep 17 00:00:00 2001
From: Levi Behunin <l3ehunin@gmail.com>
Date: Thu, 24 Sep 2020 22:12:13 -0600
Subject: [PATCH 4/4] More forgetting... duh

---
 src/video_core/shader/shader_ir.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index 7d144b9cf..f207bbfbf 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -389,7 +389,7 @@ void ShaderIR::SetInternalFlagsFromInteger(NodeBlock& bb, Node value, bool sets_
     }
     switch (value->index()) {
     case 0: // Operation Node
-        Iterop(bb, value);
+        SearchOperands(bb, value);
         break;
     case 2: // Genral Purpose Node
         if (const auto* gpr = std::get_if<GprNode>(value.get())) {
@@ -421,7 +421,7 @@ void ShaderIR::SearchOperands(NodeBlock& nb, Node var) {
     for (auto& operand : op->GetOperands()) {
         switch (operand->index()) {
         case 0: // Operation Node
-            return Iterop(nb, operand);
+            return SearchOperands(nb, operand);
         case 2: // General Purpose Node
             if (const auto* gpr = std::get_if<GprNode>(operand.get())) {
                 LOG_DEBUG(HW_GPU, "Child GprNode: index={}", gpr->GetIndex());