]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/generate.h
Limit GLSL passthrough statement to variables declared by that point
[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 private:
52         bool r_any_resolved;
53
54 public:
55         BlockHierarchyResolver(): r_any_resolved(false) { }
56
57         bool apply(Stage &s) { r_any_resolved = false; s.content.visit(*this); return r_any_resolved; }
58
59 private:
60         virtual void enter(Block &);
61 };
62
63 /** Resolves types of variables and base types of other types. */
64 class TypeResolver: private TraversingVisitor
65 {
66 private:
67         Stage *stage;
68         std::map<TypeDeclaration *, TypeDeclaration *> alias_map;
69         std::map<TypeDeclaration *, TypeDeclaration *> array_types;
70         NodeList<Statement>::iterator type_insert_point;
71         InterfaceBlock *iface_block;
72         bool r_any_resolved;
73
74 public:
75         TypeResolver();
76
77         bool apply(Stage &);
78
79 private:
80         TypeDeclaration *get_or_create_array_type(TypeDeclaration &);
81         void resolve_type(TypeDeclaration *&, const std::string &, bool);
82         virtual void visit(Block &);
83         virtual void visit(BasicTypeDeclaration &);
84         virtual void visit(ImageTypeDeclaration &);
85         virtual void visit(StructDeclaration &);
86         virtual void visit(VariableDeclaration &);
87         virtual void visit(InterfaceBlock &);
88         virtual void visit(FunctionDeclaration &);
89 };
90
91 /** Resolves variable references.  Variable references which match the name
92 of an interface block are turned into interface block references. */
93 class VariableResolver: private TraversingVisitor
94 {
95 private:
96         Stage *stage;
97         RefPtr<Expression> r_replacement_expr;
98         bool r_any_resolved;
99         bool record_target;
100         bool r_self_referencing;
101         Assignment::Target r_assignment_target;
102
103 public:
104         VariableResolver();
105
106         bool apply(Stage &);
107
108 private:
109         virtual void enter(Block &);
110         virtual void visit(RefPtr<Expression> &);
111         void check_assignment_target(Statement *);
112         virtual void visit(VariableReference &);
113         virtual void visit(InterfaceBlockReference &);
114         void add_to_chain(Assignment::Target::ChainType, unsigned);
115         virtual void visit(MemberAccess &);
116         virtual void visit(Swizzle &);
117         virtual void visit(BinaryExpression &);
118         virtual void visit(Assignment &);
119         virtual void visit(VariableDeclaration &);
120         virtual void visit(InterfaceBlock &);
121 };
122
123 /** Resolves types and lvalueness of expressions. */
124 class ExpressionResolver: private TraversingVisitor
125 {
126 private:
127         enum Compatibility
128         {
129                 NOT_COMPATIBLE,
130                 LEFT_CONVERTIBLE,
131                 RIGHT_CONVERTIBLE,
132                 SAME_TYPE
133         };
134
135         Stage *stage;
136         std::vector<BasicTypeDeclaration *> basic_types;
137         bool r_any_resolved;
138
139 public:
140         ExpressionResolver();
141
142         bool apply(Stage &);
143
144 private:
145         static bool is_scalar(BasicTypeDeclaration &);
146         static bool is_vector_or_matrix(BasicTypeDeclaration &);
147         static BasicTypeDeclaration *get_element_type(BasicTypeDeclaration &);
148         static bool can_convert(BasicTypeDeclaration &, BasicTypeDeclaration &);
149         static Compatibility get_compatibility(BasicTypeDeclaration &, BasicTypeDeclaration &);
150         BasicTypeDeclaration *find_type(BasicTypeDeclaration::Kind, unsigned);
151         BasicTypeDeclaration *find_type(BasicTypeDeclaration &, BasicTypeDeclaration::Kind, unsigned);
152         void convert_to(RefPtr<Expression> &, BasicTypeDeclaration &);
153         bool convert_to_element(RefPtr<Expression> &, BasicTypeDeclaration &);
154         void resolve(Expression &, TypeDeclaration *, bool);
155
156         virtual void visit(Literal &);
157         virtual void visit(ParenthesizedExpression &);
158         virtual void visit(VariableReference &);
159         virtual void visit(InterfaceBlockReference &);
160         virtual void visit(MemberAccess &);
161         virtual void visit(Swizzle &);
162         virtual void visit(UnaryExpression &);
163         void visit(BinaryExpression &, bool);
164         virtual void visit(BinaryExpression &);
165         virtual void visit(Assignment &);
166         virtual void visit(FunctionCall &);
167         virtual void visit(BasicTypeDeclaration &);
168         virtual void visit(VariableDeclaration &);
169 };
170
171 /** Resolves function declarations and calls. */
172 class FunctionResolver: private TraversingVisitor
173 {
174 private:
175         Stage *stage;
176         std::map<std::string, std::vector<FunctionDeclaration *> > declarations;
177         bool r_any_resolved;
178
179 public:
180         bool apply(Stage &);
181
182 private:
183         virtual void visit(FunctionCall &);
184         virtual void visit(FunctionDeclaration &);
185 };
186
187 /** Materializes implicitly declared interfaces.
188
189 Out variable declarations inside functions are moved to the global scope.
190
191 Passthrough statements are processed, generating out variables to match in
192 variables and copying values.
193
194 Unresolved variables are looked up in the previous stage's out variables. */
195 class InterfaceGenerator: private TraversingVisitor
196 {
197 private:
198         Stage *stage;
199         std::string in_prefix;
200         std::string out_prefix;
201         bool function_scope;
202         bool copy_block;
203         std::vector<VariableDeclaration *> declared_inputs;
204         Block *iface_target_block;
205         NodeList<Statement>::iterator iface_insert_point;
206         NodeList<Statement>::iterator assignment_insert_point;
207         std::set<Node *> nodes_to_remove;
208
209 public:
210         InterfaceGenerator();
211
212         void apply(Stage &);
213
214 private:
215         static std::string get_out_prefix(Stage::Type);
216         std::string change_prefix(const std::string &, const std::string &) const;
217         virtual void visit(Block &);
218         VariableDeclaration *generate_interface(VariableDeclaration &, const std::string &, const std::string &);
219         InterfaceBlock *generate_interface(InterfaceBlock &);
220         ExpressionStatement &insert_assignment(const std::string &, Expression *);
221         virtual void visit(VariableReference &);
222         virtual void visit(VariableDeclaration &);
223         virtual void visit(InterfaceBlock &);
224         virtual void visit(FunctionDeclaration &);
225         virtual void visit(Passthrough &);
226 };
227
228 } // namespace SL
229 } // namespace GL
230 } // namespace Msp
231
232 #endif