]> git.tdb.fi Git - libs/gl.git/blob - source/core/module.h
Check the flat qualifier from the correct member
[libs/gl.git] / source / core / module.h
1 #ifndef MSP_GL_MODULE_H_
2 #define MSP_GL_MODULE_H_
3
4 #include <map>
5 #include <string>
6 #include <vector>
7 #include <msp/io/base.h>
8 #include "datatype.h"
9 #include "module_backend.h"
10 #include "glsl/compiler.h"
11 #include "glsl/sourcemap.h"
12
13 namespace Msp {
14 namespace GL {
15
16 class invalid_module: public std::runtime_error
17 {
18 public:
19         invalid_module(const std::string &w): runtime_error(w) { }
20         virtual ~invalid_module() throw() { }
21 };
22
23 class Resources;
24
25 /**
26 Base class for shader modules.  Internal representation depends on the
27 concrete type.
28
29 Modules can be loaded from files.
30
31 Applications normally use the Program class to access shaders.
32 */
33 class Module
34 {
35 public:
36         enum Format
37         {
38                 GLSL,
39                 SPIR_V
40         };
41
42 protected:
43         Module() = default;
44 public:
45         virtual ~Module() = default;
46
47         virtual Format get_format() const = 0;
48
49         /** Sets the module's content from GLSL source code. */
50         void set_source(const std::string &);
51
52         /** Loads GLSL source from a file or other I/O object.  Any import
53         statements are resolved using res. */
54         void load_source(IO::Base &, Resources *res, const std::string &name);
55
56         /** Loads GLSL source from a file or other I/O object.  Only builtin
57         shader fragments can be imported. */
58         void load_source(IO::Base &, const std::string &);
59
60 private:
61         virtual void compile(SL::Compiler &) = 0;
62
63         SL::Features create_features() const;
64
65 public:
66         virtual void set_debug_name(const std::string &) { }
67 };
68
69 /**
70 A shader module in GLSL source code format.
71 */
72 class GlslModule: public Module
73 {
74 private:
75         std::string prepared_source;
76         SL::SourceMap source_map;
77
78 public:
79         virtual Format get_format() const { return GLSL; }
80
81 private:
82         virtual void compile(SL::Compiler &);
83
84 public:
85         const std::string &get_prepared_source() const { return prepared_source; }
86         const SL::SourceMap &get_source_map() const { return source_map; }
87 };
88
89 /**
90 A shader module in SPIR-V binary format.
91
92 When the module's contents are set from GLSL source, it will be automatically
93 compiled to SPIR-V.  Pre-compiled SPIR-V modules can also be loaded.
94
95 Afterwards reflection data is available, providing information about variables
96 forming the module's interface.
97 */
98 class SpirVModule: public Module, public SpirVModuleBackend
99 {
100         friend SpirVModuleBackend;
101
102 public:
103         enum Stage
104         {
105                 VERTEX = 0,
106                 GEOMETRY = 3,
107                 FRAGMENT = 4
108         };
109
110         enum StorageClass
111         {
112                 UNIFORM_CONSTANT = 0,
113                 INPUT = 1,
114                 UNIFORM = 2,
115                 OUTPUT = 3,
116                 PUSH_CONSTANT = 9
117         };
118
119         enum BuiltinSemantic
120         {
121                 NOT_BUILTIN = -1,
122                 POSITION = 0,
123                 CLIP_DISTANCE = 3,
124                 LAYER = 9,
125                 FRAG_DEPTH = 22
126         };
127
128         struct Constant;
129         struct Structure;
130         struct Variable;
131
132         struct EntryPoint
133         {
134                 std::string name;
135                 unsigned id = 0;
136                 Stage stage = VERTEX;
137                 std::vector<const Variable *> globals;
138         };
139
140         struct StructMember
141         {
142                 std::string name;
143                 DataType type = VOID;
144                 const Structure *struct_type = 0;
145                 unsigned offset = 0;
146                 unsigned array_size = 0;
147                 unsigned array_stride = 0;
148                 unsigned matrix_stride = 0;
149                 BuiltinSemantic builtin = NOT_BUILTIN;
150         };
151
152         struct Structure
153         {
154                 std::string name;
155                 unsigned id = 0;
156                 unsigned size = 0;
157                 std::vector<StructMember> members;
158         };
159
160         struct Variable
161         {
162                 std::string name;
163                 unsigned id = 0;
164                 DataType type = VOID;
165                 const Structure *struct_type = 0;
166                 StorageClass storage = static_cast<StorageClass>(-1);
167                 unsigned array_size = 0;
168                 int location = -1;
169                 unsigned descriptor_set = 0;
170                 int binding = -1;
171                 BuiltinSemantic builtin = NOT_BUILTIN;
172
173                 bool operator==(const Variable &) const;
174         };
175
176         struct Constant
177         {
178                 std::string name;
179                 unsigned id = 0;
180                 int constant_id = -1;
181                 DataType type = VOID;
182                 union
183                 {
184                         int i_value = 0;
185                         float f_value;
186                 };
187         };
188
189         struct InstructionBlock
190         {
191                 unsigned id = 0;
192                 bool negate_condition = false;
193                 const Constant *condition = 0;
194                 std::vector<const Variable *> accessed_variables;
195                 std::vector<const InstructionBlock *> successors;
196         };
197
198 private:
199         struct TypeInfo
200         {
201                 DataType type = VOID;
202                 const Structure *struct_type = 0;
203                 unsigned array_size = 0;
204                 unsigned array_stride = 0;
205                 StorageClass storage = static_cast<StorageClass>(-1);
206         };
207
208         struct Reflection
209         {
210                 typedef std::vector<std::uint32_t>::const_iterator CodeIterator;
211
212                 std::map<unsigned, std::string> names;
213                 std::map<unsigned, Constant> constants;
214                 std::map<unsigned, TypeInfo> types;
215                 std::map<unsigned, EntryPoint> entry_points;
216                 std::map<unsigned, Structure> structs;
217                 std::map<unsigned, Variable> variables;
218                 std::map<unsigned, InstructionBlock> blocks;
219                 std::map<unsigned, unsigned> access_chain_bases;
220                 Constant true_condition;
221                 InstructionBlock *current_block = 0;
222
223                 static std::uint32_t get_opcode(std::uint32_t);
224                 static CodeIterator get_op_end(const CodeIterator &);
225                 static std::string read_string(CodeIterator &, const CodeIterator &);
226
227                 void reflect_code(const std::vector<std::uint32_t> &);
228                 void reflect_name(CodeIterator);
229                 void reflect_member_name(CodeIterator);
230                 void reflect_entry_point(CodeIterator);
231                 void reflect_void_type(CodeIterator);
232                 void reflect_bool_type(CodeIterator);
233                 void reflect_int_type(CodeIterator);
234                 void reflect_float_type(CodeIterator);
235                 void reflect_vector_type(CodeIterator);
236                 void reflect_matrix_type(CodeIterator);
237                 void reflect_image_type(CodeIterator);
238                 void reflect_sampled_image_type(CodeIterator);
239                 void reflect_array_type(CodeIterator);
240                 void reflect_struct_type(CodeIterator);
241                 void reflect_pointer_type(CodeIterator);
242                 void reflect_constant(CodeIterator);
243                 void reflect_variable(CodeIterator);
244                 void reflect_access(CodeIterator);
245                 void reflect_access_chain(CodeIterator);
246                 void reflect_decorate(CodeIterator);
247                 void reflect_member_decorate(CodeIterator);
248                 void reflect_label(CodeIterator);
249                 void reflect_branch(CodeIterator);
250                 void reflect_branch_conditional(CodeIterator);
251         };
252
253         std::vector<std::uint32_t> code;
254         std::vector<EntryPoint> entry_points;
255         std::vector<Structure> structs;
256         std::vector<Variable> variables;
257         std::vector<Constant> spec_constants;
258         std::vector<InstructionBlock> blocks;
259         bool specializable = false;
260
261 public:
262         virtual Format get_format() const { return SPIR_V; }
263
264         /** Loads a SPIR-V binary from a file or other I/O object. */
265         void load_code(IO::Base &);
266 private:
267         virtual void compile(SL::Compiler &);
268         void reflect();
269
270 public:
271         const std::vector<std::uint32_t> &get_code() const { return code; }
272         const std::vector<EntryPoint> &get_entry_points() const { return entry_points; }
273         const std::vector<Variable> &get_variables() const { return variables; }
274         const std::vector<Constant> &get_spec_constants() const { return spec_constants; }
275         const std::vector<InstructionBlock> &get_blocks() const { return blocks; }
276         bool is_specializable() const { return specializable; }
277
278         /** Creates a new module which is a specialized version of this one. */
279         SpirVModule *specialize(const std::map<std::string, int> &) const;
280
281 private:
282         std::vector<const InstructionBlock *> collect_visited_blocks(const std::map<unsigned, int> &) const;
283         void collect_visited_blocks(unsigned, std::vector<std::uint8_t> &) const;
284
285 public:
286         void set_debug_name(const std::string &n) { SpirVModuleBackend::set_debug_name(n); }
287 };
288
289 } // namespace GL
290 } // namespace Msp
291
292 #endif