summaryrefslogtreecommitdiffstats
path: root/src/video_core/shader/ast.cpp
diff options
context:
space:
mode:
authorFernando Sahmkow <fsahmkow27@gmail.com>2019-06-27 06:39:40 +0200
committerFernandoS27 <fsahmkow27@gmail.com>2019-10-05 00:52:47 +0200
commitc17953978b16f82a3b2049f8b961275020c73dd0 (patch)
tree669f353dfa3e6a6198b404e326356ca1243a4e91 /src/video_core/shader/ast.cpp
parentMerge pull request #2941 from FernandoS27/fix-master (diff)
downloadyuzu-c17953978b16f82a3b2049f8b961275020c73dd0.tar
yuzu-c17953978b16f82a3b2049f8b961275020c73dd0.tar.gz
yuzu-c17953978b16f82a3b2049f8b961275020c73dd0.tar.bz2
yuzu-c17953978b16f82a3b2049f8b961275020c73dd0.tar.lz
yuzu-c17953978b16f82a3b2049f8b961275020c73dd0.tar.xz
yuzu-c17953978b16f82a3b2049f8b961275020c73dd0.tar.zst
yuzu-c17953978b16f82a3b2049f8b961275020c73dd0.zip
Diffstat (limited to '')
-rw-r--r--src/video_core/shader/ast.cpp180
1 files changed, 180 insertions, 0 deletions
diff --git a/src/video_core/shader/ast.cpp b/src/video_core/shader/ast.cpp
new file mode 100644
index 000000000..5d0e85f42
--- /dev/null
+++ b/src/video_core/shader/ast.cpp
@@ -0,0 +1,180 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <string>
+
+#include "common/assert.h"
+#include "common/common_types.h"
+#include "video_core/shader/ast.h"
+#include "video_core/shader/expr.h"
+
+namespace VideoCommon::Shader {
+
+class ExprPrinter final {
+public:
+ ExprPrinter() = default;
+
+ void operator()(ExprAnd const& expr) {
+ inner += "( ";
+ std::visit(*this, *expr.operand1);
+ inner += " && ";
+ std::visit(*this, *expr.operand2);
+ inner += ')';
+ }
+
+ void operator()(ExprOr const& expr) {
+ inner += "( ";
+ std::visit(*this, *expr.operand1);
+ inner += " || ";
+ std::visit(*this, *expr.operand2);
+ inner += ')';
+ }
+
+ void operator()(ExprNot const& expr) {
+ inner += "!";
+ std::visit(*this, *expr.operand1);
+ }
+
+ void operator()(ExprPredicate const& expr) {
+ u32 pred = static_cast<u32>(expr.predicate);
+ if (pred > 7) {
+ inner += "!";
+ pred -= 8;
+ }
+ inner += "P" + std::to_string(pred);
+ }
+
+ void operator()(ExprCondCode const& expr) {
+ u32 cc = static_cast<u32>(expr.cc);
+ inner += "CC" + std::to_string(cc);
+ }
+
+ void operator()(ExprVar const& expr) {
+ inner += "V" + std::to_string(expr.var_index);
+ }
+
+ void operator()(ExprBoolean const& expr) {
+ inner += expr.value ? "true" : "false";
+ }
+
+ std::string& GetResult() {
+ return inner;
+ }
+
+ std::string inner{};
+};
+
+class ASTPrinter {
+public:
+ ASTPrinter() = default;
+
+ void operator()(ASTProgram& ast) {
+ scope++;
+ inner += "program {\n";
+ for (ASTNode& node : ast.nodes) {
+ Visit(node);
+ }
+ inner += "}\n";
+ scope--;
+ }
+
+ void operator()(ASTIf& ast) {
+ ExprPrinter expr_parser{};
+ std::visit(expr_parser, *ast.condition);
+ inner += Ident() + "if (" + expr_parser.GetResult() + ") {\n";
+ scope++;
+ for (auto& node : ast.then_nodes) {
+ Visit(node);
+ }
+ scope--;
+ if (ast.else_nodes.size() > 0) {
+ inner += Ident() + "} else {\n";
+ scope++;
+ for (auto& node : ast.else_nodes) {
+ Visit(node);
+ }
+ scope--;
+ } else {
+ inner += Ident() + "}\n";
+ }
+ }
+
+ void operator()(ASTBlockEncoded& ast) {
+ inner += Ident() + "Block(" + std::to_string(ast.start) + ", " + std::to_string(ast.end) +
+ ");\n";
+ }
+
+ void operator()(ASTVarSet& ast) {
+ ExprPrinter expr_parser{};
+ std::visit(expr_parser, *ast.condition);
+ inner +=
+ Ident() + "V" + std::to_string(ast.index) + " := " + expr_parser.GetResult() + ";\n";
+ }
+
+ void operator()(ASTLabel& ast) {
+ inner += "Label_" + std::to_string(ast.index) + ":\n";
+ }
+
+ void operator()(ASTGoto& ast) {
+ ExprPrinter expr_parser{};
+ std::visit(expr_parser, *ast.condition);
+ inner += Ident() + "(" + expr_parser.GetResult() + ") -> goto Label_" +
+ std::to_string(ast.label) + ";\n";
+ }
+
+ void operator()(ASTDoWhile& ast) {
+ ExprPrinter expr_parser{};
+ std::visit(expr_parser, *ast.condition);
+ inner += Ident() + "do {\n";
+ scope++;
+ for (auto& node : ast.loop_nodes) {
+ Visit(node);
+ }
+ scope--;
+ inner += Ident() + "} while (" + expr_parser.GetResult() + ")\n";
+ }
+
+ void operator()(ASTReturn& ast) {
+ ExprPrinter expr_parser{};
+ std::visit(expr_parser, *ast.condition);
+ inner += Ident() + "(" + expr_parser.GetResult() + ") -> " +
+ (ast.kills ? "discard" : "exit") + ";\n";
+ }
+
+ std::string& Ident() {
+ if (memo_scope == scope) {
+ return tabs_memo;
+ }
+ tabs_memo = tabs.substr(0, scope * 2);
+ memo_scope = scope;
+ return tabs_memo;
+ }
+
+ void Visit(ASTNode& node) {
+ std::visit(*this, *node->GetInnerData());
+ }
+
+ std::string& GetResult() {
+ return inner;
+ }
+
+private:
+ std::string inner{};
+ u32 scope{};
+
+ std::string tabs_memo{};
+ u32 memo_scope{};
+
+ static std::string tabs;
+};
+
+std::string ASTPrinter::tabs = " ";
+
+std::string ASTManager::Print() {
+ ASTPrinter printer{};
+ printer.Visit(main_node);
+ return printer.GetResult();
+}
+
+} // namespace VideoCommon::Shader