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