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