• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SRC_READER_SPIRV_PARSER_TYPE_H_
16 #define SRC_READER_SPIRV_PARSER_TYPE_H_
17 
18 #include <memory>
19 #include <string>
20 #include <vector>
21 
22 #include "src/ast/access.h"
23 #include "src/ast/sampler.h"
24 #include "src/ast/storage_class.h"
25 #include "src/ast/storage_texture.h"
26 #include "src/ast/texture.h"
27 #include "src/block_allocator.h"
28 #include "src/castable.h"
29 
30 // Forward declarations
31 namespace tint {
32 class ProgramBuilder;
33 namespace ast {
34 class Type;
35 }  // namespace ast
36 }  // namespace tint
37 
38 namespace tint {
39 namespace reader {
40 namespace spirv {
41 
42 /// Type is the base class for all types
43 class Type : public Castable<Type> {
44  public:
45   /// @param b the ProgramBuilder used to construct the AST types
46   /// @returns the constructed ast::Type node for the given type
47   virtual const ast::Type* Build(ProgramBuilder& b) const = 0;
48 
49   /// @returns the inner most store type if this is a pointer, `this` otherwise
50   const Type* UnwrapPtr() const;
51 
52   /// @returns the inner most store type if this is a reference, `this`
53   /// otherwise
54   const Type* UnwrapRef() const;
55 
56   /// @returns the inner most aliased type if this is an alias, `this` otherwise
57   const Type* UnwrapAlias() const;
58 
59   /// @returns the type with all aliasing, access control and pointers removed
60   const Type* UnwrapAll() const;
61 
62   /// @returns true if this type is a float scalar
63   bool IsFloatScalar() const;
64   /// @returns true if this type is a float scalar or vector
65   bool IsFloatScalarOrVector() const;
66   /// @returns true if this type is a float vector
67   bool IsFloatVector() const;
68   /// @returns true if this type is an integer scalar
69   bool IsIntegerScalar() const;
70   /// @returns true if this type is an integer scalar or vector
71   bool IsIntegerScalarOrVector() const;
72   /// @returns true if this type is a scalar
73   bool IsScalar() const;
74   /// @returns true if this type is a signed integer vector
75   bool IsSignedIntegerVector() const;
76   /// @returns true if this type is a signed scalar or vector
77   bool IsSignedScalarOrVector() const;
78   /// @returns true if this type is an unsigned integer vector
79   bool IsUnsignedIntegerVector() const;
80   /// @returns true if this type is an unsigned scalar or vector
81   bool IsUnsignedScalarOrVector() const;
82 
83 #ifdef NDEBUG
84   /// @returns "<no-type-info>", for debug purposes only
String()85   std::string String() const { return "<no-type-info>"; }
86 #else
87   /// @returns a string representation of the type, for debug purposes only
88   virtual std::string String() const = 0;
89 #endif  // NDEBUG
90 };
91 
92 using TypeList = std::vector<const Type*>;
93 
94 /// `void` type
95 struct Void : public Castable<Void, Type> {
96   /// @param b the ProgramBuilder used to construct the AST types
97   /// @returns the constructed ast::Type node for the given type
98   const ast::Type* Build(ProgramBuilder& b) const override;
99 
100 #ifndef NDEBUG
101   /// @returns a string representation of the type, for debug purposes only
102   std::string String() const override;
103 #endif  // NDEBUG
104 };
105 
106 /// `bool` type
107 struct Bool : public Castable<Bool, Type> {
108   /// @param b the ProgramBuilder used to construct the AST types
109   /// @returns the constructed ast::Type node for the given type
110   const ast::Type* Build(ProgramBuilder& b) const override;
111 
112 #ifndef NDEBUG
113   /// @returns a string representation of the type, for debug purposes only
114   std::string String() const override;
115 #endif  // NDEBUG
116 };
117 
118 /// `u32` type
119 struct U32 : public Castable<U32, Type> {
120   /// @param b the ProgramBuilder used to construct the AST types
121   /// @returns the constructed ast::Type node for the given type
122   const ast::Type* Build(ProgramBuilder& b) const override;
123 
124 #ifndef NDEBUG
125   /// @returns a string representation of the type, for debug purposes only
126   std::string String() const override;
127 #endif  // NDEBUG
128 };
129 
130 /// `f32` type
131 struct F32 : public Castable<F32, Type> {
132   /// @param b the ProgramBuilder used to construct the AST types
133   /// @returns the constructed ast::Type node for the given type
134   const ast::Type* Build(ProgramBuilder& b) const override;
135 
136 #ifndef NDEBUG
137   /// @returns a string representation of the type, for debug purposes only
138   std::string String() const override;
139 #endif  // NDEBUG
140 };
141 
142 /// `i32` type
143 struct I32 : public Castable<I32, Type> {
144   /// @param b the ProgramBuilder used to construct the AST types
145   /// @returns the constructed ast::Type node for the given type
146   const ast::Type* Build(ProgramBuilder& b) const override;
147 
148 #ifndef NDEBUG
149   /// @returns a string representation of the type, for debug purposes only
150   std::string String() const override;
151 #endif  // NDEBUG
152 };
153 
154 /// `ptr<SC, T>` type
155 struct Pointer : public Castable<Pointer, Type> {
156   /// Constructor
157   /// @param ty the store type
158   /// @param sc the pointer storage class
159   Pointer(const Type* ty, ast::StorageClass sc);
160 
161   /// Copy constructor
162   /// @param other the other type to copy
163   Pointer(const Pointer& other);
164 
165   /// @param b the ProgramBuilder used to construct the AST types
166   /// @returns the constructed ast::Type node for the given type
167   const ast::Type* Build(ProgramBuilder& b) const override;
168 
169 #ifndef NDEBUG
170   /// @returns a string representation of the type, for debug purposes only
171   std::string String() const override;
172 #endif  // NDEBUG
173 
174   /// the store type
175   Type const* const type;
176   /// the pointer storage class
177   ast::StorageClass const storage_class;
178 };
179 
180 /// `ref<SC, T>` type
181 /// Note this has no AST representation, but is used for type tracking in the
182 /// reader.
183 struct Reference : public Castable<Reference, Type> {
184   /// Constructor
185   /// @param ty the referenced type
186   /// @param sc the reference storage class
187   Reference(const Type* ty, ast::StorageClass sc);
188 
189   /// Copy constructor
190   /// @param other the other type to copy
191   Reference(const Reference& other);
192 
193   /// @param b the ProgramBuilder used to construct the AST types
194   /// @returns the constructed ast::Type node for the given type
195   const ast::Type* Build(ProgramBuilder& b) const override;
196 
197 #ifndef NDEBUG
198   /// @returns a string representation of the type, for debug purposes only
199   std::string String() const override;
200 #endif  // NDEBUG
201 
202   /// the store type
203   Type const* const type;
204   /// the pointer storage class
205   ast::StorageClass const storage_class;
206 };
207 
208 /// `vecN<T>` type
209 struct Vector : public Castable<Vector, Type> {
210   /// Constructor
211   /// @param ty the element type
212   /// @param sz the number of elements in the vector
213   Vector(const Type* ty, uint32_t sz);
214 
215   /// Copy constructor
216   /// @param other the other type to copy
217   Vector(const Vector& other);
218 
219   /// @param b the ProgramBuilder used to construct the AST types
220   /// @returns the constructed ast::Type node for the given type
221   const ast::Type* Build(ProgramBuilder& b) const override;
222 
223 #ifndef NDEBUG
224   /// @returns a string representation of the type, for debug purposes only
225   std::string String() const override;
226 #endif  // NDEBUG
227 
228   /// the element type
229   Type const* const type;
230   /// the number of elements in the vector
231   const uint32_t size;
232 };
233 
234 /// `matNxM<T>` type
235 struct Matrix : public Castable<Matrix, Type> {
236   /// Constructor
237   /// @param ty the matrix element type
238   /// @param c the number of columns in the matrix
239   /// @param r the number of rows in the matrix
240   Matrix(const Type* ty, uint32_t c, uint32_t r);
241 
242   /// Copy constructor
243   /// @param other the other type to copy
244   Matrix(const Matrix& other);
245 
246   /// @param b the ProgramBuilder used to construct the AST types
247   /// @returns the constructed ast::Type node for the given type
248   const ast::Type* Build(ProgramBuilder& b) const override;
249 
250 #ifndef NDEBUG
251   /// @returns a string representation of the type, for debug purposes only
252   std::string String() const override;
253 #endif  // NDEBUG
254 
255   /// the matrix element type
256   Type const* const type;
257   /// the number of columns in the matrix
258   const uint32_t columns;
259   /// the number of rows in the matrix
260   const uint32_t rows;
261 };
262 
263 /// `array<T, N>` type
264 struct Array : public Castable<Array, Type> {
265   /// Constructor
266   /// @param el the element type
267   /// @param sz the number of elements in the array. 0 represents runtime-sized
268   /// array.
269   /// @param st the byte stride of the array. 0 means use implicit stride.
270   Array(const Type* el, uint32_t sz, uint32_t st);
271 
272   /// Copy constructor
273   /// @param other the other type to copy
274   Array(const Array& other);
275 
276   /// @param b the ProgramBuilder used to construct the AST types
277   /// @returns the constructed ast::Type node for the given type
278   const ast::Type* Build(ProgramBuilder& b) const override;
279 
280 #ifndef NDEBUG
281   /// @returns a string representation of the type, for debug purposes only
282   std::string String() const override;
283 #endif  // NDEBUG
284 
285   /// the element type
286   Type const* const type;
287   /// the number of elements in the array. 0 represents runtime-sized array.
288   const uint32_t size;
289   /// the byte stride of the array
290   const uint32_t stride;
291 };
292 
293 /// `sampler` type
294 struct Sampler : public Castable<Sampler, Type> {
295   /// Constructor
296   /// @param k the sampler kind
297   explicit Sampler(ast::SamplerKind k);
298 
299   /// Copy constructor
300   /// @param other the other type to copy
301   Sampler(const Sampler& other);
302 
303   /// @param b the ProgramBuilder used to construct the AST types
304   /// @returns the constructed ast::Type node for the given type
305   const ast::Type* Build(ProgramBuilder& b) const override;
306 
307 #ifndef NDEBUG
308   /// @returns a string representation of the type, for debug purposes only
309   std::string String() const override;
310 #endif  // NDEBUG
311 
312   /// the sampler kind
313   ast::SamplerKind const kind;
314 };
315 
316 /// Base class for texture types
317 struct Texture : public Castable<Texture, Type> {
318   /// Constructor
319   /// @param d the texture dimensions
320   explicit Texture(ast::TextureDimension d);
321 
322   /// Copy constructor
323   /// @param other the other type to copy
324   Texture(const Texture& other);
325 
326   /// the texture dimensions
327   ast::TextureDimension const dims;
328 };
329 
330 /// `texture_depth_D` type
331 struct DepthTexture : public Castable<DepthTexture, Texture> {
332   /// Constructor
333   /// @param d the texture dimensions
334   explicit DepthTexture(ast::TextureDimension d);
335 
336   /// Copy constructor
337   /// @param other the other type to copy
338   DepthTexture(const DepthTexture& other);
339 
340   /// @param b the ProgramBuilder used to construct the AST types
341   /// @returns the constructed ast::Type node for the given type
342   const ast::Type* Build(ProgramBuilder& b) const override;
343 
344 #ifndef NDEBUG
345   /// @returns a string representation of the type, for debug purposes only
346   std::string String() const override;
347 #endif  // NDEBUG
348 };
349 
350 /// `texture_depth_multisampled_D` type
351 struct DepthMultisampledTexture
352     : public Castable<DepthMultisampledTexture, Texture> {
353   /// Constructor
354   /// @param d the texture dimensions
355   explicit DepthMultisampledTexture(ast::TextureDimension d);
356 
357   /// Copy constructor
358   /// @param other the other type to copy
359   DepthMultisampledTexture(const DepthMultisampledTexture& other);
360 
361   /// @param b the ProgramBuilder used to construct the AST types
362   /// @returns the constructed ast::Type node for the given type
363   const ast::Type* Build(ProgramBuilder& b) const override;
364 
365 #ifndef NDEBUG
366   /// @returns a string representation of the type, for debug purposes only
367   std::string String() const override;
368 #endif  // NDEBUG
369 };
370 
371 /// `texture_multisampled_D<T>` type
372 struct MultisampledTexture : public Castable<MultisampledTexture, Texture> {
373   /// Constructor
374   /// @param d the texture dimensions
375   /// @param t the multisampled texture type
376   MultisampledTexture(ast::TextureDimension d, const Type* t);
377 
378   /// Copy constructor
379   /// @param other the other type to copy
380   MultisampledTexture(const MultisampledTexture& other);
381 
382   /// @param b the ProgramBuilder used to construct the AST types
383   /// @returns the constructed ast::Type node for the given type
384   const ast::Type* Build(ProgramBuilder& b) const override;
385 
386 #ifndef NDEBUG
387   /// @returns a string representation of the type, for debug purposes only
388   std::string String() const override;
389 #endif  // NDEBUG
390 
391   /// the multisampled texture type
392   Type const* const type;
393 };
394 
395 /// `texture_D<T>` type
396 struct SampledTexture : public Castable<SampledTexture, Texture> {
397   /// Constructor
398   /// @param d the texture dimensions
399   /// @param t the sampled texture type
400   SampledTexture(ast::TextureDimension d, const Type* t);
401 
402   /// Copy constructor
403   /// @param other the other type to copy
404   SampledTexture(const SampledTexture& other);
405 
406   /// @param b the ProgramBuilder used to construct the AST types
407   /// @returns the constructed ast::Type node for the given type
408   const ast::Type* Build(ProgramBuilder& b) const override;
409 
410 #ifndef NDEBUG
411   /// @returns a string representation of the type, for debug purposes only
412   std::string String() const override;
413 #endif  // NDEBUG
414 
415   /// the sampled texture type
416   Type const* const type;
417 };
418 
419 /// `texture_storage_D<F>` type
420 struct StorageTexture : public Castable<StorageTexture, Texture> {
421   /// Constructor
422   /// @param d the texture dimensions
423   /// @param f the storage image format
424   /// @param a the access control
425   StorageTexture(ast::TextureDimension d, ast::ImageFormat f, ast::Access a);
426 
427   /// Copy constructor
428   /// @param other the other type to copy
429   StorageTexture(const StorageTexture& other);
430 
431   /// @param b the ProgramBuilder used to construct the AST types
432   /// @returns the constructed ast::Type node for the given type
433   const ast::Type* Build(ProgramBuilder& b) const override;
434 
435 #ifndef NDEBUG
436   /// @returns a string representation of the type, for debug purposes only
437   std::string String() const override;
438 #endif  // NDEBUG
439 
440   /// the storage image format
441   ast::ImageFormat const format;
442 
443   /// the access control
444   ast::Access const access;
445 };
446 
447 /// Base class for named types
448 struct Named : public Castable<Named, Type> {
449   /// Constructor
450   /// @param n the type name
451   explicit Named(Symbol n);
452 
453   /// Copy constructor
454   /// @param other the other type to copy
455   Named(const Named& other);
456 
457   /// Destructor
458   ~Named() override;
459 
460 #ifndef NDEBUG
461   /// @returns a string representation of the type, for debug purposes only
462   std::string String() const override;
463 #endif  // NDEBUG
464 
465   /// the type name
466   const Symbol name;
467 };
468 
469 /// `type T = N` type
470 struct Alias : public Castable<Alias, Named> {
471   /// Constructor
472   /// @param n the alias name
473   /// @param t the aliased type
474   Alias(Symbol n, const Type* t);
475 
476   /// Copy constructor
477   /// @param other the other type to copy
478   Alias(const Alias& other);
479 
480   /// @param b the ProgramBuilder used to construct the AST types
481   /// @returns the constructed ast::Type node for the given type
482   const ast::Type* Build(ProgramBuilder& b) const override;
483 
484   /// the aliased type
485   Type const* const type;
486 };
487 
488 /// `struct N { ... };` type
489 struct Struct : public Castable<Struct, Named> {
490   /// Constructor
491   /// @param n the struct name
492   /// @param m the member types
493   Struct(Symbol n, TypeList m);
494 
495   /// Copy constructor
496   /// @param other the other type to copy
497   Struct(const Struct& other);
498 
499   /// Destructor
500   ~Struct() override;
501 
502   /// @param b the ProgramBuilder used to construct the AST types
503   /// @returns the constructed ast::Type node for the given type
504   const ast::Type* Build(ProgramBuilder& b) const override;
505 
506   /// the member types
507   const TypeList members;
508 };
509 
510 /// A manager of types
511 class TypeManager {
512  public:
513   /// Constructor
514   TypeManager();
515 
516   /// Destructor
517   ~TypeManager();
518 
519   /// @return a Void type. Repeated calls will return the same pointer.
520   const spirv::Void* Void();
521   /// @return a Bool type. Repeated calls will return the same pointer.
522   const spirv::Bool* Bool();
523   /// @return a U32 type. Repeated calls will return the same pointer.
524   const spirv::U32* U32();
525   /// @return a F32 type. Repeated calls will return the same pointer.
526   const spirv::F32* F32();
527   /// @return a I32 type. Repeated calls will return the same pointer.
528   const spirv::I32* I32();
529   /// @param ty the store type
530   /// @param sc the pointer storage class
531   /// @return a Pointer type. Repeated calls with the same arguments will return
532   /// the same pointer.
533   const spirv::Pointer* Pointer(const Type* ty, ast::StorageClass sc);
534   /// @param ty the referenced type
535   /// @param sc the reference storage class
536   /// @return a Reference type. Repeated calls with the same arguments will
537   /// return the same pointer.
538   const spirv::Reference* Reference(const Type* ty, ast::StorageClass sc);
539   /// @param ty the element type
540   /// @param sz the number of elements in the vector
541   /// @return a Vector type. Repeated calls with the same arguments will return
542   /// the same pointer.
543   const spirv::Vector* Vector(const Type* ty, uint32_t sz);
544   /// @param ty the matrix element type
545   /// @param c the number of columns in the matrix
546   /// @param r the number of rows in the matrix
547   /// @return a Matrix type. Repeated calls with the same arguments will return
548   /// the same pointer.
549   const spirv::Matrix* Matrix(const Type* ty, uint32_t c, uint32_t r);
550   /// @param el the element type
551   /// @param sz the number of elements in the array. 0 represents runtime-sized
552   /// array.
553   /// @param st the byte stride of the array
554   /// @return a Array type. Repeated calls with the same arguments will return
555   /// the same pointer.
556   const spirv::Array* Array(const Type* el, uint32_t sz, uint32_t st);
557   /// @param n the alias name
558   /// @param t the aliased type
559   /// @return a Alias type. Repeated calls with the same arguments will return
560   /// the same pointer.
561   const spirv::Alias* Alias(Symbol n, const Type* t);
562   /// @param n the struct name
563   /// @param m the member types
564   /// @return a Struct type. Repeated calls with the same arguments will return
565   /// the same pointer.
566   const spirv::Struct* Struct(Symbol n, TypeList m);
567   /// @param k the sampler kind
568   /// @return a Sampler type. Repeated calls with the same arguments will return
569   /// the same pointer.
570   const spirv::Sampler* Sampler(ast::SamplerKind k);
571   /// @param d the texture dimensions
572   /// @return a DepthTexture type. Repeated calls with the same arguments will
573   /// return the same pointer.
574   const spirv::DepthTexture* DepthTexture(ast::TextureDimension d);
575   /// @param d the texture dimensions
576   /// @return a DepthMultisampledTexture type. Repeated calls with the same
577   /// arguments will return the same pointer.
578   const spirv::DepthMultisampledTexture* DepthMultisampledTexture(
579       ast::TextureDimension d);
580   /// @param d the texture dimensions
581   /// @param t the multisampled texture type
582   /// @return a MultisampledTexture type. Repeated calls with the same arguments
583   /// will return the same pointer.
584   const spirv::MultisampledTexture* MultisampledTexture(ast::TextureDimension d,
585                                                         const Type* t);
586   /// @param d the texture dimensions
587   /// @param t the sampled texture type
588   /// @return a SampledTexture type. Repeated calls with the same arguments will
589   /// return the same pointer.
590   const spirv::SampledTexture* SampledTexture(ast::TextureDimension d,
591                                               const Type* t);
592   /// @param d the texture dimensions
593   /// @param f the storage image format
594   /// @param a the access control
595   /// @return a StorageTexture type. Repeated calls with the same arguments will
596   /// return the same pointer.
597   const spirv::StorageTexture* StorageTexture(ast::TextureDimension d,
598                                               ast::ImageFormat f,
599                                               ast::Access a);
600 
601  private:
602   struct State;
603   std::unique_ptr<State> state;
604 };
605 
606 }  // namespace spirv
607 }  // namespace reader
608 }  // namespace tint
609 
610 #endif  // SRC_READER_SPIRV_PARSER_TYPE_H_
611