1 //
2 // Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
3 // Copyright (C) 2012-2016 LunarG, Inc.
4 // Copyright (C) 2017 ARM Limited.
5 // Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
6 //
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions
11 // are met:
12 //
13 // Redistributions of source code must retain the above copyright
14 // notice, this list of conditions and the following disclaimer.
15 //
16 // Redistributions in binary form must reproduce the above
17 // copyright notice, this list of conditions and the following
18 // disclaimer in the documentation and/or other materials provided
19 // with the distribution.
20 //
21 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
22 // contributors may be used to endorse or promote products derived
23 // from this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 // POSSIBILITY OF SUCH DAMAGE.
37 //
38
39 //
40 // Definition of the in-memory high-level intermediate representation
41 // of shaders. This is a tree that parser creates.
42 //
43 // Nodes in the tree are defined as a hierarchy of classes derived from
44 // TIntermNode. Each is a node in a tree. There is no preset branching factor;
45 // each node can have it's own type of list of children.
46 //
47
48 #ifndef __INTERMEDIATE_H
49 #define __INTERMEDIATE_H
50
51 #if defined(_MSC_VER) && _MSC_VER >= 1900
52 #pragma warning(disable : 4464) // relative include path contains '..'
53 #pragma warning(disable : 5026) // 'glslang::TIntermUnary': move constructor was implicitly defined as deleted
54 #endif
55
56 #include "../Include/Common.h"
57 #include "../Include/Types.h"
58 #include "../Include/ConstantUnion.h"
59
60 namespace glslang {
61
62 class TIntermediate;
63
64 //
65 // Operators used by the high-level (parse tree) representation.
66 //
67 enum TOperator {
68 EOpNull, // if in a node, should only mean a node is still being built
69 EOpSequence, // denotes a list of statements, or parameters, etc.
70 EOpScope, // Used by debugging to denote a scoped list of statements
71 EOpLinkerObjects, // for aggregate node of objects the linker may need, if not reference by the rest of the AST
72 EOpFunctionCall,
73 EOpFunction, // For function definition
74 EOpParameters, // an aggregate listing the parameters to a function
75 #ifndef GLSLANG_WEB
76 EOpSpirvInst,
77 #endif
78
79 //
80 // Unary operators
81 //
82
83 EOpNegative,
84 EOpLogicalNot,
85 EOpVectorLogicalNot,
86 EOpBitwiseNot,
87
88 EOpPostIncrement,
89 EOpPostDecrement,
90 EOpPreIncrement,
91 EOpPreDecrement,
92
93 EOpCopyObject,
94
95 EOpDeclare, // Used by debugging to force declaration of variable in correct scope
96
97 // (u)int* -> bool
98 EOpConvInt8ToBool,
99 EOpConvUint8ToBool,
100 EOpConvInt16ToBool,
101 EOpConvUint16ToBool,
102 EOpConvIntToBool,
103 EOpConvUintToBool,
104 EOpConvInt64ToBool,
105 EOpConvUint64ToBool,
106
107 // float* -> bool
108 EOpConvFloat16ToBool,
109 EOpConvFloatToBool,
110 EOpConvDoubleToBool,
111
112 // bool -> (u)int*
113 EOpConvBoolToInt8,
114 EOpConvBoolToUint8,
115 EOpConvBoolToInt16,
116 EOpConvBoolToUint16,
117 EOpConvBoolToInt,
118 EOpConvBoolToUint,
119 EOpConvBoolToInt64,
120 EOpConvBoolToUint64,
121
122 // bool -> float*
123 EOpConvBoolToFloat16,
124 EOpConvBoolToFloat,
125 EOpConvBoolToDouble,
126
127 // int8_t -> (u)int*
128 EOpConvInt8ToInt16,
129 EOpConvInt8ToInt,
130 EOpConvInt8ToInt64,
131 EOpConvInt8ToUint8,
132 EOpConvInt8ToUint16,
133 EOpConvInt8ToUint,
134 EOpConvInt8ToUint64,
135
136 // uint8_t -> (u)int*
137 EOpConvUint8ToInt8,
138 EOpConvUint8ToInt16,
139 EOpConvUint8ToInt,
140 EOpConvUint8ToInt64,
141 EOpConvUint8ToUint16,
142 EOpConvUint8ToUint,
143 EOpConvUint8ToUint64,
144
145 // int8_t -> float*
146 EOpConvInt8ToFloat16,
147 EOpConvInt8ToFloat,
148 EOpConvInt8ToDouble,
149
150 // uint8_t -> float*
151 EOpConvUint8ToFloat16,
152 EOpConvUint8ToFloat,
153 EOpConvUint8ToDouble,
154
155 // int16_t -> (u)int*
156 EOpConvInt16ToInt8,
157 EOpConvInt16ToInt,
158 EOpConvInt16ToInt64,
159 EOpConvInt16ToUint8,
160 EOpConvInt16ToUint16,
161 EOpConvInt16ToUint,
162 EOpConvInt16ToUint64,
163
164 // uint16_t -> (u)int*
165 EOpConvUint16ToInt8,
166 EOpConvUint16ToInt16,
167 EOpConvUint16ToInt,
168 EOpConvUint16ToInt64,
169 EOpConvUint16ToUint8,
170 EOpConvUint16ToUint,
171 EOpConvUint16ToUint64,
172
173 // int16_t -> float*
174 EOpConvInt16ToFloat16,
175 EOpConvInt16ToFloat,
176 EOpConvInt16ToDouble,
177
178 // uint16_t -> float*
179 EOpConvUint16ToFloat16,
180 EOpConvUint16ToFloat,
181 EOpConvUint16ToDouble,
182
183 // int32_t -> (u)int*
184 EOpConvIntToInt8,
185 EOpConvIntToInt16,
186 EOpConvIntToInt64,
187 EOpConvIntToUint8,
188 EOpConvIntToUint16,
189 EOpConvIntToUint,
190 EOpConvIntToUint64,
191
192 // uint32_t -> (u)int*
193 EOpConvUintToInt8,
194 EOpConvUintToInt16,
195 EOpConvUintToInt,
196 EOpConvUintToInt64,
197 EOpConvUintToUint8,
198 EOpConvUintToUint16,
199 EOpConvUintToUint64,
200
201 // int32_t -> float*
202 EOpConvIntToFloat16,
203 EOpConvIntToFloat,
204 EOpConvIntToDouble,
205
206 // uint32_t -> float*
207 EOpConvUintToFloat16,
208 EOpConvUintToFloat,
209 EOpConvUintToDouble,
210
211 // int64_t -> (u)int*
212 EOpConvInt64ToInt8,
213 EOpConvInt64ToInt16,
214 EOpConvInt64ToInt,
215 EOpConvInt64ToUint8,
216 EOpConvInt64ToUint16,
217 EOpConvInt64ToUint,
218 EOpConvInt64ToUint64,
219
220 // uint64_t -> (u)int*
221 EOpConvUint64ToInt8,
222 EOpConvUint64ToInt16,
223 EOpConvUint64ToInt,
224 EOpConvUint64ToInt64,
225 EOpConvUint64ToUint8,
226 EOpConvUint64ToUint16,
227 EOpConvUint64ToUint,
228
229 // int64_t -> float*
230 EOpConvInt64ToFloat16,
231 EOpConvInt64ToFloat,
232 EOpConvInt64ToDouble,
233
234 // uint64_t -> float*
235 EOpConvUint64ToFloat16,
236 EOpConvUint64ToFloat,
237 EOpConvUint64ToDouble,
238
239 // float16_t -> (u)int*
240 EOpConvFloat16ToInt8,
241 EOpConvFloat16ToInt16,
242 EOpConvFloat16ToInt,
243 EOpConvFloat16ToInt64,
244 EOpConvFloat16ToUint8,
245 EOpConvFloat16ToUint16,
246 EOpConvFloat16ToUint,
247 EOpConvFloat16ToUint64,
248
249 // float16_t -> float*
250 EOpConvFloat16ToFloat,
251 EOpConvFloat16ToDouble,
252
253 // float -> (u)int*
254 EOpConvFloatToInt8,
255 EOpConvFloatToInt16,
256 EOpConvFloatToInt,
257 EOpConvFloatToInt64,
258 EOpConvFloatToUint8,
259 EOpConvFloatToUint16,
260 EOpConvFloatToUint,
261 EOpConvFloatToUint64,
262
263 // float -> float*
264 EOpConvFloatToFloat16,
265 EOpConvFloatToDouble,
266
267 // float64 _t-> (u)int*
268 EOpConvDoubleToInt8,
269 EOpConvDoubleToInt16,
270 EOpConvDoubleToInt,
271 EOpConvDoubleToInt64,
272 EOpConvDoubleToUint8,
273 EOpConvDoubleToUint16,
274 EOpConvDoubleToUint,
275 EOpConvDoubleToUint64,
276
277 // float64_t -> float*
278 EOpConvDoubleToFloat16,
279 EOpConvDoubleToFloat,
280
281 // uint64_t <-> pointer
282 EOpConvUint64ToPtr,
283 EOpConvPtrToUint64,
284
285 // uvec2 <-> pointer
286 EOpConvUvec2ToPtr,
287 EOpConvPtrToUvec2,
288
289 // uint64_t -> accelerationStructureEXT
290 EOpConvUint64ToAccStruct,
291
292 // uvec2 -> accelerationStructureEXT
293 EOpConvUvec2ToAccStruct,
294
295 //
296 // binary operations
297 //
298
299 EOpAdd,
300 EOpSub,
301 EOpMul,
302 EOpDiv,
303 EOpMod,
304 EOpRightShift,
305 EOpLeftShift,
306 EOpAnd,
307 EOpInclusiveOr,
308 EOpExclusiveOr,
309 EOpEqual,
310 EOpNotEqual,
311 EOpVectorEqual,
312 EOpVectorNotEqual,
313 EOpLessThan,
314 EOpGreaterThan,
315 EOpLessThanEqual,
316 EOpGreaterThanEqual,
317 EOpComma,
318
319 EOpVectorTimesScalar,
320 EOpVectorTimesMatrix,
321 EOpMatrixTimesVector,
322 EOpMatrixTimesScalar,
323
324 EOpLogicalOr,
325 EOpLogicalXor,
326 EOpLogicalAnd,
327
328 EOpIndexDirect,
329 EOpIndexIndirect,
330 EOpIndexDirectStruct,
331
332 EOpVectorSwizzle,
333
334 EOpMethod,
335 EOpScoping,
336
337 //
338 // Built-in functions mapped to operators
339 //
340
341 EOpRadians,
342 EOpDegrees,
343 EOpSin,
344 EOpCos,
345 EOpTan,
346 EOpAsin,
347 EOpAcos,
348 EOpAtan,
349 EOpSinh,
350 EOpCosh,
351 EOpTanh,
352 EOpAsinh,
353 EOpAcosh,
354 EOpAtanh,
355
356 EOpPow,
357 EOpExp,
358 EOpLog,
359 EOpExp2,
360 EOpLog2,
361 EOpSqrt,
362 EOpInverseSqrt,
363
364 EOpAbs,
365 EOpSign,
366 EOpFloor,
367 EOpTrunc,
368 EOpRound,
369 EOpRoundEven,
370 EOpCeil,
371 EOpFract,
372 EOpModf,
373 EOpMin,
374 EOpMax,
375 EOpClamp,
376 EOpMix,
377 EOpStep,
378 EOpSmoothStep,
379
380 EOpIsNan,
381 EOpIsInf,
382
383 EOpFma,
384
385 EOpFrexp,
386 EOpLdexp,
387
388 EOpFloatBitsToInt,
389 EOpFloatBitsToUint,
390 EOpIntBitsToFloat,
391 EOpUintBitsToFloat,
392 EOpDoubleBitsToInt64,
393 EOpDoubleBitsToUint64,
394 EOpInt64BitsToDouble,
395 EOpUint64BitsToDouble,
396 EOpFloat16BitsToInt16,
397 EOpFloat16BitsToUint16,
398 EOpInt16BitsToFloat16,
399 EOpUint16BitsToFloat16,
400 EOpPackSnorm2x16,
401 EOpUnpackSnorm2x16,
402 EOpPackUnorm2x16,
403 EOpUnpackUnorm2x16,
404 EOpPackSnorm4x8,
405 EOpUnpackSnorm4x8,
406 EOpPackUnorm4x8,
407 EOpUnpackUnorm4x8,
408 EOpPackHalf2x16,
409 EOpUnpackHalf2x16,
410 EOpPackDouble2x32,
411 EOpUnpackDouble2x32,
412 EOpPackInt2x32,
413 EOpUnpackInt2x32,
414 EOpPackUint2x32,
415 EOpUnpackUint2x32,
416 EOpPackFloat2x16,
417 EOpUnpackFloat2x16,
418 EOpPackInt2x16,
419 EOpUnpackInt2x16,
420 EOpPackUint2x16,
421 EOpUnpackUint2x16,
422 EOpPackInt4x16,
423 EOpUnpackInt4x16,
424 EOpPackUint4x16,
425 EOpUnpackUint4x16,
426 EOpPack16,
427 EOpPack32,
428 EOpPack64,
429 EOpUnpack32,
430 EOpUnpack16,
431 EOpUnpack8,
432
433 EOpLength,
434 EOpDistance,
435 EOpDot,
436 EOpCross,
437 EOpNormalize,
438 EOpFaceForward,
439 EOpReflect,
440 EOpRefract,
441
442 EOpMin3,
443 EOpMax3,
444 EOpMid3,
445
446 EOpDPdx, // Fragment only
447 EOpDPdy, // Fragment only
448 EOpFwidth, // Fragment only
449 EOpDPdxFine, // Fragment only
450 EOpDPdyFine, // Fragment only
451 EOpFwidthFine, // Fragment only
452 EOpDPdxCoarse, // Fragment only
453 EOpDPdyCoarse, // Fragment only
454 EOpFwidthCoarse, // Fragment only
455
456 EOpInterpolateAtCentroid, // Fragment only
457 EOpInterpolateAtSample, // Fragment only
458 EOpInterpolateAtOffset, // Fragment only
459 EOpInterpolateAtVertex,
460
461 EOpMatrixTimesMatrix,
462 EOpOuterProduct,
463 EOpDeterminant,
464 EOpMatrixInverse,
465 EOpTranspose,
466
467 EOpFtransform,
468
469 EOpNoise,
470
471 EOpEmitVertex, // geometry only
472 EOpEndPrimitive, // geometry only
473 EOpEmitStreamVertex, // geometry only
474 EOpEndStreamPrimitive, // geometry only
475
476 EOpBarrier,
477 EOpMemoryBarrier,
478 EOpMemoryBarrierAtomicCounter,
479 EOpMemoryBarrierBuffer,
480 EOpMemoryBarrierImage,
481 EOpMemoryBarrierShared, // compute only
482 EOpGroupMemoryBarrier, // compute only
483
484 EOpBallot,
485 EOpReadInvocation,
486 EOpReadFirstInvocation,
487
488 EOpAnyInvocation,
489 EOpAllInvocations,
490 EOpAllInvocationsEqual,
491
492 EOpSubgroupGuardStart,
493 EOpSubgroupBarrier,
494 EOpSubgroupMemoryBarrier,
495 EOpSubgroupMemoryBarrierBuffer,
496 EOpSubgroupMemoryBarrierImage,
497 EOpSubgroupMemoryBarrierShared, // compute only
498 EOpSubgroupElect,
499 EOpSubgroupAll,
500 EOpSubgroupAny,
501 EOpSubgroupAllEqual,
502 EOpSubgroupBroadcast,
503 EOpSubgroupBroadcastFirst,
504 EOpSubgroupBallot,
505 EOpSubgroupInverseBallot,
506 EOpSubgroupBallotBitExtract,
507 EOpSubgroupBallotBitCount,
508 EOpSubgroupBallotInclusiveBitCount,
509 EOpSubgroupBallotExclusiveBitCount,
510 EOpSubgroupBallotFindLSB,
511 EOpSubgroupBallotFindMSB,
512 EOpSubgroupShuffle,
513 EOpSubgroupShuffleXor,
514 EOpSubgroupShuffleUp,
515 EOpSubgroupShuffleDown,
516 EOpSubgroupAdd,
517 EOpSubgroupMul,
518 EOpSubgroupMin,
519 EOpSubgroupMax,
520 EOpSubgroupAnd,
521 EOpSubgroupOr,
522 EOpSubgroupXor,
523 EOpSubgroupInclusiveAdd,
524 EOpSubgroupInclusiveMul,
525 EOpSubgroupInclusiveMin,
526 EOpSubgroupInclusiveMax,
527 EOpSubgroupInclusiveAnd,
528 EOpSubgroupInclusiveOr,
529 EOpSubgroupInclusiveXor,
530 EOpSubgroupExclusiveAdd,
531 EOpSubgroupExclusiveMul,
532 EOpSubgroupExclusiveMin,
533 EOpSubgroupExclusiveMax,
534 EOpSubgroupExclusiveAnd,
535 EOpSubgroupExclusiveOr,
536 EOpSubgroupExclusiveXor,
537 EOpSubgroupClusteredAdd,
538 EOpSubgroupClusteredMul,
539 EOpSubgroupClusteredMin,
540 EOpSubgroupClusteredMax,
541 EOpSubgroupClusteredAnd,
542 EOpSubgroupClusteredOr,
543 EOpSubgroupClusteredXor,
544 EOpSubgroupQuadBroadcast,
545 EOpSubgroupQuadSwapHorizontal,
546 EOpSubgroupQuadSwapVertical,
547 EOpSubgroupQuadSwapDiagonal,
548
549 EOpSubgroupPartition,
550 EOpSubgroupPartitionedAdd,
551 EOpSubgroupPartitionedMul,
552 EOpSubgroupPartitionedMin,
553 EOpSubgroupPartitionedMax,
554 EOpSubgroupPartitionedAnd,
555 EOpSubgroupPartitionedOr,
556 EOpSubgroupPartitionedXor,
557 EOpSubgroupPartitionedInclusiveAdd,
558 EOpSubgroupPartitionedInclusiveMul,
559 EOpSubgroupPartitionedInclusiveMin,
560 EOpSubgroupPartitionedInclusiveMax,
561 EOpSubgroupPartitionedInclusiveAnd,
562 EOpSubgroupPartitionedInclusiveOr,
563 EOpSubgroupPartitionedInclusiveXor,
564 EOpSubgroupPartitionedExclusiveAdd,
565 EOpSubgroupPartitionedExclusiveMul,
566 EOpSubgroupPartitionedExclusiveMin,
567 EOpSubgroupPartitionedExclusiveMax,
568 EOpSubgroupPartitionedExclusiveAnd,
569 EOpSubgroupPartitionedExclusiveOr,
570 EOpSubgroupPartitionedExclusiveXor,
571
572 EOpSubgroupGuardStop,
573
574 EOpMinInvocations,
575 EOpMaxInvocations,
576 EOpAddInvocations,
577 EOpMinInvocationsNonUniform,
578 EOpMaxInvocationsNonUniform,
579 EOpAddInvocationsNonUniform,
580 EOpMinInvocationsInclusiveScan,
581 EOpMaxInvocationsInclusiveScan,
582 EOpAddInvocationsInclusiveScan,
583 EOpMinInvocationsInclusiveScanNonUniform,
584 EOpMaxInvocationsInclusiveScanNonUniform,
585 EOpAddInvocationsInclusiveScanNonUniform,
586 EOpMinInvocationsExclusiveScan,
587 EOpMaxInvocationsExclusiveScan,
588 EOpAddInvocationsExclusiveScan,
589 EOpMinInvocationsExclusiveScanNonUniform,
590 EOpMaxInvocationsExclusiveScanNonUniform,
591 EOpAddInvocationsExclusiveScanNonUniform,
592 EOpSwizzleInvocations,
593 EOpSwizzleInvocationsMasked,
594 EOpWriteInvocation,
595 EOpMbcnt,
596
597 EOpCubeFaceIndex,
598 EOpCubeFaceCoord,
599 EOpTime,
600
601 EOpAtomicAdd,
602 EOpAtomicSubtract,
603 EOpAtomicMin,
604 EOpAtomicMax,
605 EOpAtomicAnd,
606 EOpAtomicOr,
607 EOpAtomicXor,
608 EOpAtomicExchange,
609 EOpAtomicCompSwap,
610 EOpAtomicLoad,
611 EOpAtomicStore,
612
613 EOpAtomicCounterIncrement, // results in pre-increment value
614 EOpAtomicCounterDecrement, // results in post-decrement value
615 EOpAtomicCounter,
616 EOpAtomicCounterAdd,
617 EOpAtomicCounterSubtract,
618 EOpAtomicCounterMin,
619 EOpAtomicCounterMax,
620 EOpAtomicCounterAnd,
621 EOpAtomicCounterOr,
622 EOpAtomicCounterXor,
623 EOpAtomicCounterExchange,
624 EOpAtomicCounterCompSwap,
625
626 EOpAny,
627 EOpAll,
628
629 EOpCooperativeMatrixLoad,
630 EOpCooperativeMatrixStore,
631 EOpCooperativeMatrixMulAdd,
632
633 EOpBeginInvocationInterlock, // Fragment only
634 EOpEndInvocationInterlock, // Fragment only
635
636 EOpIsHelperInvocation,
637
638 EOpDebugPrintf,
639
640 //
641 // Branch
642 //
643
644 EOpKill, // Fragment only
645 EOpTerminateInvocation, // Fragment only
646 EOpDemote, // Fragment only
647 EOpTerminateRayKHR, // Any-hit only
648 EOpIgnoreIntersectionKHR, // Any-hit only
649 EOpReturn,
650 EOpBreak,
651 EOpContinue,
652 EOpCase,
653 EOpDefault,
654
655 //
656 // Constructors
657 //
658
659 EOpConstructGuardStart,
660 EOpConstructInt, // these first scalar forms also identify what implicit conversion is needed
661 EOpConstructUint,
662 EOpConstructInt8,
663 EOpConstructUint8,
664 EOpConstructInt16,
665 EOpConstructUint16,
666 EOpConstructInt64,
667 EOpConstructUint64,
668 EOpConstructBool,
669 EOpConstructFloat,
670 EOpConstructDouble,
671 // Keep vector and matrix constructors in a consistent relative order for
672 // TParseContext::constructBuiltIn, which converts between 8/16/32 bit
673 // vector constructors
674 EOpConstructVec2,
675 EOpConstructVec3,
676 EOpConstructVec4,
677 EOpConstructMat2x2,
678 EOpConstructMat2x3,
679 EOpConstructMat2x4,
680 EOpConstructMat3x2,
681 EOpConstructMat3x3,
682 EOpConstructMat3x4,
683 EOpConstructMat4x2,
684 EOpConstructMat4x3,
685 EOpConstructMat4x4,
686 EOpConstructDVec2,
687 EOpConstructDVec3,
688 EOpConstructDVec4,
689 EOpConstructBVec2,
690 EOpConstructBVec3,
691 EOpConstructBVec4,
692 EOpConstructI8Vec2,
693 EOpConstructI8Vec3,
694 EOpConstructI8Vec4,
695 EOpConstructU8Vec2,
696 EOpConstructU8Vec3,
697 EOpConstructU8Vec4,
698 EOpConstructI16Vec2,
699 EOpConstructI16Vec3,
700 EOpConstructI16Vec4,
701 EOpConstructU16Vec2,
702 EOpConstructU16Vec3,
703 EOpConstructU16Vec4,
704 EOpConstructIVec2,
705 EOpConstructIVec3,
706 EOpConstructIVec4,
707 EOpConstructUVec2,
708 EOpConstructUVec3,
709 EOpConstructUVec4,
710 EOpConstructI64Vec2,
711 EOpConstructI64Vec3,
712 EOpConstructI64Vec4,
713 EOpConstructU64Vec2,
714 EOpConstructU64Vec3,
715 EOpConstructU64Vec4,
716 EOpConstructDMat2x2,
717 EOpConstructDMat2x3,
718 EOpConstructDMat2x4,
719 EOpConstructDMat3x2,
720 EOpConstructDMat3x3,
721 EOpConstructDMat3x4,
722 EOpConstructDMat4x2,
723 EOpConstructDMat4x3,
724 EOpConstructDMat4x4,
725 EOpConstructIMat2x2,
726 EOpConstructIMat2x3,
727 EOpConstructIMat2x4,
728 EOpConstructIMat3x2,
729 EOpConstructIMat3x3,
730 EOpConstructIMat3x4,
731 EOpConstructIMat4x2,
732 EOpConstructIMat4x3,
733 EOpConstructIMat4x4,
734 EOpConstructUMat2x2,
735 EOpConstructUMat2x3,
736 EOpConstructUMat2x4,
737 EOpConstructUMat3x2,
738 EOpConstructUMat3x3,
739 EOpConstructUMat3x4,
740 EOpConstructUMat4x2,
741 EOpConstructUMat4x3,
742 EOpConstructUMat4x4,
743 EOpConstructBMat2x2,
744 EOpConstructBMat2x3,
745 EOpConstructBMat2x4,
746 EOpConstructBMat3x2,
747 EOpConstructBMat3x3,
748 EOpConstructBMat3x4,
749 EOpConstructBMat4x2,
750 EOpConstructBMat4x3,
751 EOpConstructBMat4x4,
752 EOpConstructFloat16,
753 EOpConstructF16Vec2,
754 EOpConstructF16Vec3,
755 EOpConstructF16Vec4,
756 EOpConstructF16Mat2x2,
757 EOpConstructF16Mat2x3,
758 EOpConstructF16Mat2x4,
759 EOpConstructF16Mat3x2,
760 EOpConstructF16Mat3x3,
761 EOpConstructF16Mat3x4,
762 EOpConstructF16Mat4x2,
763 EOpConstructF16Mat4x3,
764 EOpConstructF16Mat4x4,
765 EOpConstructStruct,
766 EOpConstructTextureSampler,
767 EOpConstructNonuniform, // expected to be transformed away, not present in final AST
768 EOpConstructReference,
769 EOpConstructCooperativeMatrix,
770 EOpConstructAccStruct,
771 EOpConstructGuardEnd,
772
773 //
774 // moves
775 //
776
777 EOpAssign,
778 EOpAddAssign,
779 EOpSubAssign,
780 EOpMulAssign,
781 EOpVectorTimesMatrixAssign,
782 EOpVectorTimesScalarAssign,
783 EOpMatrixTimesScalarAssign,
784 EOpMatrixTimesMatrixAssign,
785 EOpDivAssign,
786 EOpModAssign,
787 EOpAndAssign,
788 EOpInclusiveOrAssign,
789 EOpExclusiveOrAssign,
790 EOpLeftShiftAssign,
791 EOpRightShiftAssign,
792
793 //
794 // Array operators
795 //
796
797 // Can apply to arrays, vectors, or matrices.
798 // Can be decomposed to a constant at compile time, but this does not always happen,
799 // due to link-time effects. So, consumer can expect either a link-time sized or
800 // run-time sized array.
801 EOpArrayLength,
802
803 //
804 // Image operations
805 //
806
807 EOpImageGuardBegin,
808
809 EOpImageQuerySize,
810 EOpImageQuerySamples,
811 EOpImageLoad,
812 EOpImageStore,
813 EOpImageLoadLod,
814 EOpImageStoreLod,
815 EOpImageAtomicAdd,
816 EOpImageAtomicMin,
817 EOpImageAtomicMax,
818 EOpImageAtomicAnd,
819 EOpImageAtomicOr,
820 EOpImageAtomicXor,
821 EOpImageAtomicExchange,
822 EOpImageAtomicCompSwap,
823 EOpImageAtomicLoad,
824 EOpImageAtomicStore,
825
826 EOpSubpassLoad,
827 EOpSubpassLoadMS,
828 EOpSparseImageLoad,
829 EOpSparseImageLoadLod,
830
831 EOpImageGuardEnd,
832
833 //
834 // Texture operations
835 //
836
837 EOpTextureGuardBegin,
838
839 EOpTextureQuerySize,
840 EOpTextureQueryLod,
841 EOpTextureQueryLevels,
842 EOpTextureQuerySamples,
843
844 EOpSamplingGuardBegin,
845
846 EOpTexture,
847 EOpTextureProj,
848 EOpTextureLod,
849 EOpTextureOffset,
850 EOpTextureFetch,
851 EOpTextureFetchOffset,
852 EOpTextureProjOffset,
853 EOpTextureLodOffset,
854 EOpTextureProjLod,
855 EOpTextureProjLodOffset,
856 EOpTextureGrad,
857 EOpTextureGradOffset,
858 EOpTextureProjGrad,
859 EOpTextureProjGradOffset,
860 EOpTextureGather,
861 EOpTextureGatherOffset,
862 EOpTextureGatherOffsets,
863 EOpTextureClamp,
864 EOpTextureOffsetClamp,
865 EOpTextureGradClamp,
866 EOpTextureGradOffsetClamp,
867 EOpTextureGatherLod,
868 EOpTextureGatherLodOffset,
869 EOpTextureGatherLodOffsets,
870 EOpFragmentMaskFetch,
871 EOpFragmentFetch,
872
873 EOpSparseTextureGuardBegin,
874
875 EOpSparseTexture,
876 EOpSparseTextureLod,
877 EOpSparseTextureOffset,
878 EOpSparseTextureFetch,
879 EOpSparseTextureFetchOffset,
880 EOpSparseTextureLodOffset,
881 EOpSparseTextureGrad,
882 EOpSparseTextureGradOffset,
883 EOpSparseTextureGather,
884 EOpSparseTextureGatherOffset,
885 EOpSparseTextureGatherOffsets,
886 EOpSparseTexelsResident,
887 EOpSparseTextureClamp,
888 EOpSparseTextureOffsetClamp,
889 EOpSparseTextureGradClamp,
890 EOpSparseTextureGradOffsetClamp,
891 EOpSparseTextureGatherLod,
892 EOpSparseTextureGatherLodOffset,
893 EOpSparseTextureGatherLodOffsets,
894
895 EOpSparseTextureGuardEnd,
896
897 EOpImageFootprintGuardBegin,
898 EOpImageSampleFootprintNV,
899 EOpImageSampleFootprintClampNV,
900 EOpImageSampleFootprintLodNV,
901 EOpImageSampleFootprintGradNV,
902 EOpImageSampleFootprintGradClampNV,
903 EOpImageFootprintGuardEnd,
904 EOpSamplingGuardEnd,
905 EOpTextureGuardEnd,
906
907 //
908 // Integer operations
909 //
910
911 EOpAddCarry,
912 EOpSubBorrow,
913 EOpUMulExtended,
914 EOpIMulExtended,
915 EOpBitfieldExtract,
916 EOpBitfieldInsert,
917 EOpBitFieldReverse,
918 EOpBitCount,
919 EOpFindLSB,
920 EOpFindMSB,
921
922 EOpCountLeadingZeros,
923 EOpCountTrailingZeros,
924 EOpAbsDifference,
925 EOpAddSaturate,
926 EOpSubSaturate,
927 EOpAverage,
928 EOpAverageRounded,
929 EOpMul32x16,
930
931 EOpTraceNV,
932 EOpTraceRayMotionNV,
933 EOpTraceKHR,
934 EOpReportIntersection,
935 EOpIgnoreIntersectionNV,
936 EOpTerminateRayNV,
937 EOpExecuteCallableNV,
938 EOpExecuteCallableKHR,
939 EOpWritePackedPrimitiveIndices4x8NV,
940 EOpEmitMeshTasksEXT,
941 EOpSetMeshOutputsEXT,
942
943 //
944 // GL_EXT_ray_query operations
945 //
946
947 EOpRayQueryInitialize,
948 EOpRayQueryTerminate,
949 EOpRayQueryGenerateIntersection,
950 EOpRayQueryConfirmIntersection,
951 EOpRayQueryProceed,
952 EOpRayQueryGetIntersectionType,
953 EOpRayQueryGetRayTMin,
954 EOpRayQueryGetRayFlags,
955 EOpRayQueryGetIntersectionT,
956 EOpRayQueryGetIntersectionInstanceCustomIndex,
957 EOpRayQueryGetIntersectionInstanceId,
958 EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset,
959 EOpRayQueryGetIntersectionGeometryIndex,
960 EOpRayQueryGetIntersectionPrimitiveIndex,
961 EOpRayQueryGetIntersectionBarycentrics,
962 EOpRayQueryGetIntersectionFrontFace,
963 EOpRayQueryGetIntersectionCandidateAABBOpaque,
964 EOpRayQueryGetIntersectionObjectRayDirection,
965 EOpRayQueryGetIntersectionObjectRayOrigin,
966 EOpRayQueryGetWorldRayDirection,
967 EOpRayQueryGetWorldRayOrigin,
968 EOpRayQueryGetIntersectionObjectToWorld,
969 EOpRayQueryGetIntersectionWorldToObject,
970
971 //
972 // HLSL operations
973 //
974
975 EOpClip, // discard if input value < 0
976 EOpIsFinite,
977 EOpLog10, // base 10 log
978 EOpRcp, // 1/x
979 EOpSaturate, // clamp from 0 to 1
980 EOpSinCos, // sin and cos in out parameters
981 EOpGenMul, // mul(x,y) on any of mat/vec/scalars
982 EOpDst, // x = 1, y=src0.y * src1.y, z=src0.z, w=src1.w
983 EOpInterlockedAdd, // atomic ops, but uses [optional] out arg instead of return
984 EOpInterlockedAnd, // ...
985 EOpInterlockedCompareExchange, // ...
986 EOpInterlockedCompareStore, // ...
987 EOpInterlockedExchange, // ...
988 EOpInterlockedMax, // ...
989 EOpInterlockedMin, // ...
990 EOpInterlockedOr, // ...
991 EOpInterlockedXor, // ...
992 EOpAllMemoryBarrierWithGroupSync, // memory barriers without non-hlsl AST equivalents
993 EOpDeviceMemoryBarrier, // ...
994 EOpDeviceMemoryBarrierWithGroupSync, // ...
995 EOpWorkgroupMemoryBarrier, // ...
996 EOpWorkgroupMemoryBarrierWithGroupSync, // ...
997 EOpEvaluateAttributeSnapped, // InterpolateAtOffset with int position on 16x16 grid
998 EOpF32tof16, // HLSL conversion: half of a PackHalf2x16
999 EOpF16tof32, // HLSL conversion: half of an UnpackHalf2x16
1000 EOpLit, // HLSL lighting coefficient vector
1001 EOpTextureBias, // HLSL texture bias: will be lowered to EOpTexture
1002 EOpAsDouble, // slightly different from EOpUint64BitsToDouble
1003 EOpD3DCOLORtoUBYTE4, // convert and swizzle 4-component color to UBYTE4 range
1004
1005 EOpMethodSample, // Texture object methods. These are translated to existing
1006 EOpMethodSampleBias, // AST methods, and exist to represent HLSL semantics until that
1007 EOpMethodSampleCmp, // translation is performed. See HlslParseContext::decomposeSampleMethods().
1008 EOpMethodSampleCmpLevelZero, // ...
1009 EOpMethodSampleGrad, // ...
1010 EOpMethodSampleLevel, // ...
1011 EOpMethodLoad, // ...
1012 EOpMethodGetDimensions, // ...
1013 EOpMethodGetSamplePosition, // ...
1014 EOpMethodGather, // ...
1015 EOpMethodCalculateLevelOfDetail, // ...
1016 EOpMethodCalculateLevelOfDetailUnclamped, // ...
1017
1018 // Load already defined above for textures
1019 EOpMethodLoad2, // Structure buffer object methods. These are translated to existing
1020 EOpMethodLoad3, // AST methods, and exist to represent HLSL semantics until that
1021 EOpMethodLoad4, // translation is performed. See HlslParseContext::decomposeSampleMethods().
1022 EOpMethodStore, // ...
1023 EOpMethodStore2, // ...
1024 EOpMethodStore3, // ...
1025 EOpMethodStore4, // ...
1026 EOpMethodIncrementCounter, // ...
1027 EOpMethodDecrementCounter, // ...
1028 // EOpMethodAppend is defined for geo shaders below
1029 EOpMethodConsume,
1030
1031 // SM5 texture methods
1032 EOpMethodGatherRed, // These are covered under the above EOpMethodSample comment about
1033 EOpMethodGatherGreen, // translation to existing AST opcodes. They exist temporarily
1034 EOpMethodGatherBlue, // because HLSL arguments are slightly different.
1035 EOpMethodGatherAlpha, // ...
1036 EOpMethodGatherCmp, // ...
1037 EOpMethodGatherCmpRed, // ...
1038 EOpMethodGatherCmpGreen, // ...
1039 EOpMethodGatherCmpBlue, // ...
1040 EOpMethodGatherCmpAlpha, // ...
1041
1042 // geometry methods
1043 EOpMethodAppend, // Geometry shader methods
1044 EOpMethodRestartStrip, // ...
1045
1046 // matrix
1047 EOpMatrixSwizzle, // select multiple matrix components (non-column)
1048
1049 // SM6 wave ops
1050 EOpWaveGetLaneCount, // Will decompose to gl_SubgroupSize.
1051 EOpWaveGetLaneIndex, // Will decompose to gl_SubgroupInvocationID.
1052 EOpWaveActiveCountBits, // Will decompose to subgroupBallotBitCount(subgroupBallot()).
1053 EOpWavePrefixCountBits, // Will decompose to subgroupBallotInclusiveBitCount(subgroupBallot()).
1054
1055 // Shader Clock Ops
1056 EOpReadClockSubgroupKHR,
1057 EOpReadClockDeviceKHR,
1058 };
1059
1060 class TIntermTraverser;
1061 class TIntermOperator;
1062 class TIntermAggregate;
1063 class TIntermUnary;
1064 class TIntermBinary;
1065 class TIntermConstantUnion;
1066 class TIntermSelection;
1067 class TIntermSwitch;
1068 class TIntermBranch;
1069 class TIntermTyped;
1070 class TIntermMethod;
1071 class TIntermSymbol;
1072 class TIntermLoop;
1073
1074 } // end namespace glslang
1075
1076 //
1077 // Base class for the tree nodes
1078 //
1079 // (Put outside the glslang namespace, as it's used as part of the external interface.)
1080 //
1081 class TIntermNode {
1082 public:
POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator ())1083 POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
1084
1085 TIntermNode() { loc.init(); }
getLoc()1086 virtual const glslang::TSourceLoc& getLoc() const { return loc; }
setLoc(const glslang::TSourceLoc & l)1087 virtual void setLoc(const glslang::TSourceLoc& l) { loc = l; }
1088 virtual void traverse(glslang::TIntermTraverser*) = 0;
getAsTyped()1089 virtual glslang::TIntermTyped* getAsTyped() { return nullptr; }
getAsOperator()1090 virtual glslang::TIntermOperator* getAsOperator() { return nullptr; }
getAsConstantUnion()1091 virtual glslang::TIntermConstantUnion* getAsConstantUnion() { return nullptr; }
getAsAggregate()1092 virtual glslang::TIntermAggregate* getAsAggregate() { return nullptr; }
getAsUnaryNode()1093 virtual glslang::TIntermUnary* getAsUnaryNode() { return nullptr; }
getAsBinaryNode()1094 virtual glslang::TIntermBinary* getAsBinaryNode() { return nullptr; }
getAsSelectionNode()1095 virtual glslang::TIntermSelection* getAsSelectionNode() { return nullptr; }
getAsSwitchNode()1096 virtual glslang::TIntermSwitch* getAsSwitchNode() { return nullptr; }
getAsMethodNode()1097 virtual glslang::TIntermMethod* getAsMethodNode() { return nullptr; }
getAsSymbolNode()1098 virtual glslang::TIntermSymbol* getAsSymbolNode() { return nullptr; }
getAsBranchNode()1099 virtual glslang::TIntermBranch* getAsBranchNode() { return nullptr; }
getAsLoopNode()1100 virtual glslang::TIntermLoop* getAsLoopNode() { return nullptr; }
1101
getAsTyped()1102 virtual const glslang::TIntermTyped* getAsTyped() const { return nullptr; }
getAsOperator()1103 virtual const glslang::TIntermOperator* getAsOperator() const { return nullptr; }
getAsConstantUnion()1104 virtual const glslang::TIntermConstantUnion* getAsConstantUnion() const { return nullptr; }
getAsAggregate()1105 virtual const glslang::TIntermAggregate* getAsAggregate() const { return nullptr; }
getAsUnaryNode()1106 virtual const glslang::TIntermUnary* getAsUnaryNode() const { return nullptr; }
getAsBinaryNode()1107 virtual const glslang::TIntermBinary* getAsBinaryNode() const { return nullptr; }
getAsSelectionNode()1108 virtual const glslang::TIntermSelection* getAsSelectionNode() const { return nullptr; }
getAsSwitchNode()1109 virtual const glslang::TIntermSwitch* getAsSwitchNode() const { return nullptr; }
getAsMethodNode()1110 virtual const glslang::TIntermMethod* getAsMethodNode() const { return nullptr; }
getAsSymbolNode()1111 virtual const glslang::TIntermSymbol* getAsSymbolNode() const { return nullptr; }
getAsBranchNode()1112 virtual const glslang::TIntermBranch* getAsBranchNode() const { return nullptr; }
getAsLoopNode()1113 virtual const glslang::TIntermLoop* getAsLoopNode() const { return nullptr; }
~TIntermNode()1114 virtual ~TIntermNode() { }
1115
1116 protected:
1117 TIntermNode(const TIntermNode&);
1118 TIntermNode& operator=(const TIntermNode&);
1119 glslang::TSourceLoc loc;
1120 };
1121
1122 namespace glslang {
1123
1124 //
1125 // This is just to help yacc.
1126 //
1127 struct TIntermNodePair {
1128 TIntermNode* node1;
1129 TIntermNode* node2;
1130 };
1131
1132 //
1133 // Intermediate class for nodes that have a type.
1134 //
1135 class TIntermTyped : public TIntermNode {
1136 public:
TIntermTyped(const TType & t)1137 TIntermTyped(const TType& t) { type.shallowCopy(t); }
TIntermTyped(TBasicType basicType)1138 TIntermTyped(TBasicType basicType) { TType bt(basicType); type.shallowCopy(bt); }
getAsTyped()1139 virtual TIntermTyped* getAsTyped() { return this; }
getAsTyped()1140 virtual const TIntermTyped* getAsTyped() const { return this; }
setType(const TType & t)1141 virtual void setType(const TType& t) { type.shallowCopy(t); }
getType()1142 virtual const TType& getType() const { return type; }
getWritableType()1143 virtual TType& getWritableType() { return type; }
1144
getBasicType()1145 virtual TBasicType getBasicType() const { return type.getBasicType(); }
getQualifier()1146 virtual TQualifier& getQualifier() { return type.getQualifier(); }
getQualifier()1147 virtual const TQualifier& getQualifier() const { return type.getQualifier(); }
getArraySizes()1148 virtual TArraySizes* getArraySizes() { return type.getArraySizes(); }
getArraySizes()1149 virtual const TArraySizes* getArraySizes() const { return type.getArraySizes(); }
1150 virtual void propagatePrecision(TPrecisionQualifier);
getVectorSize()1151 virtual int getVectorSize() const { return type.getVectorSize(); }
getMatrixCols()1152 virtual int getMatrixCols() const { return type.getMatrixCols(); }
getMatrixRows()1153 virtual int getMatrixRows() const { return type.getMatrixRows(); }
isMatrix()1154 virtual bool isMatrix() const { return type.isMatrix(); }
isArray()1155 virtual bool isArray() const { return type.isArray(); }
isVector()1156 virtual bool isVector() const { return type.isVector(); }
isScalar()1157 virtual bool isScalar() const { return type.isScalar(); }
isStruct()1158 virtual bool isStruct() const { return type.isStruct(); }
isFloatingDomain()1159 virtual bool isFloatingDomain() const { return type.isFloatingDomain(); }
isIntegerDomain()1160 virtual bool isIntegerDomain() const { return type.isIntegerDomain(); }
isAtomic()1161 bool isAtomic() const { return type.isAtomic(); }
isReference()1162 bool isReference() const { return type.isReference(); }
1163 TString getCompleteString(bool enhanced = false) const { return type.getCompleteString(enhanced); }
1164
1165 protected:
1166 TIntermTyped& operator=(const TIntermTyped&);
1167 TType type;
1168 };
1169
1170 //
1171 // Handle for, do-while, and while loops.
1172 //
1173 class TIntermLoop : public TIntermNode {
1174 public:
TIntermLoop(TIntermNode * aBody,TIntermTyped * aTest,TIntermTyped * aTerminal,bool testFirst)1175 TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) :
1176 body(aBody),
1177 test(aTest),
1178 terminal(aTerminal),
1179 first(testFirst),
1180 unroll(false),
1181 dontUnroll(false),
1182 dependency(0),
1183 minIterations(0),
1184 maxIterations(iterationsInfinite),
1185 iterationMultiple(1),
1186 peelCount(0),
1187 partialCount(0)
1188 { }
1189
getAsLoopNode()1190 virtual TIntermLoop* getAsLoopNode() { return this; }
getAsLoopNode()1191 virtual const TIntermLoop* getAsLoopNode() const { return this; }
1192 virtual void traverse(TIntermTraverser*);
getBody()1193 TIntermNode* getBody() const { return body; }
getTest()1194 TIntermTyped* getTest() const { return test; }
getTerminal()1195 TIntermTyped* getTerminal() const { return terminal; }
testFirst()1196 bool testFirst() const { return first; }
1197
setUnroll()1198 void setUnroll() { unroll = true; }
setDontUnroll()1199 void setDontUnroll() {
1200 dontUnroll = true;
1201 peelCount = 0;
1202 partialCount = 0;
1203 }
getUnroll()1204 bool getUnroll() const { return unroll; }
getDontUnroll()1205 bool getDontUnroll() const { return dontUnroll; }
1206
1207 static const unsigned int dependencyInfinite = 0xFFFFFFFF;
1208 static const unsigned int iterationsInfinite = 0xFFFFFFFF;
setLoopDependency(int d)1209 void setLoopDependency(int d) { dependency = d; }
getLoopDependency()1210 int getLoopDependency() const { return dependency; }
1211
setMinIterations(unsigned int v)1212 void setMinIterations(unsigned int v) { minIterations = v; }
getMinIterations()1213 unsigned int getMinIterations() const { return minIterations; }
setMaxIterations(unsigned int v)1214 void setMaxIterations(unsigned int v) { maxIterations = v; }
getMaxIterations()1215 unsigned int getMaxIterations() const { return maxIterations; }
setIterationMultiple(unsigned int v)1216 void setIterationMultiple(unsigned int v) { iterationMultiple = v; }
getIterationMultiple()1217 unsigned int getIterationMultiple() const { return iterationMultiple; }
setPeelCount(unsigned int v)1218 void setPeelCount(unsigned int v) {
1219 peelCount = v;
1220 dontUnroll = false;
1221 }
getPeelCount()1222 unsigned int getPeelCount() const { return peelCount; }
setPartialCount(unsigned int v)1223 void setPartialCount(unsigned int v) {
1224 partialCount = v;
1225 dontUnroll = false;
1226 }
getPartialCount()1227 unsigned int getPartialCount() const { return partialCount; }
1228
1229 protected:
1230 TIntermNode* body; // code to loop over
1231 TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops
1232 TIntermTyped* terminal; // exists for for-loops
1233 bool first; // true for while and for, not for do-while
1234 bool unroll; // true if unroll requested
1235 bool dontUnroll; // true if request to not unroll
1236 unsigned int dependency; // loop dependency hint; 0 means not set or unknown
1237 unsigned int minIterations; // as per the SPIR-V specification
1238 unsigned int maxIterations; // as per the SPIR-V specification
1239 unsigned int iterationMultiple; // as per the SPIR-V specification
1240 unsigned int peelCount; // as per the SPIR-V specification
1241 unsigned int partialCount; // as per the SPIR-V specification
1242 };
1243
1244 //
1245 // Handle case, break, continue, return, and kill.
1246 //
1247 class TIntermBranch : public TIntermNode {
1248 public:
TIntermBranch(TOperator op,TIntermTyped * e)1249 TIntermBranch(TOperator op, TIntermTyped* e) :
1250 flowOp(op),
1251 expression(e) { }
getAsBranchNode()1252 virtual TIntermBranch* getAsBranchNode() { return this; }
getAsBranchNode()1253 virtual const TIntermBranch* getAsBranchNode() const { return this; }
1254 virtual void traverse(TIntermTraverser*);
getFlowOp()1255 TOperator getFlowOp() const { return flowOp; }
getExpression()1256 TIntermTyped* getExpression() const { return expression; }
setExpression(TIntermTyped * pExpression)1257 void setExpression(TIntermTyped* pExpression) { expression = pExpression; }
1258 void updatePrecision(TPrecisionQualifier parentPrecision);
1259 protected:
1260 TOperator flowOp;
1261 TIntermTyped* expression;
1262 };
1263
1264 //
1265 // Represent method names before seeing their calling signature
1266 // or resolving them to operations. Just an expression as the base object
1267 // and a textural name.
1268 //
1269 class TIntermMethod : public TIntermTyped {
1270 public:
TIntermMethod(TIntermTyped * o,const TType & t,const TString & m)1271 TIntermMethod(TIntermTyped* o, const TType& t, const TString& m) : TIntermTyped(t), object(o), method(m) { }
getAsMethodNode()1272 virtual TIntermMethod* getAsMethodNode() { return this; }
getAsMethodNode()1273 virtual const TIntermMethod* getAsMethodNode() const { return this; }
getMethodName()1274 virtual const TString& getMethodName() const { return method; }
getObject()1275 virtual TIntermTyped* getObject() const { return object; }
1276 virtual void traverse(TIntermTraverser*);
1277 protected:
1278 TIntermTyped* object;
1279 TString method;
1280 };
1281
1282 //
1283 // Nodes that correspond to symbols or constants in the source code.
1284 //
1285 class TIntermSymbol : public TIntermTyped {
1286 public:
1287 // if symbol is initialized as symbol(sym), the memory comes from the pool allocator of sym. If sym comes from
1288 // per process threadPoolAllocator, then it causes increased memory usage per compile
1289 // it is essential to use "symbol = sym" to assign to symbol
TIntermSymbol(long long i,const TString & n,const TType & t)1290 TIntermSymbol(long long i, const TString& n, const TType& t)
1291 : TIntermTyped(t), id(i),
1292 #ifndef GLSLANG_WEB
1293 flattenSubset(-1),
1294 #endif
1295 constSubtree(nullptr)
1296 { name = n; }
getId()1297 virtual long long getId() const { return id; }
changeId(long long i)1298 virtual void changeId(long long i) { id = i; }
getName()1299 virtual const TString& getName() const { return name; }
1300 virtual void traverse(TIntermTraverser*);
getAsSymbolNode()1301 virtual TIntermSymbol* getAsSymbolNode() { return this; }
getAsSymbolNode()1302 virtual const TIntermSymbol* getAsSymbolNode() const { return this; }
setConstArray(const TConstUnionArray & c)1303 void setConstArray(const TConstUnionArray& c) { constArray = c; }
getConstArray()1304 const TConstUnionArray& getConstArray() const { return constArray; }
setConstSubtree(TIntermTyped * subtree)1305 void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
getConstSubtree()1306 TIntermTyped* getConstSubtree() const { return constSubtree; }
1307 #ifndef GLSLANG_WEB
setFlattenSubset(int subset)1308 void setFlattenSubset(int subset) { flattenSubset = subset; }
1309 virtual const TString& getAccessName() const;
1310
getFlattenSubset()1311 int getFlattenSubset() const { return flattenSubset; } // -1 means full object
1312 #endif
1313
1314 // This is meant for cases where a node has already been constructed, and
1315 // later on, it becomes necessary to switch to a different symbol.
switchId(long long newId)1316 virtual void switchId(long long newId) { id = newId; }
1317
1318 protected:
1319 long long id; // the unique id of the symbol this node represents
1320 #ifndef GLSLANG_WEB
1321 int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced
1322 #endif
1323 TString name; // the name of the symbol this node represents
1324 TConstUnionArray constArray; // if the symbol is a front-end compile-time constant, this is its value
1325 TIntermTyped* constSubtree;
1326 };
1327
1328 class TIntermConstantUnion : public TIntermTyped {
1329 public:
TIntermConstantUnion(const TConstUnionArray & ua,const TType & t)1330 TIntermConstantUnion(const TConstUnionArray& ua, const TType& t) : TIntermTyped(t), constArray(ua), literal(false) { }
getConstArray()1331 const TConstUnionArray& getConstArray() const { return constArray; }
getAsConstantUnion()1332 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
getAsConstantUnion()1333 virtual const TIntermConstantUnion* getAsConstantUnion() const { return this; }
1334 virtual void traverse(TIntermTraverser*);
1335 virtual TIntermTyped* fold(TOperator, const TIntermTyped*) const;
1336 virtual TIntermTyped* fold(TOperator, const TType&) const;
setLiteral()1337 void setLiteral() { literal = true; }
setExpression()1338 void setExpression() { literal = false; }
isLiteral()1339 bool isLiteral() const { return literal; }
1340
1341 protected:
1342 TIntermConstantUnion& operator=(const TIntermConstantUnion&);
1343
1344 const TConstUnionArray constArray;
1345 bool literal; // true if node represents a literal in the source code
1346 };
1347
1348 // Represent the independent aspects of a texturing TOperator
1349 struct TCrackedTextureOp {
1350 bool query;
1351 bool proj;
1352 bool lod;
1353 bool fetch;
1354 bool offset;
1355 bool offsets;
1356 bool gather;
1357 bool grad;
1358 bool subpass;
1359 bool lodClamp;
1360 bool fragMask;
1361 };
1362
1363 //
1364 // Intermediate class for node types that hold operators.
1365 //
1366 class TIntermOperator : public TIntermTyped {
1367 public:
getAsOperator()1368 virtual TIntermOperator* getAsOperator() { return this; }
getAsOperator()1369 virtual const TIntermOperator* getAsOperator() const { return this; }
getOp()1370 TOperator getOp() const { return op; }
setOp(TOperator newOp)1371 void setOp(TOperator newOp) { op = newOp; }
1372 bool modifiesState() const;
1373 bool isConstructor() const;
isTexture()1374 bool isTexture() const { return op > EOpTextureGuardBegin && op < EOpTextureGuardEnd; }
isSampling()1375 bool isSampling() const { return op > EOpSamplingGuardBegin && op < EOpSamplingGuardEnd; }
1376 #ifdef GLSLANG_WEB
isImage()1377 bool isImage() const { return false; }
isSparseTexture()1378 bool isSparseTexture() const { return false; }
isImageFootprint()1379 bool isImageFootprint() const { return false; }
isSparseImage()1380 bool isSparseImage() const { return false; }
isSubgroup()1381 bool isSubgroup() const { return false; }
1382 #else
isImage()1383 bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; }
isSparseTexture()1384 bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; }
isImageFootprint()1385 bool isImageFootprint() const { return op > EOpImageFootprintGuardBegin && op < EOpImageFootprintGuardEnd; }
isSparseImage()1386 bool isSparseImage() const { return op == EOpSparseImageLoad; }
isSubgroup()1387 bool isSubgroup() const { return op > EOpSubgroupGuardStart && op < EOpSubgroupGuardStop; }
1388 #endif
1389
setOperationPrecision(TPrecisionQualifier p)1390 void setOperationPrecision(TPrecisionQualifier p) { operationPrecision = p; }
getOperationPrecision()1391 TPrecisionQualifier getOperationPrecision() const { return operationPrecision != EpqNone ?
1392 operationPrecision :
1393 type.getQualifier().precision; }
getCompleteString()1394 TString getCompleteString() const
1395 {
1396 TString cs = type.getCompleteString();
1397 if (getOperationPrecision() != type.getQualifier().precision) {
1398 cs += ", operation at ";
1399 cs += GetPrecisionQualifierString(getOperationPrecision());
1400 }
1401
1402 return cs;
1403 }
1404
1405 // Crack the op into the individual dimensions of texturing operation.
crackTexture(TSampler sampler,TCrackedTextureOp & cracked)1406 void crackTexture(TSampler sampler, TCrackedTextureOp& cracked) const
1407 {
1408 cracked.query = false;
1409 cracked.proj = false;
1410 cracked.lod = false;
1411 cracked.fetch = false;
1412 cracked.offset = false;
1413 cracked.offsets = false;
1414 cracked.gather = false;
1415 cracked.grad = false;
1416 cracked.subpass = false;
1417 cracked.lodClamp = false;
1418 cracked.fragMask = false;
1419
1420 switch (op) {
1421 case EOpImageQuerySize:
1422 case EOpImageQuerySamples:
1423 case EOpTextureQuerySize:
1424 case EOpTextureQueryLod:
1425 case EOpTextureQueryLevels:
1426 case EOpTextureQuerySamples:
1427 case EOpSparseTexelsResident:
1428 cracked.query = true;
1429 break;
1430 case EOpTexture:
1431 case EOpSparseTexture:
1432 break;
1433 case EOpTextureProj:
1434 cracked.proj = true;
1435 break;
1436 case EOpTextureLod:
1437 case EOpSparseTextureLod:
1438 cracked.lod = true;
1439 break;
1440 case EOpTextureOffset:
1441 case EOpSparseTextureOffset:
1442 cracked.offset = true;
1443 break;
1444 case EOpTextureFetch:
1445 case EOpSparseTextureFetch:
1446 cracked.fetch = true;
1447 if (sampler.is1D() || (sampler.dim == Esd2D && ! sampler.isMultiSample()) || sampler.dim == Esd3D)
1448 cracked.lod = true;
1449 break;
1450 case EOpTextureFetchOffset:
1451 case EOpSparseTextureFetchOffset:
1452 cracked.fetch = true;
1453 cracked.offset = true;
1454 if (sampler.is1D() || (sampler.dim == Esd2D && ! sampler.isMultiSample()) || sampler.dim == Esd3D)
1455 cracked.lod = true;
1456 break;
1457 case EOpTextureProjOffset:
1458 cracked.offset = true;
1459 cracked.proj = true;
1460 break;
1461 case EOpTextureLodOffset:
1462 case EOpSparseTextureLodOffset:
1463 cracked.offset = true;
1464 cracked.lod = true;
1465 break;
1466 case EOpTextureProjLod:
1467 cracked.lod = true;
1468 cracked.proj = true;
1469 break;
1470 case EOpTextureProjLodOffset:
1471 cracked.offset = true;
1472 cracked.lod = true;
1473 cracked.proj = true;
1474 break;
1475 case EOpTextureGrad:
1476 case EOpSparseTextureGrad:
1477 cracked.grad = true;
1478 break;
1479 case EOpTextureGradOffset:
1480 case EOpSparseTextureGradOffset:
1481 cracked.grad = true;
1482 cracked.offset = true;
1483 break;
1484 case EOpTextureProjGrad:
1485 cracked.grad = true;
1486 cracked.proj = true;
1487 break;
1488 case EOpTextureProjGradOffset:
1489 cracked.grad = true;
1490 cracked.offset = true;
1491 cracked.proj = true;
1492 break;
1493 #ifndef GLSLANG_WEB
1494 case EOpTextureClamp:
1495 case EOpSparseTextureClamp:
1496 cracked.lodClamp = true;
1497 break;
1498 case EOpTextureOffsetClamp:
1499 case EOpSparseTextureOffsetClamp:
1500 cracked.offset = true;
1501 cracked.lodClamp = true;
1502 break;
1503 case EOpTextureGradClamp:
1504 case EOpSparseTextureGradClamp:
1505 cracked.grad = true;
1506 cracked.lodClamp = true;
1507 break;
1508 case EOpTextureGradOffsetClamp:
1509 case EOpSparseTextureGradOffsetClamp:
1510 cracked.grad = true;
1511 cracked.offset = true;
1512 cracked.lodClamp = true;
1513 break;
1514 case EOpTextureGather:
1515 case EOpSparseTextureGather:
1516 cracked.gather = true;
1517 break;
1518 case EOpTextureGatherOffset:
1519 case EOpSparseTextureGatherOffset:
1520 cracked.gather = true;
1521 cracked.offset = true;
1522 break;
1523 case EOpTextureGatherOffsets:
1524 case EOpSparseTextureGatherOffsets:
1525 cracked.gather = true;
1526 cracked.offsets = true;
1527 break;
1528 case EOpTextureGatherLod:
1529 case EOpSparseTextureGatherLod:
1530 cracked.gather = true;
1531 cracked.lod = true;
1532 break;
1533 case EOpTextureGatherLodOffset:
1534 case EOpSparseTextureGatherLodOffset:
1535 cracked.gather = true;
1536 cracked.offset = true;
1537 cracked.lod = true;
1538 break;
1539 case EOpTextureGatherLodOffsets:
1540 case EOpSparseTextureGatherLodOffsets:
1541 cracked.gather = true;
1542 cracked.offsets = true;
1543 cracked.lod = true;
1544 break;
1545 case EOpImageLoadLod:
1546 case EOpImageStoreLod:
1547 case EOpSparseImageLoadLod:
1548 cracked.lod = true;
1549 break;
1550 case EOpFragmentMaskFetch:
1551 cracked.subpass = sampler.dim == EsdSubpass;
1552 cracked.fragMask = true;
1553 break;
1554 case EOpFragmentFetch:
1555 cracked.subpass = sampler.dim == EsdSubpass;
1556 cracked.fragMask = true;
1557 break;
1558 case EOpImageSampleFootprintNV:
1559 break;
1560 case EOpImageSampleFootprintClampNV:
1561 cracked.lodClamp = true;
1562 break;
1563 case EOpImageSampleFootprintLodNV:
1564 cracked.lod = true;
1565 break;
1566 case EOpImageSampleFootprintGradNV:
1567 cracked.grad = true;
1568 break;
1569 case EOpImageSampleFootprintGradClampNV:
1570 cracked.lodClamp = true;
1571 cracked.grad = true;
1572 break;
1573 case EOpSubpassLoad:
1574 case EOpSubpassLoadMS:
1575 cracked.subpass = true;
1576 break;
1577 #endif
1578 default:
1579 break;
1580 }
1581 }
1582
1583 protected:
TIntermOperator(TOperator o)1584 TIntermOperator(TOperator o) : TIntermTyped(EbtFloat), op(o), operationPrecision(EpqNone) {}
TIntermOperator(TOperator o,TType & t)1585 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o), operationPrecision(EpqNone) {}
1586 TOperator op;
1587 // The result precision is in the inherited TType, and is usually meant to be both
1588 // the operation precision and the result precision. However, some more complex things,
1589 // like built-in function calls, distinguish between the two, in which case non-EqpNone
1590 // 'operationPrecision' overrides the result precision as far as operation precision
1591 // is concerned.
1592 TPrecisionQualifier operationPrecision;
1593 };
1594
1595 //
1596 // Nodes for all the basic binary math operators.
1597 //
1598 class TIntermBinary : public TIntermOperator {
1599 public:
TIntermBinary(TOperator o)1600 TIntermBinary(TOperator o) : TIntermOperator(o) {}
1601 virtual void traverse(TIntermTraverser*);
setLeft(TIntermTyped * n)1602 virtual void setLeft(TIntermTyped* n) { left = n; }
setRight(TIntermTyped * n)1603 virtual void setRight(TIntermTyped* n) { right = n; }
getLeft()1604 virtual TIntermTyped* getLeft() const { return left; }
getRight()1605 virtual TIntermTyped* getRight() const { return right; }
getAsBinaryNode()1606 virtual TIntermBinary* getAsBinaryNode() { return this; }
getAsBinaryNode()1607 virtual const TIntermBinary* getAsBinaryNode() const { return this; }
1608 virtual void updatePrecision();
1609 protected:
1610 TIntermTyped* left;
1611 TIntermTyped* right;
1612 };
1613
1614 //
1615 // Nodes for unary math operators.
1616 //
1617 class TIntermUnary : public TIntermOperator {
1618 public:
TIntermUnary(TOperator o,TType & t)1619 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(nullptr) {}
TIntermUnary(TOperator o)1620 TIntermUnary(TOperator o) : TIntermOperator(o), operand(nullptr) {}
1621 virtual void traverse(TIntermTraverser*);
setOperand(TIntermTyped * o)1622 virtual void setOperand(TIntermTyped* o) { operand = o; }
getOperand()1623 virtual TIntermTyped* getOperand() { return operand; }
getOperand()1624 virtual const TIntermTyped* getOperand() const { return operand; }
getAsUnaryNode()1625 virtual TIntermUnary* getAsUnaryNode() { return this; }
getAsUnaryNode()1626 virtual const TIntermUnary* getAsUnaryNode() const { return this; }
1627 virtual void updatePrecision();
1628 #ifndef GLSLANG_WEB
setSpirvInstruction(const TSpirvInstruction & inst)1629 void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
getSpirvInstruction()1630 const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
1631 #endif
1632 protected:
1633 TIntermTyped* operand;
1634 #ifndef GLSLANG_WEB
1635 TSpirvInstruction spirvInst;
1636 #endif
1637 };
1638
1639 typedef TVector<TIntermNode*> TIntermSequence;
1640 typedef TVector<TStorageQualifier> TQualifierList;
1641 //
1642 // Nodes that operate on an arbitrary sized set of children.
1643 //
1644 class TIntermAggregate : public TIntermOperator {
1645 public:
TIntermAggregate()1646 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(nullptr) { }
TIntermAggregate(TOperator o)1647 TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(nullptr) { }
~TIntermAggregate()1648 ~TIntermAggregate() { delete pragmaTable; }
getAsAggregate()1649 virtual TIntermAggregate* getAsAggregate() { return this; }
getAsAggregate()1650 virtual const TIntermAggregate* getAsAggregate() const { return this; }
1651 virtual void updatePrecision();
setOperator(TOperator o)1652 virtual void setOperator(TOperator o) { op = o; }
getSequence()1653 virtual TIntermSequence& getSequence() { return sequence; }
getSequence()1654 virtual const TIntermSequence& getSequence() const { return sequence; }
setName(const TString & n)1655 virtual void setName(const TString& n) { name = n; }
getName()1656 virtual const TString& getName() const { return name; }
1657 virtual void traverse(TIntermTraverser*);
setUserDefined()1658 virtual void setUserDefined() { userDefined = true; }
isUserDefined()1659 virtual bool isUserDefined() { return userDefined; }
getQualifierList()1660 virtual TQualifierList& getQualifierList() { return qualifier; }
getQualifierList()1661 virtual const TQualifierList& getQualifierList() const { return qualifier; }
setOptimize(bool o)1662 void setOptimize(bool o) { optimize = o; }
setDebug(bool d)1663 void setDebug(bool d) { debug = d; }
getOptimize()1664 bool getOptimize() const { return optimize; }
getDebug()1665 bool getDebug() const { return debug; }
1666 void setPragmaTable(const TPragmaTable& pTable);
getPragmaTable()1667 const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
1668 #ifndef GLSLANG_WEB
setSpirvInstruction(const TSpirvInstruction & inst)1669 void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
getSpirvInstruction()1670 const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
1671 #endif
1672 protected:
1673 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
1674 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
1675 TIntermSequence sequence;
1676 TQualifierList qualifier;
1677 TString name;
1678 bool userDefined; // used for user defined function names
1679 bool optimize;
1680 bool debug;
1681 TPragmaTable* pragmaTable;
1682 #ifndef GLSLANG_WEB
1683 TSpirvInstruction spirvInst;
1684 #endif
1685 };
1686
1687 //
1688 // For if tests.
1689 //
1690 class TIntermSelection : public TIntermTyped {
1691 public:
TIntermSelection(TIntermTyped * cond,TIntermNode * trueB,TIntermNode * falseB)1692 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
1693 TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB),
1694 shortCircuit(true),
1695 flatten(false), dontFlatten(false) {}
TIntermSelection(TIntermTyped * cond,TIntermNode * trueB,TIntermNode * falseB,const TType & type)1696 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
1697 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB),
1698 shortCircuit(true),
1699 flatten(false), dontFlatten(false) {}
1700 virtual void traverse(TIntermTraverser*);
getCondition()1701 virtual TIntermTyped* getCondition() const { return condition; }
setCondition(TIntermTyped * c)1702 virtual void setCondition(TIntermTyped* c) { condition = c; }
getTrueBlock()1703 virtual TIntermNode* getTrueBlock() const { return trueBlock; }
setTrueBlock(TIntermTyped * tb)1704 virtual void setTrueBlock(TIntermTyped* tb) { trueBlock = tb; }
getFalseBlock()1705 virtual TIntermNode* getFalseBlock() const { return falseBlock; }
setFalseBlock(TIntermTyped * fb)1706 virtual void setFalseBlock(TIntermTyped* fb) { falseBlock = fb; }
getAsSelectionNode()1707 virtual TIntermSelection* getAsSelectionNode() { return this; }
getAsSelectionNode()1708 virtual const TIntermSelection* getAsSelectionNode() const { return this; }
1709
setNoShortCircuit()1710 void setNoShortCircuit() { shortCircuit = false; }
getShortCircuit()1711 bool getShortCircuit() const { return shortCircuit; }
1712
setFlatten()1713 void setFlatten() { flatten = true; }
setDontFlatten()1714 void setDontFlatten() { dontFlatten = true; }
getFlatten()1715 bool getFlatten() const { return flatten; }
getDontFlatten()1716 bool getDontFlatten() const { return dontFlatten; }
1717
1718 protected:
1719 TIntermTyped* condition;
1720 TIntermNode* trueBlock;
1721 TIntermNode* falseBlock;
1722 bool shortCircuit; // normally all if-then-else and all GLSL ?: short-circuit, but HLSL ?: does not
1723 bool flatten; // true if flatten requested
1724 bool dontFlatten; // true if requested to not flatten
1725 };
1726
1727 //
1728 // For switch statements. Designed use is that a switch will have sequence of nodes
1729 // that are either case/default nodes or a *single* node that represents all the code
1730 // in between (if any) consecutive case/defaults. So, a traversal need only deal with
1731 // 0 or 1 nodes per case/default statement.
1732 //
1733 class TIntermSwitch : public TIntermNode {
1734 public:
TIntermSwitch(TIntermTyped * cond,TIntermAggregate * b)1735 TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b),
1736 flatten(false), dontFlatten(false) {}
1737 virtual void traverse(TIntermTraverser*);
getCondition()1738 virtual TIntermNode* getCondition() const { return condition; }
getBody()1739 virtual TIntermAggregate* getBody() const { return body; }
getAsSwitchNode()1740 virtual TIntermSwitch* getAsSwitchNode() { return this; }
getAsSwitchNode()1741 virtual const TIntermSwitch* getAsSwitchNode() const { return this; }
1742
setFlatten()1743 void setFlatten() { flatten = true; }
setDontFlatten()1744 void setDontFlatten() { dontFlatten = true; }
getFlatten()1745 bool getFlatten() const { return flatten; }
getDontFlatten()1746 bool getDontFlatten() const { return dontFlatten; }
1747
1748 protected:
1749 TIntermTyped* condition;
1750 TIntermAggregate* body;
1751 bool flatten; // true if flatten requested
1752 bool dontFlatten; // true if requested to not flatten
1753 };
1754
1755 enum TVisit
1756 {
1757 EvPreVisit,
1758 EvInVisit,
1759 EvPostVisit
1760 };
1761
1762 //
1763 // For traversing the tree. User should derive from this,
1764 // put their traversal specific data in it, and then pass
1765 // it to a Traverse method.
1766 //
1767 // When using this, just fill in the methods for nodes you want visited.
1768 // Return false from a pre-visit to skip visiting that node's subtree.
1769 //
1770 // Explicitly set postVisit to true if you want post visiting, otherwise,
1771 // filled in methods will only be called at pre-visit time (before processing
1772 // the subtree). Similarly for inVisit for in-order visiting of nodes with
1773 // multiple children.
1774 //
1775 // If you only want post-visits, explicitly turn off preVisit (and inVisit)
1776 // and turn on postVisit.
1777 //
1778 // In general, for the visit*() methods, return true from interior nodes
1779 // to have the traversal continue on to children.
1780 //
1781 // If you process children yourself, or don't want them processed, return false.
1782 //
1783 class TIntermTraverser {
1784 public:
POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator ())1785 POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
1786 TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
1787 preVisit(preVisit),
1788 inVisit(inVisit),
1789 postVisit(postVisit),
1790 rightToLeft(rightToLeft),
1791 depth(0),
1792 maxDepth(0) { }
~TIntermTraverser()1793 virtual ~TIntermTraverser() { }
1794
visitSymbol(TIntermSymbol *)1795 virtual void visitSymbol(TIntermSymbol*) { }
visitConstantUnion(TIntermConstantUnion *)1796 virtual void visitConstantUnion(TIntermConstantUnion*) { }
visitBinary(TVisit,TIntermBinary *)1797 virtual bool visitBinary(TVisit, TIntermBinary*) { return true; }
visitUnary(TVisit,TIntermUnary *)1798 virtual bool visitUnary(TVisit, TIntermUnary*) { return true; }
visitSelection(TVisit,TIntermSelection *)1799 virtual bool visitSelection(TVisit, TIntermSelection*) { return true; }
visitAggregate(TVisit,TIntermAggregate *)1800 virtual bool visitAggregate(TVisit, TIntermAggregate*) { return true; }
visitLoop(TVisit,TIntermLoop *)1801 virtual bool visitLoop(TVisit, TIntermLoop*) { return true; }
visitBranch(TVisit,TIntermBranch *)1802 virtual bool visitBranch(TVisit, TIntermBranch*) { return true; }
visitSwitch(TVisit,TIntermSwitch *)1803 virtual bool visitSwitch(TVisit, TIntermSwitch*) { return true; }
1804
getMaxDepth()1805 int getMaxDepth() const { return maxDepth; }
1806
incrementDepth(TIntermNode * current)1807 void incrementDepth(TIntermNode *current)
1808 {
1809 depth++;
1810 maxDepth = (std::max)(maxDepth, depth);
1811 path.push_back(current);
1812 }
1813
decrementDepth()1814 void decrementDepth()
1815 {
1816 depth--;
1817 path.pop_back();
1818 }
1819
getParentNode()1820 TIntermNode *getParentNode()
1821 {
1822 return path.size() == 0 ? nullptr : path.back();
1823 }
1824
1825 const bool preVisit;
1826 const bool inVisit;
1827 const bool postVisit;
1828 const bool rightToLeft;
1829
1830 protected:
1831 TIntermTraverser& operator=(TIntermTraverser&);
1832
1833 int depth;
1834 int maxDepth;
1835
1836 // All the nodes from root to the current node's parent during traversing.
1837 TVector<TIntermNode *> path;
1838 };
1839
1840 // KHR_vulkan_glsl says "Two arrays sized with specialization constants are the same type only if
1841 // sized with the same symbol, involving no operations"
SameSpecializationConstants(TIntermTyped * node1,TIntermTyped * node2)1842 inline bool SameSpecializationConstants(TIntermTyped* node1, TIntermTyped* node2)
1843 {
1844 return node1->getAsSymbolNode() && node2->getAsSymbolNode() &&
1845 node1->getAsSymbolNode()->getId() == node2->getAsSymbolNode()->getId();
1846 }
1847
1848 } // end namespace glslang
1849
1850 #endif // __INTERMEDIATE_H
1851