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