]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/generate.h
ddf2b5f629cb0a8aadedd76dd0eab5041dfe1fa4
[libs/gl.git] / source / glsl / generate.h
1 #ifndef MSP_GL_SL_GENERATE_H_
2 #define MSP_GL_SL_GENERATE_H_
3
4 #include <map>
5 #include <set>
6 #include <string>
7 #include <vector>
8 #include "visitor.h"
9
10 namespace Msp {
11 namespace GL {
12 namespace SL {
13
14 /** Combines multiple declarations of the same identifier into one. */
15 class DeclarationCombiner: private TraversingVisitor
16 {
17 private:
18         std::map<std::string, std::vector<FunctionDeclaration *> > functions;
19         std::map<std::string, VariableDeclaration *> variables;
20         std::set<Node *> nodes_to_remove;
21
22 public:
23         void apply(Stage &);
24
25 private:
26         virtual void visit(Block &);
27         virtual void visit(VariableDeclaration &);
28         virtual void visit(FunctionDeclaration &) { }
29 };
30
31 /** Manipulates specialization constants.  If values are specified, turns
32 specialization constants into normal constants.  Without values assigns
33 automatic constant_ids to specialization constants. */
34 class ConstantSpecializer: private TraversingVisitor
35 {
36 private:
37         const std::map<std::string, int> *values;
38
39 public:
40         ConstantSpecializer();
41
42         void apply(Stage &, const std::map<std::string, int> *);
43
44 private:
45         virtual void visit(VariableDeclaration &);
46 };
47
48 /** Forms links between nested blocks in the syntax tree. */
49 class BlockHierarchyResolver: private TraversingVisitor
50 {
51 public:
52         void apply(Stage &s) { s.content.visit(*this); }
53
54 private:
55         virtual void enter(Block &);
56 };
57
58 /** Resolves types of variables and base types of other types. */
59 class TypeResolver: private TraversingVisitor
60 {
61 private:
62         Stage *stage;
63         std::map<TypeDeclaration *, TypeDeclaration *> alias_map;
64         std::map<TypeDeclaration *, TypeDeclaration *> array_types;
65         NodeList<Statement>::iterator type_insert_point;
66
67 public:
68         TypeResolver();
69
70         void apply(Stage &);
71
72 private:
73         TypeDeclaration *resolve_type(const std::string &);
74         virtual void visit(Block &);
75         virtual void visit(BasicTypeDeclaration &);
76         virtual void visit(ImageTypeDeclaration &);
77         virtual void visit(StructDeclaration &);
78         virtual void visit(VariableDeclaration &);
79         virtual void visit(FunctionDeclaration &);
80 };
81
82 /** Resolves variable references.  Variable references which match the name
83 of an interface block are turned into interface block references. */
84 class VariableResolver: private TraversingVisitor
85 {
86 private:
87         Stage *stage;
88         std::map<std::string, VariableDeclaration *> *r_members;
89         RefPtr<InterfaceBlockReference> r_iface_ref;
90         std::string block_interface;
91         bool record_target;
92         bool r_self_referencing;
93         VariableDeclaration *r_assignment_target;
94
95 public:
96         VariableResolver();
97
98         void apply(Stage &);
99
100 private:
101         virtual void enter(Block &);
102         virtual void visit(VariableReference &);
103         virtual void visit(InterfaceBlockReference &);
104         virtual void visit(MemberAccess &);
105         virtual void visit(UnaryExpression &);
106         virtual void visit(BinaryExpression &);
107         virtual void visit(Assignment &);
108         virtual void visit(FunctionCall &);
109         virtual void visit(VariableDeclaration &);
110         virtual void visit(InterfaceBlock &);
111 };
112
113 /** Resolves types and lvalueness of expressions. */
114 class ExpressionResolver: private TraversingVisitor
115 {
116 private:
117         enum Compatibility
118         {
119                 NOT_COMPATIBLE,
120                 LEFT_CONVERTIBLE,
121                 RIGHT_CONVERTIBLE,
122                 SAME_TYPE
123         };
124
125         Stage *stage;
126         std::vector<BasicTypeDeclaration *> basic_types;
127
128 public:
129         void apply(Stage &s) { stage = &s; s.content.visit(*this); }
130
131 private:
132         static bool is_scalar(BasicTypeDeclaration &);
133         static bool is_vector_or_matrix(BasicTypeDeclaration &);
134         static BasicTypeDeclaration *get_element_type(BasicTypeDeclaration &);
135         static bool can_convert(BasicTypeDeclaration &, BasicTypeDeclaration &);
136         static Compatibility get_compatibility(BasicTypeDeclaration &, BasicTypeDeclaration &);
137         BasicTypeDeclaration *find_type(BasicTypeDeclaration::Kind, unsigned);
138         BasicTypeDeclaration *find_type(BasicTypeDeclaration &, BasicTypeDeclaration::Kind, unsigned);
139         void convert_to(RefPtr<Expression> &, BasicTypeDeclaration &);
140         bool convert_to_element(RefPtr<Expression> &, BasicTypeDeclaration &);
141
142         virtual void visit(Literal &);
143         virtual void visit(ParenthesizedExpression &);
144         virtual void visit(VariableReference &);
145         virtual void visit(InterfaceBlockReference &);
146         virtual void visit(MemberAccess &);
147         virtual void visit(UnaryExpression &);
148         virtual void visit(BinaryExpression &);
149         virtual void visit(Assignment &);
150         virtual void visit(FunctionCall &);
151         virtual void visit(BasicTypeDeclaration &);
152         virtual void visit(VariableDeclaration &);
153 };
154
155 /** Resolves function declarations and calls. */
156 class FunctionResolver: private TraversingVisitor
157 {
158 private:
159         Stage *stage;
160         std::map<std::string, std::vector<FunctionDeclaration *> > declarations;
161
162 public:
163         void apply(Stage &);
164
165 private:
166         virtual void visit(FunctionCall &);
167         virtual void visit(FunctionDeclaration &);
168 };
169
170 /** Materializes implicitly declared interfaces.
171
172 Out variable declarations inside functions are moved to the global scope.
173
174 Passthrough statements are processed, generating out variables to match in
175 variables and copying values.
176
177 Unresolved variables are looked up in the previous stage's out variables. */
178 class InterfaceGenerator: private TraversingVisitor
179 {
180 private:
181         Stage *stage;
182         std::string in_prefix;
183         std::string out_prefix;
184         bool function_scope;
185         InterfaceBlock *iface_block;
186         bool copy_block;
187         Block *iface_target_block;
188         NodeList<Statement>::iterator iface_insert_point;
189         NodeList<Statement>::iterator assignment_insert_point;
190         std::set<Node *> nodes_to_remove;
191
192 public:
193         InterfaceGenerator();
194
195         void apply(Stage &);
196
197 private:
198         static std::string get_out_prefix(Stage::Type);
199         std::string change_prefix(const std::string &, const std::string &) const;
200         virtual void visit(Block &);
201         VariableDeclaration *generate_interface(VariableDeclaration &, const std::string &, const std::string &);
202         InterfaceBlock *generate_interface(InterfaceBlock &);
203         ExpressionStatement &insert_assignment(const std::string &, Expression *);
204         virtual void visit(VariableReference &);
205         virtual void visit(VariableDeclaration &);
206         virtual void visit(InterfaceBlock &);
207         virtual void visit(FunctionDeclaration &);
208         virtual void visit(Passthrough &);
209 };
210
211 } // namespace SL
212 } // namespace GL
213 } // namespace Msp
214
215 #endif