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