summaryrefslogtreecommitdiff
path: root/src/video_core/shader/ast.h
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2019-06-27 00:39:40 -0400
committerGravatar FernandoS272019-10-04 18:52:47 -0400
commitc17953978b16f82a3b2049f8b961275020c73dd0 (patch)
tree669f353dfa3e6a6198b404e326356ca1243a4e91 /src/video_core/shader/ast.h
parentMerge pull request #2941 from FernandoS27/fix-master (diff)
downloadyuzu-c17953978b16f82a3b2049f8b961275020c73dd0.tar.gz
yuzu-c17953978b16f82a3b2049f8b961275020c73dd0.tar.xz
yuzu-c17953978b16f82a3b2049f8b961275020c73dd0.zip
shader_ir: Initial Decompile Setup
Diffstat (limited to 'src/video_core/shader/ast.h')
-rw-r--r--src/video_core/shader/ast.h184
1 files changed, 184 insertions, 0 deletions
diff --git a/src/video_core/shader/ast.h b/src/video_core/shader/ast.h
new file mode 100644
index 000000000..ca71543fb
--- /dev/null
+++ b/src/video_core/shader/ast.h
@@ -0,0 +1,184 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <list>
8#include <memory>
9#include <optional>
10#include <string>
11#include <unordered_map>
12#include <vector>
13
14#include "video_core/shader/expr.h"
15#include "video_core/shader/node.h"
16
17namespace VideoCommon::Shader {
18
19class ASTBase;
20class ASTProgram;
21class ASTIf;
22class ASTBlockEncoded;
23class ASTVarSet;
24class ASTGoto;
25class ASTLabel;
26class ASTDoWhile;
27class ASTReturn;
28
29using ASTData = std::variant<ASTProgram, ASTIf, ASTBlockEncoded, ASTVarSet, ASTGoto, ASTLabel,
30 ASTDoWhile, ASTReturn>;
31
32using ASTNode = std::shared_ptr<ASTBase>;
33
34class ASTProgram {
35public:
36 ASTProgram() = default;
37 std::list<ASTNode> nodes;
38};
39
40class ASTIf {
41public:
42 ASTIf(Expr condition, std::list<ASTNode> then_nodes, std::list<ASTNode> else_nodes)
43 : condition(condition), then_nodes{then_nodes}, else_nodes{then_nodes} {}
44 Expr condition;
45 std::list<ASTNode> then_nodes;
46 std::list<ASTNode> else_nodes;
47};
48
49class ASTBlockEncoded {
50public:
51 ASTBlockEncoded(u32 start, u32 end) : start{start}, end{end} {}
52 u32 start;
53 u32 end;
54};
55
56class ASTVarSet {
57public:
58 ASTVarSet(u32 index, Expr condition) : index{index}, condition{condition} {}
59 u32 index;
60 Expr condition;
61};
62
63class ASTLabel {
64public:
65 ASTLabel(u32 index) : index{index} {}
66 u32 index;
67};
68
69class ASTGoto {
70public:
71 ASTGoto(Expr condition, u32 label) : condition{condition}, label{label} {}
72 Expr condition;
73 u32 label;
74};
75
76class ASTDoWhile {
77public:
78 ASTDoWhile(Expr condition, std::list<ASTNode> loop_nodes)
79 : condition(condition), loop_nodes{loop_nodes} {}
80 Expr condition;
81 std::list<ASTNode> loop_nodes;
82};
83
84class ASTReturn {
85public:
86 ASTReturn(Expr condition, bool kills) : condition{condition}, kills{kills} {}
87 Expr condition;
88 bool kills;
89};
90
91class ASTBase {
92public:
93 explicit ASTBase(ASTNode parent, ASTData data) : parent{parent}, data{data} {}
94
95 template <class U, class... Args>
96 static ASTNode Make(ASTNode parent, Args&&... args) {
97 return std::make_shared<ASTBase>(parent, ASTData(U(std::forward<Args>(args)...)));
98 }
99
100 void SetParent(ASTNode new_parent) {
101 parent = new_parent;
102 }
103
104 ASTNode& GetParent() {
105 return parent;
106 }
107
108 const ASTNode& GetParent() const {
109 return parent;
110 }
111
112 u32 GetLevel() const {
113 u32 level = 0;
114 auto next = parent;
115 while (next) {
116 next = next->GetParent();
117 level++;
118 }
119 return level;
120 }
121
122 ASTData* GetInnerData() {
123 return &data;
124 }
125
126private:
127 ASTData data;
128 ASTNode parent;
129};
130
131class ASTManager final {
132public:
133 explicit ASTManager() {
134 main_node = ASTBase::Make<ASTProgram>(nullptr);
135 program = std::get_if<ASTProgram>(main_node->GetInnerData());
136 }
137
138 void DeclareLabel(u32 address) {
139 const auto pair = labels_map.emplace(address, labels_count);
140 if (pair.second) {
141 labels_count++;
142 labels.resize(labels_count);
143 }
144 }
145
146 void InsertLabel(u32 address) {
147 u32 index = labels_map[address];
148 ASTNode label = ASTBase::Make<ASTLabel>(main_node, index);
149 labels[index] = label;
150 program->nodes.push_back(label);
151 }
152
153 void InsertGoto(Expr condition, u32 address) {
154 u32 index = labels_map[address];
155 ASTNode goto_node = ASTBase::Make<ASTGoto>(main_node, condition, index);
156 gotos.push_back(goto_node);
157 program->nodes.push_back(goto_node);
158 }
159
160 void InsertBlock(u32 start_address, u32 end_address) {
161 ASTNode block = ASTBase::Make<ASTBlockEncoded>(main_node, start_address, end_address);
162 program->nodes.push_back(block);
163 }
164
165 void InsertReturn(Expr condition, bool kills) {
166 ASTNode node = ASTBase::Make<ASTReturn>(main_node, condition, kills);
167 program->nodes.push_back(node);
168 }
169
170 std::string Print();
171
172 void Decompile() {}
173
174private:
175 std::unordered_map<u32, u32> labels_map{};
176 u32 labels_count{};
177 std::vector<ASTNode> labels{};
178 std::list<ASTNode> gotos{};
179 u32 variables{};
180 ASTProgram* program;
181 ASTNode main_node;
182};
183
184} // namespace VideoCommon::Shader