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