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