blob: 54a1a2cefc13a66441da320e9af60cfd6ef6c544 [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
Qin Jiajia7835b522016-10-08 11:20:17 +0800305TType GetInterfaceBlockType(const sh::InterfaceBlock &block)
306{
307 TType type;
308 TFieldList *fields = new TFieldList;
309 TSourceLoc loc;
310 for (const auto &field : block.fields)
311 {
312 TType *fieldType = new TType(GetShaderVariableType(field));
313 fields->push_back(new TField(fieldType, new TString(field.name.c_str()), loc));
314 }
315
316 TInterfaceBlock *interfaceBlock = new TInterfaceBlock(
317 new TString(block.name.c_str()), fields, new TString(block.instanceName.c_str()),
318 block.arraySize, TLayoutQualifier::create());
319
320 type.setBasicType(EbtInterfaceBlock);
321 type.setInterfaceBlock(interfaceBlock);
322 type.setArraySize(block.arraySize);
323 return type;
324}
325
Corentin Wallez509e4562016-08-25 14:55:44 -0400326TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
Zhenyao Mo72111912016-07-20 17:45:56 -0700327{
Corentin Wallez509e4562016-08-25 14:55:44 -0400328 switch (var.type)
Zhenyao Mo72111912016-07-20 17:45:56 -0700329 {
Qin Jiajia7835b522016-10-08 11:20:17 +0800330 case GL_BOOL:
331 return TType(EbtBool);
332 case GL_BOOL_VEC2:
333 return TType(EbtBool, 2);
334 case GL_BOOL_VEC3:
335 return TType(EbtBool, 3);
336 case GL_BOOL_VEC4:
337 return TType(EbtBool, 4);
Zhenyao Mo72111912016-07-20 17:45:56 -0700338 case GL_FLOAT:
339 return TType(EbtFloat);
340 case GL_FLOAT_VEC2:
341 return TType(EbtFloat, 2);
342 case GL_FLOAT_VEC3:
343 return TType(EbtFloat, 3);
344 case GL_FLOAT_VEC4:
345 return TType(EbtFloat, 4);
346 case GL_FLOAT_MAT2:
347 return TType(EbtFloat, 2, 2);
348 case GL_FLOAT_MAT3:
349 return TType(EbtFloat, 3, 3);
350 case GL_FLOAT_MAT4:
351 return TType(EbtFloat, 4, 4);
352 case GL_FLOAT_MAT2x3:
353 return TType(EbtFloat, 2, 3);
354 case GL_FLOAT_MAT2x4:
355 return TType(EbtFloat, 2, 4);
356 case GL_FLOAT_MAT3x2:
357 return TType(EbtFloat, 3, 2);
358 case GL_FLOAT_MAT3x4:
359 return TType(EbtFloat, 3, 4);
360 case GL_FLOAT_MAT4x2:
361 return TType(EbtFloat, 4, 2);
362 case GL_FLOAT_MAT4x3:
363 return TType(EbtFloat, 4, 3);
364 case GL_INT:
365 return TType(EbtInt);
366 case GL_INT_VEC2:
367 return TType(EbtInt, 2);
368 case GL_INT_VEC3:
369 return TType(EbtInt, 3);
370 case GL_INT_VEC4:
371 return TType(EbtInt, 4);
372 case GL_UNSIGNED_INT:
373 return TType(EbtUInt);
374 case GL_UNSIGNED_INT_VEC2:
375 return TType(EbtUInt, 2);
376 case GL_UNSIGNED_INT_VEC3:
377 return TType(EbtUInt, 3);
378 case GL_UNSIGNED_INT_VEC4:
379 return TType(EbtUInt, 4);
380 default:
381 UNREACHABLE();
382 return TType();
383 }
384}
385
Corentin Wallez509e4562016-08-25 14:55:44 -0400386TType GetShaderVariableType(const sh::ShaderVariable &var)
387{
388 TType type;
389 if (var.isStruct())
390 {
391 TFieldList *fields = new TFieldList;
392 TSourceLoc loc;
393 for (const auto &field : var.fields)
394 {
395 TType *fieldType = new TType(GetShaderVariableType(field));
396 fields->push_back(new TField(fieldType, new TString(field.name.c_str()), loc));
397 }
398 TStructure *structure = new TStructure(new TString(var.structName.c_str()), fields);
399
400 type.setBasicType(EbtStruct);
401 type.setStruct(structure);
402 }
403 else
404 {
405 type = GetShaderVariableBasicType(var);
406 }
407
408 if (var.isArray())
409 {
410 type.setArraySize(var.elementCount());
411 }
412 return type;
413}
414
Geoff Lang156d7192016-07-21 16:11:00 -0400415TOperator TypeToConstructorOperator(const TType &type)
416{
417 switch (type.getBasicType())
418 {
419 case EbtFloat:
420 if (type.isMatrix())
421 {
422 switch (type.getCols())
423 {
424 case 2:
425 switch (type.getRows())
426 {
427 case 2:
428 return EOpConstructMat2;
429 case 3:
430 return EOpConstructMat2x3;
431 case 4:
432 return EOpConstructMat2x4;
433 default:
434 break;
435 }
436 break;
437
438 case 3:
439 switch (type.getRows())
440 {
441 case 2:
442 return EOpConstructMat3x2;
443 case 3:
444 return EOpConstructMat3;
445 case 4:
446 return EOpConstructMat3x4;
447 default:
448 break;
449 }
450 break;
451
452 case 4:
453 switch (type.getRows())
454 {
455 case 2:
456 return EOpConstructMat4x2;
457 case 3:
458 return EOpConstructMat4x3;
459 case 4:
460 return EOpConstructMat4;
461 default:
462 break;
463 }
464 break;
465 }
466 }
467 else
468 {
469 switch (type.getNominalSize())
470 {
471 case 1:
472 return EOpConstructFloat;
473 case 2:
474 return EOpConstructVec2;
475 case 3:
476 return EOpConstructVec3;
477 case 4:
478 return EOpConstructVec4;
479 default:
480 break;
481 }
482 }
483 break;
484
485 case EbtInt:
486 switch (type.getNominalSize())
487 {
488 case 1:
489 return EOpConstructInt;
490 case 2:
491 return EOpConstructIVec2;
492 case 3:
493 return EOpConstructIVec3;
494 case 4:
495 return EOpConstructIVec4;
496 default:
497 break;
498 }
499 break;
500
501 case EbtUInt:
502 switch (type.getNominalSize())
503 {
504 case 1:
505 return EOpConstructUInt;
506 case 2:
507 return EOpConstructUVec2;
508 case 3:
509 return EOpConstructUVec3;
510 case 4:
511 return EOpConstructUVec4;
512 default:
513 break;
514 }
515 break;
516
517 case EbtBool:
518 switch (type.getNominalSize())
519 {
520 case 1:
521 return EOpConstructBool;
522 case 2:
523 return EOpConstructBVec2;
524 case 3:
525 return EOpConstructBVec3;
526 case 4:
527 return EOpConstructBVec4;
528 default:
529 break;
530 }
531 break;
532
533 case EbtStruct:
534 return EOpConstructStruct;
535
536 default:
537 break;
538 }
539
540 return EOpNull;
541}
542
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700543GetVariableTraverser::GetVariableTraverser(const TSymbolTable &symbolTable)
544 : mSymbolTable(symbolTable)
545{
546}
547
548template void GetVariableTraverser::setTypeSpecificInfo(
549 const TType &type, const TString& name, InterfaceBlockField *variable);
550template void GetVariableTraverser::setTypeSpecificInfo(
551 const TType &type, const TString& name, ShaderVariable *variable);
552template void GetVariableTraverser::setTypeSpecificInfo(
553 const TType &type, const TString& name, Uniform *variable);
554
555template<>
556void GetVariableTraverser::setTypeSpecificInfo(
557 const TType &type, const TString& name, Varying *variable)
558{
559 ASSERT(variable);
560 switch (type.getQualifier())
561 {
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700562 case EvqVaryingIn:
563 case EvqVaryingOut:
Olli Etuaho37ad4742015-04-27 13:18:50 +0300564 case EvqVertexOut:
565 case EvqSmoothOut:
566 case EvqFlatOut:
567 case EvqCentroidOut:
Olli Etuaho214c2d82015-04-27 14:49:13 +0300568 if (mSymbolTable.isVaryingInvariant(std::string(name.c_str())) || type.isInvariant())
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700569 {
570 variable->isInvariant = true;
571 }
572 break;
573 default:
574 break;
575 }
Jamie Madill70a0b2a2014-10-21 11:48:39 -0400576
577 variable->interpolation = GetInterpolationType(type.getQualifier());
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700578}
579
Jamie Madill77f74852014-07-08 15:02:34 -0400580template <typename VarT>
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700581void GetVariableTraverser::traverse(const TType &type,
582 const TString &name,
583 std::vector<VarT> *output)
Jamie Madill77f74852014-07-08 15:02:34 -0400584{
585 const TStructure *structure = type.getStruct();
586
587 VarT variable;
588 variable.name = name.c_str();
Olli Etuaho856c4972016-08-08 11:38:39 +0300589 variable.arraySize = type.getArraySize();
Jamie Madill77f74852014-07-08 15:02:34 -0400590
591 if (!structure)
592 {
593 variable.type = GLVariableType(type);
594 variable.precision = GLVariablePrecision(type);
595 }
596 else
597 {
Jamie Madill42bcf322014-08-25 16:20:46 -0400598 // Note: this enum value is not exposed outside ANGLE
Jamie Madill77f74852014-07-08 15:02:34 -0400599 variable.type = GL_STRUCT_ANGLEX;
Jamie Madill42bcf322014-08-25 16:20:46 -0400600 variable.structName = structure->name().c_str();
Jamie Madill77f74852014-07-08 15:02:34 -0400601
602 const TFieldList &fields = structure->fields();
603
604 for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
605 {
606 TField *field = fields[fieldIndex];
Jamie Madill42bcf322014-08-25 16:20:46 -0400607 traverse(*field->type(), field->name(), &variable.fields);
Jamie Madill77f74852014-07-08 15:02:34 -0400608 }
Jamie Madill77f74852014-07-08 15:02:34 -0400609 }
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700610 setTypeSpecificInfo(type, name, &variable);
Jamie Madill77f74852014-07-08 15:02:34 -0400611 visitVariable(&variable);
612
Jamie Madill77f74852014-07-08 15:02:34 -0400613 ASSERT(output);
Jamie Madill42bcf322014-08-25 16:20:46 -0400614 output->push_back(variable);
Jamie Madill77f74852014-07-08 15:02:34 -0400615}
616
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700617template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
618template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<ShaderVariable> *);
Jamie Madill42bcf322014-08-25 16:20:46 -0400619template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Uniform> *);
620template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Varying> *);
Jamie Madill77f74852014-07-08 15:02:34 -0400621
Martin Radev70866b82016-07-22 15:27:42 +0300622// GLSL ES 1.0.17 4.6.1 The Invariant Qualifier
623bool CanBeInvariantESSL1(TQualifier qualifier)
624{
625 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) ||
626 IsBuiltinOutputVariable(qualifier) ||
627 (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing);
Jamie Madill033dae62014-06-18 12:56:28 -0400628}
Martin Radev70866b82016-07-22 15:27:42 +0300629
630// GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier
631// GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier
632bool CanBeInvariantESSL3OrGreater(TQualifier qualifier)
633{
634 return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut ||
635 IsBuiltinOutputVariable(qualifier);
636}
637
638bool IsBuiltinOutputVariable(TQualifier qualifier)
639{
640 switch (qualifier)
641 {
642 case EvqPosition:
643 case EvqPointSize:
644 case EvqFragDepth:
645 case EvqFragDepthEXT:
646 case EvqFragColor:
647 case EvqSecondaryFragColorEXT:
648 case EvqFragData:
649 case EvqSecondaryFragDataEXT:
650 return true;
651 default:
652 break;
653 }
654 return false;
655}
656
657bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
658{
659 switch (qualifier)
660 {
661 case EvqFragCoord:
662 case EvqPointCoord:
663 case EvqFrontFacing:
664 return true;
665 default:
666 break;
667 }
668 return false;
669}
670} // namespace sh