1 // 2 // Copyright 2021 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // spirv_types.h: 7 // Strong types for SPIR-V Ids to prevent mistakes when using the builder and parser APIs. 8 // 9 10 #ifndef COMMON_SPIRV_TYPES_H_ 11 #define COMMON_SPIRV_TYPES_H_ 12 13 #include "common/FastVector.h" 14 15 #include <vector> 16 17 namespace angle 18 { 19 namespace spirv 20 { 21 template <typename Helper> 22 class BoxedUint32 23 { 24 public: BoxedUint32()25 BoxedUint32() : mValue{0} {} BoxedUint32(uint32_t value)26 explicit BoxedUint32(uint32_t value) : mValue{value} {} 27 template <typename T> as()28 T as() const 29 { 30 return T{mValue}; 31 } 32 BoxedUint32(const BoxedUint32 &other) = default; 33 BoxedUint32 &operator=(const BoxedUint32 &other) = default; uint32_t()34 operator uint32_t() const { return mValue.value; } 35 bool operator==(const BoxedUint32 &other) const { return mValue.value == other.mValue.value; } 36 // Applicable to ids, which cannot be 0. valid()37 bool valid() const { return static_cast<bool>(mValue.value); } 38 39 private: 40 Helper mValue; 41 }; 42 43 struct IdRefHelper 44 { 45 uint32_t value; 46 }; 47 struct LiteralIntegerHelper 48 { 49 uint32_t value; 50 }; 51 52 using IdRef = BoxedUint32<IdRefHelper>; 53 54 template <> uint32_t()55inline BoxedUint32<IdRefHelper>::operator uint32_t() const 56 { 57 ASSERT(valid()); 58 return mValue.value; 59 } 60 61 // IdResult, IdResultType, IdMemorySemantics and IdScope are all translated as IdRef. This makes 62 // the type verification weaker, but stops the API from becoming tediously verbose. 63 using IdResult = IdRef; 64 using IdResultType = IdRef; 65 using IdMemorySemantics = IdRef; 66 using IdScope = IdRef; 67 using LiteralInteger = BoxedUint32<LiteralIntegerHelper>; 68 using LiteralString = const char *; 69 // Note: In ANGLE's use cases, all literals fit in 32 bits. 70 using LiteralContextDependentNumber = LiteralInteger; 71 // TODO(syoussefi): To be made stronger when generating SPIR-V from the translator. 72 // http://anglebug.com/4889 73 using LiteralExtInstInteger = LiteralInteger; 74 75 struct PairLiteralIntegerIdRef 76 { 77 LiteralInteger literal; 78 IdRef id; 79 }; 80 81 struct PairIdRefLiteralInteger 82 { 83 IdRef id; 84 LiteralInteger literal; 85 }; 86 87 struct PairIdRefIdRef 88 { 89 IdRef id1; 90 IdRef id2; 91 }; 92 93 // Some instructions need 4 components. The drivers uniform struct in ANGLE has 8 fields. A value 94 // of 8 means almost no instruction would end up making dynamic allocations. Notable exceptions are 95 // user-defined structs/blocks and OpEntryPoint. 96 constexpr size_t kFastVectorSize = 8; 97 98 template <typename T> 99 using FastVectorHelper = angle::FastVector<T, kFastVectorSize>; 100 101 using IdRefList = FastVectorHelper<IdRef>; 102 using LiteralIntegerList = FastVectorHelper<LiteralInteger>; 103 using PairLiteralIntegerIdRefList = FastVectorHelper<PairLiteralIntegerIdRef>; 104 using PairIdRefLiteralIntegerList = FastVectorHelper<PairIdRefLiteralInteger>; 105 using PairIdRefIdRefList = FastVectorHelper<PairIdRefIdRef>; 106 107 // Id 0 is invalid in SPIR-V. 108 constexpr uint32_t kMinValidId = 1; 109 110 // The SPIR-V blob is a sequence of uint32_t's 111 using Blob = std::vector<uint32_t>; 112 113 // Returns whether SPIR-V is valid. Useful for ASSERTs. Automatically generates a warning if 114 // SPIR-V is not valid. 115 bool Validate(const Blob &blob); 116 117 } // namespace spirv 118 } // namespace angle 119 120 #endif // COMMON_SPIRV_TYPES_H_ 121