blob: ceeb1ba1e725ea83d86e1c69e08a8f0c0c734988 [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{
Geoff Lang197d5292018-04-25 14:29:00 -040017 bool success = angle::pp::numeric_lex_int(str, value);
Zhenyao Mocc4ec642013-09-23 14:57:10 -040018 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
Jiawei Shao8e4b3552017-08-30 14:20:58 +080026namespace
27{
28
29bool IsInterpolationIn(TQualifier qualifier)
30{
31 switch (qualifier)
32 {
33 case EvqSmoothIn:
34 case EvqFlatIn:
35 case EvqCentroidIn:
36 return true;
37 default:
38 return false;
39 }
40}
41
42} // anonymous namespace
43
Olli Etuaho99bd5f42016-11-07 12:44:29 +000044float NumericLexFloat32OutOfRangeToInfinity(const std::string &str)
45{
46 // Parses a decimal string using scientific notation into a floating point number.
47 // Out-of-range values are converted to infinity. Values that are too small to be
48 // represented are converted to zero.
49
50 // The mantissa in decimal scientific notation. The magnitude of the mantissa integer does not
51 // matter.
52 unsigned int decimalMantissa = 0;
53 size_t i = 0;
54 bool decimalPointSeen = false;
55 bool nonZeroSeenInMantissa = false;
56
57 // The exponent offset reflects the position of the decimal point.
58 int exponentOffset = -1;
Olli Etuahoc3907ef2018-06-08 13:03:15 +030059
60 // This is just a counter for how many decimal digits are written to decimalMantissa.
61 int mantissaDecimalDigits = 0;
62
Olli Etuaho99bd5f42016-11-07 12:44:29 +000063 while (i < str.length())
64 {
65 const char c = str[i];
66 if (c == 'e' || c == 'E')
67 {
68 break;
69 }
70 if (c == '.')
71 {
72 decimalPointSeen = true;
73 ++i;
74 continue;
75 }
76
77 unsigned int digit = static_cast<unsigned int>(c - '0');
78 ASSERT(digit < 10u);
79 if (digit != 0u)
80 {
81 nonZeroSeenInMantissa = true;
82 }
83 if (nonZeroSeenInMantissa)
84 {
85 // Add bits to the mantissa until space runs out in 32-bit int. This should be
86 // enough precision to make the resulting binary mantissa accurate to 1 ULP.
87 if (decimalMantissa <= (std::numeric_limits<unsigned int>::max() - 9u) / 10u)
88 {
89 decimalMantissa = decimalMantissa * 10u + digit;
Olli Etuahoc3907ef2018-06-08 13:03:15 +030090 ++mantissaDecimalDigits;
Olli Etuaho99bd5f42016-11-07 12:44:29 +000091 }
92 if (!decimalPointSeen)
93 {
94 ++exponentOffset;
95 }
96 }
97 else if (decimalPointSeen)
98 {
99 --exponentOffset;
100 }
101 ++i;
102 }
103 if (decimalMantissa == 0)
104 {
105 return 0.0f;
106 }
107 int exponent = 0;
108 if (i < str.length())
109 {
110 ASSERT(str[i] == 'e' || str[i] == 'E');
111 ++i;
112 bool exponentOutOfRange = false;
113 bool negativeExponent = false;
114 if (str[i] == '-')
115 {
116 negativeExponent = true;
117 ++i;
118 }
119 else if (str[i] == '+')
120 {
121 ++i;
122 }
123 while (i < str.length())
124 {
125 const char c = str[i];
126 unsigned int digit = static_cast<unsigned int>(c - '0');
127 ASSERT(digit < 10u);
128 if (exponent <= (std::numeric_limits<int>::max() - 9) / 10)
129 {
130 exponent = exponent * 10 + digit;
131 }
132 else
133 {
134 exponentOutOfRange = true;
135 }
136 ++i;
137 }
138 if (negativeExponent)
139 {
140 exponent = -exponent;
141 }
142 if (exponentOutOfRange)
143 {
144 if (negativeExponent)
145 {
146 return 0.0f;
147 }
148 else
149 {
150 return std::numeric_limits<float>::infinity();
151 }
152 }
153 }
154 // Do the calculation in 64-bit to avoid overflow.
155 long long exponentLong =
156 static_cast<long long>(exponent) + static_cast<long long>(exponentOffset);
157 if (exponentLong > std::numeric_limits<float>::max_exponent10)
158 {
159 return std::numeric_limits<float>::infinity();
160 }
161 else if (exponentLong < std::numeric_limits<float>::min_exponent10)
162 {
163 return 0.0f;
164 }
165 // The exponent is in range, so we need to actually evaluate the float.
166 exponent = static_cast<int>(exponentLong);
167 double value = decimalMantissa;
168
169 // Calculate the exponent offset to normalize the mantissa.
Olli Etuahoc3907ef2018-06-08 13:03:15 +0300170 int normalizationExponentOffset = 1 - mantissaDecimalDigits;
Olli Etuaho99bd5f42016-11-07 12:44:29 +0000171 // Apply the exponent.
172 value *= std::pow(10.0, static_cast<double>(exponent + normalizationExponentOffset));
173 if (value > static_cast<double>(std::numeric_limits<float>::max()))
174 {
175 return std::numeric_limits<float>::infinity();
176 }
177 if (value < static_cast<double>(std::numeric_limits<float>::min()))
178 {
179 return 0.0f;
180 }
181 return static_cast<float>(value);
182}
183
184bool strtof_clamp(const std::string &str, float *value)
185{
Olli Etuahoc3907ef2018-06-08 13:03:15 +0300186 // Custom float parsing that can handle the following corner cases:
Olli Etuaho99bd5f42016-11-07 12:44:29 +0000187 // 1. The decimal mantissa is very small but the exponent is very large, putting the resulting
188 // number inside the float range.
189 // 2. The decimal mantissa is very large but the exponent is very small, putting the resulting
190 // number inside the float range.
191 // 3. The value is out-of-range and should be evaluated as infinity.
192 // 4. The value is too small and should be evaluated as zero.
193 // See ESSL 3.00.6 section 4.1.4 for the relevant specification.
Olli Etuahoc3907ef2018-06-08 13:03:15 +0300194 *value = NumericLexFloat32OutOfRangeToInfinity(str);
Olli Etuaho99bd5f42016-11-07 12:44:29 +0000195 return !gl::isInf(*value);
196}
197
Jamie Madill033dae62014-06-18 12:56:28 -0400198GLenum GLVariableType(const TType &type)
199{
200 if (type.getBasicType() == EbtFloat)
201 {
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300202 if (type.isVector())
Jamie Madill033dae62014-06-18 12:56:28 -0400203 {
204 switch (type.getNominalSize())
205 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500206 case 2:
207 return GL_FLOAT_VEC2;
208 case 3:
209 return GL_FLOAT_VEC3;
210 case 4:
211 return GL_FLOAT_VEC4;
212 default:
213 UNREACHABLE();
Nico Weberb5db2b42018-02-12 15:31:56 -0500214#if !UNREACHABLE_IS_NORETURN
215 return GL_NONE;
216#endif
Jamie Madill033dae62014-06-18 12:56:28 -0400217 }
218 }
219 else if (type.isMatrix())
220 {
221 switch (type.getCols())
222 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500223 case 2:
224 switch (type.getRows())
225 {
226 case 2:
227 return GL_FLOAT_MAT2;
228 case 3:
229 return GL_FLOAT_MAT2x3;
230 case 4:
231 return GL_FLOAT_MAT2x4;
232 default:
233 UNREACHABLE();
Nico Weberb5db2b42018-02-12 15:31:56 -0500234#if !UNREACHABLE_IS_NORETURN
235 return GL_NONE;
236#endif
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500237 }
Jamie Madill033dae62014-06-18 12:56:28 -0400238
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500239 case 3:
240 switch (type.getRows())
241 {
242 case 2:
243 return GL_FLOAT_MAT3x2;
244 case 3:
245 return GL_FLOAT_MAT3;
246 case 4:
247 return GL_FLOAT_MAT3x4;
248 default:
249 UNREACHABLE();
Nico Weberb5db2b42018-02-12 15:31:56 -0500250#if !UNREACHABLE_IS_NORETURN
251 return GL_NONE;
252#endif
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500253 }
Jamie Madill033dae62014-06-18 12:56:28 -0400254
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500255 case 4:
256 switch (type.getRows())
257 {
258 case 2:
259 return GL_FLOAT_MAT4x2;
260 case 3:
261 return GL_FLOAT_MAT4x3;
262 case 4:
263 return GL_FLOAT_MAT4;
264 default:
265 UNREACHABLE();
Nico Weberb5db2b42018-02-12 15:31:56 -0500266#if !UNREACHABLE_IS_NORETURN
267 return GL_NONE;
268#endif
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500269 }
Jamie Madill033dae62014-06-18 12:56:28 -0400270
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500271 default:
272 UNREACHABLE();
Nico Weberb5db2b42018-02-12 15:31:56 -0500273#if !UNREACHABLE_IS_NORETURN
274 return GL_NONE;
275#endif
Jamie Madill033dae62014-06-18 12:56:28 -0400276 }
277 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500278 else
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300279 {
280 return GL_FLOAT;
281 }
Jamie Madill033dae62014-06-18 12:56:28 -0400282 }
283 else if (type.getBasicType() == EbtInt)
284 {
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300285 if (type.isVector())
Jamie Madill033dae62014-06-18 12:56:28 -0400286 {
287 switch (type.getNominalSize())
288 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500289 case 2:
290 return GL_INT_VEC2;
291 case 3:
292 return GL_INT_VEC3;
293 case 4:
294 return GL_INT_VEC4;
295 default:
296 UNREACHABLE();
Nico Weberb5db2b42018-02-12 15:31:56 -0500297#if !UNREACHABLE_IS_NORETURN
298 return GL_NONE;
299#endif
Jamie Madill033dae62014-06-18 12:56:28 -0400300 }
301 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500302 else
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300303 {
304 ASSERT(!type.isMatrix());
305 return GL_INT;
306 }
Jamie Madill033dae62014-06-18 12:56:28 -0400307 }
308 else if (type.getBasicType() == EbtUInt)
309 {
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300310 if (type.isVector())
Jamie Madill033dae62014-06-18 12:56:28 -0400311 {
312 switch (type.getNominalSize())
313 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500314 case 2:
315 return GL_UNSIGNED_INT_VEC2;
316 case 3:
317 return GL_UNSIGNED_INT_VEC3;
318 case 4:
319 return GL_UNSIGNED_INT_VEC4;
320 default:
321 UNREACHABLE();
Nico Weberb5db2b42018-02-12 15:31:56 -0500322#if !UNREACHABLE_IS_NORETURN
323 return GL_NONE;
324#endif
Jamie Madill033dae62014-06-18 12:56:28 -0400325 }
326 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500327 else
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300328 {
329 ASSERT(!type.isMatrix());
330 return GL_UNSIGNED_INT;
331 }
Jamie Madill033dae62014-06-18 12:56:28 -0400332 }
333 else if (type.getBasicType() == EbtBool)
334 {
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300335 if (type.isVector())
Jamie Madill033dae62014-06-18 12:56:28 -0400336 {
337 switch (type.getNominalSize())
338 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500339 case 2:
340 return GL_BOOL_VEC2;
341 case 3:
342 return GL_BOOL_VEC3;
343 case 4:
344 return GL_BOOL_VEC4;
345 default:
346 UNREACHABLE();
Nico Weberb5db2b42018-02-12 15:31:56 -0500347#if !UNREACHABLE_IS_NORETURN
348 return GL_NONE;
349#endif
Jamie Madill033dae62014-06-18 12:56:28 -0400350 }
351 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500352 else
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300353 {
354 ASSERT(!type.isMatrix());
355 return GL_BOOL;
356 }
Jamie Madill033dae62014-06-18 12:56:28 -0400357 }
358
359 switch (type.getBasicType())
360 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500361 case EbtSampler2D:
362 return GL_SAMPLER_2D;
363 case EbtSampler3D:
364 return GL_SAMPLER_3D;
365 case EbtSamplerCube:
366 return GL_SAMPLER_CUBE;
367 case EbtSamplerExternalOES:
368 return GL_SAMPLER_EXTERNAL_OES;
Andrei Volykhina5527072017-03-22 16:46:30 +0300369 case EbtSamplerExternal2DY2YEXT:
370 return GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500371 case EbtSampler2DRect:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400372 return GL_SAMPLER_2D_RECT_ANGLE;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500373 case EbtSampler2DArray:
374 return GL_SAMPLER_2D_ARRAY;
JiangYizhou40219322016-12-09 09:50:51 +0800375 case EbtSampler2DMS:
376 return GL_SAMPLER_2D_MULTISAMPLE;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500377 case EbtISampler2D:
378 return GL_INT_SAMPLER_2D;
379 case EbtISampler3D:
380 return GL_INT_SAMPLER_3D;
381 case EbtISamplerCube:
382 return GL_INT_SAMPLER_CUBE;
383 case EbtISampler2DArray:
384 return GL_INT_SAMPLER_2D_ARRAY;
JiangYizhou40219322016-12-09 09:50:51 +0800385 case EbtISampler2DMS:
386 return GL_INT_SAMPLER_2D_MULTISAMPLE;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500387 case EbtUSampler2D:
388 return GL_UNSIGNED_INT_SAMPLER_2D;
389 case EbtUSampler3D:
390 return GL_UNSIGNED_INT_SAMPLER_3D;
391 case EbtUSamplerCube:
392 return GL_UNSIGNED_INT_SAMPLER_CUBE;
393 case EbtUSampler2DArray:
394 return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
JiangYizhou40219322016-12-09 09:50:51 +0800395 case EbtUSampler2DMS:
396 return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500397 case EbtSampler2DShadow:
398 return GL_SAMPLER_2D_SHADOW;
399 case EbtSamplerCubeShadow:
400 return GL_SAMPLER_CUBE_SHADOW;
401 case EbtSampler2DArrayShadow:
402 return GL_SAMPLER_2D_ARRAY_SHADOW;
403 case EbtImage2D:
404 return GL_IMAGE_2D;
405 case EbtIImage2D:
406 return GL_INT_IMAGE_2D;
407 case EbtUImage2D:
408 return GL_UNSIGNED_INT_IMAGE_2D;
409 case EbtImage2DArray:
410 return GL_IMAGE_2D_ARRAY;
411 case EbtIImage2DArray:
412 return GL_INT_IMAGE_2D_ARRAY;
413 case EbtUImage2DArray:
414 return GL_UNSIGNED_INT_IMAGE_2D_ARRAY;
415 case EbtImage3D:
416 return GL_IMAGE_3D;
417 case EbtIImage3D:
418 return GL_INT_IMAGE_3D;
419 case EbtUImage3D:
420 return GL_UNSIGNED_INT_IMAGE_3D;
421 case EbtImageCube:
422 return GL_IMAGE_CUBE;
423 case EbtIImageCube:
424 return GL_INT_IMAGE_CUBE;
425 case EbtUImageCube:
426 return GL_UNSIGNED_INT_IMAGE_CUBE;
jchen104cdac9e2017-05-08 11:01:20 +0800427 case EbtAtomicCounter:
428 return GL_UNSIGNED_INT_ATOMIC_COUNTER;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500429 default:
430 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400431 }
432
433 return GL_NONE;
434}
435
436GLenum GLVariablePrecision(const TType &type)
437{
438 if (type.getBasicType() == EbtFloat)
439 {
440 switch (type.getPrecision())
441 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500442 case EbpHigh:
443 return GL_HIGH_FLOAT;
444 case EbpMedium:
445 return GL_MEDIUM_FLOAT;
446 case EbpLow:
447 return GL_LOW_FLOAT;
448 case EbpUndefined:
449 // Should be defined as the default precision by the parser
450 default:
451 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400452 }
453 }
454 else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
455 {
456 switch (type.getPrecision())
457 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500458 case EbpHigh:
459 return GL_HIGH_INT;
460 case EbpMedium:
461 return GL_MEDIUM_INT;
462 case EbpLow:
463 return GL_LOW_INT;
464 case EbpUndefined:
465 // Should be defined as the default precision by the parser
466 default:
467 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400468 }
469 }
470
471 // Other types (boolean, sampler) don't have a precision
472 return GL_NONE;
473}
474
475TString ArrayString(const TType &type)
476{
Olli Etuaho96f6adf2017-08-16 11:18:54 +0300477 TStringStream arrayString;
Kai Ninomiya57ea5332017-11-22 14:04:48 -0800478 if (!type.isArray())
479 return arrayString.str();
480
481 const TVector<unsigned int> &arraySizes = *type.getArraySizes();
Olli Etuaho96f6adf2017-08-16 11:18:54 +0300482 for (auto arraySizeIter = arraySizes.rbegin(); arraySizeIter != arraySizes.rend();
483 ++arraySizeIter)
Jamie Madill033dae62014-06-18 12:56:28 -0400484 {
Jiawei Shao8e4b3552017-08-30 14:20:58 +0800485 arrayString << "[";
486 if (*arraySizeIter > 0)
487 {
488 arrayString << (*arraySizeIter);
489 }
490 arrayString << "]";
Jamie Madill033dae62014-06-18 12:56:28 -0400491 }
Olli Etuaho96f6adf2017-08-16 11:18:54 +0300492 return arrayString.str();
Jamie Madill033dae62014-06-18 12:56:28 -0400493}
494
Olli Etuahofbb1c792018-01-19 16:26:59 +0200495ImmutableString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap)
Jamie Madill6276b922017-09-25 02:35:57 -0400496{
497 if (type.getBasicType() == EbtStruct)
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +0200498 return HashName(type.getStruct(), hashFunction, nameMap);
Jamie Madill6276b922017-09-25 02:35:57 -0400499 else
Olli Etuahofbb1c792018-01-19 16:26:59 +0200500 return ImmutableString(type.getBuiltInTypeNameString());
Jamie Madill6276b922017-09-25 02:35:57 -0400501}
502
Jamie Madill033dae62014-06-18 12:56:28 -0400503bool IsVaryingOut(TQualifier qualifier)
504{
505 switch (qualifier)
506 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500507 case EvqVaryingOut:
508 case EvqSmoothOut:
509 case EvqFlatOut:
510 case EvqCentroidOut:
511 case EvqVertexOut:
Jiawei Shao8e4b3552017-08-30 14:20:58 +0800512 case EvqGeometryOut:
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500513 return true;
Jamie Madill033dae62014-06-18 12:56:28 -0400514
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500515 default:
516 break;
Jamie Madill033dae62014-06-18 12:56:28 -0400517 }
518
519 return false;
520}
521
522bool IsVaryingIn(TQualifier qualifier)
523{
524 switch (qualifier)
525 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500526 case EvqVaryingIn:
527 case EvqSmoothIn:
528 case EvqFlatIn:
529 case EvqCentroidIn:
530 case EvqFragmentIn:
Jiawei Shao8e4b3552017-08-30 14:20:58 +0800531 case EvqGeometryIn:
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500532 return true;
Jamie Madill033dae62014-06-18 12:56:28 -0400533
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500534 default:
535 break;
Jamie Madill033dae62014-06-18 12:56:28 -0400536 }
537
538 return false;
539}
540
541bool IsVarying(TQualifier qualifier)
542{
543 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
544}
545
Jiawei Shao8e4b3552017-08-30 14:20:58 +0800546bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier)
547{
548 return (qualifier == EvqGeometryIn) ||
Jiawei Shaobd924af2017-11-16 15:28:04 +0800549 ((shaderType == GL_GEOMETRY_SHADER_EXT) && IsInterpolationIn(qualifier));
Jiawei Shao8e4b3552017-08-30 14:20:58 +0800550}
551
Jamie Madillf2575982014-06-25 16:04:54 -0400552InterpolationType GetInterpolationType(TQualifier qualifier)
Jamie Madill033dae62014-06-18 12:56:28 -0400553{
554 switch (qualifier)
555 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500556 case EvqFlatIn:
557 case EvqFlatOut:
558 return INTERPOLATION_FLAT;
Jamie Madill033dae62014-06-18 12:56:28 -0400559
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500560 case EvqSmoothIn:
561 case EvqSmoothOut:
562 case EvqVertexOut:
563 case EvqFragmentIn:
564 case EvqVaryingIn:
565 case EvqVaryingOut:
Jiawei Shao8e4b3552017-08-30 14:20:58 +0800566 case EvqGeometryIn:
567 case EvqGeometryOut:
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500568 return INTERPOLATION_SMOOTH;
Jamie Madill033dae62014-06-18 12:56:28 -0400569
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500570 case EvqCentroidIn:
571 case EvqCentroidOut:
572 return INTERPOLATION_CENTROID;
Jamie Madill033dae62014-06-18 12:56:28 -0400573
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500574 default:
575 UNREACHABLE();
Nico Weberb5db2b42018-02-12 15:31:56 -0500576#if !UNREACHABLE_IS_NORETURN
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500577 return INTERPOLATION_SMOOTH;
Nico Weberb5db2b42018-02-12 15:31:56 -0500578#endif
Jamie Madill033dae62014-06-18 12:56:28 -0400579 }
580}
581
Corentin Wallez509e4562016-08-25 14:55:44 -0400582TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
Zhenyao Mo72111912016-07-20 17:45:56 -0700583{
Corentin Wallez509e4562016-08-25 14:55:44 -0400584 switch (var.type)
Zhenyao Mo72111912016-07-20 17:45:56 -0700585 {
Qin Jiajia7835b522016-10-08 11:20:17 +0800586 case GL_BOOL:
587 return TType(EbtBool);
588 case GL_BOOL_VEC2:
589 return TType(EbtBool, 2);
590 case GL_BOOL_VEC3:
591 return TType(EbtBool, 3);
592 case GL_BOOL_VEC4:
593 return TType(EbtBool, 4);
Zhenyao Mo72111912016-07-20 17:45:56 -0700594 case GL_FLOAT:
595 return TType(EbtFloat);
596 case GL_FLOAT_VEC2:
597 return TType(EbtFloat, 2);
598 case GL_FLOAT_VEC3:
599 return TType(EbtFloat, 3);
600 case GL_FLOAT_VEC4:
601 return TType(EbtFloat, 4);
602 case GL_FLOAT_MAT2:
603 return TType(EbtFloat, 2, 2);
604 case GL_FLOAT_MAT3:
605 return TType(EbtFloat, 3, 3);
606 case GL_FLOAT_MAT4:
607 return TType(EbtFloat, 4, 4);
608 case GL_FLOAT_MAT2x3:
609 return TType(EbtFloat, 2, 3);
610 case GL_FLOAT_MAT2x4:
611 return TType(EbtFloat, 2, 4);
612 case GL_FLOAT_MAT3x2:
613 return TType(EbtFloat, 3, 2);
614 case GL_FLOAT_MAT3x4:
615 return TType(EbtFloat, 3, 4);
616 case GL_FLOAT_MAT4x2:
617 return TType(EbtFloat, 4, 2);
618 case GL_FLOAT_MAT4x3:
619 return TType(EbtFloat, 4, 3);
620 case GL_INT:
621 return TType(EbtInt);
622 case GL_INT_VEC2:
623 return TType(EbtInt, 2);
624 case GL_INT_VEC3:
625 return TType(EbtInt, 3);
626 case GL_INT_VEC4:
627 return TType(EbtInt, 4);
628 case GL_UNSIGNED_INT:
629 return TType(EbtUInt);
630 case GL_UNSIGNED_INT_VEC2:
631 return TType(EbtUInt, 2);
632 case GL_UNSIGNED_INT_VEC3:
633 return TType(EbtUInt, 3);
634 case GL_UNSIGNED_INT_VEC4:
635 return TType(EbtUInt, 4);
636 default:
637 UNREACHABLE();
Nico Weberb5db2b42018-02-12 15:31:56 -0500638#if !UNREACHABLE_IS_NORETURN
Zhenyao Mo72111912016-07-20 17:45:56 -0700639 return TType();
Nico Weberb5db2b42018-02-12 15:31:56 -0500640#endif
Zhenyao Mo72111912016-07-20 17:45:56 -0700641 }
642}
643
Luc Ferrone18b8142018-06-07 11:53:19 -0400644void DeclareGlobalVariable(TIntermBlock *root, const TVariable *variable)
645{
646 TIntermDeclaration *declaration = new TIntermDeclaration();
647 declaration->appendDeclarator(new TIntermSymbol(variable));
648
649 TIntermSequence *globalSequence = root->getSequence();
650 globalSequence->insert(globalSequence->begin(), declaration);
651}
652
Martin Radev70866b82016-07-22 15:27:42 +0300653// GLSL ES 1.0.17 4.6.1 The Invariant Qualifier
654bool CanBeInvariantESSL1(TQualifier qualifier)
655{
656 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) ||
657 IsBuiltinOutputVariable(qualifier) ||
658 (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing);
Jamie Madill033dae62014-06-18 12:56:28 -0400659}
Martin Radev70866b82016-07-22 15:27:42 +0300660
661// GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier
662// GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier
663bool CanBeInvariantESSL3OrGreater(TQualifier qualifier)
664{
665 return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut ||
666 IsBuiltinOutputVariable(qualifier);
667}
668
669bool IsBuiltinOutputVariable(TQualifier qualifier)
670{
671 switch (qualifier)
672 {
673 case EvqPosition:
674 case EvqPointSize:
675 case EvqFragDepth:
676 case EvqFragDepthEXT:
677 case EvqFragColor:
678 case EvqSecondaryFragColorEXT:
679 case EvqFragData:
680 case EvqSecondaryFragDataEXT:
681 return true;
682 default:
683 break;
684 }
685 return false;
686}
687
688bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
689{
690 switch (qualifier)
691 {
692 case EvqFragCoord:
693 case EvqPointCoord:
694 case EvqFrontFacing:
695 return true;
696 default:
697 break;
698 }
699 return false;
700}
Martin Radeve469de82017-07-04 11:58:35 +0300701
702bool IsOutputESSL(ShShaderOutput output)
703{
704 return output == SH_ESSL_OUTPUT;
705}
706
707bool IsOutputGLSL(ShShaderOutput output)
708{
709 switch (output)
710 {
711 case SH_GLSL_130_OUTPUT:
712 case SH_GLSL_140_OUTPUT:
713 case SH_GLSL_150_CORE_OUTPUT:
714 case SH_GLSL_330_CORE_OUTPUT:
715 case SH_GLSL_400_CORE_OUTPUT:
716 case SH_GLSL_410_CORE_OUTPUT:
717 case SH_GLSL_420_CORE_OUTPUT:
718 case SH_GLSL_430_CORE_OUTPUT:
719 case SH_GLSL_440_CORE_OUTPUT:
720 case SH_GLSL_450_CORE_OUTPUT:
721 case SH_GLSL_COMPATIBILITY_OUTPUT:
722 return true;
723 default:
724 break;
725 }
726 return false;
727}
728bool IsOutputHLSL(ShShaderOutput output)
729{
730 switch (output)
731 {
732 case SH_HLSL_3_0_OUTPUT:
733 case SH_HLSL_4_1_OUTPUT:
734 case SH_HLSL_4_0_FL9_3_OUTPUT:
735 return true;
736 default:
737 break;
738 }
739 return false;
740}
741bool IsOutputVulkan(ShShaderOutput output)
742{
743 return output == SH_GLSL_VULKAN_OUTPUT;
744}
745
Martin Radev70866b82016-07-22 15:27:42 +0300746} // namespace sh