blob: 0ddeae49a39248b8cc55df59971bf61460f9c66f [file] [log] [blame]
daniel@transgaming.com91ed1492010-10-29 03:11:43 +00001//
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
Geoff Lang17732822013-08-29 13:46:49 -04007#include "compiler/translator/util.h"
daniel@transgaming.com91ed1492010-10-29 03:11:43 +00008
Zhenyao Mof1d723c2013-09-23 14:57:07 -04009#include <limits>
10
Olli Etuaho99bd5f42016-11-07 12:44:29 +000011#include "common/utilities.h"
Zhenyao Mocc4ec642013-09-23 14:57:10 -040012#include "compiler/preprocessor/numeric_lex.h"
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070013#include "compiler/translator/SymbolTable.h"
Zhenyao Mof1d723c2013-09-23 14:57:07 -040014
Olli Etuahof541f522015-10-13 12:21:01 +030015bool atoi_clamp(const char *str, unsigned int *value)
Zhenyao Mof1d723c2013-09-23 14:57:07 -040016{
Zhenyao Mocc4ec642013-09-23 14:57:10 -040017 bool success = pp::numeric_lex_int(str, value);
18 if (!success)
Olli Etuahof541f522015-10-13 12:21:01 +030019 *value = std::numeric_limits<unsigned int>::max();
Zhenyao Mocc4ec642013-09-23 14:57:10 -040020 return success;
Zhenyao Mof1d723c2013-09-23 14:57:07 -040021}
22
Jamie Madill033dae62014-06-18 12:56:28 -040023namespace sh
24{
25
Olli Etuaho99bd5f42016-11-07 12:44:29 +000026float 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 unsigned int decimalMantissa = 0;
35 size_t i = 0;
36 bool decimalPointSeen = false;
37 bool nonZeroSeenInMantissa = false;
38
39 // The exponent offset reflects the position of the decimal point.
40 int exponentOffset = -1;
41 while (i < str.length())
42 {
43 const char c = str[i];
44 if (c == 'e' || c == 'E')
45 {
46 break;
47 }
48 if (c == '.')
49 {
50 decimalPointSeen = true;
51 ++i;
52 continue;
53 }
54
55 unsigned int digit = static_cast<unsigned int>(c - '0');
56 ASSERT(digit < 10u);
57 if (digit != 0u)
58 {
59 nonZeroSeenInMantissa = true;
60 }
61 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 if (decimalMantissa <= (std::numeric_limits<unsigned int>::max() - 9u) / 10u)
66 {
67 decimalMantissa = decimalMantissa * 10u + digit;
68 }
69 if (!decimalPointSeen)
70 {
71 ++exponentOffset;
72 }
73 }
74 else if (decimalPointSeen)
75 {
76 --exponentOffset;
77 }
78 ++i;
79 }
80 if (decimalMantissa == 0)
81 {
82 return 0.0f;
83 }
84 int exponent = 0;
85 if (i < str.length())
86 {
87 ASSERT(str[i] == 'e' || str[i] == 'E');
88 ++i;
89 bool exponentOutOfRange = false;
90 bool negativeExponent = false;
91 if (str[i] == '-')
92 {
93 negativeExponent = true;
94 ++i;
95 }
96 else if (str[i] == '+')
97 {
98 ++i;
99 }
100 while (i < str.length())
101 {
102 const char c = str[i];
103 unsigned int digit = static_cast<unsigned int>(c - '0');
104 ASSERT(digit < 10u);
105 if (exponent <= (std::numeric_limits<int>::max() - 9) / 10)
106 {
107 exponent = exponent * 10 + digit;
108 }
109 else
110 {
111 exponentOutOfRange = true;
112 }
113 ++i;
114 }
115 if (negativeExponent)
116 {
117 exponent = -exponent;
118 }
119 if (exponentOutOfRange)
120 {
121 if (negativeExponent)
122 {
123 return 0.0f;
124 }
125 else
126 {
127 return std::numeric_limits<float>::infinity();
128 }
129 }
130 }
131 // Do the calculation in 64-bit to avoid overflow.
132 long long exponentLong =
133 static_cast<long long>(exponent) + static_cast<long long>(exponentOffset);
134 if (exponentLong > std::numeric_limits<float>::max_exponent10)
135 {
136 return std::numeric_limits<float>::infinity();
137 }
138 else if (exponentLong < std::numeric_limits<float>::min_exponent10)
139 {
140 return 0.0f;
141 }
142 // The exponent is in range, so we need to actually evaluate the float.
143 exponent = static_cast<int>(exponentLong);
144 double value = decimalMantissa;
145
146 // Calculate the exponent offset to normalize the mantissa.
147 int normalizationExponentOffset = 0;
148 while (decimalMantissa >= 10u)
149 {
150 --normalizationExponentOffset;
151 decimalMantissa /= 10u;
152 }
153 // Apply the exponent.
154 value *= std::pow(10.0, static_cast<double>(exponent + normalizationExponentOffset));
155 if (value > static_cast<double>(std::numeric_limits<float>::max()))
156 {
157 return std::numeric_limits<float>::infinity();
158 }
159 if (value < static_cast<double>(std::numeric_limits<float>::min()))
160 {
161 return 0.0f;
162 }
163 return static_cast<float>(value);
164}
165
166bool strtof_clamp(const std::string &str, float *value)
167{
168 // Try the standard float parsing path first.
169 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 if (!success)
181 *value = NumericLexFloat32OutOfRangeToInfinity(str);
182 return !gl::isInf(*value);
183}
184
Jamie Madill033dae62014-06-18 12:56:28 -0400185GLenum GLVariableType(const TType &type)
186{
187 if (type.getBasicType() == EbtFloat)
188 {
189 if (type.isScalar())
190 {
191 return GL_FLOAT;
192 }
193 else if (type.isVector())
194 {
195 switch (type.getNominalSize())
196 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500197 case 2:
198 return GL_FLOAT_VEC2;
199 case 3:
200 return GL_FLOAT_VEC3;
201 case 4:
202 return GL_FLOAT_VEC4;
203 default:
204 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400205 }
206 }
207 else if (type.isMatrix())
208 {
209 switch (type.getCols())
210 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500211 case 2:
212 switch (type.getRows())
213 {
214 case 2:
215 return GL_FLOAT_MAT2;
216 case 3:
217 return GL_FLOAT_MAT2x3;
218 case 4:
219 return GL_FLOAT_MAT2x4;
220 default:
221 UNREACHABLE();
222 }
Jamie Madill033dae62014-06-18 12:56:28 -0400223
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500224 case 3:
225 switch (type.getRows())
226 {
227 case 2:
228 return GL_FLOAT_MAT3x2;
229 case 3:
230 return GL_FLOAT_MAT3;
231 case 4:
232 return GL_FLOAT_MAT3x4;
233 default:
234 UNREACHABLE();
235 }
Jamie Madill033dae62014-06-18 12:56:28 -0400236
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500237 case 4:
238 switch (type.getRows())
239 {
240 case 2:
241 return GL_FLOAT_MAT4x2;
242 case 3:
243 return GL_FLOAT_MAT4x3;
244 case 4:
245 return GL_FLOAT_MAT4;
246 default:
247 UNREACHABLE();
248 }
Jamie Madill033dae62014-06-18 12:56:28 -0400249
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500250 default:
251 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400252 }
253 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500254 else
255 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400256 }
257 else if (type.getBasicType() == EbtInt)
258 {
259 if (type.isScalar())
260 {
261 return GL_INT;
262 }
263 else if (type.isVector())
264 {
265 switch (type.getNominalSize())
266 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500267 case 2:
268 return GL_INT_VEC2;
269 case 3:
270 return GL_INT_VEC3;
271 case 4:
272 return GL_INT_VEC4;
273 default:
274 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400275 }
276 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500277 else
278 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400279 }
280 else if (type.getBasicType() == EbtUInt)
281 {
282 if (type.isScalar())
283 {
284 return GL_UNSIGNED_INT;
285 }
286 else if (type.isVector())
287 {
288 switch (type.getNominalSize())
289 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500290 case 2:
291 return GL_UNSIGNED_INT_VEC2;
292 case 3:
293 return GL_UNSIGNED_INT_VEC3;
294 case 4:
295 return GL_UNSIGNED_INT_VEC4;
296 default:
297 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400298 }
299 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500300 else
301 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400302 }
303 else if (type.getBasicType() == EbtBool)
304 {
305 if (type.isScalar())
306 {
307 return GL_BOOL;
308 }
309 else if (type.isVector())
310 {
311 switch (type.getNominalSize())
312 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500313 case 2:
314 return GL_BOOL_VEC2;
315 case 3:
316 return GL_BOOL_VEC3;
317 case 4:
318 return GL_BOOL_VEC4;
319 default:
320 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400321 }
322 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500323 else
324 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400325 }
326
327 switch (type.getBasicType())
328 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500329 case EbtSampler2D:
330 return GL_SAMPLER_2D;
331 case EbtSampler3D:
332 return GL_SAMPLER_3D;
333 case EbtSamplerCube:
334 return GL_SAMPLER_CUBE;
335 case EbtSamplerExternalOES:
336 return GL_SAMPLER_EXTERNAL_OES;
337 case EbtSampler2DRect:
338 return GL_SAMPLER_2D_RECT_ARB;
339 case EbtSampler2DArray:
340 return GL_SAMPLER_2D_ARRAY;
341 case EbtISampler2D:
342 return GL_INT_SAMPLER_2D;
343 case EbtISampler3D:
344 return GL_INT_SAMPLER_3D;
345 case EbtISamplerCube:
346 return GL_INT_SAMPLER_CUBE;
347 case EbtISampler2DArray:
348 return GL_INT_SAMPLER_2D_ARRAY;
349 case EbtUSampler2D:
350 return GL_UNSIGNED_INT_SAMPLER_2D;
351 case EbtUSampler3D:
352 return GL_UNSIGNED_INT_SAMPLER_3D;
353 case EbtUSamplerCube:
354 return GL_UNSIGNED_INT_SAMPLER_CUBE;
355 case EbtUSampler2DArray:
356 return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
357 case EbtSampler2DShadow:
358 return GL_SAMPLER_2D_SHADOW;
359 case EbtSamplerCubeShadow:
360 return GL_SAMPLER_CUBE_SHADOW;
361 case EbtSampler2DArrayShadow:
362 return GL_SAMPLER_2D_ARRAY_SHADOW;
363 case EbtImage2D:
364 return GL_IMAGE_2D;
365 case EbtIImage2D:
366 return GL_INT_IMAGE_2D;
367 case EbtUImage2D:
368 return GL_UNSIGNED_INT_IMAGE_2D;
369 case EbtImage2DArray:
370 return GL_IMAGE_2D_ARRAY;
371 case EbtIImage2DArray:
372 return GL_INT_IMAGE_2D_ARRAY;
373 case EbtUImage2DArray:
374 return GL_UNSIGNED_INT_IMAGE_2D_ARRAY;
375 case EbtImage3D:
376 return GL_IMAGE_3D;
377 case EbtIImage3D:
378 return GL_INT_IMAGE_3D;
379 case EbtUImage3D:
380 return GL_UNSIGNED_INT_IMAGE_3D;
381 case EbtImageCube:
382 return GL_IMAGE_CUBE;
383 case EbtIImageCube:
384 return GL_INT_IMAGE_CUBE;
385 case EbtUImageCube:
386 return GL_UNSIGNED_INT_IMAGE_CUBE;
387 default:
388 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400389 }
390
391 return GL_NONE;
392}
393
394GLenum GLVariablePrecision(const TType &type)
395{
396 if (type.getBasicType() == EbtFloat)
397 {
398 switch (type.getPrecision())
399 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500400 case EbpHigh:
401 return GL_HIGH_FLOAT;
402 case EbpMedium:
403 return GL_MEDIUM_FLOAT;
404 case EbpLow:
405 return GL_LOW_FLOAT;
406 case EbpUndefined:
407 // Should be defined as the default precision by the parser
408 default:
409 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400410 }
411 }
412 else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
413 {
414 switch (type.getPrecision())
415 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500416 case EbpHigh:
417 return GL_HIGH_INT;
418 case EbpMedium:
419 return GL_MEDIUM_INT;
420 case EbpLow:
421 return GL_LOW_INT;
422 case EbpUndefined:
423 // Should be defined as the default precision by the parser
424 default:
425 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400426 }
427 }
428
429 // Other types (boolean, sampler) don't have a precision
430 return GL_NONE;
431}
432
433TString ArrayString(const TType &type)
434{
435 if (!type.isArray())
436 {
437 return "";
438 }
439
440 return "[" + str(type.getArraySize()) + "]";
441}
442
443bool IsVaryingOut(TQualifier qualifier)
444{
445 switch (qualifier)
446 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500447 case EvqVaryingOut:
448 case EvqSmoothOut:
449 case EvqFlatOut:
450 case EvqCentroidOut:
451 case EvqVertexOut:
452 return true;
Jamie Madill033dae62014-06-18 12:56:28 -0400453
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500454 default:
455 break;
Jamie Madill033dae62014-06-18 12:56:28 -0400456 }
457
458 return false;
459}
460
461bool IsVaryingIn(TQualifier qualifier)
462{
463 switch (qualifier)
464 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500465 case EvqVaryingIn:
466 case EvqSmoothIn:
467 case EvqFlatIn:
468 case EvqCentroidIn:
469 case EvqFragmentIn:
470 return true;
Jamie Madill033dae62014-06-18 12:56:28 -0400471
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500472 default:
473 break;
Jamie Madill033dae62014-06-18 12:56:28 -0400474 }
475
476 return false;
477}
478
479bool IsVarying(TQualifier qualifier)
480{
481 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
482}
483
Jamie Madillf2575982014-06-25 16:04:54 -0400484InterpolationType GetInterpolationType(TQualifier qualifier)
Jamie Madill033dae62014-06-18 12:56:28 -0400485{
486 switch (qualifier)
487 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500488 case EvqFlatIn:
489 case EvqFlatOut:
490 return INTERPOLATION_FLAT;
Jamie Madill033dae62014-06-18 12:56:28 -0400491
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500492 case EvqSmoothIn:
493 case EvqSmoothOut:
494 case EvqVertexOut:
495 case EvqFragmentIn:
496 case EvqVaryingIn:
497 case EvqVaryingOut:
498 return INTERPOLATION_SMOOTH;
Jamie Madill033dae62014-06-18 12:56:28 -0400499
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500500 case EvqCentroidIn:
501 case EvqCentroidOut:
502 return INTERPOLATION_CENTROID;
Jamie Madill033dae62014-06-18 12:56:28 -0400503
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500504 default:
505 UNREACHABLE();
506 return INTERPOLATION_SMOOTH;
Jamie Madill033dae62014-06-18 12:56:28 -0400507 }
508}
509
Corentin Wallez509e4562016-08-25 14:55:44 -0400510TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
Zhenyao Mo72111912016-07-20 17:45:56 -0700511{
Corentin Wallez509e4562016-08-25 14:55:44 -0400512 switch (var.type)
Zhenyao Mo72111912016-07-20 17:45:56 -0700513 {
Qin Jiajia7835b522016-10-08 11:20:17 +0800514 case GL_BOOL:
515 return TType(EbtBool);
516 case GL_BOOL_VEC2:
517 return TType(EbtBool, 2);
518 case GL_BOOL_VEC3:
519 return TType(EbtBool, 3);
520 case GL_BOOL_VEC4:
521 return TType(EbtBool, 4);
Zhenyao Mo72111912016-07-20 17:45:56 -0700522 case GL_FLOAT:
523 return TType(EbtFloat);
524 case GL_FLOAT_VEC2:
525 return TType(EbtFloat, 2);
526 case GL_FLOAT_VEC3:
527 return TType(EbtFloat, 3);
528 case GL_FLOAT_VEC4:
529 return TType(EbtFloat, 4);
530 case GL_FLOAT_MAT2:
531 return TType(EbtFloat, 2, 2);
532 case GL_FLOAT_MAT3:
533 return TType(EbtFloat, 3, 3);
534 case GL_FLOAT_MAT4:
535 return TType(EbtFloat, 4, 4);
536 case GL_FLOAT_MAT2x3:
537 return TType(EbtFloat, 2, 3);
538 case GL_FLOAT_MAT2x4:
539 return TType(EbtFloat, 2, 4);
540 case GL_FLOAT_MAT3x2:
541 return TType(EbtFloat, 3, 2);
542 case GL_FLOAT_MAT3x4:
543 return TType(EbtFloat, 3, 4);
544 case GL_FLOAT_MAT4x2:
545 return TType(EbtFloat, 4, 2);
546 case GL_FLOAT_MAT4x3:
547 return TType(EbtFloat, 4, 3);
548 case GL_INT:
549 return TType(EbtInt);
550 case GL_INT_VEC2:
551 return TType(EbtInt, 2);
552 case GL_INT_VEC3:
553 return TType(EbtInt, 3);
554 case GL_INT_VEC4:
555 return TType(EbtInt, 4);
556 case GL_UNSIGNED_INT:
557 return TType(EbtUInt);
558 case GL_UNSIGNED_INT_VEC2:
559 return TType(EbtUInt, 2);
560 case GL_UNSIGNED_INT_VEC3:
561 return TType(EbtUInt, 3);
562 case GL_UNSIGNED_INT_VEC4:
563 return TType(EbtUInt, 4);
564 default:
565 UNREACHABLE();
566 return TType();
567 }
568}
569
Geoff Lang156d7192016-07-21 16:11:00 -0400570TOperator TypeToConstructorOperator(const TType &type)
571{
572 switch (type.getBasicType())
573 {
574 case EbtFloat:
575 if (type.isMatrix())
576 {
577 switch (type.getCols())
578 {
579 case 2:
580 switch (type.getRows())
581 {
582 case 2:
583 return EOpConstructMat2;
584 case 3:
585 return EOpConstructMat2x3;
586 case 4:
587 return EOpConstructMat2x4;
588 default:
589 break;
590 }
591 break;
592
593 case 3:
594 switch (type.getRows())
595 {
596 case 2:
597 return EOpConstructMat3x2;
598 case 3:
599 return EOpConstructMat3;
600 case 4:
601 return EOpConstructMat3x4;
602 default:
603 break;
604 }
605 break;
606
607 case 4:
608 switch (type.getRows())
609 {
610 case 2:
611 return EOpConstructMat4x2;
612 case 3:
613 return EOpConstructMat4x3;
614 case 4:
615 return EOpConstructMat4;
616 default:
617 break;
618 }
619 break;
620 }
621 }
622 else
623 {
624 switch (type.getNominalSize())
625 {
626 case 1:
627 return EOpConstructFloat;
628 case 2:
629 return EOpConstructVec2;
630 case 3:
631 return EOpConstructVec3;
632 case 4:
633 return EOpConstructVec4;
634 default:
635 break;
636 }
637 }
638 break;
639
640 case EbtInt:
641 switch (type.getNominalSize())
642 {
643 case 1:
644 return EOpConstructInt;
645 case 2:
646 return EOpConstructIVec2;
647 case 3:
648 return EOpConstructIVec3;
649 case 4:
650 return EOpConstructIVec4;
651 default:
652 break;
653 }
654 break;
655
656 case EbtUInt:
657 switch (type.getNominalSize())
658 {
659 case 1:
660 return EOpConstructUInt;
661 case 2:
662 return EOpConstructUVec2;
663 case 3:
664 return EOpConstructUVec3;
665 case 4:
666 return EOpConstructUVec4;
667 default:
668 break;
669 }
670 break;
671
672 case EbtBool:
673 switch (type.getNominalSize())
674 {
675 case 1:
676 return EOpConstructBool;
677 case 2:
678 return EOpConstructBVec2;
679 case 3:
680 return EOpConstructBVec3;
681 case 4:
682 return EOpConstructBVec4;
683 default:
684 break;
685 }
686 break;
687
688 case EbtStruct:
689 return EOpConstructStruct;
690
691 default:
692 break;
693 }
694
695 return EOpNull;
696}
697
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700698GetVariableTraverser::GetVariableTraverser(const TSymbolTable &symbolTable)
699 : mSymbolTable(symbolTable)
700{
701}
702
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500703template void GetVariableTraverser::setTypeSpecificInfo(const TType &type,
704 const TString &name,
705 InterfaceBlockField *variable);
706template void GetVariableTraverser::setTypeSpecificInfo(const TType &type,
707 const TString &name,
708 ShaderVariable *variable);
709template void GetVariableTraverser::setTypeSpecificInfo(const TType &type,
710 const TString &name,
711 Uniform *variable);
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700712
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500713template <>
714void GetVariableTraverser::setTypeSpecificInfo(const TType &type,
715 const TString &name,
716 Varying *variable)
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700717{
718 ASSERT(variable);
719 switch (type.getQualifier())
720 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500721 case EvqVaryingIn:
722 case EvqVaryingOut:
723 case EvqVertexOut:
724 case EvqSmoothOut:
725 case EvqFlatOut:
726 case EvqCentroidOut:
727 if (mSymbolTable.isVaryingInvariant(std::string(name.c_str())) || type.isInvariant())
728 {
729 variable->isInvariant = true;
730 }
731 break;
732 default:
733 break;
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700734 }
Jamie Madill70a0b2a2014-10-21 11:48:39 -0400735
736 variable->interpolation = GetInterpolationType(type.getQualifier());
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700737}
738
Jamie Madill77f74852014-07-08 15:02:34 -0400739template <typename VarT>
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700740void GetVariableTraverser::traverse(const TType &type,
741 const TString &name,
742 std::vector<VarT> *output)
Jamie Madill77f74852014-07-08 15:02:34 -0400743{
744 const TStructure *structure = type.getStruct();
745
746 VarT variable;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500747 variable.name = name.c_str();
Olli Etuaho856c4972016-08-08 11:38:39 +0300748 variable.arraySize = type.getArraySize();
Jamie Madill77f74852014-07-08 15:02:34 -0400749
750 if (!structure)
751 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500752 variable.type = GLVariableType(type);
Jamie Madill77f74852014-07-08 15:02:34 -0400753 variable.precision = GLVariablePrecision(type);
754 }
755 else
756 {
Jamie Madill42bcf322014-08-25 16:20:46 -0400757 // Note: this enum value is not exposed outside ANGLE
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500758 variable.type = GL_STRUCT_ANGLEX;
Jamie Madill42bcf322014-08-25 16:20:46 -0400759 variable.structName = structure->name().c_str();
Jamie Madill77f74852014-07-08 15:02:34 -0400760
761 const TFieldList &fields = structure->fields();
762
763 for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
764 {
765 TField *field = fields[fieldIndex];
Jamie Madill42bcf322014-08-25 16:20:46 -0400766 traverse(*field->type(), field->name(), &variable.fields);
Jamie Madill77f74852014-07-08 15:02:34 -0400767 }
Jamie Madill77f74852014-07-08 15:02:34 -0400768 }
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700769 setTypeSpecificInfo(type, name, &variable);
Jamie Madill77f74852014-07-08 15:02:34 -0400770 visitVariable(&variable);
771
Jamie Madill77f74852014-07-08 15:02:34 -0400772 ASSERT(output);
Jamie Madill42bcf322014-08-25 16:20:46 -0400773 output->push_back(variable);
Jamie Madill77f74852014-07-08 15:02:34 -0400774}
775
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500776template void GetVariableTraverser::traverse(const TType &,
777 const TString &,
778 std::vector<InterfaceBlockField> *);
779template void GetVariableTraverser::traverse(const TType &,
780 const TString &,
781 std::vector<ShaderVariable> *);
782template void GetVariableTraverser::traverse(const TType &,
783 const TString &,
784 std::vector<Uniform> *);
785template void GetVariableTraverser::traverse(const TType &,
786 const TString &,
787 std::vector<Varying> *);
Jamie Madill77f74852014-07-08 15:02:34 -0400788
Martin Radev70866b82016-07-22 15:27:42 +0300789// GLSL ES 1.0.17 4.6.1 The Invariant Qualifier
790bool CanBeInvariantESSL1(TQualifier qualifier)
791{
792 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) ||
793 IsBuiltinOutputVariable(qualifier) ||
794 (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing);
Jamie Madill033dae62014-06-18 12:56:28 -0400795}
Martin Radev70866b82016-07-22 15:27:42 +0300796
797// GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier
798// GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier
799bool CanBeInvariantESSL3OrGreater(TQualifier qualifier)
800{
801 return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut ||
802 IsBuiltinOutputVariable(qualifier);
803}
804
805bool IsBuiltinOutputVariable(TQualifier qualifier)
806{
807 switch (qualifier)
808 {
809 case EvqPosition:
810 case EvqPointSize:
811 case EvqFragDepth:
812 case EvqFragDepthEXT:
813 case EvqFragColor:
814 case EvqSecondaryFragColorEXT:
815 case EvqFragData:
816 case EvqSecondaryFragDataEXT:
817 return true;
818 default:
819 break;
820 }
821 return false;
822}
823
824bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
825{
826 switch (qualifier)
827 {
828 case EvqFragCoord:
829 case EvqPointCoord:
830 case EvqFrontFacing:
831 return true;
832 default:
833 break;
834 }
835 return false;
836}
837} // namespace sh