• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,
198           TPrecision precision,
199           unsigned char primarySize   = 1,
200           unsigned char secondarySize = 1>
GetBasic()201 constexpr const TType *GetBasic()
202 {
203     return Get<basicType, precision, EvqGlobal, primarySize, secondarySize>();
204 }
205 
206 template <TBasicType basicType,
207           TPrecision precision,
208           unsigned char primarySize   = 1,
209           unsigned char secondarySize = 1>
GetTemporary()210 constexpr const TType *GetTemporary()
211 {
212     return Get<basicType, precision, EvqTemporary, primarySize, secondarySize>();
213 }
214 
215 template <TBasicType basicType,
216           TPrecision precision,
217           TQualifier qualifier,
218           unsigned char primarySize   = 1,
219           unsigned char secondarySize = 1>
GetQualified()220 const TType *GetQualified()
221 {
222     return Get<basicType, precision, qualifier, primarySize, secondarySize>();
223 }
224 
225 // Dynamic lookup methods (convert runtime values to template args)
226 
227 namespace Helpers
228 {
229 
230 // Helper which takes secondarySize statically but primarySize dynamically.
231 template <TBasicType basicType,
232           TPrecision precision,
233           TQualifier qualifier,
234           unsigned char secondarySize>
GetForVecMatHelper(unsigned char primarySize)235 constexpr const TType *GetForVecMatHelper(unsigned char primarySize)
236 {
237     static_assert(basicType == EbtFloat || basicType == EbtInt || basicType == EbtUInt ||
238                       basicType == EbtBool,
239                   "unsupported basicType");
240     switch (primarySize)
241     {
242         case 1:
243             return Get<basicType, precision, qualifier, 1, secondarySize>();
244         case 2:
245             return Get<basicType, precision, qualifier, 2, secondarySize>();
246         case 3:
247             return Get<basicType, precision, qualifier, 3, secondarySize>();
248         case 4:
249             return Get<basicType, precision, qualifier, 4, secondarySize>();
250         default:
251             UNREACHABLE();
252             return GetBasic<EbtVoid, EbpUndefined>();
253     }
254 }
255 
256 }  // namespace Helpers
257 
258 template <TBasicType basicType, TPrecision precision, TQualifier qualifier = EvqGlobal>
259 constexpr const TType *GetForVecMat(unsigned char primarySize, unsigned char secondarySize = 1)
260 {
261     static_assert(basicType == EbtFloat || basicType == EbtInt || basicType == EbtUInt ||
262                       basicType == EbtBool,
263                   "unsupported basicType");
264     switch (secondarySize)
265     {
266         case 1:
267             return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 1>(primarySize);
268         case 2:
269             return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 2>(primarySize);
270         case 3:
271             return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 3>(primarySize);
272         case 4:
273             return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 4>(primarySize);
274         default:
275             UNREACHABLE();
276             return GetBasic<EbtVoid, EbpUndefined>();
277     }
278 }
279 
280 template <TBasicType basicType, TPrecision precision>
GetForVec(TQualifier qualifier,unsigned char size)281 constexpr const TType *GetForVec(TQualifier qualifier, unsigned char size)
282 {
283     switch (qualifier)
284     {
285         case EvqGlobal:
286             return Helpers::GetForVecMatHelper<basicType, precision, EvqGlobal, 1>(size);
287         case EvqParamOut:
288             return Helpers::GetForVecMatHelper<basicType, precision, EvqParamOut, 1>(size);
289         default:
290             UNREACHABLE();
291             return GetBasic<EbtVoid, EbpUndefined>();
292     }
293 }
294 
295 }  // namespace StaticType
296 
297 }  // namespace sh
298 
299 #endif  // COMPILER_TRANSLATOR_STATIC_TYPE_H_
300