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