xref: /aosp_15_r20/external/angle/src/compiler/translator/util.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2010 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/util.h"
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include <limits>
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #include "common/utilities.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "compiler/preprocessor/numeric_lex.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/ImmutableStringBuilder.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/SymbolTable.h"
15*8975f5c5SAndroid Build Coastguard Worker 
atoi_clamp(const char * str,unsigned int * value)16*8975f5c5SAndroid Build Coastguard Worker bool atoi_clamp(const char *str, unsigned int *value)
17*8975f5c5SAndroid Build Coastguard Worker {
18*8975f5c5SAndroid Build Coastguard Worker     bool success = angle::pp::numeric_lex_int(str, value);
19*8975f5c5SAndroid Build Coastguard Worker     if (!success)
20*8975f5c5SAndroid Build Coastguard Worker         *value = std::numeric_limits<unsigned int>::max();
21*8975f5c5SAndroid Build Coastguard Worker     return success;
22*8975f5c5SAndroid Build Coastguard Worker }
23*8975f5c5SAndroid Build Coastguard Worker 
24*8975f5c5SAndroid Build Coastguard Worker namespace sh
25*8975f5c5SAndroid Build Coastguard Worker {
26*8975f5c5SAndroid Build Coastguard Worker 
27*8975f5c5SAndroid Build Coastguard Worker namespace
28*8975f5c5SAndroid Build Coastguard Worker {
29*8975f5c5SAndroid Build Coastguard Worker // [primarySize-1][secondarySize-1] is the GL type with a basic type of float.
30*8975f5c5SAndroid Build Coastguard Worker constexpr GLenum kFloatGLType[4][4] = {
31*8975f5c5SAndroid Build Coastguard Worker     // float1xS only makes sense for S == 1
32*8975f5c5SAndroid Build Coastguard Worker     {
33*8975f5c5SAndroid Build Coastguard Worker         GL_FLOAT,
34*8975f5c5SAndroid Build Coastguard Worker         GL_NONE,
35*8975f5c5SAndroid Build Coastguard Worker         GL_NONE,
36*8975f5c5SAndroid Build Coastguard Worker         GL_NONE,
37*8975f5c5SAndroid Build Coastguard Worker     },
38*8975f5c5SAndroid Build Coastguard Worker     // float2xS is vec2 for S == 1, and mat2xS o.w.
39*8975f5c5SAndroid Build Coastguard Worker     {
40*8975f5c5SAndroid Build Coastguard Worker         GL_FLOAT_VEC2,
41*8975f5c5SAndroid Build Coastguard Worker         GL_FLOAT_MAT2,
42*8975f5c5SAndroid Build Coastguard Worker         GL_FLOAT_MAT2x3,
43*8975f5c5SAndroid Build Coastguard Worker         GL_FLOAT_MAT2x4,
44*8975f5c5SAndroid Build Coastguard Worker     },
45*8975f5c5SAndroid Build Coastguard Worker     // float3xS is vec3 for S == 1, and mat3xS o.w.
46*8975f5c5SAndroid Build Coastguard Worker     {
47*8975f5c5SAndroid Build Coastguard Worker         GL_FLOAT_VEC3,
48*8975f5c5SAndroid Build Coastguard Worker         GL_FLOAT_MAT3x2,
49*8975f5c5SAndroid Build Coastguard Worker         GL_FLOAT_MAT3,
50*8975f5c5SAndroid Build Coastguard Worker         GL_FLOAT_MAT3x4,
51*8975f5c5SAndroid Build Coastguard Worker     },
52*8975f5c5SAndroid Build Coastguard Worker     // float4xS is vec4 for S == 1, and mat4xS o.w.
53*8975f5c5SAndroid Build Coastguard Worker     {
54*8975f5c5SAndroid Build Coastguard Worker         GL_FLOAT_VEC4,
55*8975f5c5SAndroid Build Coastguard Worker         GL_FLOAT_MAT4x2,
56*8975f5c5SAndroid Build Coastguard Worker         GL_FLOAT_MAT4x3,
57*8975f5c5SAndroid Build Coastguard Worker         GL_FLOAT_MAT4,
58*8975f5c5SAndroid Build Coastguard Worker     },
59*8975f5c5SAndroid Build Coastguard Worker };
60*8975f5c5SAndroid Build Coastguard Worker // [primarySize-1] is the GL type with a basic type of int.
61*8975f5c5SAndroid Build Coastguard Worker constexpr GLenum kIntGLType[4] = {GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4};
62*8975f5c5SAndroid Build Coastguard Worker // [primarySize-1] is the GL type with a basic type of uint.
63*8975f5c5SAndroid Build Coastguard Worker constexpr GLenum kUIntGLType[4] = {GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3,
64*8975f5c5SAndroid Build Coastguard Worker                                    GL_UNSIGNED_INT_VEC4};
65*8975f5c5SAndroid Build Coastguard Worker // [primarySize-1] is the GL type with a basic type of bool.
66*8975f5c5SAndroid Build Coastguard Worker constexpr GLenum kBoolGLType[4] = {GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4};
67*8975f5c5SAndroid Build Coastguard Worker 
IsInterpolationIn(TQualifier qualifier)68*8975f5c5SAndroid Build Coastguard Worker bool IsInterpolationIn(TQualifier qualifier)
69*8975f5c5SAndroid Build Coastguard Worker {
70*8975f5c5SAndroid Build Coastguard Worker     switch (qualifier)
71*8975f5c5SAndroid Build Coastguard Worker     {
72*8975f5c5SAndroid Build Coastguard Worker         case EvqSmoothIn:
73*8975f5c5SAndroid Build Coastguard Worker         case EvqFlatIn:
74*8975f5c5SAndroid Build Coastguard Worker         case EvqNoPerspectiveIn:
75*8975f5c5SAndroid Build Coastguard Worker         case EvqCentroidIn:
76*8975f5c5SAndroid Build Coastguard Worker         case EvqSampleIn:
77*8975f5c5SAndroid Build Coastguard Worker         case EvqNoPerspectiveCentroidIn:
78*8975f5c5SAndroid Build Coastguard Worker         case EvqNoPerspectiveSampleIn:
79*8975f5c5SAndroid Build Coastguard Worker             return true;
80*8975f5c5SAndroid Build Coastguard Worker         default:
81*8975f5c5SAndroid Build Coastguard Worker             return false;
82*8975f5c5SAndroid Build Coastguard Worker     }
83*8975f5c5SAndroid Build Coastguard Worker }
84*8975f5c5SAndroid Build Coastguard Worker 
IsInterpolationOut(TQualifier qualifier)85*8975f5c5SAndroid Build Coastguard Worker bool IsInterpolationOut(TQualifier qualifier)
86*8975f5c5SAndroid Build Coastguard Worker {
87*8975f5c5SAndroid Build Coastguard Worker     switch (qualifier)
88*8975f5c5SAndroid Build Coastguard Worker     {
89*8975f5c5SAndroid Build Coastguard Worker         case EvqSmoothOut:
90*8975f5c5SAndroid Build Coastguard Worker         case EvqFlatOut:
91*8975f5c5SAndroid Build Coastguard Worker         case EvqNoPerspectiveOut:
92*8975f5c5SAndroid Build Coastguard Worker         case EvqCentroidOut:
93*8975f5c5SAndroid Build Coastguard Worker         case EvqSampleOut:
94*8975f5c5SAndroid Build Coastguard Worker         case EvqNoPerspectiveCentroidOut:
95*8975f5c5SAndroid Build Coastguard Worker         case EvqNoPerspectiveSampleOut:
96*8975f5c5SAndroid Build Coastguard Worker             return true;
97*8975f5c5SAndroid Build Coastguard Worker         default:
98*8975f5c5SAndroid Build Coastguard Worker             return false;
99*8975f5c5SAndroid Build Coastguard Worker     }
100*8975f5c5SAndroid Build Coastguard Worker }
101*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
102*8975f5c5SAndroid Build Coastguard Worker 
NumericLexFloat32OutOfRangeToInfinity(const std::string & str)103*8975f5c5SAndroid Build Coastguard Worker float NumericLexFloat32OutOfRangeToInfinity(const std::string &str)
104*8975f5c5SAndroid Build Coastguard Worker {
105*8975f5c5SAndroid Build Coastguard Worker     // Parses a decimal string using scientific notation into a floating point number.
106*8975f5c5SAndroid Build Coastguard Worker     // Out-of-range values are converted to infinity. Values that are too small to be
107*8975f5c5SAndroid Build Coastguard Worker     // represented are converted to zero.
108*8975f5c5SAndroid Build Coastguard Worker 
109*8975f5c5SAndroid Build Coastguard Worker     // The mantissa in decimal scientific notation. The magnitude of the mantissa integer does not
110*8975f5c5SAndroid Build Coastguard Worker     // matter.
111*8975f5c5SAndroid Build Coastguard Worker     unsigned int decimalMantissa = 0;
112*8975f5c5SAndroid Build Coastguard Worker     size_t i                     = 0;
113*8975f5c5SAndroid Build Coastguard Worker     bool decimalPointSeen        = false;
114*8975f5c5SAndroid Build Coastguard Worker     bool nonZeroSeenInMantissa   = false;
115*8975f5c5SAndroid Build Coastguard Worker 
116*8975f5c5SAndroid Build Coastguard Worker     // The exponent offset reflects the position of the decimal point.
117*8975f5c5SAndroid Build Coastguard Worker     int exponentOffset = -1;
118*8975f5c5SAndroid Build Coastguard Worker 
119*8975f5c5SAndroid Build Coastguard Worker     // This is just a counter for how many decimal digits are written to decimalMantissa.
120*8975f5c5SAndroid Build Coastguard Worker     int mantissaDecimalDigits = 0;
121*8975f5c5SAndroid Build Coastguard Worker 
122*8975f5c5SAndroid Build Coastguard Worker     while (i < str.length())
123*8975f5c5SAndroid Build Coastguard Worker     {
124*8975f5c5SAndroid Build Coastguard Worker         const char c = str[i];
125*8975f5c5SAndroid Build Coastguard Worker         if (c == 'e' || c == 'E')
126*8975f5c5SAndroid Build Coastguard Worker         {
127*8975f5c5SAndroid Build Coastguard Worker             break;
128*8975f5c5SAndroid Build Coastguard Worker         }
129*8975f5c5SAndroid Build Coastguard Worker         if (c == '.')
130*8975f5c5SAndroid Build Coastguard Worker         {
131*8975f5c5SAndroid Build Coastguard Worker             decimalPointSeen = true;
132*8975f5c5SAndroid Build Coastguard Worker             ++i;
133*8975f5c5SAndroid Build Coastguard Worker             continue;
134*8975f5c5SAndroid Build Coastguard Worker         }
135*8975f5c5SAndroid Build Coastguard Worker 
136*8975f5c5SAndroid Build Coastguard Worker         unsigned int digit = static_cast<unsigned int>(c - '0');
137*8975f5c5SAndroid Build Coastguard Worker         ASSERT(digit < 10u);
138*8975f5c5SAndroid Build Coastguard Worker         if (digit != 0u)
139*8975f5c5SAndroid Build Coastguard Worker         {
140*8975f5c5SAndroid Build Coastguard Worker             nonZeroSeenInMantissa = true;
141*8975f5c5SAndroid Build Coastguard Worker         }
142*8975f5c5SAndroid Build Coastguard Worker         if (nonZeroSeenInMantissa)
143*8975f5c5SAndroid Build Coastguard Worker         {
144*8975f5c5SAndroid Build Coastguard Worker             // Add bits to the mantissa until space runs out in 32-bit int. This should be
145*8975f5c5SAndroid Build Coastguard Worker             // enough precision to make the resulting binary mantissa accurate to 1 ULP.
146*8975f5c5SAndroid Build Coastguard Worker             if (decimalMantissa <= (std::numeric_limits<unsigned int>::max() - 9u) / 10u)
147*8975f5c5SAndroid Build Coastguard Worker             {
148*8975f5c5SAndroid Build Coastguard Worker                 decimalMantissa = decimalMantissa * 10u + digit;
149*8975f5c5SAndroid Build Coastguard Worker                 ++mantissaDecimalDigits;
150*8975f5c5SAndroid Build Coastguard Worker             }
151*8975f5c5SAndroid Build Coastguard Worker             if (!decimalPointSeen)
152*8975f5c5SAndroid Build Coastguard Worker             {
153*8975f5c5SAndroid Build Coastguard Worker                 ++exponentOffset;
154*8975f5c5SAndroid Build Coastguard Worker             }
155*8975f5c5SAndroid Build Coastguard Worker         }
156*8975f5c5SAndroid Build Coastguard Worker         else if (decimalPointSeen)
157*8975f5c5SAndroid Build Coastguard Worker         {
158*8975f5c5SAndroid Build Coastguard Worker             --exponentOffset;
159*8975f5c5SAndroid Build Coastguard Worker         }
160*8975f5c5SAndroid Build Coastguard Worker         ++i;
161*8975f5c5SAndroid Build Coastguard Worker     }
162*8975f5c5SAndroid Build Coastguard Worker     if (decimalMantissa == 0)
163*8975f5c5SAndroid Build Coastguard Worker     {
164*8975f5c5SAndroid Build Coastguard Worker         return 0.0f;
165*8975f5c5SAndroid Build Coastguard Worker     }
166*8975f5c5SAndroid Build Coastguard Worker     int exponent = 0;
167*8975f5c5SAndroid Build Coastguard Worker     if (i < str.length())
168*8975f5c5SAndroid Build Coastguard Worker     {
169*8975f5c5SAndroid Build Coastguard Worker         ASSERT(str[i] == 'e' || str[i] == 'E');
170*8975f5c5SAndroid Build Coastguard Worker         ++i;
171*8975f5c5SAndroid Build Coastguard Worker         bool exponentOutOfRange = false;
172*8975f5c5SAndroid Build Coastguard Worker         bool negativeExponent   = false;
173*8975f5c5SAndroid Build Coastguard Worker         if (str[i] == '-')
174*8975f5c5SAndroid Build Coastguard Worker         {
175*8975f5c5SAndroid Build Coastguard Worker             negativeExponent = true;
176*8975f5c5SAndroid Build Coastguard Worker             ++i;
177*8975f5c5SAndroid Build Coastguard Worker         }
178*8975f5c5SAndroid Build Coastguard Worker         else if (str[i] == '+')
179*8975f5c5SAndroid Build Coastguard Worker         {
180*8975f5c5SAndroid Build Coastguard Worker             ++i;
181*8975f5c5SAndroid Build Coastguard Worker         }
182*8975f5c5SAndroid Build Coastguard Worker         while (i < str.length())
183*8975f5c5SAndroid Build Coastguard Worker         {
184*8975f5c5SAndroid Build Coastguard Worker             const char c       = str[i];
185*8975f5c5SAndroid Build Coastguard Worker             unsigned int digit = static_cast<unsigned int>(c - '0');
186*8975f5c5SAndroid Build Coastguard Worker             ASSERT(digit < 10u);
187*8975f5c5SAndroid Build Coastguard Worker             if (exponent <= (std::numeric_limits<int>::max() - 9) / 10)
188*8975f5c5SAndroid Build Coastguard Worker             {
189*8975f5c5SAndroid Build Coastguard Worker                 exponent = exponent * 10 + digit;
190*8975f5c5SAndroid Build Coastguard Worker             }
191*8975f5c5SAndroid Build Coastguard Worker             else
192*8975f5c5SAndroid Build Coastguard Worker             {
193*8975f5c5SAndroid Build Coastguard Worker                 exponentOutOfRange = true;
194*8975f5c5SAndroid Build Coastguard Worker             }
195*8975f5c5SAndroid Build Coastguard Worker             ++i;
196*8975f5c5SAndroid Build Coastguard Worker         }
197*8975f5c5SAndroid Build Coastguard Worker         if (negativeExponent)
198*8975f5c5SAndroid Build Coastguard Worker         {
199*8975f5c5SAndroid Build Coastguard Worker             exponent = -exponent;
200*8975f5c5SAndroid Build Coastguard Worker         }
201*8975f5c5SAndroid Build Coastguard Worker         if (exponentOutOfRange)
202*8975f5c5SAndroid Build Coastguard Worker         {
203*8975f5c5SAndroid Build Coastguard Worker             if (negativeExponent)
204*8975f5c5SAndroid Build Coastguard Worker             {
205*8975f5c5SAndroid Build Coastguard Worker                 return 0.0f;
206*8975f5c5SAndroid Build Coastguard Worker             }
207*8975f5c5SAndroid Build Coastguard Worker             else
208*8975f5c5SAndroid Build Coastguard Worker             {
209*8975f5c5SAndroid Build Coastguard Worker                 return std::numeric_limits<float>::infinity();
210*8975f5c5SAndroid Build Coastguard Worker             }
211*8975f5c5SAndroid Build Coastguard Worker         }
212*8975f5c5SAndroid Build Coastguard Worker     }
213*8975f5c5SAndroid Build Coastguard Worker     // Do the calculation in 64-bit to avoid overflow.
214*8975f5c5SAndroid Build Coastguard Worker     long long exponentLong =
215*8975f5c5SAndroid Build Coastguard Worker         static_cast<long long>(exponent) + static_cast<long long>(exponentOffset);
216*8975f5c5SAndroid Build Coastguard Worker     if (exponentLong > std::numeric_limits<float>::max_exponent10)
217*8975f5c5SAndroid Build Coastguard Worker     {
218*8975f5c5SAndroid Build Coastguard Worker         return std::numeric_limits<float>::infinity();
219*8975f5c5SAndroid Build Coastguard Worker     }
220*8975f5c5SAndroid Build Coastguard Worker     // In 32-bit float, min_exponent10 is -37 but min() is
221*8975f5c5SAndroid Build Coastguard Worker     // 1.1754943E-38. 10^-37 may be the "minimum negative integer such
222*8975f5c5SAndroid Build Coastguard Worker     // that 10 raised to that power is a normalized float", but being
223*8975f5c5SAndroid Build Coastguard Worker     // constrained to powers of ten it's above min() (which is 2^-126).
224*8975f5c5SAndroid Build Coastguard Worker     // Values below min() are flushed to zero near the end of this
225*8975f5c5SAndroid Build Coastguard Worker     // function anyway so (AFAICT) this comparison is only done to ensure
226*8975f5c5SAndroid Build Coastguard Worker     // that the exponent will not make the pow() call (below) overflow.
227*8975f5c5SAndroid Build Coastguard Worker     // Comparing against -38 (min_exponent10 - 1) will do the trick.
228*8975f5c5SAndroid Build Coastguard Worker     else if (exponentLong < std::numeric_limits<float>::min_exponent10 - 1)
229*8975f5c5SAndroid Build Coastguard Worker     {
230*8975f5c5SAndroid Build Coastguard Worker         return 0.0f;
231*8975f5c5SAndroid Build Coastguard Worker     }
232*8975f5c5SAndroid Build Coastguard Worker     // The exponent is in range, so we need to actually evaluate the float.
233*8975f5c5SAndroid Build Coastguard Worker     exponent     = static_cast<int>(exponentLong);
234*8975f5c5SAndroid Build Coastguard Worker     double value = decimalMantissa;
235*8975f5c5SAndroid Build Coastguard Worker 
236*8975f5c5SAndroid Build Coastguard Worker     // Calculate the exponent offset to normalize the mantissa.
237*8975f5c5SAndroid Build Coastguard Worker     int normalizationExponentOffset = 1 - mantissaDecimalDigits;
238*8975f5c5SAndroid Build Coastguard Worker     // Apply the exponent.
239*8975f5c5SAndroid Build Coastguard Worker     value *= std::pow(10.0, static_cast<double>(exponent + normalizationExponentOffset));
240*8975f5c5SAndroid Build Coastguard Worker     if (value > static_cast<double>(std::numeric_limits<float>::max()))
241*8975f5c5SAndroid Build Coastguard Worker     {
242*8975f5c5SAndroid Build Coastguard Worker         return std::numeric_limits<float>::infinity();
243*8975f5c5SAndroid Build Coastguard Worker     }
244*8975f5c5SAndroid Build Coastguard Worker     if (static_cast<float>(value) < std::numeric_limits<float>::min())
245*8975f5c5SAndroid Build Coastguard Worker     {
246*8975f5c5SAndroid Build Coastguard Worker         return 0.0f;
247*8975f5c5SAndroid Build Coastguard Worker     }
248*8975f5c5SAndroid Build Coastguard Worker     return static_cast<float>(value);
249*8975f5c5SAndroid Build Coastguard Worker }
250*8975f5c5SAndroid Build Coastguard Worker 
strtof_clamp(const std::string & str,float * value)251*8975f5c5SAndroid Build Coastguard Worker bool strtof_clamp(const std::string &str, float *value)
252*8975f5c5SAndroid Build Coastguard Worker {
253*8975f5c5SAndroid Build Coastguard Worker     // Custom float parsing that can handle the following corner cases:
254*8975f5c5SAndroid Build Coastguard Worker     //   1. The decimal mantissa is very small but the exponent is very large, putting the resulting
255*8975f5c5SAndroid Build Coastguard Worker     //   number inside the float range.
256*8975f5c5SAndroid Build Coastguard Worker     //   2. The decimal mantissa is very large but the exponent is very small, putting the resulting
257*8975f5c5SAndroid Build Coastguard Worker     //   number inside the float range.
258*8975f5c5SAndroid Build Coastguard Worker     //   3. The value is out-of-range and should be evaluated as infinity.
259*8975f5c5SAndroid Build Coastguard Worker     //   4. The value is too small and should be evaluated as zero.
260*8975f5c5SAndroid Build Coastguard Worker     // See ESSL 3.00.6 section 4.1.4 for the relevant specification.
261*8975f5c5SAndroid Build Coastguard Worker     *value = NumericLexFloat32OutOfRangeToInfinity(str);
262*8975f5c5SAndroid Build Coastguard Worker     return !gl::isInf(*value);
263*8975f5c5SAndroid Build Coastguard Worker }
264*8975f5c5SAndroid Build Coastguard Worker 
GLVariableType(const TType & type)265*8975f5c5SAndroid Build Coastguard Worker GLenum GLVariableType(const TType &type)
266*8975f5c5SAndroid Build Coastguard Worker {
267*8975f5c5SAndroid Build Coastguard Worker     switch (type.getBasicType())
268*8975f5c5SAndroid Build Coastguard Worker     {
269*8975f5c5SAndroid Build Coastguard Worker         case EbtFloat:
270*8975f5c5SAndroid Build Coastguard Worker             ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4);
271*8975f5c5SAndroid Build Coastguard Worker             ASSERT(type.getSecondarySize() >= 1 && type.getSecondarySize() <= 4);
272*8975f5c5SAndroid Build Coastguard Worker 
273*8975f5c5SAndroid Build Coastguard Worker             return kFloatGLType[type.getNominalSize() - 1][type.getSecondarySize() - 1];
274*8975f5c5SAndroid Build Coastguard Worker 
275*8975f5c5SAndroid Build Coastguard Worker         case EbtInt:
276*8975f5c5SAndroid Build Coastguard Worker             ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4);
277*8975f5c5SAndroid Build Coastguard Worker             ASSERT(type.getSecondarySize() == 1);
278*8975f5c5SAndroid Build Coastguard Worker 
279*8975f5c5SAndroid Build Coastguard Worker             return kIntGLType[type.getNominalSize() - 1];
280*8975f5c5SAndroid Build Coastguard Worker 
281*8975f5c5SAndroid Build Coastguard Worker         case EbtUInt:
282*8975f5c5SAndroid Build Coastguard Worker             ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4);
283*8975f5c5SAndroid Build Coastguard Worker             ASSERT(type.getSecondarySize() == 1);
284*8975f5c5SAndroid Build Coastguard Worker 
285*8975f5c5SAndroid Build Coastguard Worker             return kUIntGLType[type.getNominalSize() - 1];
286*8975f5c5SAndroid Build Coastguard Worker 
287*8975f5c5SAndroid Build Coastguard Worker         case EbtBool:
288*8975f5c5SAndroid Build Coastguard Worker             ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4);
289*8975f5c5SAndroid Build Coastguard Worker             ASSERT(type.getSecondarySize() == 1);
290*8975f5c5SAndroid Build Coastguard Worker 
291*8975f5c5SAndroid Build Coastguard Worker             return kBoolGLType[type.getNominalSize() - 1];
292*8975f5c5SAndroid Build Coastguard Worker 
293*8975f5c5SAndroid Build Coastguard Worker         case EbtYuvCscStandardEXT:
294*8975f5c5SAndroid Build Coastguard Worker             return GL_UNSIGNED_INT;
295*8975f5c5SAndroid Build Coastguard Worker 
296*8975f5c5SAndroid Build Coastguard Worker         case EbtSampler2D:
297*8975f5c5SAndroid Build Coastguard Worker             return GL_SAMPLER_2D;
298*8975f5c5SAndroid Build Coastguard Worker         case EbtSampler3D:
299*8975f5c5SAndroid Build Coastguard Worker             return GL_SAMPLER_3D;
300*8975f5c5SAndroid Build Coastguard Worker         case EbtSamplerCube:
301*8975f5c5SAndroid Build Coastguard Worker             return GL_SAMPLER_CUBE;
302*8975f5c5SAndroid Build Coastguard Worker         case EbtSamplerExternalOES:
303*8975f5c5SAndroid Build Coastguard Worker             return GL_SAMPLER_EXTERNAL_OES;
304*8975f5c5SAndroid Build Coastguard Worker         case EbtSamplerExternal2DY2YEXT:
305*8975f5c5SAndroid Build Coastguard Worker             return GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT;
306*8975f5c5SAndroid Build Coastguard Worker         case EbtSampler2DRect:
307*8975f5c5SAndroid Build Coastguard Worker             return GL_SAMPLER_2D_RECT_ANGLE;
308*8975f5c5SAndroid Build Coastguard Worker         case EbtSampler2DArray:
309*8975f5c5SAndroid Build Coastguard Worker             return GL_SAMPLER_2D_ARRAY;
310*8975f5c5SAndroid Build Coastguard Worker         case EbtSampler2DMS:
311*8975f5c5SAndroid Build Coastguard Worker             return GL_SAMPLER_2D_MULTISAMPLE;
312*8975f5c5SAndroid Build Coastguard Worker         case EbtSampler2DMSArray:
313*8975f5c5SAndroid Build Coastguard Worker             return GL_SAMPLER_2D_MULTISAMPLE_ARRAY;
314*8975f5c5SAndroid Build Coastguard Worker         case EbtSamplerCubeArray:
315*8975f5c5SAndroid Build Coastguard Worker             return GL_SAMPLER_CUBE_MAP_ARRAY;
316*8975f5c5SAndroid Build Coastguard Worker         case EbtSamplerBuffer:
317*8975f5c5SAndroid Build Coastguard Worker             return GL_SAMPLER_BUFFER;
318*8975f5c5SAndroid Build Coastguard Worker         case EbtISampler2D:
319*8975f5c5SAndroid Build Coastguard Worker             return GL_INT_SAMPLER_2D;
320*8975f5c5SAndroid Build Coastguard Worker         case EbtISampler3D:
321*8975f5c5SAndroid Build Coastguard Worker             return GL_INT_SAMPLER_3D;
322*8975f5c5SAndroid Build Coastguard Worker         case EbtISamplerCube:
323*8975f5c5SAndroid Build Coastguard Worker             return GL_INT_SAMPLER_CUBE;
324*8975f5c5SAndroid Build Coastguard Worker         case EbtISampler2DArray:
325*8975f5c5SAndroid Build Coastguard Worker             return GL_INT_SAMPLER_2D_ARRAY;
326*8975f5c5SAndroid Build Coastguard Worker         case EbtISampler2DMS:
327*8975f5c5SAndroid Build Coastguard Worker             return GL_INT_SAMPLER_2D_MULTISAMPLE;
328*8975f5c5SAndroid Build Coastguard Worker         case EbtISampler2DMSArray:
329*8975f5c5SAndroid Build Coastguard Worker             return GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY;
330*8975f5c5SAndroid Build Coastguard Worker         case EbtISamplerCubeArray:
331*8975f5c5SAndroid Build Coastguard Worker             return GL_INT_SAMPLER_CUBE_MAP_ARRAY;
332*8975f5c5SAndroid Build Coastguard Worker         case EbtISamplerBuffer:
333*8975f5c5SAndroid Build Coastguard Worker             return GL_INT_SAMPLER_BUFFER;
334*8975f5c5SAndroid Build Coastguard Worker         case EbtUSampler2D:
335*8975f5c5SAndroid Build Coastguard Worker             return GL_UNSIGNED_INT_SAMPLER_2D;
336*8975f5c5SAndroid Build Coastguard Worker         case EbtUSampler3D:
337*8975f5c5SAndroid Build Coastguard Worker             return GL_UNSIGNED_INT_SAMPLER_3D;
338*8975f5c5SAndroid Build Coastguard Worker         case EbtUSamplerCube:
339*8975f5c5SAndroid Build Coastguard Worker             return GL_UNSIGNED_INT_SAMPLER_CUBE;
340*8975f5c5SAndroid Build Coastguard Worker         case EbtUSampler2DArray:
341*8975f5c5SAndroid Build Coastguard Worker             return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
342*8975f5c5SAndroid Build Coastguard Worker         case EbtUSampler2DMS:
343*8975f5c5SAndroid Build Coastguard Worker             return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE;
344*8975f5c5SAndroid Build Coastguard Worker         case EbtUSampler2DMSArray:
345*8975f5c5SAndroid Build Coastguard Worker             return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY;
346*8975f5c5SAndroid Build Coastguard Worker         case EbtUSamplerCubeArray:
347*8975f5c5SAndroid Build Coastguard Worker             return GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY;
348*8975f5c5SAndroid Build Coastguard Worker         case EbtUSamplerBuffer:
349*8975f5c5SAndroid Build Coastguard Worker             return GL_UNSIGNED_INT_SAMPLER_BUFFER;
350*8975f5c5SAndroid Build Coastguard Worker         case EbtSampler2DShadow:
351*8975f5c5SAndroid Build Coastguard Worker             return GL_SAMPLER_2D_SHADOW;
352*8975f5c5SAndroid Build Coastguard Worker         case EbtSamplerCubeShadow:
353*8975f5c5SAndroid Build Coastguard Worker             return GL_SAMPLER_CUBE_SHADOW;
354*8975f5c5SAndroid Build Coastguard Worker         case EbtSampler2DArrayShadow:
355*8975f5c5SAndroid Build Coastguard Worker             return GL_SAMPLER_2D_ARRAY_SHADOW;
356*8975f5c5SAndroid Build Coastguard Worker         case EbtSamplerCubeArrayShadow:
357*8975f5c5SAndroid Build Coastguard Worker             return GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW;
358*8975f5c5SAndroid Build Coastguard Worker         case EbtImage2D:
359*8975f5c5SAndroid Build Coastguard Worker             return GL_IMAGE_2D;
360*8975f5c5SAndroid Build Coastguard Worker         case EbtIImage2D:
361*8975f5c5SAndroid Build Coastguard Worker             return GL_INT_IMAGE_2D;
362*8975f5c5SAndroid Build Coastguard Worker         case EbtUImage2D:
363*8975f5c5SAndroid Build Coastguard Worker             return GL_UNSIGNED_INT_IMAGE_2D;
364*8975f5c5SAndroid Build Coastguard Worker         case EbtImage2DArray:
365*8975f5c5SAndroid Build Coastguard Worker             return GL_IMAGE_2D_ARRAY;
366*8975f5c5SAndroid Build Coastguard Worker         case EbtIImage2DArray:
367*8975f5c5SAndroid Build Coastguard Worker             return GL_INT_IMAGE_2D_ARRAY;
368*8975f5c5SAndroid Build Coastguard Worker         case EbtUImage2DArray:
369*8975f5c5SAndroid Build Coastguard Worker             return GL_UNSIGNED_INT_IMAGE_2D_ARRAY;
370*8975f5c5SAndroid Build Coastguard Worker         case EbtImage3D:
371*8975f5c5SAndroid Build Coastguard Worker             return GL_IMAGE_3D;
372*8975f5c5SAndroid Build Coastguard Worker         case EbtIImage3D:
373*8975f5c5SAndroid Build Coastguard Worker             return GL_INT_IMAGE_3D;
374*8975f5c5SAndroid Build Coastguard Worker         case EbtUImage3D:
375*8975f5c5SAndroid Build Coastguard Worker             return GL_UNSIGNED_INT_IMAGE_3D;
376*8975f5c5SAndroid Build Coastguard Worker         case EbtImageCube:
377*8975f5c5SAndroid Build Coastguard Worker             return GL_IMAGE_CUBE;
378*8975f5c5SAndroid Build Coastguard Worker         case EbtIImageCube:
379*8975f5c5SAndroid Build Coastguard Worker             return GL_INT_IMAGE_CUBE;
380*8975f5c5SAndroid Build Coastguard Worker         case EbtUImageCube:
381*8975f5c5SAndroid Build Coastguard Worker             return GL_UNSIGNED_INT_IMAGE_CUBE;
382*8975f5c5SAndroid Build Coastguard Worker         case EbtImageCubeArray:
383*8975f5c5SAndroid Build Coastguard Worker             return GL_IMAGE_CUBE_MAP_ARRAY;
384*8975f5c5SAndroid Build Coastguard Worker         case EbtIImageCubeArray:
385*8975f5c5SAndroid Build Coastguard Worker             return GL_INT_IMAGE_CUBE_MAP_ARRAY;
386*8975f5c5SAndroid Build Coastguard Worker         case EbtUImageCubeArray:
387*8975f5c5SAndroid Build Coastguard Worker             return GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY;
388*8975f5c5SAndroid Build Coastguard Worker         case EbtImageBuffer:
389*8975f5c5SAndroid Build Coastguard Worker             return GL_IMAGE_BUFFER;
390*8975f5c5SAndroid Build Coastguard Worker         case EbtIImageBuffer:
391*8975f5c5SAndroid Build Coastguard Worker             return GL_INT_IMAGE_BUFFER;
392*8975f5c5SAndroid Build Coastguard Worker         case EbtUImageBuffer:
393*8975f5c5SAndroid Build Coastguard Worker             return GL_UNSIGNED_INT_IMAGE_BUFFER;
394*8975f5c5SAndroid Build Coastguard Worker         case EbtAtomicCounter:
395*8975f5c5SAndroid Build Coastguard Worker             return GL_UNSIGNED_INT_ATOMIC_COUNTER;
396*8975f5c5SAndroid Build Coastguard Worker         case EbtSamplerVideoWEBGL:
397*8975f5c5SAndroid Build Coastguard Worker             return GL_SAMPLER_VIDEO_IMAGE_WEBGL;
398*8975f5c5SAndroid Build Coastguard Worker         case EbtPixelLocalANGLE:
399*8975f5c5SAndroid Build Coastguard Worker         case EbtIPixelLocalANGLE:
400*8975f5c5SAndroid Build Coastguard Worker         case EbtUPixelLocalANGLE:
401*8975f5c5SAndroid Build Coastguard Worker             // TODO(anglebug.com/40096838): For now, we can expect PLS handles to be rewritten to
402*8975f5c5SAndroid Build Coastguard Worker             // images before anyone calls into here.
403*8975f5c5SAndroid Build Coastguard Worker             [[fallthrough]];
404*8975f5c5SAndroid Build Coastguard Worker         default:
405*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
406*8975f5c5SAndroid Build Coastguard Worker             return GL_NONE;
407*8975f5c5SAndroid Build Coastguard Worker     }
408*8975f5c5SAndroid Build Coastguard Worker }
409*8975f5c5SAndroid Build Coastguard Worker 
GLVariablePrecision(const TType & type)410*8975f5c5SAndroid Build Coastguard Worker GLenum GLVariablePrecision(const TType &type)
411*8975f5c5SAndroid Build Coastguard Worker {
412*8975f5c5SAndroid Build Coastguard Worker     if (type.getBasicType() == EbtFloat)
413*8975f5c5SAndroid Build Coastguard Worker     {
414*8975f5c5SAndroid Build Coastguard Worker         switch (type.getPrecision())
415*8975f5c5SAndroid Build Coastguard Worker         {
416*8975f5c5SAndroid Build Coastguard Worker             case EbpHigh:
417*8975f5c5SAndroid Build Coastguard Worker                 return GL_HIGH_FLOAT;
418*8975f5c5SAndroid Build Coastguard Worker             case EbpMedium:
419*8975f5c5SAndroid Build Coastguard Worker                 return GL_MEDIUM_FLOAT;
420*8975f5c5SAndroid Build Coastguard Worker             case EbpLow:
421*8975f5c5SAndroid Build Coastguard Worker                 return GL_LOW_FLOAT;
422*8975f5c5SAndroid Build Coastguard Worker             default:
423*8975f5c5SAndroid Build Coastguard Worker                 UNREACHABLE();
424*8975f5c5SAndroid Build Coastguard Worker         }
425*8975f5c5SAndroid Build Coastguard Worker     }
426*8975f5c5SAndroid Build Coastguard Worker     else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
427*8975f5c5SAndroid Build Coastguard Worker     {
428*8975f5c5SAndroid Build Coastguard Worker         switch (type.getPrecision())
429*8975f5c5SAndroid Build Coastguard Worker         {
430*8975f5c5SAndroid Build Coastguard Worker             case EbpHigh:
431*8975f5c5SAndroid Build Coastguard Worker                 return GL_HIGH_INT;
432*8975f5c5SAndroid Build Coastguard Worker             case EbpMedium:
433*8975f5c5SAndroid Build Coastguard Worker                 return GL_MEDIUM_INT;
434*8975f5c5SAndroid Build Coastguard Worker             case EbpLow:
435*8975f5c5SAndroid Build Coastguard Worker                 return GL_LOW_INT;
436*8975f5c5SAndroid Build Coastguard Worker             default:
437*8975f5c5SAndroid Build Coastguard Worker                 UNREACHABLE();
438*8975f5c5SAndroid Build Coastguard Worker         }
439*8975f5c5SAndroid Build Coastguard Worker     }
440*8975f5c5SAndroid Build Coastguard Worker 
441*8975f5c5SAndroid Build Coastguard Worker     // Other types (boolean, sampler) don't have a precision
442*8975f5c5SAndroid Build Coastguard Worker     return GL_NONE;
443*8975f5c5SAndroid Build Coastguard Worker }
444*8975f5c5SAndroid Build Coastguard Worker 
ArrayString(const TType & type)445*8975f5c5SAndroid Build Coastguard Worker ImmutableString ArrayString(const TType &type)
446*8975f5c5SAndroid Build Coastguard Worker {
447*8975f5c5SAndroid Build Coastguard Worker     if (!type.isArray())
448*8975f5c5SAndroid Build Coastguard Worker         return ImmutableString("");
449*8975f5c5SAndroid Build Coastguard Worker 
450*8975f5c5SAndroid Build Coastguard Worker     const TSpan<const unsigned int> &arraySizes     = type.getArraySizes();
451*8975f5c5SAndroid Build Coastguard Worker     constexpr const size_t kMaxDecimalDigitsPerSize = 10u;
452*8975f5c5SAndroid Build Coastguard Worker     ImmutableStringBuilder arrayString(arraySizes.size() * (kMaxDecimalDigitsPerSize + 2u));
453*8975f5c5SAndroid Build Coastguard Worker     for (auto arraySizeIter = arraySizes.rbegin(); arraySizeIter != arraySizes.rend();
454*8975f5c5SAndroid Build Coastguard Worker          ++arraySizeIter)
455*8975f5c5SAndroid Build Coastguard Worker     {
456*8975f5c5SAndroid Build Coastguard Worker         arrayString << "[";
457*8975f5c5SAndroid Build Coastguard Worker         if (*arraySizeIter > 0)
458*8975f5c5SAndroid Build Coastguard Worker         {
459*8975f5c5SAndroid Build Coastguard Worker             arrayString << *arraySizeIter;
460*8975f5c5SAndroid Build Coastguard Worker         }
461*8975f5c5SAndroid Build Coastguard Worker         arrayString << "]";
462*8975f5c5SAndroid Build Coastguard Worker     }
463*8975f5c5SAndroid Build Coastguard Worker     return arrayString;
464*8975f5c5SAndroid Build Coastguard Worker }
465*8975f5c5SAndroid Build Coastguard Worker 
GetTypeName(const TType & type,ShHashFunction64 hashFunction,NameMap * nameMap)466*8975f5c5SAndroid Build Coastguard Worker ImmutableString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap)
467*8975f5c5SAndroid Build Coastguard Worker {
468*8975f5c5SAndroid Build Coastguard Worker     if (type.getBasicType() == EbtStruct)
469*8975f5c5SAndroid Build Coastguard Worker         return HashName(type.getStruct(), hashFunction, nameMap);
470*8975f5c5SAndroid Build Coastguard Worker     else
471*8975f5c5SAndroid Build Coastguard Worker         return ImmutableString(type.getBuiltInTypeNameString());
472*8975f5c5SAndroid Build Coastguard Worker }
473*8975f5c5SAndroid Build Coastguard Worker 
IsVaryingOut(TQualifier qualifier)474*8975f5c5SAndroid Build Coastguard Worker bool IsVaryingOut(TQualifier qualifier)
475*8975f5c5SAndroid Build Coastguard Worker {
476*8975f5c5SAndroid Build Coastguard Worker     switch (qualifier)
477*8975f5c5SAndroid Build Coastguard Worker     {
478*8975f5c5SAndroid Build Coastguard Worker         case EvqVaryingOut:
479*8975f5c5SAndroid Build Coastguard Worker         case EvqVertexOut:
480*8975f5c5SAndroid Build Coastguard Worker         case EvqGeometryOut:
481*8975f5c5SAndroid Build Coastguard Worker         case EvqTessControlOut:
482*8975f5c5SAndroid Build Coastguard Worker         case EvqTessEvaluationOut:
483*8975f5c5SAndroid Build Coastguard Worker         case EvqPatchOut:
484*8975f5c5SAndroid Build Coastguard Worker             return true;
485*8975f5c5SAndroid Build Coastguard Worker 
486*8975f5c5SAndroid Build Coastguard Worker         default:
487*8975f5c5SAndroid Build Coastguard Worker             break;
488*8975f5c5SAndroid Build Coastguard Worker     }
489*8975f5c5SAndroid Build Coastguard Worker 
490*8975f5c5SAndroid Build Coastguard Worker     return IsInterpolationOut(qualifier);
491*8975f5c5SAndroid Build Coastguard Worker }
492*8975f5c5SAndroid Build Coastguard Worker 
IsVaryingIn(TQualifier qualifier)493*8975f5c5SAndroid Build Coastguard Worker bool IsVaryingIn(TQualifier qualifier)
494*8975f5c5SAndroid Build Coastguard Worker {
495*8975f5c5SAndroid Build Coastguard Worker     switch (qualifier)
496*8975f5c5SAndroid Build Coastguard Worker     {
497*8975f5c5SAndroid Build Coastguard Worker         case EvqVaryingIn:
498*8975f5c5SAndroid Build Coastguard Worker         case EvqFragmentIn:
499*8975f5c5SAndroid Build Coastguard Worker         case EvqGeometryIn:
500*8975f5c5SAndroid Build Coastguard Worker         case EvqTessControlIn:
501*8975f5c5SAndroid Build Coastguard Worker         case EvqTessEvaluationIn:
502*8975f5c5SAndroid Build Coastguard Worker         case EvqPatchIn:
503*8975f5c5SAndroid Build Coastguard Worker             return true;
504*8975f5c5SAndroid Build Coastguard Worker 
505*8975f5c5SAndroid Build Coastguard Worker         default:
506*8975f5c5SAndroid Build Coastguard Worker             break;
507*8975f5c5SAndroid Build Coastguard Worker     }
508*8975f5c5SAndroid Build Coastguard Worker 
509*8975f5c5SAndroid Build Coastguard Worker     return IsInterpolationIn(qualifier);
510*8975f5c5SAndroid Build Coastguard Worker }
511*8975f5c5SAndroid Build Coastguard Worker 
IsVarying(TQualifier qualifier)512*8975f5c5SAndroid Build Coastguard Worker bool IsVarying(TQualifier qualifier)
513*8975f5c5SAndroid Build Coastguard Worker {
514*8975f5c5SAndroid Build Coastguard Worker     return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
515*8975f5c5SAndroid Build Coastguard Worker }
516*8975f5c5SAndroid Build Coastguard Worker 
IsMatrixGLType(GLenum type)517*8975f5c5SAndroid Build Coastguard Worker bool IsMatrixGLType(GLenum type)
518*8975f5c5SAndroid Build Coastguard Worker {
519*8975f5c5SAndroid Build Coastguard Worker     switch (type)
520*8975f5c5SAndroid Build Coastguard Worker     {
521*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_MAT2:
522*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_MAT3:
523*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_MAT4:
524*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_MAT2x3:
525*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_MAT2x4:
526*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_MAT3x2:
527*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_MAT3x4:
528*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_MAT4x2:
529*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_MAT4x3:
530*8975f5c5SAndroid Build Coastguard Worker             return true;
531*8975f5c5SAndroid Build Coastguard Worker         default:
532*8975f5c5SAndroid Build Coastguard Worker             return false;
533*8975f5c5SAndroid Build Coastguard Worker     }
534*8975f5c5SAndroid Build Coastguard Worker }
535*8975f5c5SAndroid Build Coastguard Worker 
IsGeometryShaderInput(GLenum shaderType,TQualifier qualifier)536*8975f5c5SAndroid Build Coastguard Worker bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier)
537*8975f5c5SAndroid Build Coastguard Worker {
538*8975f5c5SAndroid Build Coastguard Worker     return (qualifier == EvqGeometryIn) ||
539*8975f5c5SAndroid Build Coastguard Worker            ((shaderType == GL_GEOMETRY_SHADER_EXT) && IsInterpolationIn(qualifier));
540*8975f5c5SAndroid Build Coastguard Worker }
541*8975f5c5SAndroid Build Coastguard Worker 
IsTessellationControlShaderInput(GLenum shaderType,TQualifier qualifier)542*8975f5c5SAndroid Build Coastguard Worker bool IsTessellationControlShaderInput(GLenum shaderType, TQualifier qualifier)
543*8975f5c5SAndroid Build Coastguard Worker {
544*8975f5c5SAndroid Build Coastguard Worker     return qualifier == EvqTessControlIn ||
545*8975f5c5SAndroid Build Coastguard Worker            ((shaderType == GL_TESS_CONTROL_SHADER) && IsInterpolationIn(qualifier));
546*8975f5c5SAndroid Build Coastguard Worker }
547*8975f5c5SAndroid Build Coastguard Worker 
IsTessellationControlShaderOutput(GLenum shaderType,TQualifier qualifier)548*8975f5c5SAndroid Build Coastguard Worker bool IsTessellationControlShaderOutput(GLenum shaderType, TQualifier qualifier)
549*8975f5c5SAndroid Build Coastguard Worker {
550*8975f5c5SAndroid Build Coastguard Worker     return qualifier == EvqTessControlOut ||
551*8975f5c5SAndroid Build Coastguard Worker            ((shaderType == GL_TESS_CONTROL_SHADER) && IsInterpolationOut(qualifier));
552*8975f5c5SAndroid Build Coastguard Worker }
553*8975f5c5SAndroid Build Coastguard Worker 
IsTessellationEvaluationShaderInput(GLenum shaderType,TQualifier qualifier)554*8975f5c5SAndroid Build Coastguard Worker bool IsTessellationEvaluationShaderInput(GLenum shaderType, TQualifier qualifier)
555*8975f5c5SAndroid Build Coastguard Worker {
556*8975f5c5SAndroid Build Coastguard Worker     return qualifier == EvqTessEvaluationIn ||
557*8975f5c5SAndroid Build Coastguard Worker            ((shaderType == GL_TESS_EVALUATION_SHADER) && IsInterpolationIn(qualifier));
558*8975f5c5SAndroid Build Coastguard Worker }
559*8975f5c5SAndroid Build Coastguard Worker 
GetInterpolationType(TQualifier qualifier)560*8975f5c5SAndroid Build Coastguard Worker InterpolationType GetInterpolationType(TQualifier qualifier)
561*8975f5c5SAndroid Build Coastguard Worker {
562*8975f5c5SAndroid Build Coastguard Worker     switch (qualifier)
563*8975f5c5SAndroid Build Coastguard Worker     {
564*8975f5c5SAndroid Build Coastguard Worker         case EvqFlatIn:
565*8975f5c5SAndroid Build Coastguard Worker         case EvqFlatOut:
566*8975f5c5SAndroid Build Coastguard Worker         // The auxiliary storage qualifier patch is not used for interpolation
567*8975f5c5SAndroid Build Coastguard Worker         // it is a compile-time error to use interpolation qualifiers with patch
568*8975f5c5SAndroid Build Coastguard Worker         case EvqPatchIn:
569*8975f5c5SAndroid Build Coastguard Worker         case EvqPatchOut:
570*8975f5c5SAndroid Build Coastguard Worker             return INTERPOLATION_FLAT;
571*8975f5c5SAndroid Build Coastguard Worker 
572*8975f5c5SAndroid Build Coastguard Worker         case EvqNoPerspectiveIn:
573*8975f5c5SAndroid Build Coastguard Worker         case EvqNoPerspectiveOut:
574*8975f5c5SAndroid Build Coastguard Worker             return INTERPOLATION_NOPERSPECTIVE;
575*8975f5c5SAndroid Build Coastguard Worker 
576*8975f5c5SAndroid Build Coastguard Worker         case EvqNoPerspectiveCentroidIn:
577*8975f5c5SAndroid Build Coastguard Worker         case EvqNoPerspectiveCentroidOut:
578*8975f5c5SAndroid Build Coastguard Worker             return INTERPOLATION_NOPERSPECTIVE_CENTROID;
579*8975f5c5SAndroid Build Coastguard Worker 
580*8975f5c5SAndroid Build Coastguard Worker         case EvqNoPerspectiveSampleIn:
581*8975f5c5SAndroid Build Coastguard Worker         case EvqNoPerspectiveSampleOut:
582*8975f5c5SAndroid Build Coastguard Worker             return INTERPOLATION_NOPERSPECTIVE_SAMPLE;
583*8975f5c5SAndroid Build Coastguard Worker 
584*8975f5c5SAndroid Build Coastguard Worker         case EvqSmoothIn:
585*8975f5c5SAndroid Build Coastguard Worker         case EvqSmoothOut:
586*8975f5c5SAndroid Build Coastguard Worker         case EvqVertexOut:
587*8975f5c5SAndroid Build Coastguard Worker         case EvqFragmentIn:
588*8975f5c5SAndroid Build Coastguard Worker         case EvqVaryingIn:
589*8975f5c5SAndroid Build Coastguard Worker         case EvqVaryingOut:
590*8975f5c5SAndroid Build Coastguard Worker         case EvqGeometryIn:
591*8975f5c5SAndroid Build Coastguard Worker         case EvqGeometryOut:
592*8975f5c5SAndroid Build Coastguard Worker         case EvqTessControlIn:
593*8975f5c5SAndroid Build Coastguard Worker         case EvqTessControlOut:
594*8975f5c5SAndroid Build Coastguard Worker         case EvqTessEvaluationIn:
595*8975f5c5SAndroid Build Coastguard Worker         case EvqTessEvaluationOut:
596*8975f5c5SAndroid Build Coastguard Worker             return INTERPOLATION_SMOOTH;
597*8975f5c5SAndroid Build Coastguard Worker 
598*8975f5c5SAndroid Build Coastguard Worker         case EvqCentroidIn:
599*8975f5c5SAndroid Build Coastguard Worker         case EvqCentroidOut:
600*8975f5c5SAndroid Build Coastguard Worker             return INTERPOLATION_CENTROID;
601*8975f5c5SAndroid Build Coastguard Worker 
602*8975f5c5SAndroid Build Coastguard Worker         case EvqSampleIn:
603*8975f5c5SAndroid Build Coastguard Worker         case EvqSampleOut:
604*8975f5c5SAndroid Build Coastguard Worker             return INTERPOLATION_SAMPLE;
605*8975f5c5SAndroid Build Coastguard Worker         default:
606*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
607*8975f5c5SAndroid Build Coastguard Worker             return INTERPOLATION_SMOOTH;
608*8975f5c5SAndroid Build Coastguard Worker     }
609*8975f5c5SAndroid Build Coastguard Worker }
610*8975f5c5SAndroid Build Coastguard Worker 
611*8975f5c5SAndroid Build Coastguard Worker // a field may not have qualifer without in or out.
GetFieldInterpolationType(TQualifier qualifier)612*8975f5c5SAndroid Build Coastguard Worker InterpolationType GetFieldInterpolationType(TQualifier qualifier)
613*8975f5c5SAndroid Build Coastguard Worker {
614*8975f5c5SAndroid Build Coastguard Worker     switch (qualifier)
615*8975f5c5SAndroid Build Coastguard Worker     {
616*8975f5c5SAndroid Build Coastguard Worker         case EvqSmooth:
617*8975f5c5SAndroid Build Coastguard Worker             return INTERPOLATION_SMOOTH;
618*8975f5c5SAndroid Build Coastguard Worker         case EvqFlat:
619*8975f5c5SAndroid Build Coastguard Worker             return INTERPOLATION_FLAT;
620*8975f5c5SAndroid Build Coastguard Worker         case EvqNoPerspective:
621*8975f5c5SAndroid Build Coastguard Worker             return INTERPOLATION_NOPERSPECTIVE;
622*8975f5c5SAndroid Build Coastguard Worker         case EvqCentroid:
623*8975f5c5SAndroid Build Coastguard Worker             return INTERPOLATION_CENTROID;
624*8975f5c5SAndroid Build Coastguard Worker         case EvqSample:
625*8975f5c5SAndroid Build Coastguard Worker             return INTERPOLATION_SAMPLE;
626*8975f5c5SAndroid Build Coastguard Worker         case EvqNoPerspectiveCentroid:
627*8975f5c5SAndroid Build Coastguard Worker             return INTERPOLATION_NOPERSPECTIVE_CENTROID;
628*8975f5c5SAndroid Build Coastguard Worker         case EvqNoPerspectiveSample:
629*8975f5c5SAndroid Build Coastguard Worker             return INTERPOLATION_NOPERSPECTIVE_SAMPLE;
630*8975f5c5SAndroid Build Coastguard Worker         default:
631*8975f5c5SAndroid Build Coastguard Worker             return GetInterpolationType(qualifier);
632*8975f5c5SAndroid Build Coastguard Worker     }
633*8975f5c5SAndroid Build Coastguard Worker }
634*8975f5c5SAndroid Build Coastguard Worker 
GetShaderVariableBasicType(const sh::ShaderVariable & var)635*8975f5c5SAndroid Build Coastguard Worker TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
636*8975f5c5SAndroid Build Coastguard Worker {
637*8975f5c5SAndroid Build Coastguard Worker     switch (var.type)
638*8975f5c5SAndroid Build Coastguard Worker     {
639*8975f5c5SAndroid Build Coastguard Worker         case GL_BOOL:
640*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtBool);
641*8975f5c5SAndroid Build Coastguard Worker         case GL_BOOL_VEC2:
642*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtBool, 2);
643*8975f5c5SAndroid Build Coastguard Worker         case GL_BOOL_VEC3:
644*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtBool, 3);
645*8975f5c5SAndroid Build Coastguard Worker         case GL_BOOL_VEC4:
646*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtBool, 4);
647*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT:
648*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtFloat);
649*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_VEC2:
650*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtFloat, 2);
651*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_VEC3:
652*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtFloat, 3);
653*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_VEC4:
654*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtFloat, 4);
655*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_MAT2:
656*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtFloat, 2, 2);
657*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_MAT3:
658*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtFloat, 3, 3);
659*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_MAT4:
660*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtFloat, 4, 4);
661*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_MAT2x3:
662*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtFloat, 2, 3);
663*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_MAT2x4:
664*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtFloat, 2, 4);
665*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_MAT3x2:
666*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtFloat, 3, 2);
667*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_MAT3x4:
668*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtFloat, 3, 4);
669*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_MAT4x2:
670*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtFloat, 4, 2);
671*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT_MAT4x3:
672*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtFloat, 4, 3);
673*8975f5c5SAndroid Build Coastguard Worker         case GL_INT:
674*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtInt);
675*8975f5c5SAndroid Build Coastguard Worker         case GL_INT_VEC2:
676*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtInt, 2);
677*8975f5c5SAndroid Build Coastguard Worker         case GL_INT_VEC3:
678*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtInt, 3);
679*8975f5c5SAndroid Build Coastguard Worker         case GL_INT_VEC4:
680*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtInt, 4);
681*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_INT:
682*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtUInt);
683*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_INT_VEC2:
684*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtUInt, 2);
685*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_INT_VEC3:
686*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtUInt, 3);
687*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_INT_VEC4:
688*8975f5c5SAndroid Build Coastguard Worker             return TType(EbtUInt, 4);
689*8975f5c5SAndroid Build Coastguard Worker         default:
690*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
691*8975f5c5SAndroid Build Coastguard Worker             return TType();
692*8975f5c5SAndroid Build Coastguard Worker     }
693*8975f5c5SAndroid Build Coastguard Worker }
694*8975f5c5SAndroid Build Coastguard Worker 
DeclareGlobalVariable(TIntermBlock * root,const TVariable * variable)695*8975f5c5SAndroid Build Coastguard Worker void DeclareGlobalVariable(TIntermBlock *root, const TVariable *variable)
696*8975f5c5SAndroid Build Coastguard Worker {
697*8975f5c5SAndroid Build Coastguard Worker     TIntermDeclaration *declaration = new TIntermDeclaration();
698*8975f5c5SAndroid Build Coastguard Worker     declaration->appendDeclarator(new TIntermSymbol(variable));
699*8975f5c5SAndroid Build Coastguard Worker 
700*8975f5c5SAndroid Build Coastguard Worker     TIntermSequence *globalSequence = root->getSequence();
701*8975f5c5SAndroid Build Coastguard Worker     globalSequence->insert(globalSequence->begin(), declaration);
702*8975f5c5SAndroid Build Coastguard Worker }
703*8975f5c5SAndroid Build Coastguard Worker 
704*8975f5c5SAndroid Build Coastguard Worker // GLSL ES 1.0.17 4.6.1 The Invariant Qualifier
CanBeInvariantESSL1(TQualifier qualifier)705*8975f5c5SAndroid Build Coastguard Worker bool CanBeInvariantESSL1(TQualifier qualifier)
706*8975f5c5SAndroid Build Coastguard Worker {
707*8975f5c5SAndroid Build Coastguard Worker     return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) ||
708*8975f5c5SAndroid Build Coastguard Worker            IsBuiltinOutputVariable(qualifier) ||
709*8975f5c5SAndroid Build Coastguard Worker            (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing);
710*8975f5c5SAndroid Build Coastguard Worker }
711*8975f5c5SAndroid Build Coastguard Worker 
712*8975f5c5SAndroid Build Coastguard Worker // GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier
713*8975f5c5SAndroid Build Coastguard Worker // GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier
CanBeInvariantESSL3OrGreater(TQualifier qualifier)714*8975f5c5SAndroid Build Coastguard Worker bool CanBeInvariantESSL3OrGreater(TQualifier qualifier)
715*8975f5c5SAndroid Build Coastguard Worker {
716*8975f5c5SAndroid Build Coastguard Worker     return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut ||
717*8975f5c5SAndroid Build Coastguard Worker            IsBuiltinOutputVariable(qualifier) || qualifier == EvqFragmentInOut;
718*8975f5c5SAndroid Build Coastguard Worker }
719*8975f5c5SAndroid Build Coastguard Worker 
IsBuiltinOutputVariable(TQualifier qualifier)720*8975f5c5SAndroid Build Coastguard Worker bool IsBuiltinOutputVariable(TQualifier qualifier)
721*8975f5c5SAndroid Build Coastguard Worker {
722*8975f5c5SAndroid Build Coastguard Worker     switch (qualifier)
723*8975f5c5SAndroid Build Coastguard Worker     {
724*8975f5c5SAndroid Build Coastguard Worker         case EvqPosition:
725*8975f5c5SAndroid Build Coastguard Worker         case EvqPointSize:
726*8975f5c5SAndroid Build Coastguard Worker         case EvqFragDepth:
727*8975f5c5SAndroid Build Coastguard Worker         case EvqFragColor:
728*8975f5c5SAndroid Build Coastguard Worker         case EvqSecondaryFragColorEXT:
729*8975f5c5SAndroid Build Coastguard Worker         case EvqFragData:
730*8975f5c5SAndroid Build Coastguard Worker         case EvqSecondaryFragDataEXT:
731*8975f5c5SAndroid Build Coastguard Worker         case EvqClipDistance:
732*8975f5c5SAndroid Build Coastguard Worker         case EvqCullDistance:
733*8975f5c5SAndroid Build Coastguard Worker         case EvqLastFragData:
734*8975f5c5SAndroid Build Coastguard Worker         case EvqLastFragColor:
735*8975f5c5SAndroid Build Coastguard Worker         case EvqSampleMask:
736*8975f5c5SAndroid Build Coastguard Worker             return true;
737*8975f5c5SAndroid Build Coastguard Worker         default:
738*8975f5c5SAndroid Build Coastguard Worker             break;
739*8975f5c5SAndroid Build Coastguard Worker     }
740*8975f5c5SAndroid Build Coastguard Worker     return false;
741*8975f5c5SAndroid Build Coastguard Worker }
742*8975f5c5SAndroid Build Coastguard Worker 
IsBuiltinFragmentInputVariable(TQualifier qualifier)743*8975f5c5SAndroid Build Coastguard Worker bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
744*8975f5c5SAndroid Build Coastguard Worker {
745*8975f5c5SAndroid Build Coastguard Worker     switch (qualifier)
746*8975f5c5SAndroid Build Coastguard Worker     {
747*8975f5c5SAndroid Build Coastguard Worker         case EvqFragCoord:
748*8975f5c5SAndroid Build Coastguard Worker         case EvqPointCoord:
749*8975f5c5SAndroid Build Coastguard Worker         case EvqFrontFacing:
750*8975f5c5SAndroid Build Coastguard Worker         case EvqHelperInvocation:
751*8975f5c5SAndroid Build Coastguard Worker         case EvqLastFragData:
752*8975f5c5SAndroid Build Coastguard Worker         case EvqLastFragColor:
753*8975f5c5SAndroid Build Coastguard Worker         case EvqLastFragDepth:
754*8975f5c5SAndroid Build Coastguard Worker         case EvqLastFragStencil:
755*8975f5c5SAndroid Build Coastguard Worker             return true;
756*8975f5c5SAndroid Build Coastguard Worker         default:
757*8975f5c5SAndroid Build Coastguard Worker             break;
758*8975f5c5SAndroid Build Coastguard Worker     }
759*8975f5c5SAndroid Build Coastguard Worker     return false;
760*8975f5c5SAndroid Build Coastguard Worker }
761*8975f5c5SAndroid Build Coastguard Worker 
IsShaderOutput(TQualifier qualifier)762*8975f5c5SAndroid Build Coastguard Worker bool IsShaderOutput(TQualifier qualifier)
763*8975f5c5SAndroid Build Coastguard Worker {
764*8975f5c5SAndroid Build Coastguard Worker     return IsVaryingOut(qualifier) || IsBuiltinOutputVariable(qualifier);
765*8975f5c5SAndroid Build Coastguard Worker }
766*8975f5c5SAndroid Build Coastguard Worker 
IsFragmentOutput(TQualifier qualifier)767*8975f5c5SAndroid Build Coastguard Worker bool IsFragmentOutput(TQualifier qualifier)
768*8975f5c5SAndroid Build Coastguard Worker {
769*8975f5c5SAndroid Build Coastguard Worker     switch (qualifier)
770*8975f5c5SAndroid Build Coastguard Worker     {
771*8975f5c5SAndroid Build Coastguard Worker         case EvqFragmentOut:
772*8975f5c5SAndroid Build Coastguard Worker         case EvqFragmentInOut:
773*8975f5c5SAndroid Build Coastguard Worker             return true;
774*8975f5c5SAndroid Build Coastguard Worker         default:
775*8975f5c5SAndroid Build Coastguard Worker             return false;
776*8975f5c5SAndroid Build Coastguard Worker     }
777*8975f5c5SAndroid Build Coastguard Worker }
778*8975f5c5SAndroid Build Coastguard Worker 
IsOutputNULL(ShShaderOutput output)779*8975f5c5SAndroid Build Coastguard Worker bool IsOutputNULL(ShShaderOutput output)
780*8975f5c5SAndroid Build Coastguard Worker {
781*8975f5c5SAndroid Build Coastguard Worker     return output == SH_NULL_OUTPUT;
782*8975f5c5SAndroid Build Coastguard Worker }
783*8975f5c5SAndroid Build Coastguard Worker 
IsOutputESSL(ShShaderOutput output)784*8975f5c5SAndroid Build Coastguard Worker bool IsOutputESSL(ShShaderOutput output)
785*8975f5c5SAndroid Build Coastguard Worker {
786*8975f5c5SAndroid Build Coastguard Worker     return output == SH_ESSL_OUTPUT;
787*8975f5c5SAndroid Build Coastguard Worker }
788*8975f5c5SAndroid Build Coastguard Worker 
IsOutputGLSL(ShShaderOutput output)789*8975f5c5SAndroid Build Coastguard Worker bool IsOutputGLSL(ShShaderOutput output)
790*8975f5c5SAndroid Build Coastguard Worker {
791*8975f5c5SAndroid Build Coastguard Worker     switch (output)
792*8975f5c5SAndroid Build Coastguard Worker     {
793*8975f5c5SAndroid Build Coastguard Worker         case SH_GLSL_130_OUTPUT:
794*8975f5c5SAndroid Build Coastguard Worker         case SH_GLSL_140_OUTPUT:
795*8975f5c5SAndroid Build Coastguard Worker         case SH_GLSL_150_CORE_OUTPUT:
796*8975f5c5SAndroid Build Coastguard Worker         case SH_GLSL_330_CORE_OUTPUT:
797*8975f5c5SAndroid Build Coastguard Worker         case SH_GLSL_400_CORE_OUTPUT:
798*8975f5c5SAndroid Build Coastguard Worker         case SH_GLSL_410_CORE_OUTPUT:
799*8975f5c5SAndroid Build Coastguard Worker         case SH_GLSL_420_CORE_OUTPUT:
800*8975f5c5SAndroid Build Coastguard Worker         case SH_GLSL_430_CORE_OUTPUT:
801*8975f5c5SAndroid Build Coastguard Worker         case SH_GLSL_440_CORE_OUTPUT:
802*8975f5c5SAndroid Build Coastguard Worker         case SH_GLSL_450_CORE_OUTPUT:
803*8975f5c5SAndroid Build Coastguard Worker         case SH_GLSL_COMPATIBILITY_OUTPUT:
804*8975f5c5SAndroid Build Coastguard Worker             return true;
805*8975f5c5SAndroid Build Coastguard Worker         default:
806*8975f5c5SAndroid Build Coastguard Worker             break;
807*8975f5c5SAndroid Build Coastguard Worker     }
808*8975f5c5SAndroid Build Coastguard Worker     return false;
809*8975f5c5SAndroid Build Coastguard Worker }
IsOutputHLSL(ShShaderOutput output)810*8975f5c5SAndroid Build Coastguard Worker bool IsOutputHLSL(ShShaderOutput output)
811*8975f5c5SAndroid Build Coastguard Worker {
812*8975f5c5SAndroid Build Coastguard Worker     switch (output)
813*8975f5c5SAndroid Build Coastguard Worker     {
814*8975f5c5SAndroid Build Coastguard Worker         case SH_HLSL_3_0_OUTPUT:
815*8975f5c5SAndroid Build Coastguard Worker         case SH_HLSL_4_1_OUTPUT:
816*8975f5c5SAndroid Build Coastguard Worker             return true;
817*8975f5c5SAndroid Build Coastguard Worker         default:
818*8975f5c5SAndroid Build Coastguard Worker             break;
819*8975f5c5SAndroid Build Coastguard Worker     }
820*8975f5c5SAndroid Build Coastguard Worker     return false;
821*8975f5c5SAndroid Build Coastguard Worker }
IsOutputSPIRV(ShShaderOutput output)822*8975f5c5SAndroid Build Coastguard Worker bool IsOutputSPIRV(ShShaderOutput output)
823*8975f5c5SAndroid Build Coastguard Worker {
824*8975f5c5SAndroid Build Coastguard Worker     return output == SH_SPIRV_VULKAN_OUTPUT;
825*8975f5c5SAndroid Build Coastguard Worker }
IsOutputMSL(ShShaderOutput output)826*8975f5c5SAndroid Build Coastguard Worker bool IsOutputMSL(ShShaderOutput output)
827*8975f5c5SAndroid Build Coastguard Worker {
828*8975f5c5SAndroid Build Coastguard Worker     return output == SH_MSL_METAL_OUTPUT;
829*8975f5c5SAndroid Build Coastguard Worker }
IsOutputWGSL(ShShaderOutput output)830*8975f5c5SAndroid Build Coastguard Worker bool IsOutputWGSL(ShShaderOutput output)
831*8975f5c5SAndroid Build Coastguard Worker {
832*8975f5c5SAndroid Build Coastguard Worker     return output == SH_WGSL_OUTPUT;
833*8975f5c5SAndroid Build Coastguard Worker }
834*8975f5c5SAndroid Build Coastguard Worker 
IsInShaderStorageBlock(TIntermTyped * node)835*8975f5c5SAndroid Build Coastguard Worker bool IsInShaderStorageBlock(TIntermTyped *node)
836*8975f5c5SAndroid Build Coastguard Worker {
837*8975f5c5SAndroid Build Coastguard Worker     TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
838*8975f5c5SAndroid Build Coastguard Worker     if (swizzleNode)
839*8975f5c5SAndroid Build Coastguard Worker     {
840*8975f5c5SAndroid Build Coastguard Worker         return IsInShaderStorageBlock(swizzleNode->getOperand());
841*8975f5c5SAndroid Build Coastguard Worker     }
842*8975f5c5SAndroid Build Coastguard Worker 
843*8975f5c5SAndroid Build Coastguard Worker     TIntermBinary *binaryNode = node->getAsBinaryNode();
844*8975f5c5SAndroid Build Coastguard Worker     if (binaryNode)
845*8975f5c5SAndroid Build Coastguard Worker     {
846*8975f5c5SAndroid Build Coastguard Worker         switch (binaryNode->getOp())
847*8975f5c5SAndroid Build Coastguard Worker         {
848*8975f5c5SAndroid Build Coastguard Worker             case EOpIndexDirectInterfaceBlock:
849*8975f5c5SAndroid Build Coastguard Worker             case EOpIndexIndirect:
850*8975f5c5SAndroid Build Coastguard Worker             case EOpIndexDirect:
851*8975f5c5SAndroid Build Coastguard Worker             case EOpIndexDirectStruct:
852*8975f5c5SAndroid Build Coastguard Worker                 return IsInShaderStorageBlock(binaryNode->getLeft());
853*8975f5c5SAndroid Build Coastguard Worker             default:
854*8975f5c5SAndroid Build Coastguard Worker                 return false;
855*8975f5c5SAndroid Build Coastguard Worker         }
856*8975f5c5SAndroid Build Coastguard Worker     }
857*8975f5c5SAndroid Build Coastguard Worker 
858*8975f5c5SAndroid Build Coastguard Worker     const TType &type = node->getType();
859*8975f5c5SAndroid Build Coastguard Worker     return type.getQualifier() == EvqBuffer;
860*8975f5c5SAndroid Build Coastguard Worker }
861*8975f5c5SAndroid Build Coastguard Worker 
GetImageInternalFormatType(TLayoutImageInternalFormat iifq)862*8975f5c5SAndroid Build Coastguard Worker GLenum GetImageInternalFormatType(TLayoutImageInternalFormat iifq)
863*8975f5c5SAndroid Build Coastguard Worker {
864*8975f5c5SAndroid Build Coastguard Worker     switch (iifq)
865*8975f5c5SAndroid Build Coastguard Worker     {
866*8975f5c5SAndroid Build Coastguard Worker         case EiifRGBA32F:
867*8975f5c5SAndroid Build Coastguard Worker             return GL_RGBA32F;
868*8975f5c5SAndroid Build Coastguard Worker         case EiifRGBA16F:
869*8975f5c5SAndroid Build Coastguard Worker             return GL_RGBA16F;
870*8975f5c5SAndroid Build Coastguard Worker         case EiifR32F:
871*8975f5c5SAndroid Build Coastguard Worker             return GL_R32F;
872*8975f5c5SAndroid Build Coastguard Worker         case EiifRGBA32UI:
873*8975f5c5SAndroid Build Coastguard Worker             return GL_RGBA32UI;
874*8975f5c5SAndroid Build Coastguard Worker         case EiifRGBA16UI:
875*8975f5c5SAndroid Build Coastguard Worker             return GL_RGBA16UI;
876*8975f5c5SAndroid Build Coastguard Worker         case EiifRGBA8UI:
877*8975f5c5SAndroid Build Coastguard Worker             return GL_RGBA8UI;
878*8975f5c5SAndroid Build Coastguard Worker         case EiifR32UI:
879*8975f5c5SAndroid Build Coastguard Worker             return GL_R32UI;
880*8975f5c5SAndroid Build Coastguard Worker         case EiifRGBA32I:
881*8975f5c5SAndroid Build Coastguard Worker             return GL_RGBA32I;
882*8975f5c5SAndroid Build Coastguard Worker         case EiifRGBA16I:
883*8975f5c5SAndroid Build Coastguard Worker             return GL_RGBA16I;
884*8975f5c5SAndroid Build Coastguard Worker         case EiifRGBA8I:
885*8975f5c5SAndroid Build Coastguard Worker             return GL_RGBA8I;
886*8975f5c5SAndroid Build Coastguard Worker         case EiifR32I:
887*8975f5c5SAndroid Build Coastguard Worker             return GL_R32I;
888*8975f5c5SAndroid Build Coastguard Worker         case EiifRGBA8:
889*8975f5c5SAndroid Build Coastguard Worker             return GL_RGBA8;
890*8975f5c5SAndroid Build Coastguard Worker         case EiifRGBA8_SNORM:
891*8975f5c5SAndroid Build Coastguard Worker             return GL_RGBA8_SNORM;
892*8975f5c5SAndroid Build Coastguard Worker         default:
893*8975f5c5SAndroid Build Coastguard Worker             return GL_NONE;
894*8975f5c5SAndroid Build Coastguard Worker     }
895*8975f5c5SAndroid Build Coastguard Worker }
896*8975f5c5SAndroid Build Coastguard Worker 
IsSpecWithFunctionBodyNewScope(ShShaderSpec shaderSpec,int shaderVersion)897*8975f5c5SAndroid Build Coastguard Worker bool IsSpecWithFunctionBodyNewScope(ShShaderSpec shaderSpec, int shaderVersion)
898*8975f5c5SAndroid Build Coastguard Worker {
899*8975f5c5SAndroid Build Coastguard Worker     return (shaderVersion == 100 && !sh::IsWebGLBasedSpec(shaderSpec));
900*8975f5c5SAndroid Build Coastguard Worker }
901*8975f5c5SAndroid Build Coastguard Worker 
IsPrecisionApplicableToType(TBasicType type)902*8975f5c5SAndroid Build Coastguard Worker bool IsPrecisionApplicableToType(TBasicType type)
903*8975f5c5SAndroid Build Coastguard Worker {
904*8975f5c5SAndroid Build Coastguard Worker     switch (type)
905*8975f5c5SAndroid Build Coastguard Worker     {
906*8975f5c5SAndroid Build Coastguard Worker         case EbtInt:
907*8975f5c5SAndroid Build Coastguard Worker         case EbtUInt:
908*8975f5c5SAndroid Build Coastguard Worker         case EbtFloat:
909*8975f5c5SAndroid Build Coastguard Worker             // TODO: find all types where precision is applicable; for example samplers.
910*8975f5c5SAndroid Build Coastguard Worker             // http://anglebug.com/42264661
911*8975f5c5SAndroid Build Coastguard Worker             return true;
912*8975f5c5SAndroid Build Coastguard Worker         default:
913*8975f5c5SAndroid Build Coastguard Worker             return false;
914*8975f5c5SAndroid Build Coastguard Worker     }
915*8975f5c5SAndroid Build Coastguard Worker }
916*8975f5c5SAndroid Build Coastguard Worker 
IsRedeclarableBuiltIn(const ImmutableString & name)917*8975f5c5SAndroid Build Coastguard Worker bool IsRedeclarableBuiltIn(const ImmutableString &name)
918*8975f5c5SAndroid Build Coastguard Worker {
919*8975f5c5SAndroid Build Coastguard Worker     return name == "gl_ClipDistance" || name == "gl_CullDistance" || name == "gl_FragDepth" ||
920*8975f5c5SAndroid Build Coastguard Worker            name == "gl_LastFragData" || name == "gl_LastFragColorARM" ||
921*8975f5c5SAndroid Build Coastguard Worker            name == "gl_LastFragDepthARM" || name == "gl_LastFragStencilARM" ||
922*8975f5c5SAndroid Build Coastguard Worker            name == "gl_PerVertex" || name == "gl_Position" || name == "gl_PointSize";
923*8975f5c5SAndroid Build Coastguard Worker }
924*8975f5c5SAndroid Build Coastguard Worker 
FindFieldIndex(const TFieldList & fieldList,const char * fieldName)925*8975f5c5SAndroid Build Coastguard Worker size_t FindFieldIndex(const TFieldList &fieldList, const char *fieldName)
926*8975f5c5SAndroid Build Coastguard Worker {
927*8975f5c5SAndroid Build Coastguard Worker     for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex)
928*8975f5c5SAndroid Build Coastguard Worker     {
929*8975f5c5SAndroid Build Coastguard Worker         if (strcmp(fieldList[fieldIndex]->name().data(), fieldName) == 0)
930*8975f5c5SAndroid Build Coastguard Worker         {
931*8975f5c5SAndroid Build Coastguard Worker             return fieldIndex;
932*8975f5c5SAndroid Build Coastguard Worker         }
933*8975f5c5SAndroid Build Coastguard Worker     }
934*8975f5c5SAndroid Build Coastguard Worker     UNREACHABLE();
935*8975f5c5SAndroid Build Coastguard Worker     return 0;
936*8975f5c5SAndroid Build Coastguard Worker }
937*8975f5c5SAndroid Build Coastguard Worker 
ViewDeclaration(TIntermDeclaration & declNode,uint32_t index)938*8975f5c5SAndroid Build Coastguard Worker Declaration ViewDeclaration(TIntermDeclaration &declNode, uint32_t index)
939*8975f5c5SAndroid Build Coastguard Worker {
940*8975f5c5SAndroid Build Coastguard Worker     ASSERT(declNode.getChildCount() > index);
941*8975f5c5SAndroid Build Coastguard Worker     TIntermNode *childNode = declNode.getChildNode(index);
942*8975f5c5SAndroid Build Coastguard Worker     ASSERT(childNode);
943*8975f5c5SAndroid Build Coastguard Worker     TIntermSymbol *symbolNode;
944*8975f5c5SAndroid Build Coastguard Worker     if ((symbolNode = childNode->getAsSymbolNode()))
945*8975f5c5SAndroid Build Coastguard Worker     {
946*8975f5c5SAndroid Build Coastguard Worker         return {*symbolNode, nullptr};
947*8975f5c5SAndroid Build Coastguard Worker     }
948*8975f5c5SAndroid Build Coastguard Worker     else
949*8975f5c5SAndroid Build Coastguard Worker     {
950*8975f5c5SAndroid Build Coastguard Worker         TIntermBinary *initNode = childNode->getAsBinaryNode();
951*8975f5c5SAndroid Build Coastguard Worker         ASSERT(initNode);
952*8975f5c5SAndroid Build Coastguard Worker         ASSERT(initNode->getOp() == TOperator::EOpInitialize);
953*8975f5c5SAndroid Build Coastguard Worker         symbolNode = initNode->getLeft()->getAsSymbolNode();
954*8975f5c5SAndroid Build Coastguard Worker         ASSERT(symbolNode);
955*8975f5c5SAndroid Build Coastguard Worker         return {*symbolNode, initNode->getRight()};
956*8975f5c5SAndroid Build Coastguard Worker     }
957*8975f5c5SAndroid Build Coastguard Worker }
958*8975f5c5SAndroid Build Coastguard Worker 
959*8975f5c5SAndroid Build Coastguard Worker }  // namespace sh
960