blob: 22f4ea9928d486108d1a06311f52af823aaec6a7 [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 {
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300189 if (type.isVector())
Jamie Madill033dae62014-06-18 12:56:28 -0400190 {
191 switch (type.getNominalSize())
192 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500193 case 2:
194 return GL_FLOAT_VEC2;
195 case 3:
196 return GL_FLOAT_VEC3;
197 case 4:
198 return GL_FLOAT_VEC4;
199 default:
200 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400201 }
202 }
203 else if (type.isMatrix())
204 {
205 switch (type.getCols())
206 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500207 case 2:
208 switch (type.getRows())
209 {
210 case 2:
211 return GL_FLOAT_MAT2;
212 case 3:
213 return GL_FLOAT_MAT2x3;
214 case 4:
215 return GL_FLOAT_MAT2x4;
216 default:
217 UNREACHABLE();
218 }
Jamie Madill033dae62014-06-18 12:56:28 -0400219
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500220 case 3:
221 switch (type.getRows())
222 {
223 case 2:
224 return GL_FLOAT_MAT3x2;
225 case 3:
226 return GL_FLOAT_MAT3;
227 case 4:
228 return GL_FLOAT_MAT3x4;
229 default:
230 UNREACHABLE();
231 }
Jamie Madill033dae62014-06-18 12:56:28 -0400232
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500233 case 4:
234 switch (type.getRows())
235 {
236 case 2:
237 return GL_FLOAT_MAT4x2;
238 case 3:
239 return GL_FLOAT_MAT4x3;
240 case 4:
241 return GL_FLOAT_MAT4;
242 default:
243 UNREACHABLE();
244 }
Jamie Madill033dae62014-06-18 12:56:28 -0400245
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500246 default:
247 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400248 }
249 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500250 else
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300251 {
252 return GL_FLOAT;
253 }
Jamie Madill033dae62014-06-18 12:56:28 -0400254 }
255 else if (type.getBasicType() == EbtInt)
256 {
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300257 if (type.isVector())
Jamie Madill033dae62014-06-18 12:56:28 -0400258 {
259 switch (type.getNominalSize())
260 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500261 case 2:
262 return GL_INT_VEC2;
263 case 3:
264 return GL_INT_VEC3;
265 case 4:
266 return GL_INT_VEC4;
267 default:
268 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400269 }
270 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500271 else
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300272 {
273 ASSERT(!type.isMatrix());
274 return GL_INT;
275 }
Jamie Madill033dae62014-06-18 12:56:28 -0400276 }
277 else if (type.getBasicType() == EbtUInt)
278 {
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300279 if (type.isVector())
Jamie Madill033dae62014-06-18 12:56:28 -0400280 {
281 switch (type.getNominalSize())
282 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500283 case 2:
284 return GL_UNSIGNED_INT_VEC2;
285 case 3:
286 return GL_UNSIGNED_INT_VEC3;
287 case 4:
288 return GL_UNSIGNED_INT_VEC4;
289 default:
290 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400291 }
292 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500293 else
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300294 {
295 ASSERT(!type.isMatrix());
296 return GL_UNSIGNED_INT;
297 }
Jamie Madill033dae62014-06-18 12:56:28 -0400298 }
299 else if (type.getBasicType() == EbtBool)
300 {
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300301 if (type.isVector())
Jamie Madill033dae62014-06-18 12:56:28 -0400302 {
303 switch (type.getNominalSize())
304 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500305 case 2:
306 return GL_BOOL_VEC2;
307 case 3:
308 return GL_BOOL_VEC3;
309 case 4:
310 return GL_BOOL_VEC4;
311 default:
312 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400313 }
314 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500315 else
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300316 {
317 ASSERT(!type.isMatrix());
318 return GL_BOOL;
319 }
Jamie Madill033dae62014-06-18 12:56:28 -0400320 }
321
322 switch (type.getBasicType())
323 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500324 case EbtSampler2D:
325 return GL_SAMPLER_2D;
326 case EbtSampler3D:
327 return GL_SAMPLER_3D;
328 case EbtSamplerCube:
329 return GL_SAMPLER_CUBE;
330 case EbtSamplerExternalOES:
331 return GL_SAMPLER_EXTERNAL_OES;
Andrei Volykhina5527072017-03-22 16:46:30 +0300332 case EbtSamplerExternal2DY2YEXT:
333 return GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500334 case EbtSampler2DRect:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400335 return GL_SAMPLER_2D_RECT_ANGLE;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500336 case EbtSampler2DArray:
337 return GL_SAMPLER_2D_ARRAY;
JiangYizhou40219322016-12-09 09:50:51 +0800338 case EbtSampler2DMS:
339 return GL_SAMPLER_2D_MULTISAMPLE;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500340 case EbtISampler2D:
341 return GL_INT_SAMPLER_2D;
342 case EbtISampler3D:
343 return GL_INT_SAMPLER_3D;
344 case EbtISamplerCube:
345 return GL_INT_SAMPLER_CUBE;
346 case EbtISampler2DArray:
347 return GL_INT_SAMPLER_2D_ARRAY;
JiangYizhou40219322016-12-09 09:50:51 +0800348 case EbtISampler2DMS:
349 return GL_INT_SAMPLER_2D_MULTISAMPLE;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500350 case EbtUSampler2D:
351 return GL_UNSIGNED_INT_SAMPLER_2D;
352 case EbtUSampler3D:
353 return GL_UNSIGNED_INT_SAMPLER_3D;
354 case EbtUSamplerCube:
355 return GL_UNSIGNED_INT_SAMPLER_CUBE;
356 case EbtUSampler2DArray:
357 return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
JiangYizhou40219322016-12-09 09:50:51 +0800358 case EbtUSampler2DMS:
359 return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500360 case EbtSampler2DShadow:
361 return GL_SAMPLER_2D_SHADOW;
362 case EbtSamplerCubeShadow:
363 return GL_SAMPLER_CUBE_SHADOW;
364 case EbtSampler2DArrayShadow:
365 return GL_SAMPLER_2D_ARRAY_SHADOW;
366 case EbtImage2D:
367 return GL_IMAGE_2D;
368 case EbtIImage2D:
369 return GL_INT_IMAGE_2D;
370 case EbtUImage2D:
371 return GL_UNSIGNED_INT_IMAGE_2D;
372 case EbtImage2DArray:
373 return GL_IMAGE_2D_ARRAY;
374 case EbtIImage2DArray:
375 return GL_INT_IMAGE_2D_ARRAY;
376 case EbtUImage2DArray:
377 return GL_UNSIGNED_INT_IMAGE_2D_ARRAY;
378 case EbtImage3D:
379 return GL_IMAGE_3D;
380 case EbtIImage3D:
381 return GL_INT_IMAGE_3D;
382 case EbtUImage3D:
383 return GL_UNSIGNED_INT_IMAGE_3D;
384 case EbtImageCube:
385 return GL_IMAGE_CUBE;
386 case EbtIImageCube:
387 return GL_INT_IMAGE_CUBE;
388 case EbtUImageCube:
389 return GL_UNSIGNED_INT_IMAGE_CUBE;
jchen104cdac9e2017-05-08 11:01:20 +0800390 case EbtAtomicCounter:
391 return GL_UNSIGNED_INT_ATOMIC_COUNTER;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500392 default:
393 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400394 }
395
396 return GL_NONE;
397}
398
399GLenum GLVariablePrecision(const TType &type)
400{
401 if (type.getBasicType() == EbtFloat)
402 {
403 switch (type.getPrecision())
404 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500405 case EbpHigh:
406 return GL_HIGH_FLOAT;
407 case EbpMedium:
408 return GL_MEDIUM_FLOAT;
409 case EbpLow:
410 return GL_LOW_FLOAT;
411 case EbpUndefined:
412 // Should be defined as the default precision by the parser
413 default:
414 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400415 }
416 }
417 else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
418 {
419 switch (type.getPrecision())
420 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500421 case EbpHigh:
422 return GL_HIGH_INT;
423 case EbpMedium:
424 return GL_MEDIUM_INT;
425 case EbpLow:
426 return GL_LOW_INT;
427 case EbpUndefined:
428 // Should be defined as the default precision by the parser
429 default:
430 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400431 }
432 }
433
434 // Other types (boolean, sampler) don't have a precision
435 return GL_NONE;
436}
437
438TString ArrayString(const TType &type)
439{
Olli Etuaho96f6adf2017-08-16 11:18:54 +0300440 TStringStream arrayString;
441 const TVector<unsigned int> &arraySizes = type.getArraySizes();
442 for (auto arraySizeIter = arraySizes.rbegin(); arraySizeIter != arraySizes.rend();
443 ++arraySizeIter)
Jamie Madill033dae62014-06-18 12:56:28 -0400444 {
Olli Etuaho96f6adf2017-08-16 11:18:54 +0300445 arrayString << "[" << (*arraySizeIter) << "]";
Jamie Madill033dae62014-06-18 12:56:28 -0400446 }
Olli Etuaho96f6adf2017-08-16 11:18:54 +0300447 return arrayString.str();
Jamie Madill033dae62014-06-18 12:56:28 -0400448}
449
450bool IsVaryingOut(TQualifier qualifier)
451{
452 switch (qualifier)
453 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500454 case EvqVaryingOut:
455 case EvqSmoothOut:
456 case EvqFlatOut:
457 case EvqCentroidOut:
458 case EvqVertexOut:
459 return true;
Jamie Madill033dae62014-06-18 12:56:28 -0400460
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500461 default:
462 break;
Jamie Madill033dae62014-06-18 12:56:28 -0400463 }
464
465 return false;
466}
467
468bool IsVaryingIn(TQualifier qualifier)
469{
470 switch (qualifier)
471 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500472 case EvqVaryingIn:
473 case EvqSmoothIn:
474 case EvqFlatIn:
475 case EvqCentroidIn:
476 case EvqFragmentIn:
477 return true;
Jamie Madill033dae62014-06-18 12:56:28 -0400478
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500479 default:
480 break;
Jamie Madill033dae62014-06-18 12:56:28 -0400481 }
482
483 return false;
484}
485
486bool IsVarying(TQualifier qualifier)
487{
488 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
489}
490
Jamie Madillf2575982014-06-25 16:04:54 -0400491InterpolationType GetInterpolationType(TQualifier qualifier)
Jamie Madill033dae62014-06-18 12:56:28 -0400492{
493 switch (qualifier)
494 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500495 case EvqFlatIn:
496 case EvqFlatOut:
497 return INTERPOLATION_FLAT;
Jamie Madill033dae62014-06-18 12:56:28 -0400498
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500499 case EvqSmoothIn:
500 case EvqSmoothOut:
501 case EvqVertexOut:
502 case EvqFragmentIn:
503 case EvqVaryingIn:
504 case EvqVaryingOut:
505 return INTERPOLATION_SMOOTH;
Jamie Madill033dae62014-06-18 12:56:28 -0400506
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500507 case EvqCentroidIn:
508 case EvqCentroidOut:
509 return INTERPOLATION_CENTROID;
Jamie Madill033dae62014-06-18 12:56:28 -0400510
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500511 default:
512 UNREACHABLE();
513 return INTERPOLATION_SMOOTH;
Jamie Madill033dae62014-06-18 12:56:28 -0400514 }
515}
516
Corentin Wallez509e4562016-08-25 14:55:44 -0400517TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
Zhenyao Mo72111912016-07-20 17:45:56 -0700518{
Corentin Wallez509e4562016-08-25 14:55:44 -0400519 switch (var.type)
Zhenyao Mo72111912016-07-20 17:45:56 -0700520 {
Qin Jiajia7835b522016-10-08 11:20:17 +0800521 case GL_BOOL:
522 return TType(EbtBool);
523 case GL_BOOL_VEC2:
524 return TType(EbtBool, 2);
525 case GL_BOOL_VEC3:
526 return TType(EbtBool, 3);
527 case GL_BOOL_VEC4:
528 return TType(EbtBool, 4);
Zhenyao Mo72111912016-07-20 17:45:56 -0700529 case GL_FLOAT:
530 return TType(EbtFloat);
531 case GL_FLOAT_VEC2:
532 return TType(EbtFloat, 2);
533 case GL_FLOAT_VEC3:
534 return TType(EbtFloat, 3);
535 case GL_FLOAT_VEC4:
536 return TType(EbtFloat, 4);
537 case GL_FLOAT_MAT2:
538 return TType(EbtFloat, 2, 2);
539 case GL_FLOAT_MAT3:
540 return TType(EbtFloat, 3, 3);
541 case GL_FLOAT_MAT4:
542 return TType(EbtFloat, 4, 4);
543 case GL_FLOAT_MAT2x3:
544 return TType(EbtFloat, 2, 3);
545 case GL_FLOAT_MAT2x4:
546 return TType(EbtFloat, 2, 4);
547 case GL_FLOAT_MAT3x2:
548 return TType(EbtFloat, 3, 2);
549 case GL_FLOAT_MAT3x4:
550 return TType(EbtFloat, 3, 4);
551 case GL_FLOAT_MAT4x2:
552 return TType(EbtFloat, 4, 2);
553 case GL_FLOAT_MAT4x3:
554 return TType(EbtFloat, 4, 3);
555 case GL_INT:
556 return TType(EbtInt);
557 case GL_INT_VEC2:
558 return TType(EbtInt, 2);
559 case GL_INT_VEC3:
560 return TType(EbtInt, 3);
561 case GL_INT_VEC4:
562 return TType(EbtInt, 4);
563 case GL_UNSIGNED_INT:
564 return TType(EbtUInt);
565 case GL_UNSIGNED_INT_VEC2:
566 return TType(EbtUInt, 2);
567 case GL_UNSIGNED_INT_VEC3:
568 return TType(EbtUInt, 3);
569 case GL_UNSIGNED_INT_VEC4:
570 return TType(EbtUInt, 4);
571 default:
572 UNREACHABLE();
573 return TType();
574 }
575}
576
Martin Radev70866b82016-07-22 15:27:42 +0300577// GLSL ES 1.0.17 4.6.1 The Invariant Qualifier
578bool CanBeInvariantESSL1(TQualifier qualifier)
579{
580 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) ||
581 IsBuiltinOutputVariable(qualifier) ||
582 (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing);
Jamie Madill033dae62014-06-18 12:56:28 -0400583}
Martin Radev70866b82016-07-22 15:27:42 +0300584
585// GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier
586// GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier
587bool CanBeInvariantESSL3OrGreater(TQualifier qualifier)
588{
589 return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut ||
590 IsBuiltinOutputVariable(qualifier);
591}
592
593bool IsBuiltinOutputVariable(TQualifier qualifier)
594{
595 switch (qualifier)
596 {
597 case EvqPosition:
598 case EvqPointSize:
599 case EvqFragDepth:
600 case EvqFragDepthEXT:
601 case EvqFragColor:
602 case EvqSecondaryFragColorEXT:
603 case EvqFragData:
604 case EvqSecondaryFragDataEXT:
605 return true;
606 default:
607 break;
608 }
609 return false;
610}
611
612bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
613{
614 switch (qualifier)
615 {
616 case EvqFragCoord:
617 case EvqPointCoord:
618 case EvqFrontFacing:
619 return true;
620 default:
621 break;
622 }
623 return false;
624}
Martin Radeve469de82017-07-04 11:58:35 +0300625
626bool IsOutputESSL(ShShaderOutput output)
627{
628 return output == SH_ESSL_OUTPUT;
629}
630
631bool IsOutputGLSL(ShShaderOutput output)
632{
633 switch (output)
634 {
635 case SH_GLSL_130_OUTPUT:
636 case SH_GLSL_140_OUTPUT:
637 case SH_GLSL_150_CORE_OUTPUT:
638 case SH_GLSL_330_CORE_OUTPUT:
639 case SH_GLSL_400_CORE_OUTPUT:
640 case SH_GLSL_410_CORE_OUTPUT:
641 case SH_GLSL_420_CORE_OUTPUT:
642 case SH_GLSL_430_CORE_OUTPUT:
643 case SH_GLSL_440_CORE_OUTPUT:
644 case SH_GLSL_450_CORE_OUTPUT:
645 case SH_GLSL_COMPATIBILITY_OUTPUT:
646 return true;
647 default:
648 break;
649 }
650 return false;
651}
652bool IsOutputHLSL(ShShaderOutput output)
653{
654 switch (output)
655 {
656 case SH_HLSL_3_0_OUTPUT:
657 case SH_HLSL_4_1_OUTPUT:
658 case SH_HLSL_4_0_FL9_3_OUTPUT:
659 return true;
660 default:
661 break;
662 }
663 return false;
664}
665bool IsOutputVulkan(ShShaderOutput output)
666{
667 return output == SH_GLSL_VULKAN_OUTPUT;
668}
669
Martin Radev70866b82016-07-22 15:27:42 +0300670} // namespace sh