1 //
2 // Copyright 2017 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 // Compile-time instances of many common TType values. These are looked up
7 // (statically or dynamically) through the methods defined in the namespace.
8 //
9
10 #ifndef COMPILER_TRANSLATOR_STATIC_TYPE_H_
11 #define COMPILER_TRANSLATOR_STATIC_TYPE_H_
12
13 #include "compiler/translator/Types.h"
14
15 namespace sh
16 {
17
18 namespace StaticType
19 {
20
21 namespace Helpers
22 {
23
24 //
25 // Generation and static allocation of type mangled name values.
26 //
27
28 // Size of the constexpr-generated mangled name.
29 // If this value is too small, the compiler will produce errors.
30 static constexpr size_t kStaticMangledNameLength = TBasicMangledName::mangledNameSize + 1;
31
32 // Type which holds the mangled names for constexpr-generated TTypes.
33 // This simple struct is needed so that a char array can be returned by value.
34 struct StaticMangledName
35 {
36 // If this array is too small, the compiler will produce errors.
37 char name[kStaticMangledNameLength + 1] = {};
38 };
39
40 // Generates a mangled name for a TType given its parameters.
BuildStaticMangledName(TBasicType basicType,TPrecision precision,TQualifier qualifier,unsigned char primarySize,unsigned char secondarySize)41 constexpr StaticMangledName BuildStaticMangledName(TBasicType basicType,
42 TPrecision precision,
43 TQualifier qualifier,
44 unsigned char primarySize,
45 unsigned char secondarySize)
46 {
47 StaticMangledName name = {};
48 name.name[0] = TType::GetSizeMangledName(primarySize, secondarySize);
49 TBasicMangledName typeName(basicType);
50 char *mangledName = typeName.getName();
51 static_assert(TBasicMangledName::mangledNameSize == 2, "Mangled name size is not 2");
52 name.name[1] = mangledName[0];
53 name.name[2] = mangledName[1];
54 name.name[3] = '\0';
55 return name;
56 }
57
58 // Similar mangled name builder but for array types. Currently, only single-dimension arrays of
59 // single-digit size are necessary and supported.
60 static constexpr size_t kStaticArrayMangledNameLength = kStaticMangledNameLength + 2;
61 struct StaticArrayMangledName
62 {
63 char name[kStaticArrayMangledNameLength + 1] = {};
64 };
BuildStaticArrayMangledName(TBasicType basicType,TPrecision precision,TQualifier qualifier,unsigned char primarySize,unsigned char secondarySize,const unsigned int * arraySizes,size_t numArraySizes)65 constexpr StaticArrayMangledName BuildStaticArrayMangledName(TBasicType basicType,
66 TPrecision precision,
67 TQualifier qualifier,
68 unsigned char primarySize,
69 unsigned char secondarySize,
70 const unsigned int *arraySizes,
71 size_t numArraySizes)
72 {
73 StaticMangledName nonArrayName =
74 BuildStaticMangledName(basicType, precision, qualifier, primarySize, secondarySize);
75
76 StaticArrayMangledName arrayName = {};
77 static_assert(kStaticMangledNameLength == 3, "Static mangled name size is not 3");
78
79 arrayName.name[0] = nonArrayName.name[0];
80 arrayName.name[1] = nonArrayName.name[1];
81 arrayName.name[2] = nonArrayName.name[2];
82 arrayName.name[3] = 'x';
83 arrayName.name[4] = static_cast<char>('0' + arraySizes[0]);
84 arrayName.name[5] = '\0';
85 return arrayName;
86 }
87
88 // This "variable" contains the mangled names for every constexpr-generated TType.
89 // If kMangledNameInstance<B, P, Q, PS, SS> is used anywhere (specifally
90 // in instance, below), this is where the appropriate type will be stored.
91 template <TBasicType basicType,
92 TPrecision precision,
93 TQualifier qualifier,
94 unsigned char primarySize,
95 unsigned char secondarySize>
96 static constexpr StaticMangledName kMangledNameInstance =
97 BuildStaticMangledName(basicType, precision, qualifier, primarySize, secondarySize);
98
99 // Same as kMangledNameInstance, but for array types.
100 template <TBasicType basicType,
101 TPrecision precision,
102 TQualifier qualifier,
103 unsigned char primarySize,
104 unsigned char secondarySize,
105 const unsigned int *arraySizes,
106 size_t numArraySizes>
107 static constexpr StaticArrayMangledName kMangledNameArrayInstance =
108 BuildStaticArrayMangledName(basicType,
109 precision,
110 qualifier,
111 primarySize,
112 secondarySize,
113 arraySizes,
114 numArraySizes);
115
116 //
117 // Generation and static allocation of TType values.
118 //
119
120 // This "variable" contains every constexpr-generated TType.
121 // If instance<B, P, Q, PS, SS> is used anywhere (specifally
122 // in Get, below), this is where the appropriate type will be stored.
123 //
124 // TODO(crbug.com/981610): This is constexpr but doesn't follow the kConstant naming convention
125 // because TType has a mutable member that prevents it from being in .data.rel.ro and makes the
126 // Android Binary Size builder complain when ANGLE is rolled in Chromium.
127 template <TBasicType basicType,
128 TPrecision precision,
129 TQualifier qualifier,
130 unsigned char primarySize,
131 unsigned char secondarySize>
132 static constexpr TType instance =
133 TType(basicType,
134 precision,
135 qualifier,
136 primarySize,
137 secondarySize,
138 TSpan<const unsigned int>(),
139 kMangledNameInstance<basicType, precision, qualifier, primarySize, secondarySize>.name);
140
141 // Same as instance, but for array types.
142 template <TBasicType basicType,
143 TPrecision precision,
144 TQualifier qualifier,
145 unsigned char primarySize,
146 unsigned char secondarySize,
147 const unsigned int *arraySizes,
148 size_t numArraySizes>
149 static constexpr TType arrayInstance =
150 TType(basicType,
151 precision,
152 qualifier,
153 primarySize,
154 secondarySize,
155 TSpan<const unsigned int>(arraySizes, numArraySizes),
156 kMangledNameArrayInstance<basicType, precision, qualifier, primarySize, secondarySize, arraySizes, numArraySizes>.name);
157
158 } // namespace Helpers
159
160 //
161 // Fully-qualified type lookup.
162 //
163
164 template <TBasicType basicType,
165 TPrecision precision,
166 TQualifier qualifier,
167 unsigned char primarySize,
168 unsigned char secondarySize>
Get()169 constexpr const TType *Get()
170 {
171 static_assert(1 <= primarySize && primarySize <= 4, "primarySize out of bounds");
172 static_assert(1 <= secondarySize && secondarySize <= 4, "secondarySize out of bounds");
173 return &Helpers::instance<basicType, precision, qualifier, primarySize, secondarySize>;
174 }
175
176 template <TBasicType basicType,
177 TPrecision precision,
178 TQualifier qualifier,
179 unsigned char primarySize,
180 unsigned char secondarySize,
181 const unsigned int *arraySizes,
182 size_t numArraySizes>
GetArray()183 constexpr const TType *GetArray()
184 {
185 static_assert(1 <= primarySize && primarySize <= 4, "primarySize out of bounds");
186 static_assert(1 <= secondarySize && secondarySize <= 4, "secondarySize out of bounds");
187 static_assert(numArraySizes == 1, "only single-dimension static types are supported");
188 static_assert(arraySizes[0] < 10, "only single-digit dimensions are supported in static types");
189 return &Helpers::arrayInstance<basicType, precision, qualifier, primarySize, secondarySize,
190 arraySizes, numArraySizes>;
191 }
192
193 //
194 // Overloads
195 //
196
197 template <TBasicType basicType, unsigned char primarySize = 1, unsigned char secondarySize = 1>
GetBasic()198 constexpr const TType *GetBasic()
199 {
200 return Get<basicType, EbpUndefined, EvqGlobal, primarySize, secondarySize>();
201 }
202
203 template <TBasicType basicType,
204 TQualifier qualifier,
205 unsigned char primarySize = 1,
206 unsigned char secondarySize = 1>
GetQualified()207 const TType *GetQualified()
208 {
209 return Get<basicType, EbpUndefined, qualifier, primarySize, secondarySize>();
210 }
211
212 // Dynamic lookup methods (convert runtime values to template args)
213
214 namespace Helpers
215 {
216
217 // Helper which takes secondarySize statically but primarySize dynamically.
218 template <TBasicType basicType,
219 TPrecision precision,
220 TQualifier qualifier,
221 unsigned char secondarySize>
GetForVecMatHelper(unsigned char primarySize)222 constexpr const TType *GetForVecMatHelper(unsigned char primarySize)
223 {
224 static_assert(basicType == EbtFloat || basicType == EbtInt || basicType == EbtUInt ||
225 basicType == EbtBool,
226 "unsupported basicType");
227 switch (primarySize)
228 {
229 case 1:
230 return Get<basicType, precision, qualifier, 1, secondarySize>();
231 case 2:
232 return Get<basicType, precision, qualifier, 2, secondarySize>();
233 case 3:
234 return Get<basicType, precision, qualifier, 3, secondarySize>();
235 case 4:
236 return Get<basicType, precision, qualifier, 4, secondarySize>();
237 default:
238 UNREACHABLE();
239 return GetBasic<EbtVoid>();
240 }
241 }
242
243 } // namespace Helpers
244
245 template <TBasicType basicType,
246 TPrecision precision = EbpUndefined,
247 TQualifier qualifier = EvqGlobal>
248 constexpr const TType *GetForVecMat(unsigned char primarySize, unsigned char secondarySize = 1)
249 {
250 static_assert(basicType == EbtFloat || basicType == EbtInt || basicType == EbtUInt ||
251 basicType == EbtBool,
252 "unsupported basicType");
253 switch (secondarySize)
254 {
255 case 1:
256 return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 1>(primarySize);
257 case 2:
258 return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 2>(primarySize);
259 case 3:
260 return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 3>(primarySize);
261 case 4:
262 return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 4>(primarySize);
263 default:
264 UNREACHABLE();
265 return GetBasic<EbtVoid>();
266 }
267 }
268
269 template <TBasicType basicType, TPrecision precision = EbpUndefined>
GetForVec(TQualifier qualifier,unsigned char size)270 constexpr const TType *GetForVec(TQualifier qualifier, unsigned char size)
271 {
272 switch (qualifier)
273 {
274 case EvqGlobal:
275 return Helpers::GetForVecMatHelper<basicType, precision, EvqGlobal, 1>(size);
276 case EvqOut:
277 return Helpers::GetForVecMatHelper<basicType, precision, EvqOut, 1>(size);
278 default:
279 UNREACHABLE();
280 return GetBasic<EbtVoid>();
281 }
282 }
283
284 } // namespace StaticType
285
286 } // namespace sh
287
288 #endif // COMPILER_TRANSLATOR_STATIC_TYPE_H_
289