]> git.tdb.fi Git - libs/gl.git/blob - source/glsl/finalize.h
Check the flat qualifier from the correct member
[libs/gl.git] / source / glsl / finalize.h
1 #ifndef MSP_GL_SL_FINALIZE_H_
2 #define MSP_GL_SL_FINALIZE_H_
3
4 #include <string>
5 #include "visitor.h"
6
7 namespace Msp {
8 namespace GL {
9 namespace SL {
10
11 /** Assigns offset layout qualifiers to struct members. */
12 class StructOrganizer: private TraversingVisitor
13 {
14 private:
15         int offset = -1;
16
17 public:
18         void apply(Stage &s) { s.content.visit(*this); }
19
20 private:
21         virtual void visit(StructDeclaration &);
22         virtual void visit(VariableDeclaration &);
23 };
24
25 /** Assigns location and binding layout qualifiers to interface variables and
26 blocks. */
27 class LocationAllocator: private TraversingVisitor
28 {
29 private:
30         struct Uniform
31         {
32                 int location = -1;
33                 int desc_set = 0;
34                 int bind_point = -1;
35         };
36
37         Features features;
38         bool alloc_new = true;
39         std::map<std::string, std::set<unsigned> > used_locations;
40         std::map<std::string, Uniform> uniforms;
41         std::map<unsigned, std::set<unsigned> > used_bindings;
42         std::vector<VariableDeclaration *> unplaced_variables;
43         std::vector<VariableDeclaration *> unbound_textures;
44         std::vector<VariableDeclaration *> unbound_blocks;
45
46         /* Dirty hack to work around an issue where vertex attributes prevent the
47         flat qualifier from working on the same location. */
48         std::set<unsigned> used_vertex_attribs;
49
50 public:
51         void apply(Module &, const Features &, bool = true);
52 private:
53         void apply(Stage &);
54
55         void allocate_locations(const std::string &);
56         void bind_uniform(RefPtr<Layout> &, const std::string &, unsigned);
57
58         bool visit_uniform(const std::string &, RefPtr<Layout> &);
59         virtual void visit(VariableDeclaration &);
60         virtual void visit(FunctionDeclaration &) { }
61 };
62
63 /**
64 Converts the output depth range to match expectations of the target API.
65 */
66 class DepthRangeConverter: private TraversingVisitor
67 {
68 private:
69         bool assignment_target = false;
70         bool r_gl_pervertex = false;
71         bool r_gl_position = false;
72         bool r_position_z_assigned = false;
73
74 public:
75         void apply(Stage &, const Features &);
76
77 private:
78         virtual void visit(VariableReference &);
79         virtual void visit(MemberAccess &);
80         virtual void visit(Swizzle &);
81         virtual void visit(Assignment &);
82         virtual void visit(FunctionDeclaration &);
83 };
84
85 /** Generates default precision declarations or removes precision declarations
86 according to the requirements of the target API. */
87 class PrecisionConverter: private TraversingVisitor
88 {
89 private:
90         Stage *stage = 0;
91         std::set<std::string> have_default;
92         NodeList<Statement>::iterator insert_point;
93         std::set<Node *> nodes_to_remove;
94
95 public:
96         void apply(Stage &);
97
98 private:
99         virtual void visit(Block &);
100         virtual void visit(Precision &);
101         virtual void visit(VariableDeclaration &);
102 };
103
104 /** Base class for feature converters. */
105 class FeatureConverter: protected TraversingVisitor
106 {
107 protected:
108         Stage *stage = 0;
109         Features features;
110
111         FeatureConverter() = default;
112
113 public:
114         void apply(Stage &, const Features &);
115 protected:
116         virtual void apply() = 0;
117
118         void unsupported(const std::string &);
119
120         bool check_version(const Version &) const;
121         bool check_extension(bool Features::*) const;
122 };
123
124 /** Converts structures of the syntax tree to match a particular set of
125 features. */
126 class StructuralFeatureConverter: public FeatureConverter
127 {
128 private:
129         VariableDeclaration *frag_out = 0;
130         NodeList<Statement>::iterator uniform_insert_point;
131         std::set<Node *> nodes_to_remove;
132         RefPtr<Expression> r_replaced_reference;
133         bool r_flattened_interface = false;
134
135 public:
136         void apply(Stage &s, const Features &f) { FeatureConverter::apply(s, f); }
137 private:
138         virtual void apply();
139
140         virtual void visit(Block &);
141         virtual void visit(RefPtr<Expression> &);
142         bool supports_stage(Stage::Type) const;
143         bool supports_unified_interface_syntax() const;
144         virtual void visit(VariableReference &);
145         virtual void visit(MemberAccess &);
146         virtual void visit(Assignment &);
147         bool supports_unified_sampling_functions() const;
148         virtual void visit(FunctionCall &);
149         bool supports_interface_blocks(const std::string &) const;
150         virtual void visit(VariableDeclaration &);
151 };
152
153 /** Converts qualifiers on variables and blocksto match a particular set of
154 features. */
155 class QualifierConverter: private FeatureConverter
156 {
157 public:
158         void apply(Stage &s, const Features &f) { FeatureConverter::apply(s, f); }
159 private:
160         virtual void apply();
161
162         bool supports_interface_layouts() const;
163         bool supports_stage_interface_layouts() const;
164         bool supports_centroid_sampling() const;
165         bool supports_sample_sampling() const;
166         bool supports_uniform_location() const;
167         bool supports_binding() const;
168         bool supports_interface_block_location() const;
169         virtual void visit(VariableDeclaration &);
170 };
171
172 } // namespace SL
173 } // namespace GL
174 } // namespace Msp
175
176 #endif