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