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