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