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