• 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/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/7279): For now, we can expect PLS handles to be rewritten to images
402             // 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             case EbpUndefined:
423                 // Desktop specs do not use precision
424                 return GL_NONE;
425             default:
426                 UNREACHABLE();
427         }
428     }
429     else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
430     {
431         switch (type.getPrecision())
432         {
433             case EbpHigh:
434                 return GL_HIGH_INT;
435             case EbpMedium:
436                 return GL_MEDIUM_INT;
437             case EbpLow:
438                 return GL_LOW_INT;
439             case EbpUndefined:
440                 // Desktop specs do not use precision
441                 return GL_NONE;
442             default:
443                 UNREACHABLE();
444         }
445     }
446 
447     // Other types (boolean, sampler) don't have a precision
448     return GL_NONE;
449 }
450 
ArrayString(const TType & type)451 ImmutableString ArrayString(const TType &type)
452 {
453     if (!type.isArray())
454         return ImmutableString("");
455 
456     const TSpan<const unsigned int> &arraySizes     = type.getArraySizes();
457     constexpr const size_t kMaxDecimalDigitsPerSize = 10u;
458     ImmutableStringBuilder arrayString(arraySizes.size() * (kMaxDecimalDigitsPerSize + 2u));
459     for (auto arraySizeIter = arraySizes.rbegin(); arraySizeIter != arraySizes.rend();
460          ++arraySizeIter)
461     {
462         arrayString << "[";
463         if (*arraySizeIter > 0)
464         {
465             arrayString.appendDecimal(*arraySizeIter);
466         }
467         arrayString << "]";
468     }
469     return arrayString;
470 }
471 
GetTypeName(const TType & type,ShHashFunction64 hashFunction,NameMap * nameMap)472 ImmutableString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap)
473 {
474     if (type.getBasicType() == EbtStruct)
475         return HashName(type.getStruct(), hashFunction, nameMap);
476     else
477         return ImmutableString(type.getBuiltInTypeNameString());
478 }
479 
IsVaryingOut(TQualifier qualifier)480 bool IsVaryingOut(TQualifier qualifier)
481 {
482     switch (qualifier)
483     {
484         case EvqVaryingOut:
485         case EvqVertexOut:
486         case EvqGeometryOut:
487         case EvqTessControlOut:
488         case EvqTessEvaluationOut:
489         case EvqPatchOut:
490             return true;
491 
492         default:
493             break;
494     }
495 
496     return IsInterpolationOut(qualifier);
497 }
498 
IsVaryingIn(TQualifier qualifier)499 bool IsVaryingIn(TQualifier qualifier)
500 {
501     switch (qualifier)
502     {
503         case EvqVaryingIn:
504         case EvqFragmentIn:
505         case EvqGeometryIn:
506         case EvqTessControlIn:
507         case EvqTessEvaluationIn:
508         case EvqPatchIn:
509             return true;
510 
511         default:
512             break;
513     }
514 
515     return IsInterpolationIn(qualifier);
516 }
517 
IsVarying(TQualifier qualifier)518 bool IsVarying(TQualifier qualifier)
519 {
520     return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
521 }
522 
IsMatrixGLType(GLenum type)523 bool IsMatrixGLType(GLenum type)
524 {
525     switch (type)
526     {
527         case GL_FLOAT_MAT2:
528         case GL_FLOAT_MAT3:
529         case GL_FLOAT_MAT4:
530         case GL_FLOAT_MAT2x3:
531         case GL_FLOAT_MAT2x4:
532         case GL_FLOAT_MAT3x2:
533         case GL_FLOAT_MAT3x4:
534         case GL_FLOAT_MAT4x2:
535         case GL_FLOAT_MAT4x3:
536             return true;
537         default:
538             return false;
539     }
540 }
541 
IsGeometryShaderInput(GLenum shaderType,TQualifier qualifier)542 bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier)
543 {
544     return (qualifier == EvqGeometryIn) ||
545            ((shaderType == GL_GEOMETRY_SHADER_EXT) && IsInterpolationIn(qualifier));
546 }
547 
IsTessellationControlShaderInput(GLenum shaderType,TQualifier qualifier)548 bool IsTessellationControlShaderInput(GLenum shaderType, TQualifier qualifier)
549 {
550     return qualifier == EvqTessControlIn ||
551            ((shaderType == GL_TESS_CONTROL_SHADER) && IsInterpolationIn(qualifier));
552 }
553 
IsTessellationControlShaderOutput(GLenum shaderType,TQualifier qualifier)554 bool IsTessellationControlShaderOutput(GLenum shaderType, TQualifier qualifier)
555 {
556     return qualifier == EvqTessControlOut ||
557            ((shaderType == GL_TESS_CONTROL_SHADER) && IsInterpolationOut(qualifier));
558 }
559 
IsTessellationEvaluationShaderInput(GLenum shaderType,TQualifier qualifier)560 bool IsTessellationEvaluationShaderInput(GLenum shaderType, TQualifier qualifier)
561 {
562     return qualifier == EvqTessEvaluationIn ||
563            ((shaderType == GL_TESS_EVALUATION_SHADER) && IsInterpolationIn(qualifier));
564 }
565 
GetInterpolationType(TQualifier qualifier)566 InterpolationType GetInterpolationType(TQualifier qualifier)
567 {
568     switch (qualifier)
569     {
570         case EvqFlatIn:
571         case EvqFlatOut:
572         // The auxiliary storage qualifier patch is not used for interpolation
573         // it is a compile-time error to use interpolation qualifiers with patch
574         case EvqPatchIn:
575         case EvqPatchOut:
576             return INTERPOLATION_FLAT;
577 
578         case EvqNoPerspectiveIn:
579         case EvqNoPerspectiveOut:
580             return INTERPOLATION_NOPERSPECTIVE;
581 
582         case EvqNoPerspectiveCentroidIn:
583         case EvqNoPerspectiveCentroidOut:
584             return INTERPOLATION_NOPERSPECTIVE_CENTROID;
585 
586         case EvqNoPerspectiveSampleIn:
587         case EvqNoPerspectiveSampleOut:
588             return INTERPOLATION_NOPERSPECTIVE_SAMPLE;
589 
590         case EvqSmoothIn:
591         case EvqSmoothOut:
592         case EvqVertexOut:
593         case EvqFragmentIn:
594         case EvqVaryingIn:
595         case EvqVaryingOut:
596         case EvqGeometryIn:
597         case EvqGeometryOut:
598         case EvqTessControlIn:
599         case EvqTessControlOut:
600         case EvqTessEvaluationIn:
601         case EvqTessEvaluationOut:
602             return INTERPOLATION_SMOOTH;
603 
604         case EvqCentroidIn:
605         case EvqCentroidOut:
606             return INTERPOLATION_CENTROID;
607 
608         case EvqSampleIn:
609         case EvqSampleOut:
610             return INTERPOLATION_SAMPLE;
611         default:
612             UNREACHABLE();
613             return INTERPOLATION_SMOOTH;
614     }
615 }
616 
617 // a field may not have qualifer without in or out.
GetFieldInterpolationType(TQualifier qualifier)618 InterpolationType GetFieldInterpolationType(TQualifier qualifier)
619 {
620     switch (qualifier)
621     {
622         case EvqSmooth:
623             return INTERPOLATION_SMOOTH;
624         case EvqFlat:
625             return INTERPOLATION_FLAT;
626         case EvqNoPerspective:
627             return INTERPOLATION_NOPERSPECTIVE;
628         case EvqCentroid:
629             return INTERPOLATION_CENTROID;
630         case EvqSample:
631             return INTERPOLATION_SAMPLE;
632         case EvqNoPerspectiveCentroid:
633             return INTERPOLATION_NOPERSPECTIVE_CENTROID;
634         case EvqNoPerspectiveSample:
635             return INTERPOLATION_NOPERSPECTIVE_SAMPLE;
636         default:
637             return GetInterpolationType(qualifier);
638     }
639 }
640 
GetShaderVariableBasicType(const sh::ShaderVariable & var)641 TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
642 {
643     switch (var.type)
644     {
645         case GL_BOOL:
646             return TType(EbtBool);
647         case GL_BOOL_VEC2:
648             return TType(EbtBool, 2);
649         case GL_BOOL_VEC3:
650             return TType(EbtBool, 3);
651         case GL_BOOL_VEC4:
652             return TType(EbtBool, 4);
653         case GL_FLOAT:
654             return TType(EbtFloat);
655         case GL_FLOAT_VEC2:
656             return TType(EbtFloat, 2);
657         case GL_FLOAT_VEC3:
658             return TType(EbtFloat, 3);
659         case GL_FLOAT_VEC4:
660             return TType(EbtFloat, 4);
661         case GL_FLOAT_MAT2:
662             return TType(EbtFloat, 2, 2);
663         case GL_FLOAT_MAT3:
664             return TType(EbtFloat, 3, 3);
665         case GL_FLOAT_MAT4:
666             return TType(EbtFloat, 4, 4);
667         case GL_FLOAT_MAT2x3:
668             return TType(EbtFloat, 2, 3);
669         case GL_FLOAT_MAT2x4:
670             return TType(EbtFloat, 2, 4);
671         case GL_FLOAT_MAT3x2:
672             return TType(EbtFloat, 3, 2);
673         case GL_FLOAT_MAT3x4:
674             return TType(EbtFloat, 3, 4);
675         case GL_FLOAT_MAT4x2:
676             return TType(EbtFloat, 4, 2);
677         case GL_FLOAT_MAT4x3:
678             return TType(EbtFloat, 4, 3);
679         case GL_INT:
680             return TType(EbtInt);
681         case GL_INT_VEC2:
682             return TType(EbtInt, 2);
683         case GL_INT_VEC3:
684             return TType(EbtInt, 3);
685         case GL_INT_VEC4:
686             return TType(EbtInt, 4);
687         case GL_UNSIGNED_INT:
688             return TType(EbtUInt);
689         case GL_UNSIGNED_INT_VEC2:
690             return TType(EbtUInt, 2);
691         case GL_UNSIGNED_INT_VEC3:
692             return TType(EbtUInt, 3);
693         case GL_UNSIGNED_INT_VEC4:
694             return TType(EbtUInt, 4);
695         default:
696             UNREACHABLE();
697             return TType();
698     }
699 }
700 
DeclareGlobalVariable(TIntermBlock * root,const TVariable * variable)701 void DeclareGlobalVariable(TIntermBlock *root, const TVariable *variable)
702 {
703     TIntermDeclaration *declaration = new TIntermDeclaration();
704     declaration->appendDeclarator(new TIntermSymbol(variable));
705 
706     TIntermSequence *globalSequence = root->getSequence();
707     globalSequence->insert(globalSequence->begin(), declaration);
708 }
709 
710 // GLSL ES 1.0.17 4.6.1 The Invariant Qualifier
CanBeInvariantESSL1(TQualifier qualifier)711 bool CanBeInvariantESSL1(TQualifier qualifier)
712 {
713     return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) ||
714            IsBuiltinOutputVariable(qualifier) ||
715            (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing);
716 }
717 
718 // GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier
719 // GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier
CanBeInvariantESSL3OrGreater(TQualifier qualifier)720 bool CanBeInvariantESSL3OrGreater(TQualifier qualifier)
721 {
722     return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut ||
723            IsBuiltinOutputVariable(qualifier) || qualifier == EvqFragmentInOut;
724 }
725 
IsBuiltinOutputVariable(TQualifier qualifier)726 bool IsBuiltinOutputVariable(TQualifier qualifier)
727 {
728     switch (qualifier)
729     {
730         case EvqPosition:
731         case EvqPointSize:
732         case EvqFragDepth:
733         case EvqFragColor:
734         case EvqSecondaryFragColorEXT:
735         case EvqFragData:
736         case EvqSecondaryFragDataEXT:
737         case EvqClipDistance:
738         case EvqCullDistance:
739         case EvqLastFragData:
740         case EvqLastFragColor:
741         case EvqSampleMask:
742             return true;
743         default:
744             break;
745     }
746     return false;
747 }
748 
IsBuiltinFragmentInputVariable(TQualifier qualifier)749 bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
750 {
751     switch (qualifier)
752     {
753         case EvqFragCoord:
754         case EvqPointCoord:
755         case EvqFrontFacing:
756         case EvqHelperInvocation:
757         case EvqLastFragData:
758         case EvqLastFragColor:
759             return true;
760         default:
761             break;
762     }
763     return false;
764 }
765 
IsShaderOutput(TQualifier qualifier)766 bool IsShaderOutput(TQualifier qualifier)
767 {
768     return IsVaryingOut(qualifier) || IsBuiltinOutputVariable(qualifier);
769 }
770 
IsFragmentOutput(TQualifier qualifier)771 bool IsFragmentOutput(TQualifier qualifier)
772 {
773     switch (qualifier)
774     {
775         case EvqFragmentOut:
776         case EvqFragmentInOut:
777             return true;
778         default:
779             return false;
780     }
781 }
782 
IsOutputESSL(ShShaderOutput output)783 bool IsOutputESSL(ShShaderOutput output)
784 {
785     return output == SH_ESSL_OUTPUT;
786 }
787 
IsOutputGLSL(ShShaderOutput output)788 bool IsOutputGLSL(ShShaderOutput output)
789 {
790     switch (output)
791     {
792         case SH_GLSL_130_OUTPUT:
793         case SH_GLSL_140_OUTPUT:
794         case SH_GLSL_150_CORE_OUTPUT:
795         case SH_GLSL_330_CORE_OUTPUT:
796         case SH_GLSL_400_CORE_OUTPUT:
797         case SH_GLSL_410_CORE_OUTPUT:
798         case SH_GLSL_420_CORE_OUTPUT:
799         case SH_GLSL_430_CORE_OUTPUT:
800         case SH_GLSL_440_CORE_OUTPUT:
801         case SH_GLSL_450_CORE_OUTPUT:
802         case SH_GLSL_COMPATIBILITY_OUTPUT:
803             return true;
804         default:
805             break;
806     }
807     return false;
808 }
IsOutputHLSL(ShShaderOutput output)809 bool IsOutputHLSL(ShShaderOutput output)
810 {
811     switch (output)
812     {
813         case SH_HLSL_3_0_OUTPUT:
814         case SH_HLSL_4_1_OUTPUT:
815         case SH_HLSL_4_0_FL9_3_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 
GetConversion(TBasicType t1,TBasicType t2)902 ImplicitTypeConversion GetConversion(TBasicType t1, TBasicType t2)
903 {
904     if (t1 == t2)
905         return ImplicitTypeConversion::Same;
906 
907     switch (t1)
908     {
909         case EbtInt:
910             switch (t2)
911             {
912                 case EbtInt:
913                     UNREACHABLE();
914                     break;
915                 case EbtUInt:
916                     return ImplicitTypeConversion::Invalid;
917                 case EbtFloat:
918                     return ImplicitTypeConversion::Left;
919                 default:
920                     return ImplicitTypeConversion::Invalid;
921             }
922             break;
923         case EbtUInt:
924             switch (t2)
925             {
926                 case EbtInt:
927                     return ImplicitTypeConversion::Invalid;
928                 case EbtUInt:
929                     UNREACHABLE();
930                     break;
931                 case EbtFloat:
932                     return ImplicitTypeConversion::Left;
933                 default:
934                     return ImplicitTypeConversion::Invalid;
935             }
936             break;
937         case EbtFloat:
938             switch (t2)
939             {
940                 case EbtInt:
941                 case EbtUInt:
942                     return ImplicitTypeConversion::Right;
943                 case EbtFloat:
944                     UNREACHABLE();
945                     break;
946                 default:
947                     return ImplicitTypeConversion::Invalid;
948             }
949             break;
950         default:
951             return ImplicitTypeConversion::Invalid;
952     }
953     return ImplicitTypeConversion::Invalid;
954 }
955 
IsValidImplicitConversion(sh::ImplicitTypeConversion conversion,TOperator op)956 bool IsValidImplicitConversion(sh::ImplicitTypeConversion conversion, TOperator op)
957 {
958     switch (conversion)
959     {
960         case sh::ImplicitTypeConversion::Same:
961             return true;
962         case sh::ImplicitTypeConversion::Left:
963             switch (op)
964             {
965                 case EOpEqual:
966                 case EOpNotEqual:
967                 case EOpLessThan:
968                 case EOpGreaterThan:
969                 case EOpLessThanEqual:
970                 case EOpGreaterThanEqual:
971                 case EOpAdd:
972                 case EOpSub:
973                 case EOpMul:
974                 case EOpDiv:
975                     return true;
976                 default:
977                     break;
978             }
979             break;
980         case sh::ImplicitTypeConversion::Right:
981             switch (op)
982             {
983                 case EOpAssign:
984                 case EOpInitialize:
985                 case EOpEqual:
986                 case EOpNotEqual:
987                 case EOpLessThan:
988                 case EOpGreaterThan:
989                 case EOpLessThanEqual:
990                 case EOpGreaterThanEqual:
991                 case EOpAdd:
992                 case EOpSub:
993                 case EOpMul:
994                 case EOpDiv:
995                 case EOpAddAssign:
996                 case EOpSubAssign:
997                 case EOpMulAssign:
998                 case EOpDivAssign:
999                     return true;
1000                 default:
1001                     break;
1002             }
1003             break;
1004         case sh::ImplicitTypeConversion::Invalid:
1005             break;
1006     }
1007     return false;
1008 }
1009 
IsPrecisionApplicableToType(TBasicType type)1010 bool IsPrecisionApplicableToType(TBasicType type)
1011 {
1012     switch (type)
1013     {
1014         case EbtInt:
1015         case EbtUInt:
1016         case EbtFloat:
1017             // TODO: find all types where precision is applicable; for example samplers.
1018             // http://anglebug.com/6132
1019             return true;
1020         default:
1021             return false;
1022     }
1023 }
1024 
IsRedeclarableBuiltIn(const ImmutableString & name)1025 bool IsRedeclarableBuiltIn(const ImmutableString &name)
1026 {
1027     return name == "gl_ClipDistance" || name == "gl_CullDistance" || name == "gl_FragDepth" ||
1028            name == "gl_LastFragData" || name == "gl_LastFragColorARM" || name == "gl_PerVertex" ||
1029            name == "gl_Position" || name == "gl_PointSize";
1030 }
1031 
FindFieldIndex(const TFieldList & fieldList,const char * fieldName)1032 size_t FindFieldIndex(const TFieldList &fieldList, const char *fieldName)
1033 {
1034     for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex)
1035     {
1036         if (strcmp(fieldList[fieldIndex]->name().data(), fieldName) == 0)
1037         {
1038             return fieldIndex;
1039         }
1040     }
1041     UNREACHABLE();
1042     return 0;
1043 }
1044 
ViewDeclaration(TIntermDeclaration & declNode,uint32_t index)1045 Declaration ViewDeclaration(TIntermDeclaration &declNode, uint32_t index)
1046 {
1047     ASSERT(declNode.getChildCount() > index);
1048     TIntermNode *childNode = declNode.getChildNode(index);
1049     ASSERT(childNode);
1050     TIntermSymbol *symbolNode;
1051     if ((symbolNode = childNode->getAsSymbolNode()))
1052     {
1053         return {*symbolNode, nullptr};
1054     }
1055     else
1056     {
1057         TIntermBinary *initNode = childNode->getAsBinaryNode();
1058         ASSERT(initNode);
1059         ASSERT(initNode->getOp() == TOperator::EOpInitialize);
1060         symbolNode = initNode->getLeft()->getAsSymbolNode();
1061         ASSERT(symbolNode);
1062         return {*symbolNode, initNode->getRight()};
1063     }
1064 }
1065 
1066 }  // namespace sh
1067