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