Просмотр исходного кода

Merge pull request #4713 from behunin/int-flags

Start of Integer flags implementation
bunnei 5 лет назад
Родитель
Сommit
302a5f00e8
3 измененных файлов с 59 добавлено и 3 удалено
  1. 8 0
      src/video_core/shader/node.h
  2. 48 3
      src/video_core/shader/shader_ir.cpp
  3. 3 0
      src/video_core/shader/shader_ir.h

+ 8 - 0
src/video_core/shader/node.h

@@ -465,6 +465,14 @@ public:
         return operands.size();
         return operands.size();
     }
     }
 
 
+    NodeBlock& GetOperands() {
+        return operands;
+    }
+
+    const NodeBlock& GetOperands() const {
+        return operands;
+    }
+
     [[nodiscard]] const Node& operator[](std::size_t operand_index) const {
     [[nodiscard]] const Node& operator[](std::size_t operand_index) const {
         return operands.at(operand_index);
         return operands.at(operand_index);
     }
     }

+ 48 - 3
src/video_core/shader/shader_ir.cpp

@@ -388,9 +388,54 @@ void ShaderIR::SetInternalFlagsFromInteger(NodeBlock& bb, Node value, bool sets_
     if (!sets_cc) {
     if (!sets_cc) {
         return;
         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: // Operation Node
+        SearchOperands(bb, value);
+        break;
+    case 2: // Genral Purpose Node
+        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()));
+            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::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 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());
+                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;
+        }
+    }
 }
 }
 
 
 Node ShaderIR::BitfieldExtract(Node value, u32 offset, u32 bits) {
 Node ShaderIR::BitfieldExtract(Node value, u32 offset, u32 bits) {

+ 3 - 0
src/video_core/shader/shader_ir.h

@@ -346,6 +346,9 @@ private:
     /// Access a bindless image sampler.
     /// Access a bindless image sampler.
     ImageEntry& GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type);
     ImageEntry& GetBindlessImage(Tegra::Shader::Register reg, Tegra::Shader::ImageType type);
 
 
+    /// Recursive Iteration over the OperationNode operands, searching for GprNodes.
+    void SearchOperands(NodeBlock& nb, Node var);
+
     /// Extracts a sequence of bits from a node
     /// Extracts a sequence of bits from a node
     Node BitfieldExtract(Node value, u32 offset, u32 bits);
     Node BitfieldExtract(Node value, u32 offset, u32 bits);