blob: 067b7de5d1d2369b46fefca4d89d6f9057caf97a [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"
Olli Etuahod8b1c5c2018-06-20 12:08:46 +030013#include "compiler/translator/ImmutableStringBuilder.h"
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070014#include "compiler/translator/SymbolTable.h"
Zhenyao Mof1d723c2013-09-23 14:57:07 -040015
Olli Etuahof541f522015-10-13 12:21:01 +030016bool atoi_clamp(const char *str, unsigned int *value)
Zhenyao Mof1d723c2013-09-23 14:57:07 -040017{
Geoff Lang197d5292018-04-25 14:29:00 -040018 bool success = angle::pp::numeric_lex_int(str, value);
Zhenyao Mocc4ec642013-09-23 14:57:10 -040019 if (!success)
Olli Etuahof541f522015-10-13 12:21:01 +030020 *value = std::numeric_limits<unsigned int>::max();
Zhenyao Mocc4ec642013-09-23 14:57:10 -040021 return success;
Zhenyao Mof1d723c2013-09-23 14:57:07 -040022}
23
Jamie Madill033dae62014-06-18 12:56:28 -040024namespace sh
25{
26
Jiawei Shao8e4b3552017-08-30 14:20:58 +080027namespace
28{
29
30bool 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
Olli Etuaho99bd5f42016-11-07 12:44:29 +000045float 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;
Olli Etuahoc3907ef2018-06-08 13:03:15 +030060
61 // This is just a counter for how many decimal digits are written to decimalMantissa.
62 int mantissaDecimalDigits = 0;
63
Olli Etuaho99bd5f42016-11-07 12:44:29 +000064 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;
Olli Etuahoc3907ef2018-06-08 13:03:15 +030091 ++mantissaDecimalDigits;
Olli Etuaho99bd5f42016-11-07 12:44:29 +000092 }
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.
Olli Etuahoc3907ef2018-06-08 13:03:15 +0300171 int normalizationExponentOffset = 1 - mantissaDecimalDigits;
Olli Etuaho99bd5f42016-11-07 12:44:29 +0000172 // 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
185bool strtof_clamp(const std::string &str, float *value)
186{
Olli Etuahoc3907ef2018-06-08 13:03:15 +0300187 // Custom float parsing that can handle the following corner cases:
Olli Etuaho99bd5f42016-11-07 12:44:29 +0000188 // 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.
Olli Etuahoc3907ef2018-06-08 13:03:15 +0300195 *value = NumericLexFloat32OutOfRangeToInfinity(str);
Olli Etuaho99bd5f42016-11-07 12:44:29 +0000196 return !gl::isInf(*value);
197}
198
Jamie Madill033dae62014-06-18 12:56:28 -0400199GLenum GLVariableType(const TType &type)
200{
201 if (type.getBasicType() == EbtFloat)
202 {
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300203 if (type.isVector())
Jamie Madill033dae62014-06-18 12:56:28 -0400204 {
205 switch (type.getNominalSize())
206 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500207 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();
Nico Weberb5db2b42018-02-12 15:31:56 -0500215#if !UNREACHABLE_IS_NORETURN
216 return GL_NONE;
217#endif
Jamie Madill033dae62014-06-18 12:56:28 -0400218 }
219 }
220 else if (type.isMatrix())
221 {
222 switch (type.getCols())
223 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500224 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();
Nico Weberb5db2b42018-02-12 15:31:56 -0500235#if !UNREACHABLE_IS_NORETURN
236 return GL_NONE;
237#endif
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500238 }
Jamie Madill033dae62014-06-18 12:56:28 -0400239
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500240 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();
Nico Weberb5db2b42018-02-12 15:31:56 -0500251#if !UNREACHABLE_IS_NORETURN
252 return GL_NONE;
253#endif
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500254 }
Jamie Madill033dae62014-06-18 12:56:28 -0400255
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500256 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();
Nico Weberb5db2b42018-02-12 15:31:56 -0500267#if !UNREACHABLE_IS_NORETURN
268 return GL_NONE;
269#endif
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500270 }
Jamie Madill033dae62014-06-18 12:56:28 -0400271
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500272 default:
273 UNREACHABLE();
Nico Weberb5db2b42018-02-12 15:31:56 -0500274#if !UNREACHABLE_IS_NORETURN
275 return GL_NONE;
276#endif
Jamie Madill033dae62014-06-18 12:56:28 -0400277 }
278 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500279 else
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300280 {
281 return GL_FLOAT;
282 }
Jamie Madill033dae62014-06-18 12:56:28 -0400283 }
284 else if (type.getBasicType() == EbtInt)
285 {
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300286 if (type.isVector())
Jamie Madill033dae62014-06-18 12:56:28 -0400287 {
288 switch (type.getNominalSize())
289 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500290 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();
Nico Weberb5db2b42018-02-12 15:31:56 -0500298#if !UNREACHABLE_IS_NORETURN
299 return GL_NONE;
300#endif
Jamie Madill033dae62014-06-18 12:56:28 -0400301 }
302 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500303 else
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300304 {
305 ASSERT(!type.isMatrix());
306 return GL_INT;
307 }
Jamie Madill033dae62014-06-18 12:56:28 -0400308 }
309 else if (type.getBasicType() == EbtUInt)
310 {
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300311 if (type.isVector())
Jamie Madill033dae62014-06-18 12:56:28 -0400312 {
313 switch (type.getNominalSize())
314 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500315 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();
Nico Weberb5db2b42018-02-12 15:31:56 -0500323#if !UNREACHABLE_IS_NORETURN
324 return GL_NONE;
325#endif
Jamie Madill033dae62014-06-18 12:56:28 -0400326 }
327 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500328 else
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300329 {
330 ASSERT(!type.isMatrix());
331 return GL_UNSIGNED_INT;
332 }
Jamie Madill033dae62014-06-18 12:56:28 -0400333 }
334 else if (type.getBasicType() == EbtBool)
335 {
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300336 if (type.isVector())
Jamie Madill033dae62014-06-18 12:56:28 -0400337 {
338 switch (type.getNominalSize())
339 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500340 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();
Nico Weberb5db2b42018-02-12 15:31:56 -0500348#if !UNREACHABLE_IS_NORETURN
349 return GL_NONE;
350#endif
Jamie Madill033dae62014-06-18 12:56:28 -0400351 }
352 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500353 else
Olli Etuaho37d96cc2017-07-11 14:14:03 +0300354 {
355 ASSERT(!type.isMatrix());
356 return GL_BOOL;
357 }
Jamie Madill033dae62014-06-18 12:56:28 -0400358 }
359
360 switch (type.getBasicType())
361 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500362 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;
Andrei Volykhina5527072017-03-22 16:46:30 +0300370 case EbtSamplerExternal2DY2YEXT:
371 return GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500372 case EbtSampler2DRect:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400373 return GL_SAMPLER_2D_RECT_ANGLE;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500374 case EbtSampler2DArray:
375 return GL_SAMPLER_2D_ARRAY;
JiangYizhou40219322016-12-09 09:50:51 +0800376 case EbtSampler2DMS:
377 return GL_SAMPLER_2D_MULTISAMPLE;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500378 case EbtISampler2D:
379 return GL_INT_SAMPLER_2D;
380 case EbtISampler3D:
381 return GL_INT_SAMPLER_3D;
382 case EbtISamplerCube:
383 return GL_INT_SAMPLER_CUBE;
384 case EbtISampler2DArray:
385 return GL_INT_SAMPLER_2D_ARRAY;
JiangYizhou40219322016-12-09 09:50:51 +0800386 case EbtISampler2DMS:
387 return GL_INT_SAMPLER_2D_MULTISAMPLE;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500388 case EbtUSampler2D:
389 return GL_UNSIGNED_INT_SAMPLER_2D;
390 case EbtUSampler3D:
391 return GL_UNSIGNED_INT_SAMPLER_3D;
392 case EbtUSamplerCube:
393 return GL_UNSIGNED_INT_SAMPLER_CUBE;
394 case EbtUSampler2DArray:
395 return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
JiangYizhou40219322016-12-09 09:50:51 +0800396 case EbtUSampler2DMS:
397 return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500398 case EbtSampler2DShadow:
399 return GL_SAMPLER_2D_SHADOW;
400 case EbtSamplerCubeShadow:
401 return GL_SAMPLER_CUBE_SHADOW;
402 case EbtSampler2DArrayShadow:
403 return GL_SAMPLER_2D_ARRAY_SHADOW;
404 case EbtImage2D:
405 return GL_IMAGE_2D;
406 case EbtIImage2D:
407 return GL_INT_IMAGE_2D;
408 case EbtUImage2D:
409 return GL_UNSIGNED_INT_IMAGE_2D;
410 case EbtImage2DArray:
411 return GL_IMAGE_2D_ARRAY;
412 case EbtIImage2DArray:
413 return GL_INT_IMAGE_2D_ARRAY;
414 case EbtUImage2DArray:
415 return GL_UNSIGNED_INT_IMAGE_2D_ARRAY;
416 case EbtImage3D:
417 return GL_IMAGE_3D;
418 case EbtIImage3D:
419 return GL_INT_IMAGE_3D;
420 case EbtUImage3D:
421 return GL_UNSIGNED_INT_IMAGE_3D;
422 case EbtImageCube:
423 return GL_IMAGE_CUBE;
424 case EbtIImageCube:
425 return GL_INT_IMAGE_CUBE;
426 case EbtUImageCube:
427 return GL_UNSIGNED_INT_IMAGE_CUBE;
jchen104cdac9e2017-05-08 11:01:20 +0800428 case EbtAtomicCounter:
429 return GL_UNSIGNED_INT_ATOMIC_COUNTER;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500430 default:
431 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400432 }
433
434 return GL_NONE;
435}
436
437GLenum GLVariablePrecision(const TType &type)
438{
439 if (type.getBasicType() == EbtFloat)
440 {
441 switch (type.getPrecision())
442 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500443 case EbpHigh:
444 return GL_HIGH_FLOAT;
445 case EbpMedium:
446 return GL_MEDIUM_FLOAT;
447 case EbpLow:
448 return GL_LOW_FLOAT;
449 case EbpUndefined:
450 // Should be defined as the default precision by the parser
451 default:
452 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400453 }
454 }
455 else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
456 {
457 switch (type.getPrecision())
458 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500459 case EbpHigh:
460 return GL_HIGH_INT;
461 case EbpMedium:
462 return GL_MEDIUM_INT;
463 case EbpLow:
464 return GL_LOW_INT;
465 case EbpUndefined:
466 // Should be defined as the default precision by the parser
467 default:
468 UNREACHABLE();
Jamie Madill033dae62014-06-18 12:56:28 -0400469 }
470 }
471
472 // Other types (boolean, sampler) don't have a precision
473 return GL_NONE;
474}
475
Olli Etuahod8b1c5c2018-06-20 12:08:46 +0300476ImmutableString ArrayString(const TType &type)
Jamie Madill033dae62014-06-18 12:56:28 -0400477{
Kai Ninomiya57ea5332017-11-22 14:04:48 -0800478 if (!type.isArray())
Olli Etuahod8b1c5c2018-06-20 12:08:46 +0300479 return ImmutableString("");
Kai Ninomiya57ea5332017-11-22 14:04:48 -0800480
481 const TVector<unsigned int> &arraySizes = *type.getArraySizes();
Olli Etuahod8b1c5c2018-06-20 12:08:46 +0300482 constexpr const size_t kMaxDecimalDigitsPerSize = 10u;
483 ImmutableStringBuilder arrayString(arraySizes.size() * (kMaxDecimalDigitsPerSize + 2u));
Olli Etuaho96f6adf2017-08-16 11:18:54 +0300484 for (auto arraySizeIter = arraySizes.rbegin(); arraySizeIter != arraySizes.rend();
485 ++arraySizeIter)
Jamie Madill033dae62014-06-18 12:56:28 -0400486 {
Jiawei Shao8e4b3552017-08-30 14:20:58 +0800487 arrayString << "[";
488 if (*arraySizeIter > 0)
489 {
Olli Etuahod8b1c5c2018-06-20 12:08:46 +0300490 arrayString.appendDecimal(*arraySizeIter);
Jiawei Shao8e4b3552017-08-30 14:20:58 +0800491 }
492 arrayString << "]";
Jamie Madill033dae62014-06-18 12:56:28 -0400493 }
Olli Etuahod8b1c5c2018-06-20 12:08:46 +0300494 return arrayString;
Jamie Madill033dae62014-06-18 12:56:28 -0400495}
496
Olli Etuahofbb1c792018-01-19 16:26:59 +0200497ImmutableString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap)
Jamie Madill6276b922017-09-25 02:35:57 -0400498{
499 if (type.getBasicType() == EbtStruct)
Olli Etuaho8b5e8fd2017-12-15 14:59:15 +0200500 return HashName(type.getStruct(), hashFunction, nameMap);
Jamie Madill6276b922017-09-25 02:35:57 -0400501 else
Olli Etuahofbb1c792018-01-19 16:26:59 +0200502 return ImmutableString(type.getBuiltInTypeNameString());
Jamie Madill6276b922017-09-25 02:35:57 -0400503}
504
Jamie Madill033dae62014-06-18 12:56:28 -0400505bool IsVaryingOut(TQualifier qualifier)
506{
507 switch (qualifier)
508 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500509 case EvqVaryingOut:
510 case EvqSmoothOut:
511 case EvqFlatOut:
512 case EvqCentroidOut:
513 case EvqVertexOut:
Jiawei Shao8e4b3552017-08-30 14:20:58 +0800514 case EvqGeometryOut:
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500515 return true;
Jamie Madill033dae62014-06-18 12:56:28 -0400516
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500517 default:
518 break;
Jamie Madill033dae62014-06-18 12:56:28 -0400519 }
520
521 return false;
522}
523
524bool IsVaryingIn(TQualifier qualifier)
525{
526 switch (qualifier)
527 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500528 case EvqVaryingIn:
529 case EvqSmoothIn:
530 case EvqFlatIn:
531 case EvqCentroidIn:
532 case EvqFragmentIn:
Jiawei Shao8e4b3552017-08-30 14:20:58 +0800533 case EvqGeometryIn:
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500534 return true;
Jamie Madill033dae62014-06-18 12:56:28 -0400535
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500536 default:
537 break;
Jamie Madill033dae62014-06-18 12:56:28 -0400538 }
539
540 return false;
541}
542
543bool IsVarying(TQualifier qualifier)
544{
545 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
546}
547
Jiawei Shao8e4b3552017-08-30 14:20:58 +0800548bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier)
549{
550 return (qualifier == EvqGeometryIn) ||
Jiawei Shaobd924af2017-11-16 15:28:04 +0800551 ((shaderType == GL_GEOMETRY_SHADER_EXT) && IsInterpolationIn(qualifier));
Jiawei Shao8e4b3552017-08-30 14:20:58 +0800552}
553
Jamie Madillf2575982014-06-25 16:04:54 -0400554InterpolationType GetInterpolationType(TQualifier qualifier)
Jamie Madill033dae62014-06-18 12:56:28 -0400555{
556 switch (qualifier)
557 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500558 case EvqFlatIn:
559 case EvqFlatOut:
560 return INTERPOLATION_FLAT;
Jamie Madill033dae62014-06-18 12:56:28 -0400561
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500562 case EvqSmoothIn:
563 case EvqSmoothOut:
564 case EvqVertexOut:
565 case EvqFragmentIn:
566 case EvqVaryingIn:
567 case EvqVaryingOut:
Jiawei Shao8e4b3552017-08-30 14:20:58 +0800568 case EvqGeometryIn:
569 case EvqGeometryOut:
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500570 return INTERPOLATION_SMOOTH;
Jamie Madill033dae62014-06-18 12:56:28 -0400571
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500572 case EvqCentroidIn:
573 case EvqCentroidOut:
574 return INTERPOLATION_CENTROID;
Jamie Madill033dae62014-06-18 12:56:28 -0400575
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500576 default:
577 UNREACHABLE();
Nico Weberb5db2b42018-02-12 15:31:56 -0500578#if !UNREACHABLE_IS_NORETURN
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500579 return INTERPOLATION_SMOOTH;
Nico Weberb5db2b42018-02-12 15:31:56 -0500580#endif
Jamie Madill033dae62014-06-18 12:56:28 -0400581 }
582}
583
Corentin Wallez509e4562016-08-25 14:55:44 -0400584TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
Zhenyao Mo72111912016-07-20 17:45:56 -0700585{
Corentin Wallez509e4562016-08-25 14:55:44 -0400586 switch (var.type)
Zhenyao Mo72111912016-07-20 17:45:56 -0700587 {
Qin Jiajia7835b522016-10-08 11:20:17 +0800588 case GL_BOOL:
589 return TType(EbtBool);
590 case GL_BOOL_VEC2:
591 return TType(EbtBool, 2);
592 case GL_BOOL_VEC3:
593 return TType(EbtBool, 3);
594 case GL_BOOL_VEC4:
595 return TType(EbtBool, 4);
Zhenyao Mo72111912016-07-20 17:45:56 -0700596 case GL_FLOAT:
597 return TType(EbtFloat);
598 case GL_FLOAT_VEC2:
599 return TType(EbtFloat, 2);
600 case GL_FLOAT_VEC3:
601 return TType(EbtFloat, 3);
602 case GL_FLOAT_VEC4:
603 return TType(EbtFloat, 4);
604 case GL_FLOAT_MAT2:
605 return TType(EbtFloat, 2, 2);
606 case GL_FLOAT_MAT3:
607 return TType(EbtFloat, 3, 3);
608 case GL_FLOAT_MAT4:
609 return TType(EbtFloat, 4, 4);
610 case GL_FLOAT_MAT2x3:
611 return TType(EbtFloat, 2, 3);
612 case GL_FLOAT_MAT2x4:
613 return TType(EbtFloat, 2, 4);
614 case GL_FLOAT_MAT3x2:
615 return TType(EbtFloat, 3, 2);
616 case GL_FLOAT_MAT3x4:
617 return TType(EbtFloat, 3, 4);
618 case GL_FLOAT_MAT4x2:
619 return TType(EbtFloat, 4, 2);
620 case GL_FLOAT_MAT4x3:
621 return TType(EbtFloat, 4, 3);
622 case GL_INT:
623 return TType(EbtInt);
624 case GL_INT_VEC2:
625 return TType(EbtInt, 2);
626 case GL_INT_VEC3:
627 return TType(EbtInt, 3);
628 case GL_INT_VEC4:
629 return TType(EbtInt, 4);
630 case GL_UNSIGNED_INT:
631 return TType(EbtUInt);
632 case GL_UNSIGNED_INT_VEC2:
633 return TType(EbtUInt, 2);
634 case GL_UNSIGNED_INT_VEC3:
635 return TType(EbtUInt, 3);
636 case GL_UNSIGNED_INT_VEC4:
637 return TType(EbtUInt, 4);
638 default:
639 UNREACHABLE();
Nico Weberb5db2b42018-02-12 15:31:56 -0500640#if !UNREACHABLE_IS_NORETURN
Zhenyao Mo72111912016-07-20 17:45:56 -0700641 return TType();
Nico Weberb5db2b42018-02-12 15:31:56 -0500642#endif
Zhenyao Mo72111912016-07-20 17:45:56 -0700643 }
644}
645
Luc Ferrone18b8142018-06-07 11:53:19 -0400646void DeclareGlobalVariable(TIntermBlock *root, const TVariable *variable)
647{
648 TIntermDeclaration *declaration = new TIntermDeclaration();
649 declaration->appendDeclarator(new TIntermSymbol(variable));
650
651 TIntermSequence *globalSequence = root->getSequence();
652 globalSequence->insert(globalSequence->begin(), declaration);
653}
654
Martin Radev70866b82016-07-22 15:27:42 +0300655// GLSL ES 1.0.17 4.6.1 The Invariant Qualifier
656bool CanBeInvariantESSL1(TQualifier qualifier)
657{
658 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) ||
659 IsBuiltinOutputVariable(qualifier) ||
660 (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing);
Jamie Madill033dae62014-06-18 12:56:28 -0400661}
Martin Radev70866b82016-07-22 15:27:42 +0300662
663// GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier
664// GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier
665bool CanBeInvariantESSL3OrGreater(TQualifier qualifier)
666{
667 return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut ||
668 IsBuiltinOutputVariable(qualifier);
669}
670
671bool IsBuiltinOutputVariable(TQualifier qualifier)
672{
673 switch (qualifier)
674 {
675 case EvqPosition:
676 case EvqPointSize:
677 case EvqFragDepth:
678 case EvqFragDepthEXT:
679 case EvqFragColor:
680 case EvqSecondaryFragColorEXT:
681 case EvqFragData:
682 case EvqSecondaryFragDataEXT:
683 return true;
684 default:
685 break;
686 }
687 return false;
688}
689
690bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
691{
692 switch (qualifier)
693 {
694 case EvqFragCoord:
695 case EvqPointCoord:
696 case EvqFrontFacing:
697 return true;
698 default:
699 break;
700 }
701 return false;
702}
Martin Radeve469de82017-07-04 11:58:35 +0300703
704bool IsOutputESSL(ShShaderOutput output)
705{
706 return output == SH_ESSL_OUTPUT;
707}
708
709bool IsOutputGLSL(ShShaderOutput output)
710{
711 switch (output)
712 {
713 case SH_GLSL_130_OUTPUT:
714 case SH_GLSL_140_OUTPUT:
715 case SH_GLSL_150_CORE_OUTPUT:
716 case SH_GLSL_330_CORE_OUTPUT:
717 case SH_GLSL_400_CORE_OUTPUT:
718 case SH_GLSL_410_CORE_OUTPUT:
719 case SH_GLSL_420_CORE_OUTPUT:
720 case SH_GLSL_430_CORE_OUTPUT:
721 case SH_GLSL_440_CORE_OUTPUT:
722 case SH_GLSL_450_CORE_OUTPUT:
723 case SH_GLSL_COMPATIBILITY_OUTPUT:
724 return true;
725 default:
726 break;
727 }
728 return false;
729}
730bool IsOutputHLSL(ShShaderOutput output)
731{
732 switch (output)
733 {
734 case SH_HLSL_3_0_OUTPUT:
735 case SH_HLSL_4_1_OUTPUT:
736 case SH_HLSL_4_0_FL9_3_OUTPUT:
737 return true;
738 default:
739 break;
740 }
741 return false;
742}
743bool IsOutputVulkan(ShShaderOutput output)
744{
745 return output == SH_GLSL_VULKAN_OUTPUT;
746}
747
Martin Radev70866b82016-07-22 15:27:42 +0300748} // namespace sh