• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 constexpr BoxedUint32(uint32_t value) : mValue{value} {}
27     template <typename T>
as()28     constexpr T as() const
29     {
30         return static_cast<T>(mValue.value);
31     }
32     constexpr BoxedUint32(const BoxedUint32 &other)            = default;
33     constexpr BoxedUint32 &operator=(const BoxedUint32 &other) = default;
uint32_t()34     constexpr operator uint32_t() const { return mValue.value; }
35     constexpr bool operator==(const BoxedUint32 &other) const
36     {
37         return mValue.value == other.mValue.value;
38     }
39     constexpr bool operator!=(const BoxedUint32 &other) const
40     {
41         return mValue.value != other.mValue.value;
42     }
43     // Applicable to ids, which cannot be 0.
valid()44     constexpr bool valid() const { return static_cast<bool>(mValue.value); }
45 
46   private:
47     Helper mValue;
48 };
49 
50 struct IdRefHelper
51 {
52     uint32_t value;
53 };
54 struct LiteralIntegerHelper
55 {
56     uint32_t value;
57 };
58 
59 using IdRef = BoxedUint32<IdRefHelper>;
60 
61 template <>
uint32_t()62 inline constexpr BoxedUint32<IdRefHelper>::operator uint32_t() const
63 {
64     ASSERT(valid());
65     return mValue.value;
66 }
67 
68 // IdResult, IdResultType, IdMemorySemantics and IdScope are all translated as IdRef.  This makes
69 // the type verification weaker, but stops the API from becoming tediously verbose.
70 using IdResult          = IdRef;
71 using IdResultType      = IdRef;
72 using IdMemorySemantics = IdRef;
73 using IdScope           = IdRef;
74 using LiteralInteger    = BoxedUint32<LiteralIntegerHelper>;
75 using LiteralString     = const char *;
76 // Note: In ANGLE's use cases, all literals fit in 32 bits.
77 using LiteralContextDependentNumber = LiteralInteger;
78 // TODO(syoussefi): To be made stronger when generating SPIR-V from the translator.
79 // http://anglebug.com/40096715
80 using LiteralExtInstInteger = LiteralInteger;
81 
82 struct PairLiteralIntegerIdRef
83 {
84     LiteralInteger literal;
85     IdRef id;
86 };
87 
88 struct PairIdRefLiteralInteger
89 {
90     IdRef id;
91     LiteralInteger literal;
92 };
93 
94 struct PairIdRefIdRef
95 {
96     IdRef id1;
97     IdRef id2;
98 };
99 
100 // Some instructions need 4 components.  The drivers uniform struct in ANGLE has 8 fields.  A value
101 // of 8 means almost no instruction would end up making dynamic allocations.  Notable exceptions are
102 // user-defined structs/blocks and OpEntryPoint.
103 constexpr size_t kFastVectorSize = 8;
104 
105 template <typename T>
106 using FastVectorHelper = angle::FastVector<T, kFastVectorSize>;
107 
108 using IdRefList                   = FastVectorHelper<IdRef>;
109 using LiteralIntegerList          = FastVectorHelper<LiteralInteger>;
110 using PairLiteralIntegerIdRefList = FastVectorHelper<PairLiteralIntegerIdRef>;
111 using PairIdRefLiteralIntegerList = FastVectorHelper<PairIdRefLiteralInteger>;
112 using PairIdRefIdRefList          = FastVectorHelper<PairIdRefIdRef>;
113 
114 // Id 0 is invalid in SPIR-V.
115 constexpr uint32_t kMinValidId = 1;
116 
117 // The SPIR-V blob is a sequence of uint32_t's
118 using Blob = std::vector<uint32_t>;
119 
120 // Format of the SPIR-V header.
121 // SPIR-V 1.0 Table 1: First Words of Physical Layout
122 enum HeaderIndex
123 {
124     kHeaderIndexMagic        = 0,
125     kHeaderIndexVersion      = 1,
126     kHeaderIndexGenerator    = 2,
127     kHeaderIndexIndexBound   = 3,
128     kHeaderIndexSchema       = 4,
129     kHeaderIndexInstructions = 5,
130 };
131 
132 // SPIR-V version
133 constexpr uint32_t kVersion_1_0 = 0x00010000;
134 constexpr uint32_t kVersion_1_3 = 0x00010300;
135 constexpr uint32_t kVersion_1_4 = 0x00010400;
136 
137 // Returns whether SPIR-V is valid.  Useful for ASSERTs.  Automatically generates a warning if
138 // SPIR-V is not valid.
139 bool Validate(const Blob &blob);
140 void Print(const Blob &blob);
141 
142 }  // namespace spirv
143 }  // namespace angle
144 
145 #endif  // COMMON_SPIRV_TYPES_H_
146