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 else if (exponentLong < std::numeric_limits<float>::min_exponent10)
221 {
222 return 0.0f;
223 }
224 // The exponent is in range, so we need to actually evaluate the float.
225 exponent = static_cast<int>(exponentLong);
226 double value = decimalMantissa;
227
228 // Calculate the exponent offset to normalize the mantissa.
229 int normalizationExponentOffset = 1 - mantissaDecimalDigits;
230 // Apply the exponent.
231 value *= std::pow(10.0, static_cast<double>(exponent + normalizationExponentOffset));
232 if (value > static_cast<double>(std::numeric_limits<float>::max()))
233 {
234 return std::numeric_limits<float>::infinity();
235 }
236 if (value < static_cast<double>(std::numeric_limits<float>::min()))
237 {
238 return 0.0f;
239 }
240 return static_cast<float>(value);
241 }
242
strtof_clamp(const std::string & str,float * value)243 bool strtof_clamp(const std::string &str, float *value)
244 {
245 // Custom float parsing that can handle the following corner cases:
246 // 1. The decimal mantissa is very small but the exponent is very large, putting the resulting
247 // number inside the float range.
248 // 2. The decimal mantissa is very large but the exponent is very small, putting the resulting
249 // number inside the float range.
250 // 3. The value is out-of-range and should be evaluated as infinity.
251 // 4. The value is too small and should be evaluated as zero.
252 // See ESSL 3.00.6 section 4.1.4 for the relevant specification.
253 *value = NumericLexFloat32OutOfRangeToInfinity(str);
254 return !gl::isInf(*value);
255 }
256
GLVariableType(const TType & type)257 GLenum GLVariableType(const TType &type)
258 {
259 switch (type.getBasicType())
260 {
261 case EbtFloat:
262 ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4);
263 ASSERT(type.getSecondarySize() >= 1 && type.getSecondarySize() <= 4);
264
265 return kFloatGLType[type.getNominalSize() - 1][type.getSecondarySize() - 1];
266
267 case EbtInt:
268 ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4);
269 ASSERT(type.getSecondarySize() == 1);
270
271 return kIntGLType[type.getNominalSize() - 1];
272
273 case EbtUInt:
274 ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4);
275 ASSERT(type.getSecondarySize() == 1);
276
277 return kUIntGLType[type.getNominalSize() - 1];
278
279 case EbtBool:
280 ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4);
281 ASSERT(type.getSecondarySize() == 1);
282
283 return kBoolGLType[type.getNominalSize() - 1];
284
285 case EbtYuvCscStandardEXT:
286 return GL_UNSIGNED_INT;
287
288 case EbtSampler2D:
289 return GL_SAMPLER_2D;
290 case EbtSampler3D:
291 return GL_SAMPLER_3D;
292 case EbtSamplerCube:
293 return GL_SAMPLER_CUBE;
294 case EbtSamplerExternalOES:
295 return GL_SAMPLER_EXTERNAL_OES;
296 case EbtSamplerExternal2DY2YEXT:
297 return GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT;
298 case EbtSampler2DRect:
299 return GL_SAMPLER_2D_RECT_ANGLE;
300 case EbtSampler2DArray:
301 return GL_SAMPLER_2D_ARRAY;
302 case EbtSampler2DMS:
303 return GL_SAMPLER_2D_MULTISAMPLE;
304 case EbtSampler2DMSArray:
305 return GL_SAMPLER_2D_MULTISAMPLE_ARRAY;
306 case EbtSamplerCubeArray:
307 return GL_SAMPLER_CUBE_MAP_ARRAY;
308 case EbtSamplerBuffer:
309 return GL_SAMPLER_BUFFER;
310 case EbtISampler2D:
311 return GL_INT_SAMPLER_2D;
312 case EbtISampler3D:
313 return GL_INT_SAMPLER_3D;
314 case EbtISamplerCube:
315 return GL_INT_SAMPLER_CUBE;
316 case EbtISampler2DArray:
317 return GL_INT_SAMPLER_2D_ARRAY;
318 case EbtISampler2DMS:
319 return GL_INT_SAMPLER_2D_MULTISAMPLE;
320 case EbtISampler2DMSArray:
321 return GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY;
322 case EbtISamplerCubeArray:
323 return GL_INT_SAMPLER_CUBE_MAP_ARRAY;
324 case EbtISamplerBuffer:
325 return GL_INT_SAMPLER_BUFFER;
326 case EbtUSampler2D:
327 return GL_UNSIGNED_INT_SAMPLER_2D;
328 case EbtUSampler3D:
329 return GL_UNSIGNED_INT_SAMPLER_3D;
330 case EbtUSamplerCube:
331 return GL_UNSIGNED_INT_SAMPLER_CUBE;
332 case EbtUSampler2DArray:
333 return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
334 case EbtUSampler2DMS:
335 return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE;
336 case EbtUSampler2DMSArray:
337 return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY;
338 case EbtUSamplerCubeArray:
339 return GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY;
340 case EbtUSamplerBuffer:
341 return GL_UNSIGNED_INT_SAMPLER_BUFFER;
342 case EbtSampler2DShadow:
343 return GL_SAMPLER_2D_SHADOW;
344 case EbtSamplerCubeShadow:
345 return GL_SAMPLER_CUBE_SHADOW;
346 case EbtSampler2DArrayShadow:
347 return GL_SAMPLER_2D_ARRAY_SHADOW;
348 case EbtSamplerCubeArrayShadow:
349 return GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW;
350 case EbtImage2D:
351 return GL_IMAGE_2D;
352 case EbtIImage2D:
353 return GL_INT_IMAGE_2D;
354 case EbtUImage2D:
355 return GL_UNSIGNED_INT_IMAGE_2D;
356 case EbtImage2DArray:
357 return GL_IMAGE_2D_ARRAY;
358 case EbtIImage2DArray:
359 return GL_INT_IMAGE_2D_ARRAY;
360 case EbtUImage2DArray:
361 return GL_UNSIGNED_INT_IMAGE_2D_ARRAY;
362 case EbtImage3D:
363 return GL_IMAGE_3D;
364 case EbtIImage3D:
365 return GL_INT_IMAGE_3D;
366 case EbtUImage3D:
367 return GL_UNSIGNED_INT_IMAGE_3D;
368 case EbtImageCube:
369 return GL_IMAGE_CUBE;
370 case EbtIImageCube:
371 return GL_INT_IMAGE_CUBE;
372 case EbtUImageCube:
373 return GL_UNSIGNED_INT_IMAGE_CUBE;
374 case EbtImageCubeArray:
375 return GL_IMAGE_CUBE_MAP_ARRAY;
376 case EbtIImageCubeArray:
377 return GL_INT_IMAGE_CUBE_MAP_ARRAY;
378 case EbtUImageCubeArray:
379 return GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY;
380 case EbtImageBuffer:
381 return GL_IMAGE_BUFFER;
382 case EbtIImageBuffer:
383 return GL_INT_IMAGE_BUFFER;
384 case EbtUImageBuffer:
385 return GL_UNSIGNED_INT_IMAGE_BUFFER;
386 case EbtAtomicCounter:
387 return GL_UNSIGNED_INT_ATOMIC_COUNTER;
388 case EbtSamplerVideoWEBGL:
389 return GL_SAMPLER_VIDEO_IMAGE_WEBGL;
390 case EbtPixelLocalANGLE:
391 case EbtIPixelLocalANGLE:
392 case EbtUPixelLocalANGLE:
393 // TODO(anglebug.com/7279): For now, we can expect PLS handles to be rewritten to images
394 // before anyone calls into here.
395 [[fallthrough]];
396 default:
397 UNREACHABLE();
398 return GL_NONE;
399 }
400 }
401
GLVariablePrecision(const TType & type)402 GLenum GLVariablePrecision(const TType &type)
403 {
404 if (type.getBasicType() == EbtFloat)
405 {
406 switch (type.getPrecision())
407 {
408 case EbpHigh:
409 return GL_HIGH_FLOAT;
410 case EbpMedium:
411 return GL_MEDIUM_FLOAT;
412 case EbpLow:
413 return GL_LOW_FLOAT;
414 case EbpUndefined:
415 // Desktop specs do not use precision
416 return GL_NONE;
417 default:
418 UNREACHABLE();
419 }
420 }
421 else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
422 {
423 switch (type.getPrecision())
424 {
425 case EbpHigh:
426 return GL_HIGH_INT;
427 case EbpMedium:
428 return GL_MEDIUM_INT;
429 case EbpLow:
430 return GL_LOW_INT;
431 case EbpUndefined:
432 // Desktop specs do not use precision
433 return GL_NONE;
434 default:
435 UNREACHABLE();
436 }
437 }
438
439 // Other types (boolean, sampler) don't have a precision
440 return GL_NONE;
441 }
442
ArrayString(const TType & type)443 ImmutableString ArrayString(const TType &type)
444 {
445 if (!type.isArray())
446 return ImmutableString("");
447
448 const TSpan<const unsigned int> &arraySizes = type.getArraySizes();
449 constexpr const size_t kMaxDecimalDigitsPerSize = 10u;
450 ImmutableStringBuilder arrayString(arraySizes.size() * (kMaxDecimalDigitsPerSize + 2u));
451 for (auto arraySizeIter = arraySizes.rbegin(); arraySizeIter != arraySizes.rend();
452 ++arraySizeIter)
453 {
454 arrayString << "[";
455 if (*arraySizeIter > 0)
456 {
457 arrayString.appendDecimal(*arraySizeIter);
458 }
459 arrayString << "]";
460 }
461 return arrayString;
462 }
463
GetTypeName(const TType & type,ShHashFunction64 hashFunction,NameMap * nameMap)464 ImmutableString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap)
465 {
466 if (type.getBasicType() == EbtStruct)
467 return HashName(type.getStruct(), hashFunction, nameMap);
468 else
469 return ImmutableString(type.getBuiltInTypeNameString());
470 }
471
IsVaryingOut(TQualifier qualifier)472 bool IsVaryingOut(TQualifier qualifier)
473 {
474 switch (qualifier)
475 {
476 case EvqVaryingOut:
477 case EvqVertexOut:
478 case EvqGeometryOut:
479 case EvqTessControlOut:
480 case EvqTessEvaluationOut:
481 case EvqPatchOut:
482 return true;
483
484 default:
485 break;
486 }
487
488 return IsInterpolationOut(qualifier);
489 }
490
IsVaryingIn(TQualifier qualifier)491 bool IsVaryingIn(TQualifier qualifier)
492 {
493 switch (qualifier)
494 {
495 case EvqVaryingIn:
496 case EvqFragmentIn:
497 case EvqGeometryIn:
498 case EvqTessControlIn:
499 case EvqTessEvaluationIn:
500 case EvqPatchIn:
501 return true;
502
503 default:
504 break;
505 }
506
507 return IsInterpolationIn(qualifier);
508 }
509
IsVarying(TQualifier qualifier)510 bool IsVarying(TQualifier qualifier)
511 {
512 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
513 }
514
IsMatrixGLType(GLenum type)515 bool IsMatrixGLType(GLenum type)
516 {
517 switch (type)
518 {
519 case GL_FLOAT_MAT2:
520 case GL_FLOAT_MAT3:
521 case GL_FLOAT_MAT4:
522 case GL_FLOAT_MAT2x3:
523 case GL_FLOAT_MAT2x4:
524 case GL_FLOAT_MAT3x2:
525 case GL_FLOAT_MAT3x4:
526 case GL_FLOAT_MAT4x2:
527 case GL_FLOAT_MAT4x3:
528 return true;
529 default:
530 return false;
531 }
532 }
533
IsGeometryShaderInput(GLenum shaderType,TQualifier qualifier)534 bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier)
535 {
536 return (qualifier == EvqGeometryIn) ||
537 ((shaderType == GL_GEOMETRY_SHADER_EXT) && IsInterpolationIn(qualifier));
538 }
539
IsTessellationControlShaderInput(GLenum shaderType,TQualifier qualifier)540 bool IsTessellationControlShaderInput(GLenum shaderType, TQualifier qualifier)
541 {
542 return qualifier == EvqTessControlIn ||
543 ((shaderType == GL_TESS_CONTROL_SHADER) && IsInterpolationIn(qualifier));
544 }
545
IsTessellationControlShaderOutput(GLenum shaderType,TQualifier qualifier)546 bool IsTessellationControlShaderOutput(GLenum shaderType, TQualifier qualifier)
547 {
548 return qualifier == EvqTessControlOut ||
549 ((shaderType == GL_TESS_CONTROL_SHADER) && IsInterpolationOut(qualifier));
550 }
551
IsTessellationEvaluationShaderInput(GLenum shaderType,TQualifier qualifier)552 bool IsTessellationEvaluationShaderInput(GLenum shaderType, TQualifier qualifier)
553 {
554 return qualifier == EvqTessEvaluationIn ||
555 ((shaderType == GL_TESS_EVALUATION_SHADER) && IsInterpolationIn(qualifier));
556 }
557
GetInterpolationType(TQualifier qualifier)558 InterpolationType GetInterpolationType(TQualifier qualifier)
559 {
560 switch (qualifier)
561 {
562 case EvqFlatIn:
563 case EvqFlatOut:
564 // The auxiliary storage qualifier patch is not used for interpolation
565 // it is a compile-time error to use interpolation qualifiers with patch
566 case EvqPatchIn:
567 case EvqPatchOut:
568 return INTERPOLATION_FLAT;
569
570 case EvqNoPerspectiveIn:
571 case EvqNoPerspectiveOut:
572 return INTERPOLATION_NOPERSPECTIVE;
573
574 case EvqNoPerspectiveCentroidIn:
575 case EvqNoPerspectiveCentroidOut:
576 return INTERPOLATION_NOPERSPECTIVE_CENTROID;
577
578 case EvqNoPerspectiveSampleIn:
579 case EvqNoPerspectiveSampleOut:
580 return INTERPOLATION_NOPERSPECTIVE_SAMPLE;
581
582 case EvqSmoothIn:
583 case EvqSmoothOut:
584 case EvqVertexOut:
585 case EvqFragmentIn:
586 case EvqVaryingIn:
587 case EvqVaryingOut:
588 case EvqGeometryIn:
589 case EvqGeometryOut:
590 case EvqTessControlIn:
591 case EvqTessControlOut:
592 case EvqTessEvaluationIn:
593 case EvqTessEvaluationOut:
594 return INTERPOLATION_SMOOTH;
595
596 case EvqCentroidIn:
597 case EvqCentroidOut:
598 return INTERPOLATION_CENTROID;
599
600 case EvqSampleIn:
601 case EvqSampleOut:
602 return INTERPOLATION_SAMPLE;
603 default:
604 UNREACHABLE();
605 return INTERPOLATION_SMOOTH;
606 }
607 }
608
609 // a field may not have qualifer without in or out.
GetFieldInterpolationType(TQualifier qualifier)610 InterpolationType GetFieldInterpolationType(TQualifier qualifier)
611 {
612 switch (qualifier)
613 {
614 case EvqSmooth:
615 return INTERPOLATION_SMOOTH;
616 case EvqFlat:
617 return INTERPOLATION_FLAT;
618 case EvqNoPerspective:
619 return INTERPOLATION_NOPERSPECTIVE;
620 case EvqCentroid:
621 return INTERPOLATION_CENTROID;
622 case EvqSample:
623 return INTERPOLATION_SAMPLE;
624 case EvqNoPerspectiveCentroid:
625 return INTERPOLATION_NOPERSPECTIVE_CENTROID;
626 case EvqNoPerspectiveSample:
627 return INTERPOLATION_NOPERSPECTIVE_SAMPLE;
628 default:
629 return GetInterpolationType(qualifier);
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 return TType();
690 }
691 }
692
DeclareGlobalVariable(TIntermBlock * root,const TVariable * variable)693 void DeclareGlobalVariable(TIntermBlock *root, const TVariable *variable)
694 {
695 TIntermDeclaration *declaration = new TIntermDeclaration();
696 declaration->appendDeclarator(new TIntermSymbol(variable));
697
698 TIntermSequence *globalSequence = root->getSequence();
699 globalSequence->insert(globalSequence->begin(), declaration);
700 }
701
702 // GLSL ES 1.0.17 4.6.1 The Invariant Qualifier
CanBeInvariantESSL1(TQualifier qualifier)703 bool CanBeInvariantESSL1(TQualifier qualifier)
704 {
705 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) ||
706 IsBuiltinOutputVariable(qualifier) ||
707 (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing);
708 }
709
710 // GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier
711 // GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier
CanBeInvariantESSL3OrGreater(TQualifier qualifier)712 bool CanBeInvariantESSL3OrGreater(TQualifier qualifier)
713 {
714 return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut ||
715 IsBuiltinOutputVariable(qualifier) || qualifier == EvqFragmentInOut;
716 }
717
IsBuiltinOutputVariable(TQualifier qualifier)718 bool IsBuiltinOutputVariable(TQualifier qualifier)
719 {
720 switch (qualifier)
721 {
722 case EvqPosition:
723 case EvqPointSize:
724 case EvqFragDepth:
725 case EvqFragColor:
726 case EvqSecondaryFragColorEXT:
727 case EvqFragData:
728 case EvqSecondaryFragDataEXT:
729 case EvqClipDistance:
730 case EvqCullDistance:
731 case EvqLastFragData:
732 case EvqLastFragColor:
733 case EvqSampleMask:
734 return true;
735 default:
736 break;
737 }
738 return false;
739 }
740
IsBuiltinFragmentInputVariable(TQualifier qualifier)741 bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
742 {
743 switch (qualifier)
744 {
745 case EvqFragCoord:
746 case EvqPointCoord:
747 case EvqFrontFacing:
748 case EvqHelperInvocation:
749 case EvqLastFragData:
750 case EvqLastFragColor:
751 return true;
752 default:
753 break;
754 }
755 return false;
756 }
757
IsShaderOutput(TQualifier qualifier)758 bool IsShaderOutput(TQualifier qualifier)
759 {
760 return IsVaryingOut(qualifier) || IsBuiltinOutputVariable(qualifier);
761 }
762
IsFragmentOutput(TQualifier qualifier)763 bool IsFragmentOutput(TQualifier qualifier)
764 {
765 switch (qualifier)
766 {
767 case EvqFragmentOut:
768 case EvqFragmentInOut:
769 return true;
770 default:
771 return false;
772 }
773 }
774
IsOutputESSL(ShShaderOutput output)775 bool IsOutputESSL(ShShaderOutput output)
776 {
777 return output == SH_ESSL_OUTPUT;
778 }
779
IsOutputGLSL(ShShaderOutput output)780 bool IsOutputGLSL(ShShaderOutput output)
781 {
782 switch (output)
783 {
784 case SH_GLSL_130_OUTPUT:
785 case SH_GLSL_140_OUTPUT:
786 case SH_GLSL_150_CORE_OUTPUT:
787 case SH_GLSL_330_CORE_OUTPUT:
788 case SH_GLSL_400_CORE_OUTPUT:
789 case SH_GLSL_410_CORE_OUTPUT:
790 case SH_GLSL_420_CORE_OUTPUT:
791 case SH_GLSL_430_CORE_OUTPUT:
792 case SH_GLSL_440_CORE_OUTPUT:
793 case SH_GLSL_450_CORE_OUTPUT:
794 case SH_GLSL_COMPATIBILITY_OUTPUT:
795 return true;
796 default:
797 break;
798 }
799 return false;
800 }
IsOutputHLSL(ShShaderOutput output)801 bool IsOutputHLSL(ShShaderOutput output)
802 {
803 switch (output)
804 {
805 case SH_HLSL_3_0_OUTPUT:
806 case SH_HLSL_4_1_OUTPUT:
807 case SH_HLSL_4_0_FL9_3_OUTPUT:
808 return true;
809 default:
810 break;
811 }
812 return false;
813 }
IsOutputSPIRV(ShShaderOutput output)814 bool IsOutputSPIRV(ShShaderOutput output)
815 {
816 return output == SH_SPIRV_VULKAN_OUTPUT;
817 }
IsOutputMSL(ShShaderOutput output)818 bool IsOutputMSL(ShShaderOutput output)
819 {
820 return output == SH_MSL_METAL_OUTPUT;
821 }
822
IsInShaderStorageBlock(TIntermTyped * node)823 bool IsInShaderStorageBlock(TIntermTyped *node)
824 {
825 TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
826 if (swizzleNode)
827 {
828 return IsInShaderStorageBlock(swizzleNode->getOperand());
829 }
830
831 TIntermBinary *binaryNode = node->getAsBinaryNode();
832 if (binaryNode)
833 {
834 switch (binaryNode->getOp())
835 {
836 case EOpIndexDirectInterfaceBlock:
837 case EOpIndexIndirect:
838 case EOpIndexDirect:
839 case EOpIndexDirectStruct:
840 return IsInShaderStorageBlock(binaryNode->getLeft());
841 default:
842 return false;
843 }
844 }
845
846 const TType &type = node->getType();
847 return type.getQualifier() == EvqBuffer;
848 }
849
GetImageInternalFormatType(TLayoutImageInternalFormat iifq)850 GLenum GetImageInternalFormatType(TLayoutImageInternalFormat iifq)
851 {
852 switch (iifq)
853 {
854 case EiifRGBA32F:
855 return GL_RGBA32F;
856 case EiifRGBA16F:
857 return GL_RGBA16F;
858 case EiifR32F:
859 return GL_R32F;
860 case EiifRGBA32UI:
861 return GL_RGBA32UI;
862 case EiifRGBA16UI:
863 return GL_RGBA16UI;
864 case EiifRGBA8UI:
865 return GL_RGBA8UI;
866 case EiifR32UI:
867 return GL_R32UI;
868 case EiifRGBA32I:
869 return GL_RGBA32I;
870 case EiifRGBA16I:
871 return GL_RGBA16I;
872 case EiifRGBA8I:
873 return GL_RGBA8I;
874 case EiifR32I:
875 return GL_R32I;
876 case EiifRGBA8:
877 return GL_RGBA8;
878 case EiifRGBA8_SNORM:
879 return GL_RGBA8_SNORM;
880 default:
881 return GL_NONE;
882 }
883 }
884
IsSpecWithFunctionBodyNewScope(ShShaderSpec shaderSpec,int shaderVersion)885 bool IsSpecWithFunctionBodyNewScope(ShShaderSpec shaderSpec, int shaderVersion)
886 {
887 return (shaderVersion == 100 && !sh::IsWebGLBasedSpec(shaderSpec));
888 }
889
GetConversion(TBasicType t1,TBasicType t2)890 ImplicitTypeConversion GetConversion(TBasicType t1, TBasicType t2)
891 {
892 if (t1 == t2)
893 return ImplicitTypeConversion::Same;
894
895 switch (t1)
896 {
897 case EbtInt:
898 switch (t2)
899 {
900 case EbtInt:
901 UNREACHABLE();
902 break;
903 case EbtUInt:
904 return ImplicitTypeConversion::Invalid;
905 case EbtFloat:
906 return ImplicitTypeConversion::Left;
907 default:
908 return ImplicitTypeConversion::Invalid;
909 }
910 break;
911 case EbtUInt:
912 switch (t2)
913 {
914 case EbtInt:
915 return ImplicitTypeConversion::Invalid;
916 case EbtUInt:
917 UNREACHABLE();
918 break;
919 case EbtFloat:
920 return ImplicitTypeConversion::Left;
921 default:
922 return ImplicitTypeConversion::Invalid;
923 }
924 break;
925 case EbtFloat:
926 switch (t2)
927 {
928 case EbtInt:
929 case EbtUInt:
930 return ImplicitTypeConversion::Right;
931 case EbtFloat:
932 UNREACHABLE();
933 break;
934 default:
935 return ImplicitTypeConversion::Invalid;
936 }
937 break;
938 default:
939 return ImplicitTypeConversion::Invalid;
940 }
941 return ImplicitTypeConversion::Invalid;
942 }
943
IsValidImplicitConversion(sh::ImplicitTypeConversion conversion,TOperator op)944 bool IsValidImplicitConversion(sh::ImplicitTypeConversion conversion, TOperator op)
945 {
946 switch (conversion)
947 {
948 case sh::ImplicitTypeConversion::Same:
949 return true;
950 case sh::ImplicitTypeConversion::Left:
951 switch (op)
952 {
953 case EOpEqual:
954 case EOpNotEqual:
955 case EOpLessThan:
956 case EOpGreaterThan:
957 case EOpLessThanEqual:
958 case EOpGreaterThanEqual:
959 case EOpAdd:
960 case EOpSub:
961 case EOpMul:
962 case EOpDiv:
963 return true;
964 default:
965 break;
966 }
967 break;
968 case sh::ImplicitTypeConversion::Right:
969 switch (op)
970 {
971 case EOpAssign:
972 case EOpInitialize:
973 case EOpEqual:
974 case EOpNotEqual:
975 case EOpLessThan:
976 case EOpGreaterThan:
977 case EOpLessThanEqual:
978 case EOpGreaterThanEqual:
979 case EOpAdd:
980 case EOpSub:
981 case EOpMul:
982 case EOpDiv:
983 case EOpAddAssign:
984 case EOpSubAssign:
985 case EOpMulAssign:
986 case EOpDivAssign:
987 return true;
988 default:
989 break;
990 }
991 break;
992 case sh::ImplicitTypeConversion::Invalid:
993 break;
994 }
995 return false;
996 }
997
IsPrecisionApplicableToType(TBasicType type)998 bool IsPrecisionApplicableToType(TBasicType type)
999 {
1000 switch (type)
1001 {
1002 case EbtInt:
1003 case EbtUInt:
1004 case EbtFloat:
1005 // TODO: find all types where precision is applicable; for example samplers.
1006 // http://anglebug.com/6132
1007 return true;
1008 default:
1009 return false;
1010 }
1011 }
1012
IsRedeclarableBuiltIn(const ImmutableString & name)1013 bool IsRedeclarableBuiltIn(const ImmutableString &name)
1014 {
1015 return name == "gl_ClipDistance" || name == "gl_CullDistance" || name == "gl_FragDepth" ||
1016 name == "gl_LastFragData" || name == "gl_LastFragColorARM" || name == "gl_PerVertex" ||
1017 name == "gl_Position" || name == "gl_PointSize";
1018 }
1019
FindFieldIndex(const TFieldList & fieldList,const char * fieldName)1020 size_t FindFieldIndex(const TFieldList &fieldList, const char *fieldName)
1021 {
1022 for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex)
1023 {
1024 if (strcmp(fieldList[fieldIndex]->name().data(), fieldName) == 0)
1025 {
1026 return fieldIndex;
1027 }
1028 }
1029 UNREACHABLE();
1030 return 0;
1031 }
1032
1033 } // namespace sh
1034