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