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