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