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