]> git.tdb.fi Git - libs/gl.git/blob - source/core/module.h
Always set uniform array size to at least one
[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                 const Constant *array_size_spec = 0;
138                 unsigned array_stride = 0;
139                 unsigned matrix_stride = 0;
140                 BuiltinSemantic builtin = NOT_BUILTIN;
141         };
142
143         struct Structure
144         {
145                 std::string name;
146                 std::vector<StructMember> members;
147                 unsigned size = 0;
148         };
149
150         struct Variable
151         {
152                 std::string name;
153                 StorageClass storage = static_cast<StorageClass>(-1);
154                 DataType type = VOID;
155                 const Structure *struct_type = 0;
156                 const Constant *array_size_spec = 0;
157                 unsigned array_size = 0;
158                 int location = -1;
159                 int descriptor_set = -1;
160                 int binding = -1;
161                 BuiltinSemantic builtin = NOT_BUILTIN;
162
163                 bool operator==(const Variable &) const;
164         };
165
166         struct Constant
167         {
168                 std::string name;
169                 int constant_id = -1;
170                 DataType type = VOID;
171                 union
172                 {
173                         int i_value = 0;
174                         float f_value;
175                 };
176         };
177
178 private:
179         struct TypeInfo
180         {
181                 DataType type = VOID;
182                 const Structure *struct_type = 0;
183                 const Constant *array_size_spec = 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