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/ImmutableStringBuilder.h" |
14 | #include "compiler/translator/SymbolTable.h" |
15 | |
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 | |
30 | bool IsInterpolationIn(TQualifier qualifier) |
31 | { |
32 | switch (qualifier) |
33 | { |
34 | case EvqSmoothIn: |
35 | case EvqFlatIn: |
36 | case EvqCentroidIn: |
37 | return true; |
38 | default: |
39 | return false; |
40 | } |
41 | } |
42 | |
43 | } // anonymous namespace |
44 | |
45 | float NumericLexFloat32OutOfRangeToInfinity(const std::string &str) |
46 | { |
47 | // Parses a decimal string using scientific notation into a floating point number. |
48 | // Out-of-range values are converted to infinity. Values that are too small to be |
49 | // represented are converted to zero. |
50 | |
51 | // The mantissa in decimal scientific notation. The magnitude of the mantissa integer does not |
52 | // matter. |
53 | unsigned int decimalMantissa = 0; |
54 | size_t i = 0; |
55 | bool decimalPointSeen = false; |
56 | bool nonZeroSeenInMantissa = false; |
57 | |
58 | // The exponent offset reflects the position of the decimal point. |
59 | int exponentOffset = -1; |
60 | |
61 | // This is just a counter for how many decimal digits are written to decimalMantissa. |
62 | int mantissaDecimalDigits = 0; |
63 | |
64 | while (i < str.length()) |
65 | { |
66 | const char c = str[i]; |
67 | if (c == 'e' || c == 'E') |
68 | { |
69 | break; |
70 | } |
71 | if (c == '.') |
72 | { |
73 | decimalPointSeen = true; |
74 | ++i; |
75 | continue; |
76 | } |
77 | |
78 | unsigned int digit = static_cast<unsigned int>(c - '0'); |
79 | ASSERT(digit < 10u); |
80 | if (digit != 0u) |
81 | { |
82 | nonZeroSeenInMantissa = true; |
83 | } |
84 | if (nonZeroSeenInMantissa) |
85 | { |
86 | // Add bits to the mantissa until space runs out in 32-bit int. This should be |
87 | // enough precision to make the resulting binary mantissa accurate to 1 ULP. |
88 | if (decimalMantissa <= (std::numeric_limits<unsigned int>::max() - 9u) / 10u) |
89 | { |
90 | decimalMantissa = decimalMantissa * 10u + digit; |
91 | ++mantissaDecimalDigits; |
92 | } |
93 | if (!decimalPointSeen) |
94 | { |
95 | ++exponentOffset; |
96 | } |
97 | } |
98 | else if (decimalPointSeen) |
99 | { |
100 | --exponentOffset; |
101 | } |
102 | ++i; |
103 | } |
104 | if (decimalMantissa == 0) |
105 | { |
106 | return 0.0f; |
107 | } |
108 | int exponent = 0; |
109 | if (i < str.length()) |
110 | { |
111 | ASSERT(str[i] == 'e' || str[i] == 'E'); |
112 | ++i; |
113 | bool exponentOutOfRange = false; |
114 | bool negativeExponent = false; |
115 | if (str[i] == '-') |
116 | { |
117 | negativeExponent = true; |
118 | ++i; |
119 | } |
120 | else if (str[i] == '+') |
121 | { |
122 | ++i; |
123 | } |
124 | while (i < str.length()) |
125 | { |
126 | const char c = str[i]; |
127 | unsigned int digit = static_cast<unsigned int>(c - '0'); |
128 | ASSERT(digit < 10u); |
129 | if (exponent <= (std::numeric_limits<int>::max() - 9) / 10) |
130 | { |
131 | exponent = exponent * 10 + digit; |
132 | } |
133 | else |
134 | { |
135 | exponentOutOfRange = true; |
136 | } |
137 | ++i; |
138 | } |
139 | if (negativeExponent) |
140 | { |
141 | exponent = -exponent; |
142 | } |
143 | if (exponentOutOfRange) |
144 | { |
145 | if (negativeExponent) |
146 | { |
147 | return 0.0f; |
148 | } |
149 | else |
150 | { |
151 | return std::numeric_limits<float>::infinity(); |
152 | } |
153 | } |
154 | } |
155 | // Do the calculation in 64-bit to avoid overflow. |
156 | long long exponentLong = |
157 | static_cast<long long>(exponent) + static_cast<long long>(exponentOffset); |
158 | if (exponentLong > std::numeric_limits<float>::max_exponent10) |
159 | { |
160 | return std::numeric_limits<float>::infinity(); |
161 | } |
162 | else if (exponentLong < std::numeric_limits<float>::min_exponent10) |
163 | { |
164 | return 0.0f; |
165 | } |
166 | // The exponent is in range, so we need to actually evaluate the float. |
167 | exponent = static_cast<int>(exponentLong); |
168 | double value = decimalMantissa; |
169 | |
170 | // Calculate the exponent offset to normalize the mantissa. |
171 | int normalizationExponentOffset = 1 - mantissaDecimalDigits; |
172 | // Apply the exponent. |
173 | value *= std::pow(10.0, static_cast<double>(exponent + normalizationExponentOffset)); |
174 | if (value > static_cast<double>(std::numeric_limits<float>::max())) |
175 | { |
176 | return std::numeric_limits<float>::infinity(); |
177 | } |
178 | if (value < static_cast<double>(std::numeric_limits<float>::min())) |
179 | { |
180 | return 0.0f; |
181 | } |
182 | return static_cast<float>(value); |
183 | } |
184 | |
185 | bool strtof_clamp(const std::string &str, float *value) |
186 | { |
187 | // Custom float parsing that can handle the following corner cases: |
188 | // 1. The decimal mantissa is very small but the exponent is very large, putting the resulting |
189 | // number inside the float range. |
190 | // 2. The decimal mantissa is very large but the exponent is very small, putting the resulting |
191 | // number inside the float range. |
192 | // 3. The value is out-of-range and should be evaluated as infinity. |
193 | // 4. The value is too small and should be evaluated as zero. |
194 | // See ESSL 3.00.6 section 4.1.4 for the relevant specification. |
195 | *value = NumericLexFloat32OutOfRangeToInfinity(str); |
196 | return !gl::isInf(*value); |
197 | } |
198 | |
199 | GLenum GLVariableType(const TType &type) |
200 | { |
201 | if (type.getBasicType() == EbtFloat) |
202 | { |
203 | if (type.isVector()) |
204 | { |
205 | switch (type.getNominalSize()) |
206 | { |
207 | case 2: |
208 | return GL_FLOAT_VEC2; |
209 | case 3: |
210 | return GL_FLOAT_VEC3; |
211 | case 4: |
212 | return GL_FLOAT_VEC4; |
213 | default: |
214 | UNREACHABLE(); |
215 | #if !UNREACHABLE_IS_NORETURN |
216 | return GL_NONE; |
217 | #endif |
218 | } |
219 | } |
220 | else if (type.isMatrix()) |
221 | { |
222 | switch (type.getCols()) |
223 | { |
224 | case 2: |
225 | switch (type.getRows()) |
226 | { |
227 | case 2: |
228 | return GL_FLOAT_MAT2; |
229 | case 3: |
230 | return GL_FLOAT_MAT2x3; |
231 | case 4: |
232 | return GL_FLOAT_MAT2x4; |
233 | default: |
234 | UNREACHABLE(); |
235 | #if !UNREACHABLE_IS_NORETURN |
236 | return GL_NONE; |
237 | #endif |
238 | } |
239 | |
240 | case 3: |
241 | switch (type.getRows()) |
242 | { |
243 | case 2: |
244 | return GL_FLOAT_MAT3x2; |
245 | case 3: |
246 | return GL_FLOAT_MAT3; |
247 | case 4: |
248 | return GL_FLOAT_MAT3x4; |
249 | default: |
250 | UNREACHABLE(); |
251 | #if !UNREACHABLE_IS_NORETURN |
252 | return GL_NONE; |
253 | #endif |
254 | } |
255 | |
256 | case 4: |
257 | switch (type.getRows()) |
258 | { |
259 | case 2: |
260 | return GL_FLOAT_MAT4x2; |
261 | case 3: |
262 | return GL_FLOAT_MAT4x3; |
263 | case 4: |
264 | return GL_FLOAT_MAT4; |
265 | default: |
266 | UNREACHABLE(); |
267 | #if !UNREACHABLE_IS_NORETURN |
268 | return GL_NONE; |
269 | #endif |
270 | } |
271 | |
272 | default: |
273 | UNREACHABLE(); |
274 | #if !UNREACHABLE_IS_NORETURN |
275 | return GL_NONE; |
276 | #endif |
277 | } |
278 | } |
279 | else |
280 | { |
281 | return GL_FLOAT; |
282 | } |
283 | } |
284 | else if (type.getBasicType() == EbtInt) |
285 | { |
286 | if (type.isVector()) |
287 | { |
288 | switch (type.getNominalSize()) |
289 | { |
290 | case 2: |
291 | return GL_INT_VEC2; |
292 | case 3: |
293 | return GL_INT_VEC3; |
294 | case 4: |
295 | return GL_INT_VEC4; |
296 | default: |
297 | UNREACHABLE(); |
298 | #if !UNREACHABLE_IS_NORETURN |
299 | return GL_NONE; |
300 | #endif |
301 | } |
302 | } |
303 | else |
304 | { |
305 | ASSERT(!type.isMatrix()); |
306 | return GL_INT; |
307 | } |
308 | } |
309 | else if (type.getBasicType() == EbtUInt) |
310 | { |
311 | if (type.isVector()) |
312 | { |
313 | switch (type.getNominalSize()) |
314 | { |
315 | case 2: |
316 | return GL_UNSIGNED_INT_VEC2; |
317 | case 3: |
318 | return GL_UNSIGNED_INT_VEC3; |
319 | case 4: |
320 | return GL_UNSIGNED_INT_VEC4; |
321 | default: |
322 | UNREACHABLE(); |
323 | #if !UNREACHABLE_IS_NORETURN |
324 | return GL_NONE; |
325 | #endif |
326 | } |
327 | } |
328 | else |
329 | { |
330 | ASSERT(!type.isMatrix()); |
331 | return GL_UNSIGNED_INT; |
332 | } |
333 | } |
334 | else if (type.getBasicType() == EbtBool) |
335 | { |
336 | if (type.isVector()) |
337 | { |
338 | switch (type.getNominalSize()) |
339 | { |
340 | case 2: |
341 | return GL_BOOL_VEC2; |
342 | case 3: |
343 | return GL_BOOL_VEC3; |
344 | case 4: |
345 | return GL_BOOL_VEC4; |
346 | default: |
347 | UNREACHABLE(); |
348 | #if !UNREACHABLE_IS_NORETURN |
349 | return GL_NONE; |
350 | #endif |
351 | } |
352 | } |
353 | else |
354 | { |
355 | ASSERT(!type.isMatrix()); |
356 | return GL_BOOL; |
357 | } |
358 | } |
359 | |
360 | switch (type.getBasicType()) |
361 | { |
362 | case EbtSampler2D: |
363 | return GL_SAMPLER_2D; |
364 | case EbtSampler3D: |
365 | return GL_SAMPLER_3D; |
366 | case EbtSamplerCube: |
367 | return GL_SAMPLER_CUBE; |
368 | case EbtSamplerExternalOES: |
369 | return GL_SAMPLER_EXTERNAL_OES; |
370 | case EbtSamplerExternal2DY2YEXT: |
371 | return GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT; |
372 | case EbtSampler2DRect: |
373 | return GL_SAMPLER_2D_RECT_ANGLE; |
374 | case EbtSampler2DArray: |
375 | return GL_SAMPLER_2D_ARRAY; |
376 | case EbtSampler2DMS: |
377 | return GL_SAMPLER_2D_MULTISAMPLE; |
378 | case EbtSampler2DMSArray: |
379 | return GL_SAMPLER_2D_MULTISAMPLE_ARRAY; |
380 | case EbtISampler2D: |
381 | return GL_INT_SAMPLER_2D; |
382 | case EbtISampler3D: |
383 | return GL_INT_SAMPLER_3D; |
384 | case EbtISamplerCube: |
385 | return GL_INT_SAMPLER_CUBE; |
386 | case EbtISampler2DArray: |
387 | return GL_INT_SAMPLER_2D_ARRAY; |
388 | case EbtISampler2DMS: |
389 | return GL_INT_SAMPLER_2D_MULTISAMPLE; |
390 | case EbtISampler2DMSArray: |
391 | return GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY; |
392 | case EbtUSampler2D: |
393 | return GL_UNSIGNED_INT_SAMPLER_2D; |
394 | case EbtUSampler3D: |
395 | return GL_UNSIGNED_INT_SAMPLER_3D; |
396 | case EbtUSamplerCube: |
397 | return GL_UNSIGNED_INT_SAMPLER_CUBE; |
398 | case EbtUSampler2DArray: |
399 | return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY; |
400 | case EbtUSampler2DMS: |
401 | return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE; |
402 | case EbtUSampler2DMSArray: |
403 | return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY; |
404 | case EbtSampler2DShadow: |
405 | return GL_SAMPLER_2D_SHADOW; |
406 | case EbtSamplerCubeShadow: |
407 | return GL_SAMPLER_CUBE_SHADOW; |
408 | case EbtSampler2DArrayShadow: |
409 | return GL_SAMPLER_2D_ARRAY_SHADOW; |
410 | case EbtImage2D: |
411 | return GL_IMAGE_2D; |
412 | case EbtIImage2D: |
413 | return GL_INT_IMAGE_2D; |
414 | case EbtUImage2D: |
415 | return GL_UNSIGNED_INT_IMAGE_2D; |
416 | case EbtImage2DArray: |
417 | return GL_IMAGE_2D_ARRAY; |
418 | case EbtIImage2DArray: |
419 | return GL_INT_IMAGE_2D_ARRAY; |
420 | case EbtUImage2DArray: |
421 | return GL_UNSIGNED_INT_IMAGE_2D_ARRAY; |
422 | case EbtImage3D: |
423 | return GL_IMAGE_3D; |
424 | case EbtIImage3D: |
425 | return GL_INT_IMAGE_3D; |
426 | case EbtUImage3D: |
427 | return GL_UNSIGNED_INT_IMAGE_3D; |
428 | case EbtImageCube: |
429 | return GL_IMAGE_CUBE; |
430 | case EbtIImageCube: |
431 | return GL_INT_IMAGE_CUBE; |
432 | case EbtUImageCube: |
433 | return GL_UNSIGNED_INT_IMAGE_CUBE; |
434 | case EbtAtomicCounter: |
435 | return GL_UNSIGNED_INT_ATOMIC_COUNTER; |
436 | default: |
437 | UNREACHABLE(); |
438 | } |
439 | |
440 | return GL_NONE; |
441 | } |
442 | |
443 | GLenum GLVariablePrecision(const TType &type) |
444 | { |
445 | if (type.getBasicType() == EbtFloat) |
446 | { |
447 | switch (type.getPrecision()) |
448 | { |
449 | case EbpHigh: |
450 | return GL_HIGH_FLOAT; |
451 | case EbpMedium: |
452 | return GL_MEDIUM_FLOAT; |
453 | case EbpLow: |
454 | return GL_LOW_FLOAT; |
455 | case EbpUndefined: |
456 | // Should be defined as the default precision by the parser |
457 | default: |
458 | UNREACHABLE(); |
459 | } |
460 | } |
461 | else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt) |
462 | { |
463 | switch (type.getPrecision()) |
464 | { |
465 | case EbpHigh: |
466 | return GL_HIGH_INT; |
467 | case EbpMedium: |
468 | return GL_MEDIUM_INT; |
469 | case EbpLow: |
470 | return GL_LOW_INT; |
471 | case EbpUndefined: |
472 | // Should be defined as the default precision by the parser |
473 | default: |
474 | UNREACHABLE(); |
475 | } |
476 | } |
477 | |
478 | // Other types (boolean, sampler) don't have a precision |
479 | return GL_NONE; |
480 | } |
481 | |
482 | ImmutableString ArrayString(const TType &type) |
483 | { |
484 | if (!type.isArray()) |
485 | return ImmutableString("" ); |
486 | |
487 | const TVector<unsigned int> &arraySizes = *type.getArraySizes(); |
488 | constexpr const size_t kMaxDecimalDigitsPerSize = 10u; |
489 | ImmutableStringBuilder arrayString(arraySizes.size() * (kMaxDecimalDigitsPerSize + 2u)); |
490 | for (auto arraySizeIter = arraySizes.rbegin(); arraySizeIter != arraySizes.rend(); |
491 | ++arraySizeIter) |
492 | { |
493 | arrayString << "[" ; |
494 | if (*arraySizeIter > 0) |
495 | { |
496 | arrayString.appendDecimal(*arraySizeIter); |
497 | } |
498 | arrayString << "]" ; |
499 | } |
500 | return arrayString; |
501 | } |
502 | |
503 | ImmutableString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap) |
504 | { |
505 | if (type.getBasicType() == EbtStruct) |
506 | return HashName(type.getStruct(), hashFunction, nameMap); |
507 | else |
508 | return ImmutableString(type.getBuiltInTypeNameString()); |
509 | } |
510 | |
511 | bool IsVaryingOut(TQualifier qualifier) |
512 | { |
513 | switch (qualifier) |
514 | { |
515 | case EvqVaryingOut: |
516 | case EvqSmoothOut: |
517 | case EvqFlatOut: |
518 | case EvqCentroidOut: |
519 | case EvqVertexOut: |
520 | case EvqGeometryOut: |
521 | return true; |
522 | |
523 | default: |
524 | break; |
525 | } |
526 | |
527 | return false; |
528 | } |
529 | |
530 | bool IsVaryingIn(TQualifier qualifier) |
531 | { |
532 | switch (qualifier) |
533 | { |
534 | case EvqVaryingIn: |
535 | case EvqSmoothIn: |
536 | case EvqFlatIn: |
537 | case EvqCentroidIn: |
538 | case EvqFragmentIn: |
539 | case EvqGeometryIn: |
540 | return true; |
541 | |
542 | default: |
543 | break; |
544 | } |
545 | |
546 | return false; |
547 | } |
548 | |
549 | bool IsVarying(TQualifier qualifier) |
550 | { |
551 | return IsVaryingIn(qualifier) || IsVaryingOut(qualifier); |
552 | } |
553 | |
554 | bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier) |
555 | { |
556 | return (qualifier == EvqGeometryIn) || |
557 | ((shaderType == GL_GEOMETRY_SHADER_EXT) && IsInterpolationIn(qualifier)); |
558 | } |
559 | |
560 | InterpolationType GetInterpolationType(TQualifier qualifier) |
561 | { |
562 | switch (qualifier) |
563 | { |
564 | case EvqFlatIn: |
565 | case EvqFlatOut: |
566 | return INTERPOLATION_FLAT; |
567 | |
568 | case EvqSmoothIn: |
569 | case EvqSmoothOut: |
570 | case EvqVertexOut: |
571 | case EvqFragmentIn: |
572 | case EvqVaryingIn: |
573 | case EvqVaryingOut: |
574 | case EvqGeometryIn: |
575 | case EvqGeometryOut: |
576 | return INTERPOLATION_SMOOTH; |
577 | |
578 | case EvqCentroidIn: |
579 | case EvqCentroidOut: |
580 | return INTERPOLATION_CENTROID; |
581 | |
582 | default: |
583 | UNREACHABLE(); |
584 | #if !UNREACHABLE_IS_NORETURN |
585 | return INTERPOLATION_SMOOTH; |
586 | #endif |
587 | } |
588 | } |
589 | |
590 | TType GetShaderVariableBasicType(const sh::ShaderVariable &var) |
591 | { |
592 | switch (var.type) |
593 | { |
594 | case GL_BOOL: |
595 | return TType(EbtBool); |
596 | case GL_BOOL_VEC2: |
597 | return TType(EbtBool, 2); |
598 | case GL_BOOL_VEC3: |
599 | return TType(EbtBool, 3); |
600 | case GL_BOOL_VEC4: |
601 | return TType(EbtBool, 4); |
602 | case GL_FLOAT: |
603 | return TType(EbtFloat); |
604 | case GL_FLOAT_VEC2: |
605 | return TType(EbtFloat, 2); |
606 | case GL_FLOAT_VEC3: |
607 | return TType(EbtFloat, 3); |
608 | case GL_FLOAT_VEC4: |
609 | return TType(EbtFloat, 4); |
610 | case GL_FLOAT_MAT2: |
611 | return TType(EbtFloat, 2, 2); |
612 | case GL_FLOAT_MAT3: |
613 | return TType(EbtFloat, 3, 3); |
614 | case GL_FLOAT_MAT4: |
615 | return TType(EbtFloat, 4, 4); |
616 | case GL_FLOAT_MAT2x3: |
617 | return TType(EbtFloat, 2, 3); |
618 | case GL_FLOAT_MAT2x4: |
619 | return TType(EbtFloat, 2, 4); |
620 | case GL_FLOAT_MAT3x2: |
621 | return TType(EbtFloat, 3, 2); |
622 | case GL_FLOAT_MAT3x4: |
623 | return TType(EbtFloat, 3, 4); |
624 | case GL_FLOAT_MAT4x2: |
625 | return TType(EbtFloat, 4, 2); |
626 | case GL_FLOAT_MAT4x3: |
627 | return TType(EbtFloat, 4, 3); |
628 | case GL_INT: |
629 | return TType(EbtInt); |
630 | case GL_INT_VEC2: |
631 | return TType(EbtInt, 2); |
632 | case GL_INT_VEC3: |
633 | return TType(EbtInt, 3); |
634 | case GL_INT_VEC4: |
635 | return TType(EbtInt, 4); |
636 | case GL_UNSIGNED_INT: |
637 | return TType(EbtUInt); |
638 | case GL_UNSIGNED_INT_VEC2: |
639 | return TType(EbtUInt, 2); |
640 | case GL_UNSIGNED_INT_VEC3: |
641 | return TType(EbtUInt, 3); |
642 | case GL_UNSIGNED_INT_VEC4: |
643 | return TType(EbtUInt, 4); |
644 | default: |
645 | UNREACHABLE(); |
646 | #if !UNREACHABLE_IS_NORETURN |
647 | return TType(); |
648 | #endif |
649 | } |
650 | } |
651 | |
652 | void DeclareGlobalVariable(TIntermBlock *root, const TVariable *variable) |
653 | { |
654 | TIntermDeclaration *declaration = new TIntermDeclaration(); |
655 | declaration->appendDeclarator(new TIntermSymbol(variable)); |
656 | |
657 | TIntermSequence *globalSequence = root->getSequence(); |
658 | globalSequence->insert(globalSequence->begin(), declaration); |
659 | } |
660 | |
661 | // GLSL ES 1.0.17 4.6.1 The Invariant Qualifier |
662 | bool CanBeInvariantESSL1(TQualifier qualifier) |
663 | { |
664 | return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) || |
665 | IsBuiltinOutputVariable(qualifier) || |
666 | (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing); |
667 | } |
668 | |
669 | // GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier |
670 | // GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier |
671 | bool CanBeInvariantESSL3OrGreater(TQualifier qualifier) |
672 | { |
673 | return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut || |
674 | IsBuiltinOutputVariable(qualifier); |
675 | } |
676 | |
677 | bool IsBuiltinOutputVariable(TQualifier qualifier) |
678 | { |
679 | switch (qualifier) |
680 | { |
681 | case EvqPosition: |
682 | case EvqPointSize: |
683 | case EvqFragDepth: |
684 | case EvqFragDepthEXT: |
685 | case EvqFragColor: |
686 | case EvqSecondaryFragColorEXT: |
687 | case EvqFragData: |
688 | case EvqSecondaryFragDataEXT: |
689 | return true; |
690 | default: |
691 | break; |
692 | } |
693 | return false; |
694 | } |
695 | |
696 | bool IsBuiltinFragmentInputVariable(TQualifier qualifier) |
697 | { |
698 | switch (qualifier) |
699 | { |
700 | case EvqFragCoord: |
701 | case EvqPointCoord: |
702 | case EvqFrontFacing: |
703 | return true; |
704 | default: |
705 | break; |
706 | } |
707 | return false; |
708 | } |
709 | |
710 | bool IsOutputESSL(ShShaderOutput output) |
711 | { |
712 | return output == SH_ESSL_OUTPUT; |
713 | } |
714 | |
715 | bool IsOutputGLSL(ShShaderOutput output) |
716 | { |
717 | switch (output) |
718 | { |
719 | case SH_GLSL_130_OUTPUT: |
720 | case SH_GLSL_140_OUTPUT: |
721 | case SH_GLSL_150_CORE_OUTPUT: |
722 | case SH_GLSL_330_CORE_OUTPUT: |
723 | case SH_GLSL_400_CORE_OUTPUT: |
724 | case SH_GLSL_410_CORE_OUTPUT: |
725 | case SH_GLSL_420_CORE_OUTPUT: |
726 | case SH_GLSL_430_CORE_OUTPUT: |
727 | case SH_GLSL_440_CORE_OUTPUT: |
728 | case SH_GLSL_450_CORE_OUTPUT: |
729 | case SH_GLSL_COMPATIBILITY_OUTPUT: |
730 | return true; |
731 | default: |
732 | break; |
733 | } |
734 | return false; |
735 | } |
736 | bool IsOutputHLSL(ShShaderOutput output) |
737 | { |
738 | switch (output) |
739 | { |
740 | case SH_HLSL_3_0_OUTPUT: |
741 | case SH_HLSL_4_1_OUTPUT: |
742 | case SH_HLSL_4_0_FL9_3_OUTPUT: |
743 | return true; |
744 | default: |
745 | break; |
746 | } |
747 | return false; |
748 | } |
749 | bool IsOutputVulkan(ShShaderOutput output) |
750 | { |
751 | return output == SH_GLSL_VULKAN_OUTPUT; |
752 | } |
753 | |
754 | bool IsInShaderStorageBlock(TIntermTyped *node) |
755 | { |
756 | TIntermSwizzle *swizzleNode = node->getAsSwizzleNode(); |
757 | if (swizzleNode) |
758 | { |
759 | return IsInShaderStorageBlock(swizzleNode->getOperand()); |
760 | } |
761 | |
762 | TIntermBinary *binaryNode = node->getAsBinaryNode(); |
763 | if (binaryNode) |
764 | { |
765 | switch (binaryNode->getOp()) |
766 | { |
767 | case EOpIndexDirectInterfaceBlock: |
768 | case EOpIndexIndirect: |
769 | case EOpIndexDirect: |
770 | case EOpIndexDirectStruct: |
771 | return IsInShaderStorageBlock(binaryNode->getLeft()); |
772 | default: |
773 | return false; |
774 | } |
775 | } |
776 | |
777 | const TType &type = node->getType(); |
778 | return type.getQualifier() == EvqBuffer; |
779 | } |
780 | |
781 | GLenum GetImageInternalFormatType(TLayoutImageInternalFormat iifq) |
782 | { |
783 | switch (iifq) |
784 | { |
785 | case EiifRGBA32F: |
786 | return GL_RGBA32F; |
787 | case EiifRGBA16F: |
788 | return GL_RGBA16F; |
789 | case EiifR32F: |
790 | return GL_R32F; |
791 | case EiifRGBA32UI: |
792 | return GL_RGBA32UI; |
793 | case EiifRGBA16UI: |
794 | return GL_RGBA16UI; |
795 | case EiifRGBA8UI: |
796 | return GL_RGBA8UI; |
797 | case EiifR32UI: |
798 | return GL_R32UI; |
799 | case EiifRGBA32I: |
800 | return GL_RGBA32I; |
801 | case EiifRGBA16I: |
802 | return GL_RGBA16I; |
803 | case EiifRGBA8I: |
804 | return GL_RGBA8I; |
805 | case EiifR32I: |
806 | return GL_R32I; |
807 | case EiifRGBA8: |
808 | return GL_RGBA8; |
809 | case EiifRGBA8_SNORM: |
810 | return GL_RGBA8_SNORM; |
811 | default: |
812 | return GL_NONE; |
813 | } |
814 | } |
815 | |
816 | } // namespace sh |
817 | |