]> git.tdb.fi Git - libs/gl.git/blob - source/core/module.h
Comment fixes
[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
66 /**
67 A shader module in GLSL source code format.
68 */
69 class GlslModule: public Module
70 {
71 private:
72         std::string prepared_source;
73         SL::SourceMap source_map;
74
75 public:
76         virtual Format get_format() const { return GLSL; }
77
78 private:
79         virtual void compile(SL::Compiler &);
80
81 public:
82         const std::string &get_prepared_source() const { return prepared_source; }
83         const SL::SourceMap &get_source_map() const { return source_map; }
84 };
85
86 /**
87 A shader module in SPIR-V binary format.
88
89 When the module's contents are set from GLSL source, it will be automatically
90 compiled to SPIR-V.  Pre-compiled SPIR-V modules can also be loaded.
91
92 Afterwards reflection data is available, providing information about variables
93 forming the module's interface.
94 */
95 class SpirVModule: public Module, public SpirVModuleBackend
96 {
97 public:
98         enum Stage
99         {
100                 VERTEX = 0,
101                 GEOMETRY = 3,
102                 FRAGMENT = 4
103         };
104
105         enum StorageClass
106         {
107                 UNIFORM_CONSTANT = 0,
108                 INPUT = 1,
109                 UNIFORM = 2,
110                 OUTPUT = 3,
111                 PUSH_CONSTANT = 9
112         };
113
114         enum BuiltinSemantic
115         {
116                 NOT_BUILTIN = -1,
117                 POSITION = 0,
118                 CLIP_DISTANCE = 3,
119                 LAYER = 9,
120                 FRAG_DEPTH = 22
121         };
122
123         struct Constant;
124         struct Structure;
125         struct Variable;
126
127         struct EntryPoint
128         {
129                 std::string name;
130                 Stage stage = VERTEX;
131                 std::vector<const Variable *> globals;
132         };
133
134         struct StructMember
135         {
136                 std::string name;
137                 DataType type = VOID;
138                 const Structure *struct_type = 0;
139                 unsigned offset = 0;
140                 unsigned array_size = 0;
141                 unsigned array_stride = 0;
142                 unsigned matrix_stride = 0;
143                 BuiltinSemantic builtin = NOT_BUILTIN;
144         };
145
146         struct Structure
147         {
148                 std::string name;
149                 std::vector<StructMember> members;
150                 unsigned size = 0;
151         };
152
153         struct Variable
154         {
155                 std::string name;
156                 StorageClass storage = static_cast<StorageClass>(-1);
157                 DataType type = VOID;
158                 const Structure *struct_type = 0;
159                 unsigned array_size = 0;
160                 int location = -1;
161                 unsigned descriptor_set = 0;
162                 int binding = -1;
163                 BuiltinSemantic builtin = NOT_BUILTIN;
164
165                 bool operator==(const Variable &) const;
166         };
167
168         struct Constant
169         {
170                 std::string name;
171                 int constant_id = -1;
172                 DataType type = VOID;
173                 union
174                 {
175                         int i_value = 0;
176                         float f_value;
177                 };
178         };
179
180         struct InstructionBlock
181         {
182                 const Constant *condition = 0;
183                 bool negate_condition = false;
184                 std::vector<const Variable *> accessed_variables;
185                 std::vector<const InstructionBlock *> successors;
186         };
187
188 private:
189         struct TypeInfo
190         {
191                 DataType type = VOID;
192                 const Structure *struct_type = 0;
193                 unsigned array_size = 0;
194                 unsigned array_stride = 0;
195                 StorageClass storage = static_cast<StorageClass>(-1);
196         };
197
198         struct Reflection
199         {
200                 typedef std::vector<std::uint32_t>::const_iterator CodeIterator;
201
202                 std::map<unsigned, std::string> names;
203                 std::map<unsigned, Constant> constants;
204                 std::map<unsigned, TypeInfo> types;
205                 std::map<unsigned, EntryPoint> entry_points;
206                 std::map<unsigned, Structure> structs;
207                 std::map<unsigned, Variable> variables;
208                 std::map<unsigned, InstructionBlock> blocks;
209                 std::map<unsigned, unsigned> access_chain_bases;
210                 Constant true_condition;
211                 InstructionBlock *current_block = 0;
212
213                 static std::uint32_t get_opcode(std::uint32_t);
214                 static CodeIterator get_op_end(const CodeIterator &);
215                 static std::string read_string(CodeIterator &, const CodeIterator &);
216
217                 void reflect_code(const std::vector<std::uint32_t> &);
218                 void reflect_name(CodeIterator);
219                 void reflect_member_name(CodeIterator);
220                 void reflect_entry_point(CodeIterator);
221                 void reflect_void_type(CodeIterator);
222                 void reflect_bool_type(CodeIterator);
223                 void reflect_int_type(CodeIterator);
224                 void reflect_float_type(CodeIterator);
225                 void reflect_vector_type(CodeIterator);
226                 void reflect_matrix_type(CodeIterator);
227                 void reflect_image_type(CodeIterator);
228                 void reflect_sampled_image_type(CodeIterator);
229                 void reflect_array_type(CodeIterator);
230                 void reflect_struct_type(CodeIterator);
231                 void reflect_pointer_type(CodeIterator);
232                 void reflect_constant(CodeIterator);
233                 void reflect_variable(CodeIterator);
234                 void reflect_access(CodeIterator);
235                 void reflect_access_chain(CodeIterator);
236                 void reflect_decorate(CodeIterator);
237                 void reflect_member_decorate(CodeIterator);
238                 void reflect_label(CodeIterator);
239                 void reflect_branch(CodeIterator);
240                 void reflect_branch_conditional(CodeIterator);
241         };
242
243         std::vector<std::uint32_t> code;
244         std::vector<EntryPoint> entry_points;
245         std::vector<Structure> structs;
246         std::vector<Variable> variables;
247         std::vector<Constant> spec_constants;
248         std::vector<InstructionBlock> blocks;
249
250 public:
251         virtual Format get_format() const { return SPIR_V; }
252
253         /** Loads a SPIR-V binary from a file or other I/O object. */
254         void load_code(IO::Base &);
255 private:
256         virtual void compile(SL::Compiler &);
257         void reflect();
258
259 public:
260         const std::vector<std::uint32_t> &get_code() const { return code; }
261         const std::vector<EntryPoint> &get_entry_points() const { return entry_points; }
262         const std::vector<Variable> &get_variables() const { return variables; }
263         const std::vector<Constant> &get_spec_constants() const { return spec_constants; }
264         const std::vector<InstructionBlock> &get_blocks() const { return blocks; }
265 };
266
267 } // namespace GL
268 } // namespace Msp
269
270 #endif