]> git.tdb.fi Git - libs/gl.git/blob - source/core/module.h
Move the Resource function override of Texture classes into backend
[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         };
111
112         enum BuiltinSemantic
113         {
114                 NOT_BUILTIN = -1,
115                 POSITION = 0,
116                 CLIP_DISTANCE = 3,
117                 LAYER = 9,
118                 FRAG_DEPTH = 22
119         };
120
121         struct Constant;
122         struct Structure;
123         struct Variable;
124
125         struct EntryPoint
126         {
127                 std::string name;
128                 Stage stage = VERTEX;
129                 std::vector<const Variable *> globals;
130         };
131
132         struct StructMember
133         {
134                 std::string name;
135                 DataType type = VOID;
136                 const Structure *struct_type = 0;
137                 unsigned offset = 0;
138                 unsigned array_size = 0;
139                 unsigned array_stride = 0;
140                 unsigned matrix_stride = 0;
141                 BuiltinSemantic builtin = NOT_BUILTIN;
142         };
143
144         struct Structure
145         {
146                 std::string name;
147                 std::vector<StructMember> members;
148                 unsigned size = 0;
149         };
150
151         struct Variable
152         {
153                 std::string name;
154                 StorageClass storage = static_cast<StorageClass>(-1);
155                 DataType type = VOID;
156                 const Structure *struct_type = 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                 unsigned array_size = 0;
184                 unsigned array_stride = 0;
185                 StorageClass storage = static_cast<StorageClass>(-1);
186         };
187
188         struct Reflection
189         {
190                 typedef std::vector<std::uint32_t>::const_iterator CodeIterator;
191
192                 std::map<unsigned, std::string> names;
193                 std::map<unsigned, Constant> constants;
194                 std::map<unsigned, TypeInfo> types;
195                 std::map<unsigned, EntryPoint> entry_points;
196                 std::map<unsigned, Structure> structs;
197                 std::map<unsigned, Variable> variables;
198
199                 static std::uint32_t get_opcode(std::uint32_t);
200                 static CodeIterator get_op_end(const CodeIterator &);
201                 static std::string read_string(CodeIterator &, const CodeIterator &);
202
203                 void reflect_code(const std::vector<std::uint32_t> &);
204                 void reflect_name(CodeIterator);
205                 void reflect_member_name(CodeIterator);
206                 void reflect_entry_point(CodeIterator);
207                 void reflect_void_type(CodeIterator);
208                 void reflect_bool_type(CodeIterator);
209                 void reflect_int_type(CodeIterator);
210                 void reflect_float_type(CodeIterator);
211                 void reflect_vector_type(CodeIterator);
212                 void reflect_matrix_type(CodeIterator);
213                 void reflect_image_type(CodeIterator);
214                 void reflect_sampled_image_type(CodeIterator);
215                 void reflect_array_type(CodeIterator);
216                 void reflect_struct_type(CodeIterator);
217                 void reflect_pointer_type(CodeIterator);
218                 void reflect_constant(CodeIterator);
219                 void reflect_variable(CodeIterator);
220                 void reflect_decorate(CodeIterator);
221                 void reflect_member_decorate(CodeIterator);
222         };
223
224         std::vector<std::uint32_t> code;
225         std::vector<EntryPoint> entry_points;
226         std::vector<Structure> structs;
227         std::vector<Variable> variables;
228         std::vector<Constant> spec_constants;
229
230 public:
231         SpirVModule() = default;
232         SpirVModule(const SpirVModule &);
233         SpirVModule &operator=(const SpirVModule &);
234 private:
235         void remap_pointers_from(const SpirVModule &);
236
237 public:
238         virtual Format get_format() const { return SPIR_V; }
239
240         /** Loads a SPIR-V binary from a file or other I/O object. */
241         void load_code(IO::Base &);
242 private:
243         virtual void compile(SL::Compiler &);
244         void reflect();
245
246 public:
247         const std::vector<std::uint32_t> &get_code() const { return code; }
248         const std::vector<EntryPoint> &get_entry_points() const { return entry_points; }
249         const std::vector<Variable> &get_variables() const { return variables; }
250         const std::vector<Constant> &get_spec_constants() const { return spec_constants; }
251 };
252
253 } // namespace GL
254 } // namespace Msp
255
256 #endif