Line data Source code
1 : //
2 : // Copyright (c) 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/SymbolTable.h"
14 :
15 0 : bool atoi_clamp(const char *str, unsigned int *value)
16 : {
17 0 : bool success = pp::numeric_lex_int(str, value);
18 0 : if (!success)
19 0 : *value = std::numeric_limits<unsigned int>::max();
20 0 : return success;
21 : }
22 :
23 : namespace sh
24 : {
25 :
26 0 : float NumericLexFloat32OutOfRangeToInfinity(const std::string &str)
27 : {
28 : // Parses a decimal string using scientific notation into a floating point number.
29 : // Out-of-range values are converted to infinity. Values that are too small to be
30 : // represented are converted to zero.
31 :
32 : // The mantissa in decimal scientific notation. The magnitude of the mantissa integer does not
33 : // matter.
34 0 : unsigned int decimalMantissa = 0;
35 0 : size_t i = 0;
36 0 : bool decimalPointSeen = false;
37 0 : bool nonZeroSeenInMantissa = false;
38 :
39 : // The exponent offset reflects the position of the decimal point.
40 0 : int exponentOffset = -1;
41 0 : while (i < str.length())
42 : {
43 0 : const char c = str[i];
44 0 : if (c == 'e' || c == 'E')
45 : {
46 : break;
47 : }
48 0 : if (c == '.')
49 : {
50 0 : decimalPointSeen = true;
51 0 : ++i;
52 0 : continue;
53 : }
54 :
55 0 : unsigned int digit = static_cast<unsigned int>(c - '0');
56 0 : ASSERT(digit < 10u);
57 0 : if (digit != 0u)
58 : {
59 0 : nonZeroSeenInMantissa = true;
60 : }
61 0 : if (nonZeroSeenInMantissa)
62 : {
63 : // Add bits to the mantissa until space runs out in 32-bit int. This should be
64 : // enough precision to make the resulting binary mantissa accurate to 1 ULP.
65 0 : if (decimalMantissa <= (std::numeric_limits<unsigned int>::max() - 9u) / 10u)
66 : {
67 0 : decimalMantissa = decimalMantissa * 10u + digit;
68 : }
69 0 : if (!decimalPointSeen)
70 : {
71 0 : ++exponentOffset;
72 : }
73 : }
74 0 : else if (decimalPointSeen)
75 : {
76 0 : --exponentOffset;
77 : }
78 0 : ++i;
79 : }
80 0 : if (decimalMantissa == 0)
81 : {
82 0 : return 0.0f;
83 : }
84 0 : int exponent = 0;
85 0 : if (i < str.length())
86 : {
87 0 : ASSERT(str[i] == 'e' || str[i] == 'E');
88 0 : ++i;
89 0 : bool exponentOutOfRange = false;
90 0 : bool negativeExponent = false;
91 0 : if (str[i] == '-')
92 : {
93 0 : negativeExponent = true;
94 0 : ++i;
95 : }
96 0 : else if (str[i] == '+')
97 : {
98 0 : ++i;
99 : }
100 0 : while (i < str.length())
101 : {
102 0 : const char c = str[i];
103 0 : unsigned int digit = static_cast<unsigned int>(c - '0');
104 0 : ASSERT(digit < 10u);
105 0 : if (exponent <= (std::numeric_limits<int>::max() - 9) / 10)
106 : {
107 0 : exponent = exponent * 10 + digit;
108 : }
109 : else
110 : {
111 0 : exponentOutOfRange = true;
112 : }
113 0 : ++i;
114 : }
115 0 : if (negativeExponent)
116 : {
117 0 : exponent = -exponent;
118 : }
119 0 : if (exponentOutOfRange)
120 : {
121 0 : if (negativeExponent)
122 : {
123 0 : return 0.0f;
124 : }
125 : else
126 : {
127 0 : return std::numeric_limits<float>::infinity();
128 : }
129 : }
130 : }
131 : // Do the calculation in 64-bit to avoid overflow.
132 : long long exponentLong =
133 0 : static_cast<long long>(exponent) + static_cast<long long>(exponentOffset);
134 0 : if (exponentLong > std::numeric_limits<float>::max_exponent10)
135 : {
136 0 : return std::numeric_limits<float>::infinity();
137 : }
138 0 : else if (exponentLong < std::numeric_limits<float>::min_exponent10)
139 : {
140 0 : return 0.0f;
141 : }
142 : // The exponent is in range, so we need to actually evaluate the float.
143 0 : exponent = static_cast<int>(exponentLong);
144 0 : double value = decimalMantissa;
145 :
146 : // Calculate the exponent offset to normalize the mantissa.
147 0 : int normalizationExponentOffset = 0;
148 0 : while (decimalMantissa >= 10u)
149 : {
150 0 : --normalizationExponentOffset;
151 0 : decimalMantissa /= 10u;
152 : }
153 : // Apply the exponent.
154 0 : value *= std::pow(10.0, static_cast<double>(exponent + normalizationExponentOffset));
155 0 : if (value > static_cast<double>(std::numeric_limits<float>::max()))
156 : {
157 0 : return std::numeric_limits<float>::infinity();
158 : }
159 0 : if (value < static_cast<double>(std::numeric_limits<float>::min()))
160 : {
161 0 : return 0.0f;
162 : }
163 0 : return static_cast<float>(value);
164 : }
165 :
166 0 : bool strtof_clamp(const std::string &str, float *value)
167 : {
168 : // Try the standard float parsing path first.
169 0 : bool success = pp::numeric_lex_float(str, value);
170 :
171 : // If the standard path doesn't succeed, take the path that can handle the following corner
172 : // cases:
173 : // 1. The decimal mantissa is very small but the exponent is very large, putting the resulting
174 : // number inside the float range.
175 : // 2. The decimal mantissa is very large but the exponent is very small, putting the resulting
176 : // number inside the float range.
177 : // 3. The value is out-of-range and should be evaluated as infinity.
178 : // 4. The value is too small and should be evaluated as zero.
179 : // See ESSL 3.00.6 section 4.1.4 for the relevant specification.
180 0 : if (!success)
181 0 : *value = NumericLexFloat32OutOfRangeToInfinity(str);
182 0 : return !gl::isInf(*value);
183 : }
184 :
185 0 : GLenum GLVariableType(const TType &type)
186 : {
187 0 : if (type.getBasicType() == EbtFloat)
188 : {
189 0 : if (type.isScalar())
190 : {
191 0 : return GL_FLOAT;
192 : }
193 0 : else if (type.isVector())
194 : {
195 0 : switch (type.getNominalSize())
196 : {
197 0 : case 2: return GL_FLOAT_VEC2;
198 0 : case 3: return GL_FLOAT_VEC3;
199 0 : case 4: return GL_FLOAT_VEC4;
200 0 : default: UNREACHABLE();
201 : }
202 : }
203 0 : else if (type.isMatrix())
204 : {
205 0 : switch (type.getCols())
206 : {
207 : case 2:
208 0 : switch (type.getRows())
209 : {
210 0 : case 2: return GL_FLOAT_MAT2;
211 0 : case 3: return GL_FLOAT_MAT2x3;
212 0 : case 4: return GL_FLOAT_MAT2x4;
213 0 : default: UNREACHABLE();
214 : }
215 :
216 : case 3:
217 0 : switch (type.getRows())
218 : {
219 0 : case 2: return GL_FLOAT_MAT3x2;
220 0 : case 3: return GL_FLOAT_MAT3;
221 0 : case 4: return GL_FLOAT_MAT3x4;
222 0 : default: UNREACHABLE();
223 : }
224 :
225 : case 4:
226 0 : switch (type.getRows())
227 : {
228 0 : case 2: return GL_FLOAT_MAT4x2;
229 0 : case 3: return GL_FLOAT_MAT4x3;
230 0 : case 4: return GL_FLOAT_MAT4;
231 0 : default: UNREACHABLE();
232 : }
233 :
234 0 : default: UNREACHABLE();
235 : }
236 : }
237 0 : else UNREACHABLE();
238 : }
239 0 : else if (type.getBasicType() == EbtInt)
240 : {
241 0 : if (type.isScalar())
242 : {
243 0 : return GL_INT;
244 : }
245 0 : else if (type.isVector())
246 : {
247 0 : switch (type.getNominalSize())
248 : {
249 0 : case 2: return GL_INT_VEC2;
250 0 : case 3: return GL_INT_VEC3;
251 0 : case 4: return GL_INT_VEC4;
252 0 : default: UNREACHABLE();
253 : }
254 : }
255 0 : else UNREACHABLE();
256 : }
257 0 : else if (type.getBasicType() == EbtUInt)
258 : {
259 0 : if (type.isScalar())
260 : {
261 0 : return GL_UNSIGNED_INT;
262 : }
263 0 : else if (type.isVector())
264 : {
265 0 : switch (type.getNominalSize())
266 : {
267 0 : case 2: return GL_UNSIGNED_INT_VEC2;
268 0 : case 3: return GL_UNSIGNED_INT_VEC3;
269 0 : case 4: return GL_UNSIGNED_INT_VEC4;
270 0 : default: UNREACHABLE();
271 : }
272 : }
273 0 : else UNREACHABLE();
274 : }
275 0 : else if (type.getBasicType() == EbtBool)
276 : {
277 0 : if (type.isScalar())
278 : {
279 0 : return GL_BOOL;
280 : }
281 0 : else if (type.isVector())
282 : {
283 0 : switch (type.getNominalSize())
284 : {
285 0 : case 2: return GL_BOOL_VEC2;
286 0 : case 3: return GL_BOOL_VEC3;
287 0 : case 4: return GL_BOOL_VEC4;
288 0 : default: UNREACHABLE();
289 : }
290 : }
291 0 : else UNREACHABLE();
292 : }
293 :
294 0 : switch (type.getBasicType())
295 : {
296 0 : case EbtSampler2D: return GL_SAMPLER_2D;
297 0 : case EbtSampler3D: return GL_SAMPLER_3D;
298 0 : case EbtSamplerCube: return GL_SAMPLER_CUBE;
299 0 : case EbtSamplerExternalOES: return GL_SAMPLER_EXTERNAL_OES;
300 0 : case EbtSampler2DRect: return GL_SAMPLER_2D_RECT_ARB;
301 0 : case EbtSampler2DArray: return GL_SAMPLER_2D_ARRAY;
302 0 : case EbtISampler2D: return GL_INT_SAMPLER_2D;
303 0 : case EbtISampler3D: return GL_INT_SAMPLER_3D;
304 0 : case EbtISamplerCube: return GL_INT_SAMPLER_CUBE;
305 0 : case EbtISampler2DArray: return GL_INT_SAMPLER_2D_ARRAY;
306 0 : case EbtUSampler2D: return GL_UNSIGNED_INT_SAMPLER_2D;
307 0 : case EbtUSampler3D: return GL_UNSIGNED_INT_SAMPLER_3D;
308 0 : case EbtUSamplerCube: return GL_UNSIGNED_INT_SAMPLER_CUBE;
309 0 : case EbtUSampler2DArray: return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
310 0 : case EbtSampler2DShadow: return GL_SAMPLER_2D_SHADOW;
311 0 : case EbtSamplerCubeShadow: return GL_SAMPLER_CUBE_SHADOW;
312 0 : case EbtSampler2DArrayShadow: return GL_SAMPLER_2D_ARRAY_SHADOW;
313 : case EbtImage2D:
314 0 : return GL_IMAGE_2D;
315 : case EbtIImage2D:
316 0 : return GL_INT_IMAGE_2D;
317 : case EbtUImage2D:
318 0 : return GL_UNSIGNED_INT_IMAGE_2D;
319 : case EbtImage2DArray:
320 0 : return GL_IMAGE_2D_ARRAY;
321 : case EbtIImage2DArray:
322 0 : return GL_INT_IMAGE_2D_ARRAY;
323 : case EbtUImage2DArray:
324 0 : return GL_UNSIGNED_INT_IMAGE_2D_ARRAY;
325 : case EbtImage3D:
326 0 : return GL_IMAGE_3D;
327 : case EbtIImage3D:
328 0 : return GL_INT_IMAGE_3D;
329 : case EbtUImage3D:
330 0 : return GL_UNSIGNED_INT_IMAGE_3D;
331 : case EbtImageCube:
332 0 : return GL_IMAGE_CUBE;
333 : case EbtIImageCube:
334 0 : return GL_INT_IMAGE_CUBE;
335 : case EbtUImageCube:
336 0 : return GL_UNSIGNED_INT_IMAGE_CUBE;
337 0 : default: UNREACHABLE();
338 : }
339 :
340 : return GL_NONE;
341 : }
342 :
343 0 : GLenum GLVariablePrecision(const TType &type)
344 : {
345 0 : if (type.getBasicType() == EbtFloat)
346 : {
347 0 : switch (type.getPrecision())
348 : {
349 : case EbpHigh:
350 0 : return GL_HIGH_FLOAT;
351 : case EbpMedium:
352 0 : return GL_MEDIUM_FLOAT;
353 : case EbpLow:
354 0 : return GL_LOW_FLOAT;
355 : case EbpUndefined:
356 : // Should be defined as the default precision by the parser
357 : default:
358 0 : UNREACHABLE();
359 : }
360 : }
361 0 : else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
362 : {
363 0 : switch (type.getPrecision())
364 : {
365 : case EbpHigh:
366 0 : return GL_HIGH_INT;
367 : case EbpMedium:
368 0 : return GL_MEDIUM_INT;
369 : case EbpLow:
370 0 : return GL_LOW_INT;
371 : case EbpUndefined:
372 : // Should be defined as the default precision by the parser
373 : default:
374 0 : UNREACHABLE();
375 : }
376 : }
377 :
378 : // Other types (boolean, sampler) don't have a precision
379 0 : return GL_NONE;
380 : }
381 :
382 0 : TString ArrayString(const TType &type)
383 : {
384 0 : if (!type.isArray())
385 : {
386 0 : return "";
387 : }
388 :
389 0 : return "[" + str(type.getArraySize()) + "]";
390 : }
391 :
392 0 : bool IsVaryingOut(TQualifier qualifier)
393 : {
394 0 : switch (qualifier)
395 : {
396 : case EvqVaryingOut:
397 : case EvqSmoothOut:
398 : case EvqFlatOut:
399 : case EvqCentroidOut:
400 : case EvqVertexOut:
401 0 : return true;
402 :
403 0 : default: break;
404 : }
405 :
406 0 : return false;
407 : }
408 :
409 0 : bool IsVaryingIn(TQualifier qualifier)
410 : {
411 0 : switch (qualifier)
412 : {
413 : case EvqVaryingIn:
414 : case EvqSmoothIn:
415 : case EvqFlatIn:
416 : case EvqCentroidIn:
417 : case EvqFragmentIn:
418 0 : return true;
419 :
420 0 : default: break;
421 : }
422 :
423 0 : return false;
424 : }
425 :
426 0 : bool IsVarying(TQualifier qualifier)
427 : {
428 0 : return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
429 : }
430 :
431 0 : InterpolationType GetInterpolationType(TQualifier qualifier)
432 : {
433 0 : switch (qualifier)
434 : {
435 : case EvqFlatIn:
436 : case EvqFlatOut:
437 0 : return INTERPOLATION_FLAT;
438 :
439 : case EvqSmoothIn:
440 : case EvqSmoothOut:
441 : case EvqVertexOut:
442 : case EvqFragmentIn:
443 : case EvqVaryingIn:
444 : case EvqVaryingOut:
445 0 : return INTERPOLATION_SMOOTH;
446 :
447 : case EvqCentroidIn:
448 : case EvqCentroidOut:
449 0 : return INTERPOLATION_CENTROID;
450 :
451 0 : default: UNREACHABLE();
452 : return INTERPOLATION_SMOOTH;
453 : }
454 : }
455 :
456 0 : TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
457 : {
458 0 : switch (var.type)
459 : {
460 : case GL_BOOL:
461 0 : return TType(EbtBool);
462 : case GL_BOOL_VEC2:
463 0 : return TType(EbtBool, 2);
464 : case GL_BOOL_VEC3:
465 0 : return TType(EbtBool, 3);
466 : case GL_BOOL_VEC4:
467 0 : return TType(EbtBool, 4);
468 : case GL_FLOAT:
469 0 : return TType(EbtFloat);
470 : case GL_FLOAT_VEC2:
471 0 : return TType(EbtFloat, 2);
472 : case GL_FLOAT_VEC3:
473 0 : return TType(EbtFloat, 3);
474 : case GL_FLOAT_VEC4:
475 0 : return TType(EbtFloat, 4);
476 : case GL_FLOAT_MAT2:
477 0 : return TType(EbtFloat, 2, 2);
478 : case GL_FLOAT_MAT3:
479 0 : return TType(EbtFloat, 3, 3);
480 : case GL_FLOAT_MAT4:
481 0 : return TType(EbtFloat, 4, 4);
482 : case GL_FLOAT_MAT2x3:
483 0 : return TType(EbtFloat, 2, 3);
484 : case GL_FLOAT_MAT2x4:
485 0 : return TType(EbtFloat, 2, 4);
486 : case GL_FLOAT_MAT3x2:
487 0 : return TType(EbtFloat, 3, 2);
488 : case GL_FLOAT_MAT3x4:
489 0 : return TType(EbtFloat, 3, 4);
490 : case GL_FLOAT_MAT4x2:
491 0 : return TType(EbtFloat, 4, 2);
492 : case GL_FLOAT_MAT4x3:
493 0 : return TType(EbtFloat, 4, 3);
494 : case GL_INT:
495 0 : return TType(EbtInt);
496 : case GL_INT_VEC2:
497 0 : return TType(EbtInt, 2);
498 : case GL_INT_VEC3:
499 0 : return TType(EbtInt, 3);
500 : case GL_INT_VEC4:
501 0 : return TType(EbtInt, 4);
502 : case GL_UNSIGNED_INT:
503 0 : return TType(EbtUInt);
504 : case GL_UNSIGNED_INT_VEC2:
505 0 : return TType(EbtUInt, 2);
506 : case GL_UNSIGNED_INT_VEC3:
507 0 : return TType(EbtUInt, 3);
508 : case GL_UNSIGNED_INT_VEC4:
509 0 : return TType(EbtUInt, 4);
510 : default:
511 0 : UNREACHABLE();
512 : return TType();
513 : }
514 : }
515 :
516 0 : TOperator TypeToConstructorOperator(const TType &type)
517 : {
518 0 : switch (type.getBasicType())
519 : {
520 : case EbtFloat:
521 0 : if (type.isMatrix())
522 : {
523 0 : switch (type.getCols())
524 : {
525 : case 2:
526 0 : switch (type.getRows())
527 : {
528 : case 2:
529 0 : return EOpConstructMat2;
530 : case 3:
531 0 : return EOpConstructMat2x3;
532 : case 4:
533 0 : return EOpConstructMat2x4;
534 : default:
535 0 : break;
536 : }
537 0 : break;
538 :
539 : case 3:
540 0 : switch (type.getRows())
541 : {
542 : case 2:
543 0 : return EOpConstructMat3x2;
544 : case 3:
545 0 : return EOpConstructMat3;
546 : case 4:
547 0 : return EOpConstructMat3x4;
548 : default:
549 0 : break;
550 : }
551 0 : break;
552 :
553 : case 4:
554 0 : switch (type.getRows())
555 : {
556 : case 2:
557 0 : return EOpConstructMat4x2;
558 : case 3:
559 0 : return EOpConstructMat4x3;
560 : case 4:
561 0 : return EOpConstructMat4;
562 : default:
563 0 : break;
564 : }
565 0 : break;
566 : }
567 : }
568 : else
569 : {
570 0 : switch (type.getNominalSize())
571 : {
572 : case 1:
573 0 : return EOpConstructFloat;
574 : case 2:
575 0 : return EOpConstructVec2;
576 : case 3:
577 0 : return EOpConstructVec3;
578 : case 4:
579 0 : return EOpConstructVec4;
580 : default:
581 0 : break;
582 : }
583 : }
584 0 : break;
585 :
586 : case EbtInt:
587 0 : switch (type.getNominalSize())
588 : {
589 : case 1:
590 0 : return EOpConstructInt;
591 : case 2:
592 0 : return EOpConstructIVec2;
593 : case 3:
594 0 : return EOpConstructIVec3;
595 : case 4:
596 0 : return EOpConstructIVec4;
597 : default:
598 0 : break;
599 : }
600 0 : break;
601 :
602 : case EbtUInt:
603 0 : switch (type.getNominalSize())
604 : {
605 : case 1:
606 0 : return EOpConstructUInt;
607 : case 2:
608 0 : return EOpConstructUVec2;
609 : case 3:
610 0 : return EOpConstructUVec3;
611 : case 4:
612 0 : return EOpConstructUVec4;
613 : default:
614 0 : break;
615 : }
616 0 : break;
617 :
618 : case EbtBool:
619 0 : switch (type.getNominalSize())
620 : {
621 : case 1:
622 0 : return EOpConstructBool;
623 : case 2:
624 0 : return EOpConstructBVec2;
625 : case 3:
626 0 : return EOpConstructBVec3;
627 : case 4:
628 0 : return EOpConstructBVec4;
629 : default:
630 0 : break;
631 : }
632 0 : break;
633 :
634 : case EbtStruct:
635 0 : return EOpConstructStruct;
636 :
637 : default:
638 0 : break;
639 : }
640 :
641 0 : return EOpNull;
642 : }
643 :
644 0 : GetVariableTraverser::GetVariableTraverser(const TSymbolTable &symbolTable)
645 0 : : mSymbolTable(symbolTable)
646 : {
647 0 : }
648 :
649 : template void GetVariableTraverser::setTypeSpecificInfo(
650 : const TType &type, const TString& name, InterfaceBlockField *variable);
651 : template void GetVariableTraverser::setTypeSpecificInfo(
652 : const TType &type, const TString& name, ShaderVariable *variable);
653 : template void GetVariableTraverser::setTypeSpecificInfo(
654 : const TType &type, const TString& name, Uniform *variable);
655 :
656 : template<>
657 0 : void GetVariableTraverser::setTypeSpecificInfo(
658 : const TType &type, const TString& name, Varying *variable)
659 : {
660 0 : ASSERT(variable);
661 0 : switch (type.getQualifier())
662 : {
663 : case EvqVaryingIn:
664 : case EvqVaryingOut:
665 : case EvqVertexOut:
666 : case EvqSmoothOut:
667 : case EvqFlatOut:
668 : case EvqCentroidOut:
669 0 : if (mSymbolTable.isVaryingInvariant(std::string(name.c_str())) || type.isInvariant())
670 : {
671 0 : variable->isInvariant = true;
672 : }
673 0 : break;
674 : default:
675 0 : break;
676 : }
677 :
678 0 : variable->interpolation = GetInterpolationType(type.getQualifier());
679 0 : }
680 :
681 : template <typename VarT>
682 0 : void GetVariableTraverser::traverse(const TType &type,
683 : const TString &name,
684 : std::vector<VarT> *output)
685 : {
686 0 : const TStructure *structure = type.getStruct();
687 :
688 0 : VarT variable;
689 0 : variable.name = name.c_str();
690 0 : variable.arraySize = type.getArraySize();
691 :
692 0 : if (!structure)
693 : {
694 0 : variable.type = GLVariableType(type);
695 0 : variable.precision = GLVariablePrecision(type);
696 : }
697 : else
698 : {
699 : // Note: this enum value is not exposed outside ANGLE
700 0 : variable.type = GL_STRUCT_ANGLEX;
701 0 : variable.structName = structure->name().c_str();
702 :
703 0 : const TFieldList &fields = structure->fields();
704 :
705 0 : for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
706 : {
707 0 : TField *field = fields[fieldIndex];
708 0 : traverse(*field->type(), field->name(), &variable.fields);
709 : }
710 : }
711 0 : setTypeSpecificInfo(type, name, &variable);
712 0 : visitVariable(&variable);
713 :
714 0 : ASSERT(output);
715 0 : output->push_back(variable);
716 0 : }
717 :
718 : template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
719 : template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<ShaderVariable> *);
720 : template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Uniform> *);
721 : template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Varying> *);
722 :
723 : // GLSL ES 1.0.17 4.6.1 The Invariant Qualifier
724 0 : bool CanBeInvariantESSL1(TQualifier qualifier)
725 : {
726 0 : return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) ||
727 0 : IsBuiltinOutputVariable(qualifier) ||
728 0 : (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing);
729 : }
730 :
731 : // GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier
732 : // GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier
733 0 : bool CanBeInvariantESSL3OrGreater(TQualifier qualifier)
734 : {
735 0 : return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut ||
736 0 : IsBuiltinOutputVariable(qualifier);
737 : }
738 :
739 0 : bool IsBuiltinOutputVariable(TQualifier qualifier)
740 : {
741 0 : switch (qualifier)
742 : {
743 : case EvqPosition:
744 : case EvqPointSize:
745 : case EvqFragDepth:
746 : case EvqFragDepthEXT:
747 : case EvqFragColor:
748 : case EvqSecondaryFragColorEXT:
749 : case EvqFragData:
750 : case EvqSecondaryFragDataEXT:
751 0 : return true;
752 : default:
753 0 : break;
754 : }
755 0 : return false;
756 : }
757 :
758 0 : bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
759 : {
760 0 : switch (qualifier)
761 : {
762 : case EvqFragCoord:
763 : case EvqPointCoord:
764 : case EvqFrontFacing:
765 0 : return true;
766 : default:
767 0 : break;
768 : }
769 0 : return false;
770 : }
771 : } // namespace sh
|