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