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 // This "variable" contains the mangled names for every constexpr-generated TType.
59 // If kMangledNameInstance<B, P, Q, PS, SS> is used anywhere (specifally
60 // in instance, below), this is where the appropriate type will be stored.
61 template <TBasicType basicType,
62 TPrecision precision,
63 TQualifier qualifier,
64 unsigned char primarySize,
65 unsigned char secondarySize>
66 static constexpr StaticMangledName kMangledNameInstance =
67 BuildStaticMangledName(basicType, precision, qualifier, primarySize, secondarySize);
68
69 //
70 // Generation and static allocation of TType values.
71 //
72
73 // This "variable" contains every constexpr-generated TType.
74 // If instance<B, P, Q, PS, SS> is used anywhere (specifally
75 // in Get, below), this is where the appropriate type will be stored.
76 //
77 // TODO(crbug.com/981610): This is constexpr but doesn't follow the kConstant naming convention
78 // because TType has a mutable member that prevents it from being in .data.rel.ro and makes the
79 // Android Binary Size builder complain when ANGLE is rolled in Chromium.
80 template <TBasicType basicType,
81 TPrecision precision,
82 TQualifier qualifier,
83 unsigned char primarySize,
84 unsigned char secondarySize>
85 static constexpr TType instance =
86 TType(basicType,
87 precision,
88 qualifier,
89 primarySize,
90 secondarySize,
91 kMangledNameInstance<basicType, precision, qualifier, primarySize, secondarySize>.name);
92
93 } // namespace Helpers
94
95 //
96 // Fully-qualified type lookup.
97 //
98
99 template <TBasicType basicType,
100 TPrecision precision,
101 TQualifier qualifier,
102 unsigned char primarySize,
103 unsigned char secondarySize>
Get()104 constexpr const TType *Get()
105 {
106 static_assert(1 <= primarySize && primarySize <= 4, "primarySize out of bounds");
107 static_assert(1 <= secondarySize && secondarySize <= 4, "secondarySize out of bounds");
108 return &Helpers::instance<basicType, precision, qualifier, primarySize, secondarySize>;
109 }
110
111 //
112 // Overloads
113 //
114
115 template <TBasicType basicType, unsigned char primarySize = 1, unsigned char secondarySize = 1>
GetBasic()116 constexpr const TType *GetBasic()
117 {
118 return Get<basicType, EbpUndefined, EvqGlobal, primarySize, secondarySize>();
119 }
120
121 template <TBasicType basicType,
122 TQualifier qualifier,
123 unsigned char primarySize = 1,
124 unsigned char secondarySize = 1>
GetQualified()125 const TType *GetQualified()
126 {
127 return Get<basicType, EbpUndefined, qualifier, primarySize, secondarySize>();
128 }
129
130 // Dynamic lookup methods (convert runtime values to template args)
131
132 namespace Helpers
133 {
134
135 // Helper which takes secondarySize statically but primarySize dynamically.
136 template <TBasicType basicType,
137 TPrecision precision,
138 TQualifier qualifier,
139 unsigned char secondarySize>
GetForVecMatHelper(unsigned char primarySize)140 constexpr const TType *GetForVecMatHelper(unsigned char primarySize)
141 {
142 static_assert(basicType == EbtFloat || basicType == EbtInt || basicType == EbtUInt ||
143 basicType == EbtBool,
144 "unsupported basicType");
145 switch (primarySize)
146 {
147 case 1:
148 return Get<basicType, precision, qualifier, 1, secondarySize>();
149 case 2:
150 return Get<basicType, precision, qualifier, 2, secondarySize>();
151 case 3:
152 return Get<basicType, precision, qualifier, 3, secondarySize>();
153 case 4:
154 return Get<basicType, precision, qualifier, 4, secondarySize>();
155 default:
156 UNREACHABLE();
157 return GetBasic<EbtVoid>();
158 }
159 }
160
161 } // namespace Helpers
162
163 template <TBasicType basicType,
164 TPrecision precision = EbpUndefined,
165 TQualifier qualifier = EvqGlobal>
166 constexpr const TType *GetForVecMat(unsigned char primarySize, unsigned char secondarySize = 1)
167 {
168 static_assert(basicType == EbtFloat || basicType == EbtInt || basicType == EbtUInt ||
169 basicType == EbtBool,
170 "unsupported basicType");
171 switch (secondarySize)
172 {
173 case 1:
174 return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 1>(primarySize);
175 case 2:
176 return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 2>(primarySize);
177 case 3:
178 return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 3>(primarySize);
179 case 4:
180 return Helpers::GetForVecMatHelper<basicType, precision, qualifier, 4>(primarySize);
181 default:
182 UNREACHABLE();
183 return GetBasic<EbtVoid>();
184 }
185 }
186
187 template <TBasicType basicType, TPrecision precision = EbpUndefined>
GetForVec(TQualifier qualifier,unsigned char size)188 constexpr const TType *GetForVec(TQualifier qualifier, unsigned char size)
189 {
190 switch (qualifier)
191 {
192 case EvqGlobal:
193 return Helpers::GetForVecMatHelper<basicType, precision, EvqGlobal, 1>(size);
194 case EvqOut:
195 return Helpers::GetForVecMatHelper<basicType, precision, EvqOut, 1>(size);
196 default:
197 UNREACHABLE();
198 return GetBasic<EbtVoid>();
199 }
200 }
201
202 } // namespace StaticType
203
204 } // namespace sh
205
206 #endif // COMPILER_TRANSLATOR_STATIC_TYPE_H_
207