diff options
Diffstat (limited to 'src/video_core/shader')
-rw-r--r-- | src/video_core/shader/node.h | 4 | ||||
-rw-r--r-- | src/video_core/shader/shader_ir.cpp | 46 | ||||
-rw-r--r-- | 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); |