1 //
2 // Copyright (c) 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/SymbolTable.h"
14 
atoi_clamp(const char * str,unsigned int * value)15 bool atoi_clamp(const char *str, unsigned int *value)
16 {
17     bool success = pp::numeric_lex_int(str, value);
18     if (!success)
19         *value = std::numeric_limits<unsigned int>::max();
20     return success;
21 }
22 
23 namespace sh
24 {
25 
26 namespace
27 {
28 
IsInterpolationIn(TQualifier qualifier)29 bool IsInterpolationIn(TQualifier qualifier)
30 {
31     switch (qualifier)
32     {
33         case EvqSmoothIn:
34         case EvqFlatIn:
35         case EvqCentroidIn:
36             return true;
37         default:
38             return false;
39     }
40 }
41 
42 }  // anonymous namespace
43 
NumericLexFloat32OutOfRangeToInfinity(const std::string & str)44 float NumericLexFloat32OutOfRangeToInfinity(const std::string &str)
45 {
46     // Parses a decimal string using scientific notation into a floating point number.
47     // Out-of-range values are converted to infinity. Values that are too small to be
48     // represented are converted to zero.
49 
50     // The mantissa in decimal scientific notation. The magnitude of the mantissa integer does not
51     // matter.
52     unsigned int decimalMantissa = 0;
53     size_t i                     = 0;
54     bool decimalPointSeen        = false;
55     bool nonZeroSeenInMantissa   = false;
56 
57     // The exponent offset reflects the position of the decimal point.
58     int exponentOffset = -1;
59     while (i < str.length())
60     {
61         const char c = str[i];
62         if (c == 'e' || c == 'E')
63         {
64             break;
65         }
66         if (c == '.')
67         {
68             decimalPointSeen = true;
69             ++i;
70             continue;
71         }
72 
73         unsigned int digit = static_cast<unsigned int>(c - '0');
74         ASSERT(digit < 10u);
75         if (digit != 0u)
76         {
77             nonZeroSeenInMantissa = true;
78         }
79         if (nonZeroSeenInMantissa)
80         {
81             // Add bits to the mantissa until space runs out in 32-bit int. This should be
82             // enough precision to make the resulting binary mantissa accurate to 1 ULP.
83             if (decimalMantissa <= (std::numeric_limits<unsigned int>::max() - 9u) / 10u)
84             {
85                 decimalMantissa = decimalMantissa * 10u + digit;
86             }
87             if (!decimalPointSeen)
88             {
89                 ++exponentOffset;
90             }
91         }
92         else if (decimalPointSeen)
93         {
94             --exponentOffset;
95         }
96         ++i;
97     }
98     if (decimalMantissa == 0)
99     {
100         return 0.0f;
101     }
102     int exponent = 0;
103     if (i < str.length())
104     {
105         ASSERT(str[i] == 'e' || str[i] == 'E');
106         ++i;
107         bool exponentOutOfRange = false;
108         bool negativeExponent   = false;
109         if (str[i] == '-')
110         {
111             negativeExponent = true;
112             ++i;
113         }
114         else if (str[i] == '+')
115         {
116             ++i;
117         }
118         while (i < str.length())
119         {
120             const char c       = str[i];
121             unsigned int digit = static_cast<unsigned int>(c - '0');
122             ASSERT(digit < 10u);
123             if (exponent <= (std::numeric_limits<int>::max() - 9) / 10)
124             {
125                 exponent = exponent * 10 + digit;
126             }
127             else
128             {
129                 exponentOutOfRange = true;
130             }
131             ++i;
132         }
133         if (negativeExponent)
134         {
135             exponent = -exponent;
136         }
137         if (exponentOutOfRange)
138         {
139             if (negativeExponent)
140             {
141                 return 0.0f;
142             }
143             else
144             {
145                 return std::numeric_limits<float>::infinity();
146             }
147         }
148     }
149     // Do the calculation in 64-bit to avoid overflow.
150     long long exponentLong =
151         static_cast<long long>(exponent) + static_cast<long long>(exponentOffset);
152     if (exponentLong > std::numeric_limits<float>::max_exponent10)
153     {
154         return std::numeric_limits<float>::infinity();
155     }
156     else if (exponentLong < std::numeric_limits<float>::min_exponent10)
157     {
158         return 0.0f;
159     }
160     // The exponent is in range, so we need to actually evaluate the float.
161     exponent     = static_cast<int>(exponentLong);
162     double value = decimalMantissa;
163 
164     // Calculate the exponent offset to normalize the mantissa.
165     int normalizationExponentOffset = 0;
166     while (decimalMantissa >= 10u)
167     {
168         --normalizationExponentOffset;
169         decimalMantissa /= 10u;
170     }
171     // Apply the exponent.
172     value *= std::pow(10.0, static_cast<double>(exponent + normalizationExponentOffset));
173     if (value > static_cast<double>(std::numeric_limits<float>::max()))
174     {
175         return std::numeric_limits<float>::infinity();
176     }
177     if (value < static_cast<double>(std::numeric_limits<float>::min()))
178     {
179         return 0.0f;
180     }
181     return static_cast<float>(value);
182 }
183 
strtof_clamp(const std::string & str,float * value)184 bool strtof_clamp(const std::string &str, float *value)
185 {
186     // Try the standard float parsing path first.
187     bool success = pp::numeric_lex_float(str, value);
188 
189     // If the standard path doesn't succeed, take the path that can handle the following corner
190     // cases:
191     //   1. The decimal mantissa is very small but the exponent is very large, putting the resulting
192     //   number inside the float range.
193     //   2. The decimal mantissa is very large but the exponent is very small, putting the resulting
194     //   number inside the float range.
195     //   3. The value is out-of-range and should be evaluated as infinity.
196     //   4. The value is too small and should be evaluated as zero.
197     // See ESSL 3.00.6 section 4.1.4 for the relevant specification.
198     if (!success)
199         *value = NumericLexFloat32OutOfRangeToInfinity(str);
200     return !gl::isInf(*value);
201 }
202 
GLVariableType(const TType & type)203 GLenum GLVariableType(const TType &type)
204 {
205     if (type.getBasicType() == EbtFloat)
206     {
207         if (type.isVector())
208         {
209             switch (type.getNominalSize())
210             {
211                 case 2:
212                     return GL_FLOAT_VEC2;
213                 case 3:
214                     return GL_FLOAT_VEC3;
215                 case 4:
216                     return GL_FLOAT_VEC4;
217                 default:
218                     UNREACHABLE();
219             }
220         }
221         else if (type.isMatrix())
222         {
223             switch (type.getCols())
224             {
225                 case 2:
226                     switch (type.getRows())
227                     {
228                         case 2:
229                             return GL_FLOAT_MAT2;
230                         case 3:
231                             return GL_FLOAT_MAT2x3;
232                         case 4:
233                             return GL_FLOAT_MAT2x4;
234                         default:
235                             UNREACHABLE();
236                     }
237 
238                 case 3:
239                     switch (type.getRows())
240                     {
241                         case 2:
242                             return GL_FLOAT_MAT3x2;
243                         case 3:
244                             return GL_FLOAT_MAT3;
245                         case 4:
246                             return GL_FLOAT_MAT3x4;
247                         default:
248                             UNREACHABLE();
249                     }
250 
251                 case 4:
252                     switch (type.getRows())
253                     {
254                         case 2:
255                             return GL_FLOAT_MAT4x2;
256                         case 3:
257                             return GL_FLOAT_MAT4x3;
258                         case 4:
259                             return GL_FLOAT_MAT4;
260                         default:
261                             UNREACHABLE();
262                     }
263 
264                 default:
265                     UNREACHABLE();
266             }
267         }
268         else
269         {
270             return GL_FLOAT;
271         }
272     }
273     else if (type.getBasicType() == EbtInt)
274     {
275         if (type.isVector())
276         {
277             switch (type.getNominalSize())
278             {
279                 case 2:
280                     return GL_INT_VEC2;
281                 case 3:
282                     return GL_INT_VEC3;
283                 case 4:
284                     return GL_INT_VEC4;
285                 default:
286                     UNREACHABLE();
287             }
288         }
289         else
290         {
291             ASSERT(!type.isMatrix());
292             return GL_INT;
293         }
294     }
295     else if (type.getBasicType() == EbtUInt)
296     {
297         if (type.isVector())
298         {
299             switch (type.getNominalSize())
300             {
301                 case 2:
302                     return GL_UNSIGNED_INT_VEC2;
303                 case 3:
304                     return GL_UNSIGNED_INT_VEC3;
305                 case 4:
306                     return GL_UNSIGNED_INT_VEC4;
307                 default:
308                     UNREACHABLE();
309             }
310         }
311         else
312         {
313             ASSERT(!type.isMatrix());
314             return GL_UNSIGNED_INT;
315         }
316     }
317     else if (type.getBasicType() == EbtBool)
318     {
319         if (type.isVector())
320         {
321             switch (type.getNominalSize())
322             {
323                 case 2:
324                     return GL_BOOL_VEC2;
325                 case 3:
326                     return GL_BOOL_VEC3;
327                 case 4:
328                     return GL_BOOL_VEC4;
329                 default:
330                     UNREACHABLE();
331             }
332         }
333         else
334         {
335             ASSERT(!type.isMatrix());
336             return GL_BOOL;
337         }
338     }
339 
340     switch (type.getBasicType())
341     {
342         case EbtSampler2D:
343             return GL_SAMPLER_2D;
344         case EbtSampler3D:
345             return GL_SAMPLER_3D;
346         case EbtSamplerCube:
347             return GL_SAMPLER_CUBE;
348         case EbtSamplerExternalOES:
349             return GL_SAMPLER_EXTERNAL_OES;
350         case EbtSamplerExternal2DY2YEXT:
351             return GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT;
352         case EbtSampler2DRect:
353             return GL_SAMPLER_2D_RECT_ANGLE;
354         case EbtSampler2DArray:
355             return GL_SAMPLER_2D_ARRAY;
356         case EbtSampler2DMS:
357             return GL_SAMPLER_2D_MULTISAMPLE;
358         case EbtISampler2D:
359             return GL_INT_SAMPLER_2D;
360         case EbtISampler3D:
361             return GL_INT_SAMPLER_3D;
362         case EbtISamplerCube:
363             return GL_INT_SAMPLER_CUBE;
364         case EbtISampler2DArray:
365             return GL_INT_SAMPLER_2D_ARRAY;
366         case EbtISampler2DMS:
367             return GL_INT_SAMPLER_2D_MULTISAMPLE;
368         case EbtUSampler2D:
369             return GL_UNSIGNED_INT_SAMPLER_2D;
370         case EbtUSampler3D:
371             return GL_UNSIGNED_INT_SAMPLER_3D;
372         case EbtUSamplerCube:
373             return GL_UNSIGNED_INT_SAMPLER_CUBE;
374         case EbtUSampler2DArray:
375             return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
376         case EbtUSampler2DMS:
377             return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE;
378         case EbtSampler2DShadow:
379             return GL_SAMPLER_2D_SHADOW;
380         case EbtSamplerCubeShadow:
381             return GL_SAMPLER_CUBE_SHADOW;
382         case EbtSampler2DArrayShadow:
383             return GL_SAMPLER_2D_ARRAY_SHADOW;
384         case EbtImage2D:
385             return GL_IMAGE_2D;
386         case EbtIImage2D:
387             return GL_INT_IMAGE_2D;
388         case EbtUImage2D:
389             return GL_UNSIGNED_INT_IMAGE_2D;
390         case EbtImage2DArray:
391             return GL_IMAGE_2D_ARRAY;
392         case EbtIImage2DArray:
393             return GL_INT_IMAGE_2D_ARRAY;
394         case EbtUImage2DArray:
395             return GL_UNSIGNED_INT_IMAGE_2D_ARRAY;
396         case EbtImage3D:
397             return GL_IMAGE_3D;
398         case EbtIImage3D:
399             return GL_INT_IMAGE_3D;
400         case EbtUImage3D:
401             return GL_UNSIGNED_INT_IMAGE_3D;
402         case EbtImageCube:
403             return GL_IMAGE_CUBE;
404         case EbtIImageCube:
405             return GL_INT_IMAGE_CUBE;
406         case EbtUImageCube:
407             return GL_UNSIGNED_INT_IMAGE_CUBE;
408         case EbtAtomicCounter:
409             return GL_UNSIGNED_INT_ATOMIC_COUNTER;
410         default:
411             UNREACHABLE();
412     }
413 
414     return GL_NONE;
415 }
416 
GLVariablePrecision(const TType & type)417 GLenum GLVariablePrecision(const TType &type)
418 {
419     if (type.getBasicType() == EbtFloat)
420     {
421         switch (type.getPrecision())
422         {
423             case EbpHigh:
424                 return GL_HIGH_FLOAT;
425             case EbpMedium:
426                 return GL_MEDIUM_FLOAT;
427             case EbpLow:
428                 return GL_LOW_FLOAT;
429             case EbpUndefined:
430             // Should be defined as the default precision by the parser
431             default:
432                 UNREACHABLE();
433         }
434     }
435     else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
436     {
437         switch (type.getPrecision())
438         {
439             case EbpHigh:
440                 return GL_HIGH_INT;
441             case EbpMedium:
442                 return GL_MEDIUM_INT;
443             case EbpLow:
444                 return GL_LOW_INT;
445             case EbpUndefined:
446             // Should be defined as the default precision by the parser
447             default:
448                 UNREACHABLE();
449         }
450     }
451 
452     // Other types (boolean, sampler) don't have a precision
453     return GL_NONE;
454 }
455 
ArrayString(const TType & type)456 TString ArrayString(const TType &type)
457 {
458     TStringStream arrayString;
459     if (!type.isArray())
460         return arrayString.str();
461 
462     const TVector<unsigned int> &arraySizes = *type.getArraySizes();
463     for (auto arraySizeIter = arraySizes.rbegin(); arraySizeIter != arraySizes.rend();
464          ++arraySizeIter)
465     {
466         arrayString << "[";
467         if (*arraySizeIter > 0)
468         {
469             arrayString << (*arraySizeIter);
470         }
471         arrayString << "]";
472     }
473     return arrayString.str();
474 }
475 
GetTypeName(const TType & type,ShHashFunction64 hashFunction,NameMap * nameMap)476 TString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap)
477 {
478     if (type.getBasicType() == EbtStruct)
479         return HashName(TName(type.getStruct()->name()), hashFunction, nameMap);
480     else
481         return type.getBuiltInTypeNameString();
482 }
483 
IsVaryingOut(TQualifier qualifier)484 bool IsVaryingOut(TQualifier qualifier)
485 {
486     switch (qualifier)
487     {
488         case EvqVaryingOut:
489         case EvqSmoothOut:
490         case EvqFlatOut:
491         case EvqCentroidOut:
492         case EvqVertexOut:
493         case EvqGeometryOut:
494             return true;
495 
496         default:
497             break;
498     }
499 
500     return false;
501 }
502 
IsVaryingIn(TQualifier qualifier)503 bool IsVaryingIn(TQualifier qualifier)
504 {
505     switch (qualifier)
506     {
507         case EvqVaryingIn:
508         case EvqSmoothIn:
509         case EvqFlatIn:
510         case EvqCentroidIn:
511         case EvqFragmentIn:
512         case EvqGeometryIn:
513             return true;
514 
515         default:
516             break;
517     }
518 
519     return false;
520 }
521 
IsVarying(TQualifier qualifier)522 bool IsVarying(TQualifier qualifier)
523 {
524     return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
525 }
526 
IsGeometryShaderInput(GLenum shaderType,TQualifier qualifier)527 bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier)
528 {
529     return (qualifier == EvqGeometryIn) ||
530            ((shaderType == GL_GEOMETRY_SHADER_OES) && IsInterpolationIn(qualifier));
531 }
532 
GetInterpolationType(TQualifier qualifier)533 InterpolationType GetInterpolationType(TQualifier qualifier)
534 {
535     switch (qualifier)
536     {
537         case EvqFlatIn:
538         case EvqFlatOut:
539             return INTERPOLATION_FLAT;
540 
541         case EvqSmoothIn:
542         case EvqSmoothOut:
543         case EvqVertexOut:
544         case EvqFragmentIn:
545         case EvqVaryingIn:
546         case EvqVaryingOut:
547         case EvqGeometryIn:
548         case EvqGeometryOut:
549             return INTERPOLATION_SMOOTH;
550 
551         case EvqCentroidIn:
552         case EvqCentroidOut:
553             return INTERPOLATION_CENTROID;
554 
555         default:
556             UNREACHABLE();
557             return INTERPOLATION_SMOOTH;
558     }
559 }
560 
GetShaderVariableBasicType(const sh::ShaderVariable & var)561 TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
562 {
563     switch (var.type)
564     {
565         case GL_BOOL:
566             return TType(EbtBool);
567         case GL_BOOL_VEC2:
568             return TType(EbtBool, 2);
569         case GL_BOOL_VEC3:
570             return TType(EbtBool, 3);
571         case GL_BOOL_VEC4:
572             return TType(EbtBool, 4);
573         case GL_FLOAT:
574             return TType(EbtFloat);
575         case GL_FLOAT_VEC2:
576             return TType(EbtFloat, 2);
577         case GL_FLOAT_VEC3:
578             return TType(EbtFloat, 3);
579         case GL_FLOAT_VEC4:
580             return TType(EbtFloat, 4);
581         case GL_FLOAT_MAT2:
582             return TType(EbtFloat, 2, 2);
583         case GL_FLOAT_MAT3:
584             return TType(EbtFloat, 3, 3);
585         case GL_FLOAT_MAT4:
586             return TType(EbtFloat, 4, 4);
587         case GL_FLOAT_MAT2x3:
588             return TType(EbtFloat, 2, 3);
589         case GL_FLOAT_MAT2x4:
590             return TType(EbtFloat, 2, 4);
591         case GL_FLOAT_MAT3x2:
592             return TType(EbtFloat, 3, 2);
593         case GL_FLOAT_MAT3x4:
594             return TType(EbtFloat, 3, 4);
595         case GL_FLOAT_MAT4x2:
596             return TType(EbtFloat, 4, 2);
597         case GL_FLOAT_MAT4x3:
598             return TType(EbtFloat, 4, 3);
599         case GL_INT:
600             return TType(EbtInt);
601         case GL_INT_VEC2:
602             return TType(EbtInt, 2);
603         case GL_INT_VEC3:
604             return TType(EbtInt, 3);
605         case GL_INT_VEC4:
606             return TType(EbtInt, 4);
607         case GL_UNSIGNED_INT:
608             return TType(EbtUInt);
609         case GL_UNSIGNED_INT_VEC2:
610             return TType(EbtUInt, 2);
611         case GL_UNSIGNED_INT_VEC3:
612             return TType(EbtUInt, 3);
613         case GL_UNSIGNED_INT_VEC4:
614             return TType(EbtUInt, 4);
615         default:
616             UNREACHABLE();
617             return TType();
618     }
619 }
620 
621 // GLSL ES 1.0.17 4.6.1 The Invariant Qualifier
CanBeInvariantESSL1(TQualifier qualifier)622 bool CanBeInvariantESSL1(TQualifier qualifier)
623 {
624     return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) ||
625            IsBuiltinOutputVariable(qualifier) ||
626            (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing);
627 }
628 
629 // GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier
630 // GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier
CanBeInvariantESSL3OrGreater(TQualifier qualifier)631 bool CanBeInvariantESSL3OrGreater(TQualifier qualifier)
632 {
633     return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut ||
634            IsBuiltinOutputVariable(qualifier);
635 }
636 
IsBuiltinOutputVariable(TQualifier qualifier)637 bool IsBuiltinOutputVariable(TQualifier qualifier)
638 {
639     switch (qualifier)
640     {
641         case EvqPosition:
642         case EvqPointSize:
643         case EvqFragDepth:
644         case EvqFragDepthEXT:
645         case EvqFragColor:
646         case EvqSecondaryFragColorEXT:
647         case EvqFragData:
648         case EvqSecondaryFragDataEXT:
649             return true;
650         default:
651             break;
652     }
653     return false;
654 }
655 
IsBuiltinFragmentInputVariable(TQualifier qualifier)656 bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
657 {
658     switch (qualifier)
659     {
660         case EvqFragCoord:
661         case EvqPointCoord:
662         case EvqFrontFacing:
663             return true;
664         default:
665             break;
666     }
667     return false;
668 }
669 
IsOutputESSL(ShShaderOutput output)670 bool IsOutputESSL(ShShaderOutput output)
671 {
672     return output == SH_ESSL_OUTPUT;
673 }
674 
IsOutputGLSL(ShShaderOutput output)675 bool IsOutputGLSL(ShShaderOutput output)
676 {
677     switch (output)
678     {
679         case SH_GLSL_130_OUTPUT:
680         case SH_GLSL_140_OUTPUT:
681         case SH_GLSL_150_CORE_OUTPUT:
682         case SH_GLSL_330_CORE_OUTPUT:
683         case SH_GLSL_400_CORE_OUTPUT:
684         case SH_GLSL_410_CORE_OUTPUT:
685         case SH_GLSL_420_CORE_OUTPUT:
686         case SH_GLSL_430_CORE_OUTPUT:
687         case SH_GLSL_440_CORE_OUTPUT:
688         case SH_GLSL_450_CORE_OUTPUT:
689         case SH_GLSL_COMPATIBILITY_OUTPUT:
690             return true;
691         default:
692             break;
693     }
694     return false;
695 }
IsOutputHLSL(ShShaderOutput output)696 bool IsOutputHLSL(ShShaderOutput output)
697 {
698     switch (output)
699     {
700         case SH_HLSL_3_0_OUTPUT:
701         case SH_HLSL_4_1_OUTPUT:
702         case SH_HLSL_4_0_FL9_3_OUTPUT:
703             return true;
704         default:
705             break;
706     }
707     return false;
708 }
IsOutputVulkan(ShShaderOutput output)709 bool IsOutputVulkan(ShShaderOutput output)
710 {
711     return output == SH_GLSL_VULKAN_OUTPUT;
712 }
713 
714 }  // namespace sh
715