blob: 89f237ceb2092c5667b7f39612b17a468f92f3fc [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
Zhenyao Mocc4ec642013-09-23 14:57:10 -040011#include "compiler/preprocessor/numeric_lex.h"
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070012#include "compiler/translator/SymbolTable.h"
Jamie Madill77f74852014-07-08 15:02:34 -040013#include "common/utilities.h"
daniel@transgaming.com91ed1492010-10-29 03:11:43 +000014
Corentin Walleze2adce12015-06-19 23:06:32 +020015bool strtof_clamp(const std::string &str, float *value)
daniel@transgaming.com91ed1492010-10-29 03:11:43 +000016{
Zhenyao Mocc4ec642013-09-23 14:57:10 -040017 bool success = pp::numeric_lex_float(str, value);
Zhenyao Mof1d723c2013-09-23 14:57:07 -040018 if (!success)
19 *value = std::numeric_limits<float>::max();
20 return success;
daniel@transgaming.com91ed1492010-10-29 03:11:43 +000021}
Zhenyao Mof1d723c2013-09-23 14:57:07 -040022
Olli Etuahof541f522015-10-13 12:21:01 +030023bool atoi_clamp(const char *str, unsigned int *value)
Zhenyao Mof1d723c2013-09-23 14:57:07 -040024{
Zhenyao Mocc4ec642013-09-23 14:57:10 -040025 bool success = pp::numeric_lex_int(str, value);
26 if (!success)
Olli Etuahof541f522015-10-13 12:21:01 +030027 *value = std::numeric_limits<unsigned int>::max();
Zhenyao Mocc4ec642013-09-23 14:57:10 -040028 return success;
Zhenyao Mof1d723c2013-09-23 14:57:07 -040029}
30
Jamie Madill033dae62014-06-18 12:56:28 -040031namespace sh
32{
33
34GLenum GLVariableType(const TType &type)
35{
36 if (type.getBasicType() == EbtFloat)
37 {
38 if (type.isScalar())
39 {
40 return GL_FLOAT;
41 }
42 else if (type.isVector())
43 {
44 switch (type.getNominalSize())
45 {
46 case 2: return GL_FLOAT_VEC2;
47 case 3: return GL_FLOAT_VEC3;
48 case 4: return GL_FLOAT_VEC4;
49 default: UNREACHABLE();
50 }
51 }
52 else if (type.isMatrix())
53 {
54 switch (type.getCols())
55 {
56 case 2:
57 switch (type.getRows())
58 {
59 case 2: return GL_FLOAT_MAT2;
60 case 3: return GL_FLOAT_MAT2x3;
61 case 4: return GL_FLOAT_MAT2x4;
62 default: UNREACHABLE();
63 }
64
65 case 3:
66 switch (type.getRows())
67 {
68 case 2: return GL_FLOAT_MAT3x2;
69 case 3: return GL_FLOAT_MAT3;
70 case 4: return GL_FLOAT_MAT3x4;
71 default: UNREACHABLE();
72 }
73
74 case 4:
75 switch (type.getRows())
76 {
77 case 2: return GL_FLOAT_MAT4x2;
78 case 3: return GL_FLOAT_MAT4x3;
79 case 4: return GL_FLOAT_MAT4;
80 default: UNREACHABLE();
81 }
82
83 default: UNREACHABLE();
84 }
85 }
86 else UNREACHABLE();
87 }
88 else if (type.getBasicType() == EbtInt)
89 {
90 if (type.isScalar())
91 {
92 return GL_INT;
93 }
94 else if (type.isVector())
95 {
96 switch (type.getNominalSize())
97 {
98 case 2: return GL_INT_VEC2;
99 case 3: return GL_INT_VEC3;
100 case 4: return GL_INT_VEC4;
101 default: UNREACHABLE();
102 }
103 }
104 else UNREACHABLE();
105 }
106 else if (type.getBasicType() == EbtUInt)
107 {
108 if (type.isScalar())
109 {
110 return GL_UNSIGNED_INT;
111 }
112 else if (type.isVector())
113 {
114 switch (type.getNominalSize())
115 {
116 case 2: return GL_UNSIGNED_INT_VEC2;
117 case 3: return GL_UNSIGNED_INT_VEC3;
118 case 4: return GL_UNSIGNED_INT_VEC4;
119 default: UNREACHABLE();
120 }
121 }
122 else UNREACHABLE();
123 }
124 else if (type.getBasicType() == EbtBool)
125 {
126 if (type.isScalar())
127 {
128 return GL_BOOL;
129 }
130 else if (type.isVector())
131 {
132 switch (type.getNominalSize())
133 {
134 case 2: return GL_BOOL_VEC2;
135 case 3: return GL_BOOL_VEC3;
136 case 4: return GL_BOOL_VEC4;
137 default: UNREACHABLE();
138 }
139 }
140 else UNREACHABLE();
141 }
142
143 switch (type.getBasicType())
144 {
145 case EbtSampler2D: return GL_SAMPLER_2D;
146 case EbtSampler3D: return GL_SAMPLER_3D;
147 case EbtSamplerCube: return GL_SAMPLER_CUBE;
Jamie Madillaa72d782014-07-02 15:31:19 -0400148 case EbtSamplerExternalOES: return GL_SAMPLER_EXTERNAL_OES;
149 case EbtSampler2DRect: return GL_SAMPLER_2D_RECT_ARB;
Jamie Madill033dae62014-06-18 12:56:28 -0400150 case EbtSampler2DArray: return GL_SAMPLER_2D_ARRAY;
151 case EbtISampler2D: return GL_INT_SAMPLER_2D;
152 case EbtISampler3D: return GL_INT_SAMPLER_3D;
153 case EbtISamplerCube: return GL_INT_SAMPLER_CUBE;
154 case EbtISampler2DArray: return GL_INT_SAMPLER_2D_ARRAY;
155 case EbtUSampler2D: return GL_UNSIGNED_INT_SAMPLER_2D;
156 case EbtUSampler3D: return GL_UNSIGNED_INT_SAMPLER_3D;
157 case EbtUSamplerCube: return GL_UNSIGNED_INT_SAMPLER_CUBE;
158 case EbtUSampler2DArray: return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY;
159 case EbtSampler2DShadow: return GL_SAMPLER_2D_SHADOW;
160 case EbtSamplerCubeShadow: return GL_SAMPLER_CUBE_SHADOW;
161 case EbtSampler2DArrayShadow: return GL_SAMPLER_2D_ARRAY_SHADOW;
Martin Radev2cc85b32016-08-05 16:22:53 +0300162 case EbtImage2D:
163 return GL_IMAGE_2D;
164 case EbtIImage2D:
165 return GL_INT_IMAGE_2D;
166 case EbtUImage2D:
167 return GL_UNSIGNED_INT_IMAGE_2D;
168 case EbtImage2DArray:
169 return GL_IMAGE_2D_ARRAY;
170 case EbtIImage2DArray:
171 return GL_INT_IMAGE_2D_ARRAY;
172 case EbtUImage2DArray:
173 return GL_UNSIGNED_INT_IMAGE_2D_ARRAY;
174 case EbtImage3D:
175 return GL_IMAGE_3D;
176 case EbtIImage3D:
177 return GL_INT_IMAGE_3D;
178 case EbtUImage3D:
179 return GL_UNSIGNED_INT_IMAGE_3D;
180 case EbtImageCube:
181 return GL_IMAGE_CUBE;
182 case EbtIImageCube:
183 return GL_INT_IMAGE_CUBE;
184 case EbtUImageCube:
185 return GL_UNSIGNED_INT_IMAGE_CUBE;
Jamie Madill033dae62014-06-18 12:56:28 -0400186 default: UNREACHABLE();
187 }
188
189 return GL_NONE;
190}
191
192GLenum GLVariablePrecision(const TType &type)
193{
194 if (type.getBasicType() == EbtFloat)
195 {
196 switch (type.getPrecision())
197 {
Jamie Madilla718c1e2014-07-02 15:31:22 -0400198 case EbpHigh:
Jamie Madill033dae62014-06-18 12:56:28 -0400199 return GL_HIGH_FLOAT;
Jamie Madilla718c1e2014-07-02 15:31:22 -0400200 case EbpMedium:
Jamie Madill033dae62014-06-18 12:56:28 -0400201 return GL_MEDIUM_FLOAT;
Jamie Madilla718c1e2014-07-02 15:31:22 -0400202 case EbpLow:
Jamie Madill033dae62014-06-18 12:56:28 -0400203 return GL_LOW_FLOAT;
Jamie Madilla718c1e2014-07-02 15:31:22 -0400204 case EbpUndefined:
205 // Should be defined as the default precision by the parser
206 default:
Jamie Madill033dae62014-06-18 12:56:28 -0400207 UNREACHABLE();
208 }
209 }
210 else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
211 {
212 switch (type.getPrecision())
213 {
214 case EbpHigh:
215 return GL_HIGH_INT;
216 case EbpMedium:
217 return GL_MEDIUM_INT;
218 case EbpLow:
219 return GL_LOW_INT;
220 case EbpUndefined:
221 // Should be defined as the default precision by the parser
222 default:
223 UNREACHABLE();
224 }
225 }
226
227 // Other types (boolean, sampler) don't have a precision
228 return GL_NONE;
229}
230
231TString ArrayString(const TType &type)
232{
233 if (!type.isArray())
234 {
235 return "";
236 }
237
238 return "[" + str(type.getArraySize()) + "]";
239}
240
241bool IsVaryingOut(TQualifier qualifier)
242{
243 switch (qualifier)
244 {
245 case EvqVaryingOut:
Jamie Madill033dae62014-06-18 12:56:28 -0400246 case EvqSmoothOut:
247 case EvqFlatOut:
248 case EvqCentroidOut:
249 case EvqVertexOut:
250 return true;
251
252 default: break;
253 }
254
255 return false;
256}
257
258bool IsVaryingIn(TQualifier qualifier)
259{
260 switch (qualifier)
261 {
262 case EvqVaryingIn:
Jamie Madill033dae62014-06-18 12:56:28 -0400263 case EvqSmoothIn:
264 case EvqFlatIn:
265 case EvqCentroidIn:
266 case EvqFragmentIn:
267 return true;
268
269 default: break;
270 }
271
272 return false;
273}
274
275bool IsVarying(TQualifier qualifier)
276{
277 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
278}
279
Jamie Madillf2575982014-06-25 16:04:54 -0400280InterpolationType GetInterpolationType(TQualifier qualifier)
Jamie Madill033dae62014-06-18 12:56:28 -0400281{
282 switch (qualifier)
283 {
284 case EvqFlatIn:
285 case EvqFlatOut:
Jamie Madillf2575982014-06-25 16:04:54 -0400286 return INTERPOLATION_FLAT;
Jamie Madill033dae62014-06-18 12:56:28 -0400287
288 case EvqSmoothIn:
289 case EvqSmoothOut:
290 case EvqVertexOut:
291 case EvqFragmentIn:
292 case EvqVaryingIn:
293 case EvqVaryingOut:
Jamie Madillf2575982014-06-25 16:04:54 -0400294 return INTERPOLATION_SMOOTH;
Jamie Madill033dae62014-06-18 12:56:28 -0400295
296 case EvqCentroidIn:
297 case EvqCentroidOut:
Jamie Madillf2575982014-06-25 16:04:54 -0400298 return INTERPOLATION_CENTROID;
Jamie Madill033dae62014-06-18 12:56:28 -0400299
300 default: UNREACHABLE();
Jamie Madillf2575982014-06-25 16:04:54 -0400301 return INTERPOLATION_SMOOTH;
Jamie Madill033dae62014-06-18 12:56:28 -0400302 }
303}
304
Corentin Wallez509e4562016-08-25 14:55:44 -0400305TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
Zhenyao Mo72111912016-07-20 17:45:56 -0700306{
Corentin Wallez509e4562016-08-25 14:55:44 -0400307 switch (var.type)
Zhenyao Mo72111912016-07-20 17:45:56 -0700308 {
Qin Jiajia7835b522016-10-08 11:20:17 +0800309 case GL_BOOL:
310 return TType(EbtBool);
311 case GL_BOOL_VEC2:
312 return TType(EbtBool, 2);
313 case GL_BOOL_VEC3:
314 return TType(EbtBool, 3);
315 case GL_BOOL_VEC4:
316 return TType(EbtBool, 4);
Zhenyao Mo72111912016-07-20 17:45:56 -0700317 case GL_FLOAT:
318 return TType(EbtFloat);
319 case GL_FLOAT_VEC2:
320 return TType(EbtFloat, 2);
321 case GL_FLOAT_VEC3:
322 return TType(EbtFloat, 3);
323 case GL_FLOAT_VEC4:
324 return TType(EbtFloat, 4);
325 case GL_FLOAT_MAT2:
326 return TType(EbtFloat, 2, 2);
327 case GL_FLOAT_MAT3:
328 return TType(EbtFloat, 3, 3);
329 case GL_FLOAT_MAT4:
330 return TType(EbtFloat, 4, 4);
331 case GL_FLOAT_MAT2x3:
332 return TType(EbtFloat, 2, 3);
333 case GL_FLOAT_MAT2x4:
334 return TType(EbtFloat, 2, 4);
335 case GL_FLOAT_MAT3x2:
336 return TType(EbtFloat, 3, 2);
337 case GL_FLOAT_MAT3x4:
338 return TType(EbtFloat, 3, 4);
339 case GL_FLOAT_MAT4x2:
340 return TType(EbtFloat, 4, 2);
341 case GL_FLOAT_MAT4x3:
342 return TType(EbtFloat, 4, 3);
343 case GL_INT:
344 return TType(EbtInt);
345 case GL_INT_VEC2:
346 return TType(EbtInt, 2);
347 case GL_INT_VEC3:
348 return TType(EbtInt, 3);
349 case GL_INT_VEC4:
350 return TType(EbtInt, 4);
351 case GL_UNSIGNED_INT:
352 return TType(EbtUInt);
353 case GL_UNSIGNED_INT_VEC2:
354 return TType(EbtUInt, 2);
355 case GL_UNSIGNED_INT_VEC3:
356 return TType(EbtUInt, 3);
357 case GL_UNSIGNED_INT_VEC4:
358 return TType(EbtUInt, 4);
359 default:
360 UNREACHABLE();
361 return TType();
362 }
363}
364
Geoff Lang156d7192016-07-21 16:11:00 -0400365TOperator TypeToConstructorOperator(const TType &type)
366{
367 switch (type.getBasicType())
368 {
369 case EbtFloat:
370 if (type.isMatrix())
371 {
372 switch (type.getCols())
373 {
374 case 2:
375 switch (type.getRows())
376 {
377 case 2:
378 return EOpConstructMat2;
379 case 3:
380 return EOpConstructMat2x3;
381 case 4:
382 return EOpConstructMat2x4;
383 default:
384 break;
385 }
386 break;
387
388 case 3:
389 switch (type.getRows())
390 {
391 case 2:
392 return EOpConstructMat3x2;
393 case 3:
394 return EOpConstructMat3;
395 case 4:
396 return EOpConstructMat3x4;
397 default:
398 break;
399 }
400 break;
401
402 case 4:
403 switch (type.getRows())
404 {
405 case 2:
406 return EOpConstructMat4x2;
407 case 3:
408 return EOpConstructMat4x3;
409 case 4:
410 return EOpConstructMat4;
411 default:
412 break;
413 }
414 break;
415 }
416 }
417 else
418 {
419 switch (type.getNominalSize())
420 {
421 case 1:
422 return EOpConstructFloat;
423 case 2:
424 return EOpConstructVec2;
425 case 3:
426 return EOpConstructVec3;
427 case 4:
428 return EOpConstructVec4;
429 default:
430 break;
431 }
432 }
433 break;
434
435 case EbtInt:
436 switch (type.getNominalSize())
437 {
438 case 1:
439 return EOpConstructInt;
440 case 2:
441 return EOpConstructIVec2;
442 case 3:
443 return EOpConstructIVec3;
444 case 4:
445 return EOpConstructIVec4;
446 default:
447 break;
448 }
449 break;
450
451 case EbtUInt:
452 switch (type.getNominalSize())
453 {
454 case 1:
455 return EOpConstructUInt;
456 case 2:
457 return EOpConstructUVec2;
458 case 3:
459 return EOpConstructUVec3;
460 case 4:
461 return EOpConstructUVec4;
462 default:
463 break;
464 }
465 break;
466
467 case EbtBool:
468 switch (type.getNominalSize())
469 {
470 case 1:
471 return EOpConstructBool;
472 case 2:
473 return EOpConstructBVec2;
474 case 3:
475 return EOpConstructBVec3;
476 case 4:
477 return EOpConstructBVec4;
478 default:
479 break;
480 }
481 break;
482
483 case EbtStruct:
484 return EOpConstructStruct;
485
486 default:
487 break;
488 }
489
490 return EOpNull;
491}
492
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700493GetVariableTraverser::GetVariableTraverser(const TSymbolTable &symbolTable)
494 : mSymbolTable(symbolTable)
495{
496}
497
498template void GetVariableTraverser::setTypeSpecificInfo(
499 const TType &type, const TString& name, InterfaceBlockField *variable);
500template void GetVariableTraverser::setTypeSpecificInfo(
501 const TType &type, const TString& name, ShaderVariable *variable);
502template void GetVariableTraverser::setTypeSpecificInfo(
503 const TType &type, const TString& name, Uniform *variable);
504
505template<>
506void GetVariableTraverser::setTypeSpecificInfo(
507 const TType &type, const TString& name, Varying *variable)
508{
509 ASSERT(variable);
510 switch (type.getQualifier())
511 {
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700512 case EvqVaryingIn:
513 case EvqVaryingOut:
Olli Etuaho37ad4742015-04-27 13:18:50 +0300514 case EvqVertexOut:
515 case EvqSmoothOut:
516 case EvqFlatOut:
517 case EvqCentroidOut:
Olli Etuaho214c2d82015-04-27 14:49:13 +0300518 if (mSymbolTable.isVaryingInvariant(std::string(name.c_str())) || type.isInvariant())
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700519 {
520 variable->isInvariant = true;
521 }
522 break;
523 default:
524 break;
525 }
Jamie Madill70a0b2a2014-10-21 11:48:39 -0400526
527 variable->interpolation = GetInterpolationType(type.getQualifier());
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700528}
529
Jamie Madill77f74852014-07-08 15:02:34 -0400530template <typename VarT>
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700531void GetVariableTraverser::traverse(const TType &type,
532 const TString &name,
533 std::vector<VarT> *output)
Jamie Madill77f74852014-07-08 15:02:34 -0400534{
535 const TStructure *structure = type.getStruct();
536
537 VarT variable;
538 variable.name = name.c_str();
Olli Etuaho856c4972016-08-08 11:38:39 +0300539 variable.arraySize = type.getArraySize();
Jamie Madill77f74852014-07-08 15:02:34 -0400540
541 if (!structure)
542 {
543 variable.type = GLVariableType(type);
544 variable.precision = GLVariablePrecision(type);
545 }
546 else
547 {
Jamie Madill42bcf322014-08-25 16:20:46 -0400548 // Note: this enum value is not exposed outside ANGLE
Jamie Madill77f74852014-07-08 15:02:34 -0400549 variable.type = GL_STRUCT_ANGLEX;
Jamie Madill42bcf322014-08-25 16:20:46 -0400550 variable.structName = structure->name().c_str();
Jamie Madill77f74852014-07-08 15:02:34 -0400551
552 const TFieldList &fields = structure->fields();
553
554 for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
555 {
556 TField *field = fields[fieldIndex];
Jamie Madill42bcf322014-08-25 16:20:46 -0400557 traverse(*field->type(), field->name(), &variable.fields);
Jamie Madill77f74852014-07-08 15:02:34 -0400558 }
Jamie Madill77f74852014-07-08 15:02:34 -0400559 }
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700560 setTypeSpecificInfo(type, name, &variable);
Jamie Madill77f74852014-07-08 15:02:34 -0400561 visitVariable(&variable);
562
Jamie Madill77f74852014-07-08 15:02:34 -0400563 ASSERT(output);
Jamie Madill42bcf322014-08-25 16:20:46 -0400564 output->push_back(variable);
Jamie Madill77f74852014-07-08 15:02:34 -0400565}
566
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700567template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
568template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<ShaderVariable> *);
Jamie Madill42bcf322014-08-25 16:20:46 -0400569template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Uniform> *);
570template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Varying> *);
Jamie Madill77f74852014-07-08 15:02:34 -0400571
Martin Radev70866b82016-07-22 15:27:42 +0300572// GLSL ES 1.0.17 4.6.1 The Invariant Qualifier
573bool CanBeInvariantESSL1(TQualifier qualifier)
574{
575 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) ||
576 IsBuiltinOutputVariable(qualifier) ||
577 (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing);
Jamie Madill033dae62014-06-18 12:56:28 -0400578}
Martin Radev70866b82016-07-22 15:27:42 +0300579
580// GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier
581// GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier
582bool CanBeInvariantESSL3OrGreater(TQualifier qualifier)
583{
584 return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut ||
585 IsBuiltinOutputVariable(qualifier);
586}
587
588bool IsBuiltinOutputVariable(TQualifier qualifier)
589{
590 switch (qualifier)
591 {
592 case EvqPosition:
593 case EvqPointSize:
594 case EvqFragDepth:
595 case EvqFragDepthEXT:
596 case EvqFragColor:
597 case EvqSecondaryFragColorEXT:
598 case EvqFragData:
599 case EvqSecondaryFragDataEXT:
600 return true;
601 default:
602 break;
603 }
604 return false;
605}
606
607bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
608{
609 switch (qualifier)
610 {
611 case EvqFragCoord:
612 case EvqPointCoord:
613 case EvqFrontFacing:
614 return true;
615 default:
616 break;
617 }
618 return false;
619}
620} // namespace sh