• 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 EbtISampler2D:
382             return GL_INT_SAMPLER_2D;
383         case EbtISampler3D:
384             return GL_INT_SAMPLER_3D;
385         case EbtISamplerCube:
386             return GL_INT_SAMPLER_CUBE;
387         case EbtISampler2DArray:
388             return GL_INT_SAMPLER_2D_ARRAY;
389         case EbtISampler2DMS:
390             return GL_INT_SAMPLER_2D_MULTISAMPLE;
391         case EbtISampler2DMSArray:
392             return GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY;
393         case EbtUSampler2D:
394             return GL_UNSIGNED_INT_SAMPLER_2D;
395         case EbtUSampler3D:
396             return GL_UNSIGNED_INT_SAMPLER_3D;
397         case EbtUSamplerCube:
398             return GL_UNSIGNED_INT_SAMPLER_CUBE;
399         case EbtUSampler2DArray:
400             return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
401         case EbtUSampler2DMS:
402             return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE;
403         case EbtUSampler2DMSArray:
404             return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY;
405         case EbtSampler2DShadow:
406             return GL_SAMPLER_2D_SHADOW;
407         case EbtSamplerCubeShadow:
408             return GL_SAMPLER_CUBE_SHADOW;
409         case EbtSampler2DArrayShadow:
410             return GL_SAMPLER_2D_ARRAY_SHADOW;
411         case EbtImage2D:
412             return GL_IMAGE_2D;
413         case EbtIImage2D:
414             return GL_INT_IMAGE_2D;
415         case EbtUImage2D:
416             return GL_UNSIGNED_INT_IMAGE_2D;
417         case EbtImage2DArray:
418             return GL_IMAGE_2D_ARRAY;
419         case EbtIImage2DArray:
420             return GL_INT_IMAGE_2D_ARRAY;
421         case EbtUImage2DArray:
422             return GL_UNSIGNED_INT_IMAGE_2D_ARRAY;
423         case EbtImage3D:
424             return GL_IMAGE_3D;
425         case EbtIImage3D:
426             return GL_INT_IMAGE_3D;
427         case EbtUImage3D:
428             return GL_UNSIGNED_INT_IMAGE_3D;
429         case EbtImageCube:
430             return GL_IMAGE_CUBE;
431         case EbtIImageCube:
432             return GL_INT_IMAGE_CUBE;
433         case EbtUImageCube:
434             return GL_UNSIGNED_INT_IMAGE_CUBE;
435         case EbtAtomicCounter:
436             return GL_UNSIGNED_INT_ATOMIC_COUNTER;
437         case EbtSamplerVideoWEBGL:
438             return GL_SAMPLER_VIDEO_IMAGE_WEBGL;
439         default:
440             UNREACHABLE();
441     }
442 
443     return GL_NONE;
444 }
445 
GLVariablePrecision(const TType & type)446 GLenum GLVariablePrecision(const TType &type)
447 {
448     if (type.getBasicType() == EbtFloat)
449     {
450         switch (type.getPrecision())
451         {
452             case EbpHigh:
453                 return GL_HIGH_FLOAT;
454             case EbpMedium:
455                 return GL_MEDIUM_FLOAT;
456             case EbpLow:
457                 return GL_LOW_FLOAT;
458             case EbpUndefined:
459                 // Desktop specs do not use precision
460                 return GL_NONE;
461             default:
462                 UNREACHABLE();
463         }
464     }
465     else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
466     {
467         switch (type.getPrecision())
468         {
469             case EbpHigh:
470                 return GL_HIGH_INT;
471             case EbpMedium:
472                 return GL_MEDIUM_INT;
473             case EbpLow:
474                 return GL_LOW_INT;
475             case EbpUndefined:
476                 // Desktop specs do not use precision
477                 return GL_NONE;
478             default:
479                 UNREACHABLE();
480         }
481     }
482 
483     // Other types (boolean, sampler) don't have a precision
484     return GL_NONE;
485 }
486 
ArrayString(const TType & type)487 ImmutableString ArrayString(const TType &type)
488 {
489     if (!type.isArray())
490         return ImmutableString("");
491 
492     const TSpan<const unsigned int> &arraySizes     = type.getArraySizes();
493     constexpr const size_t kMaxDecimalDigitsPerSize = 10u;
494     ImmutableStringBuilder arrayString(arraySizes.size() * (kMaxDecimalDigitsPerSize + 2u));
495     for (auto arraySizeIter = arraySizes.rbegin(); arraySizeIter != arraySizes.rend();
496          ++arraySizeIter)
497     {
498         arrayString << "[";
499         if (*arraySizeIter > 0)
500         {
501             arrayString.appendDecimal(*arraySizeIter);
502         }
503         arrayString << "]";
504     }
505     return arrayString;
506 }
507 
GetTypeName(const TType & type,ShHashFunction64 hashFunction,NameMap * nameMap)508 ImmutableString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap)
509 {
510     if (type.getBasicType() == EbtStruct)
511         return HashName(type.getStruct(), hashFunction, nameMap);
512     else
513         return ImmutableString(type.getBuiltInTypeNameString());
514 }
515 
IsVaryingOut(TQualifier qualifier)516 bool IsVaryingOut(TQualifier qualifier)
517 {
518     switch (qualifier)
519     {
520         case EvqVaryingOut:
521         case EvqSmoothOut:
522         case EvqFlatOut:
523         case EvqNoPerspectiveOut:
524         case EvqCentroidOut:
525         case EvqVertexOut:
526         case EvqGeometryOut:
527             return true;
528 
529         default:
530             break;
531     }
532 
533     return false;
534 }
535 
IsVaryingIn(TQualifier qualifier)536 bool IsVaryingIn(TQualifier qualifier)
537 {
538     switch (qualifier)
539     {
540         case EvqVaryingIn:
541         case EvqSmoothIn:
542         case EvqFlatIn:
543         case EvqNoPerspectiveIn:
544         case EvqCentroidIn:
545         case EvqFragmentIn:
546         case EvqGeometryIn:
547             return true;
548 
549         default:
550             break;
551     }
552 
553     return false;
554 }
555 
IsVarying(TQualifier qualifier)556 bool IsVarying(TQualifier qualifier)
557 {
558     return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
559 }
560 
IsGeometryShaderInput(GLenum shaderType,TQualifier qualifier)561 bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier)
562 {
563     return (qualifier == EvqGeometryIn) ||
564            ((shaderType == GL_GEOMETRY_SHADER_EXT) && IsInterpolationIn(qualifier));
565 }
566 
GetInterpolationType(TQualifier qualifier)567 InterpolationType GetInterpolationType(TQualifier qualifier)
568 {
569     switch (qualifier)
570     {
571         case EvqFlatIn:
572         case EvqFlatOut:
573             return INTERPOLATION_FLAT;
574 
575         case EvqNoPerspectiveIn:
576         case EvqNoPerspectiveOut:
577             return INTERPOLATION_NOPERSPECTIVE;
578 
579         case EvqSmoothIn:
580         case EvqSmoothOut:
581         case EvqVertexOut:
582         case EvqFragmentIn:
583         case EvqVaryingIn:
584         case EvqVaryingOut:
585         case EvqGeometryIn:
586         case EvqGeometryOut:
587             return INTERPOLATION_SMOOTH;
588 
589         case EvqCentroidIn:
590         case EvqCentroidOut:
591             return INTERPOLATION_CENTROID;
592 
593         default:
594             UNREACHABLE();
595 #if !UNREACHABLE_IS_NORETURN
596             return INTERPOLATION_SMOOTH;
597 #endif
598     }
599 }
600 
GetShaderVariableBasicType(const sh::ShaderVariable & var)601 TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
602 {
603     switch (var.type)
604     {
605         case GL_BOOL:
606             return TType(EbtBool);
607         case GL_BOOL_VEC2:
608             return TType(EbtBool, 2);
609         case GL_BOOL_VEC3:
610             return TType(EbtBool, 3);
611         case GL_BOOL_VEC4:
612             return TType(EbtBool, 4);
613         case GL_FLOAT:
614             return TType(EbtFloat);
615         case GL_FLOAT_VEC2:
616             return TType(EbtFloat, 2);
617         case GL_FLOAT_VEC3:
618             return TType(EbtFloat, 3);
619         case GL_FLOAT_VEC4:
620             return TType(EbtFloat, 4);
621         case GL_FLOAT_MAT2:
622             return TType(EbtFloat, 2, 2);
623         case GL_FLOAT_MAT3:
624             return TType(EbtFloat, 3, 3);
625         case GL_FLOAT_MAT4:
626             return TType(EbtFloat, 4, 4);
627         case GL_FLOAT_MAT2x3:
628             return TType(EbtFloat, 2, 3);
629         case GL_FLOAT_MAT2x4:
630             return TType(EbtFloat, 2, 4);
631         case GL_FLOAT_MAT3x2:
632             return TType(EbtFloat, 3, 2);
633         case GL_FLOAT_MAT3x4:
634             return TType(EbtFloat, 3, 4);
635         case GL_FLOAT_MAT4x2:
636             return TType(EbtFloat, 4, 2);
637         case GL_FLOAT_MAT4x3:
638             return TType(EbtFloat, 4, 3);
639         case GL_INT:
640             return TType(EbtInt);
641         case GL_INT_VEC2:
642             return TType(EbtInt, 2);
643         case GL_INT_VEC3:
644             return TType(EbtInt, 3);
645         case GL_INT_VEC4:
646             return TType(EbtInt, 4);
647         case GL_UNSIGNED_INT:
648             return TType(EbtUInt);
649         case GL_UNSIGNED_INT_VEC2:
650             return TType(EbtUInt, 2);
651         case GL_UNSIGNED_INT_VEC3:
652             return TType(EbtUInt, 3);
653         case GL_UNSIGNED_INT_VEC4:
654             return TType(EbtUInt, 4);
655         default:
656             UNREACHABLE();
657 #if !UNREACHABLE_IS_NORETURN
658             return TType();
659 #endif
660     }
661 }
662 
DeclareGlobalVariable(TIntermBlock * root,const TVariable * variable)663 void DeclareGlobalVariable(TIntermBlock *root, const TVariable *variable)
664 {
665     TIntermDeclaration *declaration = new TIntermDeclaration();
666     declaration->appendDeclarator(new TIntermSymbol(variable));
667 
668     TIntermSequence *globalSequence = root->getSequence();
669     globalSequence->insert(globalSequence->begin(), declaration);
670 }
671 
672 // GLSL ES 1.0.17 4.6.1 The Invariant Qualifier
CanBeInvariantESSL1(TQualifier qualifier)673 bool CanBeInvariantESSL1(TQualifier qualifier)
674 {
675     return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) ||
676            IsBuiltinOutputVariable(qualifier) ||
677            (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing);
678 }
679 
680 // GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier
681 // GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier
CanBeInvariantESSL3OrGreater(TQualifier qualifier)682 bool CanBeInvariantESSL3OrGreater(TQualifier qualifier)
683 {
684     return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut ||
685            IsBuiltinOutputVariable(qualifier);
686 }
687 
IsBuiltinOutputVariable(TQualifier qualifier)688 bool IsBuiltinOutputVariable(TQualifier qualifier)
689 {
690     switch (qualifier)
691     {
692         case EvqPosition:
693         case EvqPointSize:
694         case EvqFragDepth:
695         case EvqFragDepthEXT:
696         case EvqFragColor:
697         case EvqSecondaryFragColorEXT:
698         case EvqFragData:
699         case EvqSecondaryFragDataEXT:
700             return true;
701         default:
702             break;
703     }
704     return false;
705 }
706 
IsBuiltinFragmentInputVariable(TQualifier qualifier)707 bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
708 {
709     switch (qualifier)
710     {
711         case EvqFragCoord:
712         case EvqPointCoord:
713         case EvqFrontFacing:
714         case EvqHelperInvocation:
715             return true;
716         default:
717             break;
718     }
719     return false;
720 }
721 
IsShaderOutput(TQualifier qualifier)722 bool IsShaderOutput(TQualifier qualifier)
723 {
724     return IsVaryingOut(qualifier) || IsBuiltinOutputVariable(qualifier);
725 }
726 
IsOutputESSL(ShShaderOutput output)727 bool IsOutputESSL(ShShaderOutput output)
728 {
729     return output == SH_ESSL_OUTPUT;
730 }
731 
IsOutputGLSL(ShShaderOutput output)732 bool IsOutputGLSL(ShShaderOutput output)
733 {
734     switch (output)
735     {
736         case SH_GLSL_130_OUTPUT:
737         case SH_GLSL_140_OUTPUT:
738         case SH_GLSL_150_CORE_OUTPUT:
739         case SH_GLSL_330_CORE_OUTPUT:
740         case SH_GLSL_400_CORE_OUTPUT:
741         case SH_GLSL_410_CORE_OUTPUT:
742         case SH_GLSL_420_CORE_OUTPUT:
743         case SH_GLSL_430_CORE_OUTPUT:
744         case SH_GLSL_440_CORE_OUTPUT:
745         case SH_GLSL_450_CORE_OUTPUT:
746         case SH_GLSL_COMPATIBILITY_OUTPUT:
747             return true;
748         default:
749             break;
750     }
751     return false;
752 }
IsOutputHLSL(ShShaderOutput output)753 bool IsOutputHLSL(ShShaderOutput output)
754 {
755     switch (output)
756     {
757         case SH_HLSL_3_0_OUTPUT:
758         case SH_HLSL_4_1_OUTPUT:
759         case SH_HLSL_4_0_FL9_3_OUTPUT:
760             return true;
761         default:
762             break;
763     }
764     return false;
765 }
IsOutputVulkan(ShShaderOutput output)766 bool IsOutputVulkan(ShShaderOutput output)
767 {
768     return output == SH_GLSL_VULKAN_OUTPUT;
769 }
IsOutputMetal(ShShaderOutput output)770 bool IsOutputMetal(ShShaderOutput output)
771 {
772     return output == SH_GLSL_METAL_OUTPUT;
773 }
774 
IsInShaderStorageBlock(TIntermTyped * node)775 bool IsInShaderStorageBlock(TIntermTyped *node)
776 {
777     TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
778     if (swizzleNode)
779     {
780         return IsInShaderStorageBlock(swizzleNode->getOperand());
781     }
782 
783     TIntermBinary *binaryNode = node->getAsBinaryNode();
784     if (binaryNode)
785     {
786         switch (binaryNode->getOp())
787         {
788             case EOpIndexDirectInterfaceBlock:
789             case EOpIndexIndirect:
790             case EOpIndexDirect:
791             case EOpIndexDirectStruct:
792                 return IsInShaderStorageBlock(binaryNode->getLeft());
793             default:
794                 return false;
795         }
796     }
797 
798     const TType &type = node->getType();
799     return type.getQualifier() == EvqBuffer;
800 }
801 
GetImageInternalFormatType(TLayoutImageInternalFormat iifq)802 GLenum GetImageInternalFormatType(TLayoutImageInternalFormat iifq)
803 {
804     switch (iifq)
805     {
806         case EiifRGBA32F:
807             return GL_RGBA32F;
808         case EiifRGBA16F:
809             return GL_RGBA16F;
810         case EiifR32F:
811             return GL_R32F;
812         case EiifRGBA32UI:
813             return GL_RGBA32UI;
814         case EiifRGBA16UI:
815             return GL_RGBA16UI;
816         case EiifRGBA8UI:
817             return GL_RGBA8UI;
818         case EiifR32UI:
819             return GL_R32UI;
820         case EiifRGBA32I:
821             return GL_RGBA32I;
822         case EiifRGBA16I:
823             return GL_RGBA16I;
824         case EiifRGBA8I:
825             return GL_RGBA8I;
826         case EiifR32I:
827             return GL_R32I;
828         case EiifRGBA8:
829             return GL_RGBA8;
830         case EiifRGBA8_SNORM:
831             return GL_RGBA8_SNORM;
832         default:
833             return GL_NONE;
834     }
835 }
836 
IsSpecWithFunctionBodyNewScope(ShShaderSpec shaderSpec,int shaderVersion)837 bool IsSpecWithFunctionBodyNewScope(ShShaderSpec shaderSpec, int shaderVersion)
838 {
839     return (shaderVersion == 100 && !sh::IsWebGLBasedSpec(shaderSpec));
840 }
841 
GetConversion(TBasicType t1,TBasicType t2)842 ImplicitTypeConversion GetConversion(TBasicType t1, TBasicType t2)
843 {
844     if (t1 == t2)
845         return ImplicitTypeConversion::Same;
846 
847     switch (t1)
848     {
849         case EbtInt:
850             switch (t2)
851             {
852                 case EbtInt:
853                     UNREACHABLE();
854                     break;
855                 case EbtUInt:
856                     return ImplicitTypeConversion::Invalid;
857                 case EbtFloat:
858                     return ImplicitTypeConversion::Left;
859                 default:
860                     return ImplicitTypeConversion::Invalid;
861             }
862             break;
863         case EbtUInt:
864             switch (t2)
865             {
866                 case EbtInt:
867                     return ImplicitTypeConversion::Invalid;
868                 case EbtUInt:
869                     UNREACHABLE();
870                     break;
871                 case EbtFloat:
872                     return ImplicitTypeConversion::Left;
873                 default:
874                     return ImplicitTypeConversion::Invalid;
875             }
876             break;
877         case EbtFloat:
878             switch (t2)
879             {
880                 case EbtInt:
881                 case EbtUInt:
882                     return ImplicitTypeConversion::Right;
883                 case EbtFloat:
884                     UNREACHABLE();
885                     break;
886                 default:
887                     return ImplicitTypeConversion::Invalid;
888             }
889             break;
890         default:
891             return ImplicitTypeConversion::Invalid;
892     }
893     return ImplicitTypeConversion::Invalid;
894 }
895 
IsValidImplicitConversion(sh::ImplicitTypeConversion conversion,TOperator op)896 bool IsValidImplicitConversion(sh::ImplicitTypeConversion conversion, TOperator op)
897 {
898     switch (conversion)
899     {
900         case sh::ImplicitTypeConversion::Same:
901             return true;
902         case sh::ImplicitTypeConversion::Left:
903             switch (op)
904             {
905                 case EOpEqual:
906                 case EOpNotEqual:
907                 case EOpLessThan:
908                 case EOpGreaterThan:
909                 case EOpLessThanEqual:
910                 case EOpGreaterThanEqual:
911                 case EOpAdd:
912                 case EOpSub:
913                 case EOpMul:
914                 case EOpDiv:
915                     return true;
916                 default:
917                     break;
918             }
919             break;
920         case sh::ImplicitTypeConversion::Right:
921             switch (op)
922             {
923                 case EOpAssign:
924                 case EOpInitialize:
925                 case EOpEqual:
926                 case EOpNotEqual:
927                 case EOpLessThan:
928                 case EOpGreaterThan:
929                 case EOpLessThanEqual:
930                 case EOpGreaterThanEqual:
931                 case EOpAdd:
932                 case EOpSub:
933                 case EOpMul:
934                 case EOpDiv:
935                 case EOpAddAssign:
936                 case EOpSubAssign:
937                 case EOpMulAssign:
938                 case EOpDivAssign:
939                     return true;
940                 default:
941                     break;
942             }
943             break;
944         case sh::ImplicitTypeConversion::Invalid:
945             break;
946     }
947     return false;
948 }
949 
950 }  // namespace sh
951