• 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 // 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