summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/video_core/shader/node.h4
-rw-r--r--src/video_core/shader/shader_ir.cpp46
-rw-r--r--src/video_core/shader/shader_ir.h3
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);