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