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
1116 enum TLinkType {
1117 ELinkNone,
1118 ELinkExport,
1119 };
1120
1121 class TIntermTraverser;
1122 class TIntermOperator;
1123 class TIntermAggregate;
1124 class TIntermUnary;
1125 class TIntermBinary;
1126 class TIntermConstantUnion;
1127 class TIntermSelection;
1128 class TIntermSwitch;
1129 class TIntermBranch;
1130 class TIntermTyped;
1131 class TIntermMethod;
1132 class TIntermSymbol;
1133 class TIntermLoop;
1134
1135 } // end namespace glslang
1136
1137 //
1138 // Base class for the tree nodes
1139 //
1140 // (Put outside the glslang namespace, as it's used as part of the external interface.)
1141 //
1142 class TIntermNode {
1143 public:
POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator ())1144 POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
1145
1146 TIntermNode() { loc.init(); }
getLoc()1147 virtual const glslang::TSourceLoc& getLoc() const { return loc; }
setLoc(const glslang::TSourceLoc & l)1148 virtual void setLoc(const glslang::TSourceLoc& l) { loc = l; }
1149 virtual void traverse(glslang::TIntermTraverser*) = 0;
getAsTyped()1150 virtual glslang::TIntermTyped* getAsTyped() { return nullptr; }
getAsOperator()1151 virtual glslang::TIntermOperator* getAsOperator() { return nullptr; }
getAsConstantUnion()1152 virtual glslang::TIntermConstantUnion* getAsConstantUnion() { return nullptr; }
getAsAggregate()1153 virtual glslang::TIntermAggregate* getAsAggregate() { return nullptr; }
getAsUnaryNode()1154 virtual glslang::TIntermUnary* getAsUnaryNode() { return nullptr; }
getAsBinaryNode()1155 virtual glslang::TIntermBinary* getAsBinaryNode() { return nullptr; }
getAsSelectionNode()1156 virtual glslang::TIntermSelection* getAsSelectionNode() { return nullptr; }
getAsSwitchNode()1157 virtual glslang::TIntermSwitch* getAsSwitchNode() { return nullptr; }
getAsMethodNode()1158 virtual glslang::TIntermMethod* getAsMethodNode() { return nullptr; }
getAsSymbolNode()1159 virtual glslang::TIntermSymbol* getAsSymbolNode() { return nullptr; }
getAsBranchNode()1160 virtual glslang::TIntermBranch* getAsBranchNode() { return nullptr; }
getAsLoopNode()1161 virtual glslang::TIntermLoop* getAsLoopNode() { return nullptr; }
1162
getAsTyped()1163 virtual const glslang::TIntermTyped* getAsTyped() const { return nullptr; }
getAsOperator()1164 virtual const glslang::TIntermOperator* getAsOperator() const { return nullptr; }
getAsConstantUnion()1165 virtual const glslang::TIntermConstantUnion* getAsConstantUnion() const { return nullptr; }
getAsAggregate()1166 virtual const glslang::TIntermAggregate* getAsAggregate() const { return nullptr; }
getAsUnaryNode()1167 virtual const glslang::TIntermUnary* getAsUnaryNode() const { return nullptr; }
getAsBinaryNode()1168 virtual const glslang::TIntermBinary* getAsBinaryNode() const { return nullptr; }
getAsSelectionNode()1169 virtual const glslang::TIntermSelection* getAsSelectionNode() const { return nullptr; }
getAsSwitchNode()1170 virtual const glslang::TIntermSwitch* getAsSwitchNode() const { return nullptr; }
getAsMethodNode()1171 virtual const glslang::TIntermMethod* getAsMethodNode() const { return nullptr; }
getAsSymbolNode()1172 virtual const glslang::TIntermSymbol* getAsSymbolNode() const { return nullptr; }
getAsBranchNode()1173 virtual const glslang::TIntermBranch* getAsBranchNode() const { return nullptr; }
getAsLoopNode()1174 virtual const glslang::TIntermLoop* getAsLoopNode() const { return nullptr; }
~TIntermNode()1175 virtual ~TIntermNode() { }
1176
1177 protected:
1178 TIntermNode(const TIntermNode&);
1179 TIntermNode& operator=(const TIntermNode&);
1180 glslang::TSourceLoc loc;
1181 };
1182
1183 namespace glslang {
1184
1185 //
1186 // This is just to help yacc.
1187 //
1188 struct TIntermNodePair {
1189 TIntermNode* node1;
1190 TIntermNode* node2;
1191 };
1192
1193 //
1194 // Intermediate class for nodes that have a type.
1195 //
1196 class TIntermTyped : public TIntermNode {
1197 public:
TIntermTyped(const TType & t)1198 TIntermTyped(const TType& t) { type.shallowCopy(t); }
TIntermTyped(TBasicType basicType)1199 TIntermTyped(TBasicType basicType) { TType bt(basicType); type.shallowCopy(bt); }
getAsTyped()1200 virtual TIntermTyped* getAsTyped() { return this; }
getAsTyped()1201 virtual const TIntermTyped* getAsTyped() const { return this; }
setType(const TType & t)1202 virtual void setType(const TType& t) { type.shallowCopy(t); }
getType()1203 virtual const TType& getType() const { return type; }
getWritableType()1204 virtual TType& getWritableType() { return type; }
1205
getBasicType()1206 virtual TBasicType getBasicType() const { return type.getBasicType(); }
getQualifier()1207 virtual TQualifier& getQualifier() { return type.getQualifier(); }
getQualifier()1208 virtual const TQualifier& getQualifier() const { return type.getQualifier(); }
getArraySizes()1209 virtual TArraySizes* getArraySizes() { return type.getArraySizes(); }
getArraySizes()1210 virtual const TArraySizes* getArraySizes() const { return type.getArraySizes(); }
1211 virtual void propagatePrecision(TPrecisionQualifier);
getVectorSize()1212 virtual int getVectorSize() const { return type.getVectorSize(); }
getMatrixCols()1213 virtual int getMatrixCols() const { return type.getMatrixCols(); }
getMatrixRows()1214 virtual int getMatrixRows() const { return type.getMatrixRows(); }
isMatrix()1215 virtual bool isMatrix() const { return type.isMatrix(); }
isArray()1216 virtual bool isArray() const { return type.isArray(); }
isVector()1217 virtual bool isVector() const { return type.isVector(); }
isScalar()1218 virtual bool isScalar() const { return type.isScalar(); }
isStruct()1219 virtual bool isStruct() const { return type.isStruct(); }
isFloatingDomain()1220 virtual bool isFloatingDomain() const { return type.isFloatingDomain(); }
isIntegerDomain()1221 virtual bool isIntegerDomain() const { return type.isIntegerDomain(); }
isAtomic()1222 bool isAtomic() const { return type.isAtomic(); }
isReference()1223 bool isReference() const { return type.isReference(); }
1224 TString getCompleteString(bool enhanced = false) const { return type.getCompleteString(enhanced); }
1225
1226 protected:
1227 TIntermTyped& operator=(const TIntermTyped&);
1228 TType type;
1229 };
1230
1231 //
1232 // Handle for, do-while, and while loops.
1233 //
1234 class TIntermLoop : public TIntermNode {
1235 public:
TIntermLoop(TIntermNode * aBody,TIntermTyped * aTest,TIntermTyped * aTerminal,bool testFirst)1236 TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) :
1237 body(aBody),
1238 test(aTest),
1239 terminal(aTerminal),
1240 first(testFirst),
1241 unroll(false),
1242 dontUnroll(false),
1243 dependency(0),
1244 minIterations(0),
1245 maxIterations(iterationsInfinite),
1246 iterationMultiple(1),
1247 peelCount(0),
1248 partialCount(0)
1249 { }
1250
getAsLoopNode()1251 virtual TIntermLoop* getAsLoopNode() { return this; }
getAsLoopNode()1252 virtual const TIntermLoop* getAsLoopNode() const { return this; }
1253 virtual void traverse(TIntermTraverser*);
getBody()1254 TIntermNode* getBody() const { return body; }
getTest()1255 TIntermTyped* getTest() const { return test; }
getTerminal()1256 TIntermTyped* getTerminal() const { return terminal; }
testFirst()1257 bool testFirst() const { return first; }
1258
setUnroll()1259 void setUnroll() { unroll = true; }
setDontUnroll()1260 void setDontUnroll() {
1261 dontUnroll = true;
1262 peelCount = 0;
1263 partialCount = 0;
1264 }
getUnroll()1265 bool getUnroll() const { return unroll; }
getDontUnroll()1266 bool getDontUnroll() const { return dontUnroll; }
1267
1268 static const unsigned int dependencyInfinite = 0xFFFFFFFF;
1269 static const unsigned int iterationsInfinite = 0xFFFFFFFF;
setLoopDependency(int d)1270 void setLoopDependency(int d) { dependency = d; }
getLoopDependency()1271 int getLoopDependency() const { return dependency; }
1272
setMinIterations(unsigned int v)1273 void setMinIterations(unsigned int v) { minIterations = v; }
getMinIterations()1274 unsigned int getMinIterations() const { return minIterations; }
setMaxIterations(unsigned int v)1275 void setMaxIterations(unsigned int v) { maxIterations = v; }
getMaxIterations()1276 unsigned int getMaxIterations() const { return maxIterations; }
setIterationMultiple(unsigned int v)1277 void setIterationMultiple(unsigned int v) { iterationMultiple = v; }
getIterationMultiple()1278 unsigned int getIterationMultiple() const { return iterationMultiple; }
setPeelCount(unsigned int v)1279 void setPeelCount(unsigned int v) {
1280 peelCount = v;
1281 dontUnroll = false;
1282 }
getPeelCount()1283 unsigned int getPeelCount() const { return peelCount; }
setPartialCount(unsigned int v)1284 void setPartialCount(unsigned int v) {
1285 partialCount = v;
1286 dontUnroll = false;
1287 }
getPartialCount()1288 unsigned int getPartialCount() const { return partialCount; }
1289
1290 protected:
1291 TIntermNode* body; // code to loop over
1292 TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops
1293 TIntermTyped* terminal; // exists for for-loops
1294 bool first; // true for while and for, not for do-while
1295 bool unroll; // true if unroll requested
1296 bool dontUnroll; // true if request to not unroll
1297 unsigned int dependency; // loop dependency hint; 0 means not set or unknown
1298 unsigned int minIterations; // as per the SPIR-V specification
1299 unsigned int maxIterations; // as per the SPIR-V specification
1300 unsigned int iterationMultiple; // as per the SPIR-V specification
1301 unsigned int peelCount; // as per the SPIR-V specification
1302 unsigned int partialCount; // as per the SPIR-V specification
1303 };
1304
1305 //
1306 // Handle case, break, continue, return, and kill.
1307 //
1308 class TIntermBranch : public TIntermNode {
1309 public:
TIntermBranch(TOperator op,TIntermTyped * e)1310 TIntermBranch(TOperator op, TIntermTyped* e) :
1311 flowOp(op),
1312 expression(e) { }
getAsBranchNode()1313 virtual TIntermBranch* getAsBranchNode() { return this; }
getAsBranchNode()1314 virtual const TIntermBranch* getAsBranchNode() const { return this; }
1315 virtual void traverse(TIntermTraverser*);
getFlowOp()1316 TOperator getFlowOp() const { return flowOp; }
getExpression()1317 TIntermTyped* getExpression() const { return expression; }
setExpression(TIntermTyped * pExpression)1318 void setExpression(TIntermTyped* pExpression) { expression = pExpression; }
1319 void updatePrecision(TPrecisionQualifier parentPrecision);
1320 protected:
1321 TOperator flowOp;
1322 TIntermTyped* expression;
1323 };
1324
1325 //
1326 // Represent method names before seeing their calling signature
1327 // or resolving them to operations. Just an expression as the base object
1328 // and a textural name.
1329 //
1330 class TIntermMethod : public TIntermTyped {
1331 public:
TIntermMethod(TIntermTyped * o,const TType & t,const TString & m)1332 TIntermMethod(TIntermTyped* o, const TType& t, const TString& m) : TIntermTyped(t), object(o), method(m) { }
getAsMethodNode()1333 virtual TIntermMethod* getAsMethodNode() { return this; }
getAsMethodNode()1334 virtual const TIntermMethod* getAsMethodNode() const { return this; }
getMethodName()1335 virtual const TString& getMethodName() const { return method; }
getObject()1336 virtual TIntermTyped* getObject() const { return object; }
1337 virtual void traverse(TIntermTraverser*);
setExport()1338 void setExport() { linkType = ELinkExport; }
1339 protected:
1340 TIntermTyped* object;
1341 TString method;
1342 TLinkType linkType;
1343 };
1344
1345 //
1346 // Nodes that correspond to symbols or constants in the source code.
1347 //
1348 class TIntermSymbol : public TIntermTyped {
1349 public:
1350 // if symbol is initialized as symbol(sym), the memory comes from the pool allocator of sym. If sym comes from
1351 // per process threadPoolAllocator, then it causes increased memory usage per compile
1352 // it is essential to use "symbol = sym" to assign to symbol
TIntermSymbol(long long i,const TString & n,const TType & t)1353 TIntermSymbol(long long i, const TString& n, const TType& t)
1354 : TIntermTyped(t), id(i), flattenSubset(-1), constSubtree(nullptr) { name = n; }
getId()1355 virtual long long getId() const { return id; }
changeId(long long i)1356 virtual void changeId(long long i) { id = i; }
getName()1357 virtual const TString& getName() const { return name; }
1358 virtual void traverse(TIntermTraverser*);
getAsSymbolNode()1359 virtual TIntermSymbol* getAsSymbolNode() { return this; }
getAsSymbolNode()1360 virtual const TIntermSymbol* getAsSymbolNode() const { return this; }
setConstArray(const TConstUnionArray & c)1361 void setConstArray(const TConstUnionArray& c) { constArray = c; }
getConstArray()1362 const TConstUnionArray& getConstArray() const { return constArray; }
setConstSubtree(TIntermTyped * subtree)1363 void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
getConstSubtree()1364 TIntermTyped* getConstSubtree() const { return constSubtree; }
setFlattenSubset(int subset)1365 void setFlattenSubset(int subset) { flattenSubset = subset; }
1366 virtual const TString& getAccessName() const;
1367
getFlattenSubset()1368 int getFlattenSubset() const { return flattenSubset; } // -1 means full object
1369
1370 // This is meant for cases where a node has already been constructed, and
1371 // later on, it becomes necessary to switch to a different symbol.
switchId(long long newId)1372 virtual void switchId(long long newId) { id = newId; }
1373
1374 protected:
1375 long long id; // the unique id of the symbol this node represents
1376 int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced
1377 TString name; // the name of the symbol this node represents
1378 TConstUnionArray constArray; // if the symbol is a front-end compile-time constant, this is its value
1379 TIntermTyped* constSubtree;
1380 };
1381
1382 class TIntermConstantUnion : public TIntermTyped {
1383 public:
TIntermConstantUnion(const TConstUnionArray & ua,const TType & t)1384 TIntermConstantUnion(const TConstUnionArray& ua, const TType& t) : TIntermTyped(t), constArray(ua), literal(false) { }
getConstArray()1385 const TConstUnionArray& getConstArray() const { return constArray; }
getAsConstantUnion()1386 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
getAsConstantUnion()1387 virtual const TIntermConstantUnion* getAsConstantUnion() const { return this; }
1388 virtual void traverse(TIntermTraverser*);
1389 virtual TIntermTyped* fold(TOperator, const TIntermTyped*) const;
1390 virtual TIntermTyped* fold(TOperator, const TType&) const;
setLiteral()1391 void setLiteral() { literal = true; }
setExpression()1392 void setExpression() { literal = false; }
isLiteral()1393 bool isLiteral() const { return literal; }
1394
1395 protected:
1396 TIntermConstantUnion& operator=(const TIntermConstantUnion&);
1397
1398 const TConstUnionArray constArray;
1399 bool literal; // true if node represents a literal in the source code
1400 };
1401
1402 // Represent the independent aspects of a texturing TOperator
1403 struct TCrackedTextureOp {
1404 bool query;
1405 bool proj;
1406 bool lod;
1407 bool fetch;
1408 bool offset;
1409 bool offsets;
1410 bool gather;
1411 bool grad;
1412 bool subpass;
1413 bool lodClamp;
1414 bool fragMask;
1415 bool attachmentEXT;
1416 };
1417
1418 //
1419 // Intermediate class for node types that hold operators.
1420 //
1421 class TIntermOperator : public TIntermTyped {
1422 public:
getAsOperator()1423 virtual TIntermOperator* getAsOperator() { return this; }
getAsOperator()1424 virtual const TIntermOperator* getAsOperator() const { return this; }
getOp()1425 TOperator getOp() const { return op; }
setOp(TOperator newOp)1426 void setOp(TOperator newOp) { op = newOp; }
1427 bool modifiesState() const;
1428 bool isConstructor() const;
isTexture()1429 bool isTexture() const { return op > EOpTextureGuardBegin && op < EOpTextureGuardEnd; }
isSampling()1430 bool isSampling() const { return op > EOpSamplingGuardBegin && op < EOpSamplingGuardEnd; }
isImage()1431 bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; }
isSparseTexture()1432 bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; }
isImageFootprint()1433 bool isImageFootprint() const { return op > EOpImageFootprintGuardBegin && op < EOpImageFootprintGuardEnd; }
isSparseImage()1434 bool isSparseImage() const { return op == EOpSparseImageLoad; }
isSubgroup()1435 bool isSubgroup() const { return op > EOpSubgroupGuardStart && op < EOpSubgroupGuardStop; }
1436
setOperationPrecision(TPrecisionQualifier p)1437 void setOperationPrecision(TPrecisionQualifier p) { operationPrecision = p; }
getOperationPrecision()1438 TPrecisionQualifier getOperationPrecision() const { return operationPrecision != EpqNone ?
1439 operationPrecision :
1440 type.getQualifier().precision; }
getCompleteString()1441 TString getCompleteString() const
1442 {
1443 TString cs = type.getCompleteString();
1444 if (getOperationPrecision() != type.getQualifier().precision) {
1445 cs += ", operation at ";
1446 cs += GetPrecisionQualifierString(getOperationPrecision());
1447 }
1448
1449 return cs;
1450 }
1451
1452 // Crack the op into the individual dimensions of texturing operation.
crackTexture(TSampler sampler,TCrackedTextureOp & cracked)1453 void crackTexture(TSampler sampler, TCrackedTextureOp& cracked) const
1454 {
1455 cracked.query = false;
1456 cracked.proj = false;
1457 cracked.lod = false;
1458 cracked.fetch = false;
1459 cracked.offset = false;
1460 cracked.offsets = false;
1461 cracked.gather = false;
1462 cracked.grad = false;
1463 cracked.subpass = false;
1464 cracked.attachmentEXT = false;
1465 cracked.lodClamp = false;
1466 cracked.fragMask = false;
1467
1468 switch (op) {
1469 case EOpImageQuerySize:
1470 case EOpImageQuerySamples:
1471 case EOpTextureQuerySize:
1472 case EOpTextureQueryLod:
1473 case EOpTextureQueryLevels:
1474 case EOpTextureQuerySamples:
1475 case EOpSparseTexelsResident:
1476 cracked.query = true;
1477 break;
1478 case EOpTexture:
1479 case EOpSparseTexture:
1480 break;
1481 case EOpTextureProj:
1482 cracked.proj = true;
1483 break;
1484 case EOpTextureLod:
1485 case EOpSparseTextureLod:
1486 cracked.lod = true;
1487 break;
1488 case EOpTextureOffset:
1489 case EOpSparseTextureOffset:
1490 cracked.offset = true;
1491 break;
1492 case EOpTextureFetch:
1493 case EOpSparseTextureFetch:
1494 cracked.fetch = true;
1495 if (sampler.is1D() || (sampler.dim == Esd2D && ! sampler.isMultiSample()) || sampler.dim == Esd3D)
1496 cracked.lod = true;
1497 break;
1498 case EOpTextureFetchOffset:
1499 case EOpSparseTextureFetchOffset:
1500 cracked.fetch = true;
1501 cracked.offset = true;
1502 if (sampler.is1D() || (sampler.dim == Esd2D && ! sampler.isMultiSample()) || sampler.dim == Esd3D)
1503 cracked.lod = true;
1504 break;
1505 case EOpTextureProjOffset:
1506 cracked.offset = true;
1507 cracked.proj = true;
1508 break;
1509 case EOpTextureLodOffset:
1510 case EOpSparseTextureLodOffset:
1511 cracked.offset = true;
1512 cracked.lod = true;
1513 break;
1514 case EOpTextureProjLod:
1515 cracked.lod = true;
1516 cracked.proj = true;
1517 break;
1518 case EOpTextureProjLodOffset:
1519 cracked.offset = true;
1520 cracked.lod = true;
1521 cracked.proj = true;
1522 break;
1523 case EOpTextureGrad:
1524 case EOpSparseTextureGrad:
1525 cracked.grad = true;
1526 break;
1527 case EOpTextureGradOffset:
1528 case EOpSparseTextureGradOffset:
1529 cracked.grad = true;
1530 cracked.offset = true;
1531 break;
1532 case EOpTextureProjGrad:
1533 cracked.grad = true;
1534 cracked.proj = true;
1535 break;
1536 case EOpTextureProjGradOffset:
1537 cracked.grad = true;
1538 cracked.offset = true;
1539 cracked.proj = true;
1540 break;
1541 case EOpTextureClamp:
1542 case EOpSparseTextureClamp:
1543 cracked.lodClamp = true;
1544 break;
1545 case EOpTextureOffsetClamp:
1546 case EOpSparseTextureOffsetClamp:
1547 cracked.offset = true;
1548 cracked.lodClamp = true;
1549 break;
1550 case EOpTextureGradClamp:
1551 case EOpSparseTextureGradClamp:
1552 cracked.grad = true;
1553 cracked.lodClamp = true;
1554 break;
1555 case EOpTextureGradOffsetClamp:
1556 case EOpSparseTextureGradOffsetClamp:
1557 cracked.grad = true;
1558 cracked.offset = true;
1559 cracked.lodClamp = true;
1560 break;
1561 case EOpTextureGather:
1562 case EOpSparseTextureGather:
1563 cracked.gather = true;
1564 break;
1565 case EOpTextureGatherOffset:
1566 case EOpSparseTextureGatherOffset:
1567 cracked.gather = true;
1568 cracked.offset = true;
1569 break;
1570 case EOpTextureGatherOffsets:
1571 case EOpSparseTextureGatherOffsets:
1572 cracked.gather = true;
1573 cracked.offsets = true;
1574 break;
1575 case EOpTextureGatherLod:
1576 case EOpSparseTextureGatherLod:
1577 cracked.gather = true;
1578 cracked.lod = true;
1579 break;
1580 case EOpTextureGatherLodOffset:
1581 case EOpSparseTextureGatherLodOffset:
1582 cracked.gather = true;
1583 cracked.offset = true;
1584 cracked.lod = true;
1585 break;
1586 case EOpTextureGatherLodOffsets:
1587 case EOpSparseTextureGatherLodOffsets:
1588 cracked.gather = true;
1589 cracked.offsets = true;
1590 cracked.lod = true;
1591 break;
1592 case EOpImageLoadLod:
1593 case EOpImageStoreLod:
1594 case EOpSparseImageLoadLod:
1595 cracked.lod = true;
1596 break;
1597 case EOpFragmentMaskFetch:
1598 cracked.subpass = sampler.dim == EsdSubpass;
1599 cracked.fragMask = true;
1600 break;
1601 case EOpFragmentFetch:
1602 cracked.subpass = sampler.dim == EsdSubpass;
1603 cracked.fragMask = true;
1604 break;
1605 case EOpImageSampleFootprintNV:
1606 break;
1607 case EOpImageSampleFootprintClampNV:
1608 cracked.lodClamp = true;
1609 break;
1610 case EOpImageSampleFootprintLodNV:
1611 cracked.lod = true;
1612 break;
1613 case EOpImageSampleFootprintGradNV:
1614 cracked.grad = true;
1615 break;
1616 case EOpImageSampleFootprintGradClampNV:
1617 cracked.lodClamp = true;
1618 cracked.grad = true;
1619 break;
1620 case EOpSubpassLoad:
1621 case EOpSubpassLoadMS:
1622 cracked.subpass = true;
1623 break;
1624 case EOpColorAttachmentReadEXT:
1625 cracked.attachmentEXT = true;
1626 break;
1627 default:
1628 break;
1629 }
1630 }
1631
1632 protected:
TIntermOperator(TOperator o)1633 TIntermOperator(TOperator o) : TIntermTyped(EbtFloat), op(o), operationPrecision(EpqNone) {}
TIntermOperator(TOperator o,TType & t)1634 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o), operationPrecision(EpqNone) {}
1635 TOperator op;
1636 // The result precision is in the inherited TType, and is usually meant to be both
1637 // the operation precision and the result precision. However, some more complex things,
1638 // like built-in function calls, distinguish between the two, in which case non-EqpNone
1639 // 'operationPrecision' overrides the result precision as far as operation precision
1640 // is concerned.
1641 TPrecisionQualifier operationPrecision;
1642 };
1643
1644 //
1645 // Nodes for all the basic binary math operators.
1646 //
1647 class TIntermBinary : public TIntermOperator {
1648 public:
TIntermBinary(TOperator o)1649 TIntermBinary(TOperator o) : TIntermOperator(o) {}
1650 virtual void traverse(TIntermTraverser*);
setLeft(TIntermTyped * n)1651 virtual void setLeft(TIntermTyped* n) { left = n; }
setRight(TIntermTyped * n)1652 virtual void setRight(TIntermTyped* n) { right = n; }
getLeft()1653 virtual TIntermTyped* getLeft() const { return left; }
getRight()1654 virtual TIntermTyped* getRight() const { return right; }
getAsBinaryNode()1655 virtual TIntermBinary* getAsBinaryNode() { return this; }
getAsBinaryNode()1656 virtual const TIntermBinary* getAsBinaryNode() const { return this; }
1657 virtual void updatePrecision();
1658 protected:
1659 TIntermTyped* left;
1660 TIntermTyped* right;
1661 };
1662
1663 //
1664 // Nodes for unary math operators.
1665 //
1666 class TIntermUnary : public TIntermOperator {
1667 public:
TIntermUnary(TOperator o,TType & t)1668 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(nullptr) {}
TIntermUnary(TOperator o)1669 TIntermUnary(TOperator o) : TIntermOperator(o), operand(nullptr) {}
1670 virtual void traverse(TIntermTraverser*);
setOperand(TIntermTyped * o)1671 virtual void setOperand(TIntermTyped* o) { operand = o; }
getOperand()1672 virtual TIntermTyped* getOperand() { return operand; }
getOperand()1673 virtual const TIntermTyped* getOperand() const { return operand; }
getAsUnaryNode()1674 virtual TIntermUnary* getAsUnaryNode() { return this; }
getAsUnaryNode()1675 virtual const TIntermUnary* getAsUnaryNode() const { return this; }
1676 virtual void updatePrecision();
setSpirvInstruction(const TSpirvInstruction & inst)1677 void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
getSpirvInstruction()1678 const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
1679 protected:
1680 TIntermTyped* operand;
1681 TSpirvInstruction spirvInst;
1682 };
1683
1684 typedef TVector<TIntermNode*> TIntermSequence;
1685 typedef TVector<TStorageQualifier> TQualifierList;
1686 //
1687 // Nodes that operate on an arbitrary sized set of children.
1688 //
1689 class TIntermAggregate : public TIntermOperator {
1690 public:
TIntermAggregate()1691 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(nullptr) { }
TIntermAggregate(TOperator o)1692 TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(nullptr) { }
~TIntermAggregate()1693 ~TIntermAggregate() { delete pragmaTable; }
getAsAggregate()1694 virtual TIntermAggregate* getAsAggregate() { return this; }
getAsAggregate()1695 virtual const TIntermAggregate* getAsAggregate() const { return this; }
1696 virtual void updatePrecision();
setOperator(TOperator o)1697 virtual void setOperator(TOperator o) { op = o; }
getSequence()1698 virtual TIntermSequence& getSequence() { return sequence; }
getSequence()1699 virtual const TIntermSequence& getSequence() const { return sequence; }
setName(const TString & n)1700 virtual void setName(const TString& n) { name = n; }
getName()1701 virtual const TString& getName() const { return name; }
1702 virtual void traverse(TIntermTraverser*);
setUserDefined()1703 virtual void setUserDefined() { userDefined = true; }
isUserDefined()1704 virtual bool isUserDefined() { return userDefined; }
getQualifierList()1705 virtual TQualifierList& getQualifierList() { return qualifier; }
getQualifierList()1706 virtual const TQualifierList& getQualifierList() const { return qualifier; }
setOptimize(bool o)1707 void setOptimize(bool o) { optimize = o; }
setDebug(bool d)1708 void setDebug(bool d) { debug = d; }
getOptimize()1709 bool getOptimize() const { return optimize; }
getDebug()1710 bool getDebug() const { return debug; }
1711 void setPragmaTable(const TPragmaTable& pTable);
getPragmaTable()1712 const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
setSpirvInstruction(const TSpirvInstruction & inst)1713 void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
getSpirvInstruction()1714 const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
1715
setLinkType(TLinkType l)1716 void setLinkType(TLinkType l) { linkType = l; }
getLinkType()1717 TLinkType getLinkType() const { return linkType; }
1718 protected:
1719 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
1720 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
1721 TIntermSequence sequence;
1722 TQualifierList qualifier;
1723 TString name;
1724 bool userDefined; // used for user defined function names
1725 bool optimize;
1726 bool debug;
1727 TPragmaTable* pragmaTable;
1728 TSpirvInstruction spirvInst;
1729 TLinkType linkType = ELinkNone;
1730 };
1731
1732 //
1733 // For if tests.
1734 //
1735 class TIntermSelection : public TIntermTyped {
1736 public:
TIntermSelection(TIntermTyped * cond,TIntermNode * trueB,TIntermNode * falseB)1737 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
1738 TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB),
1739 shortCircuit(true),
1740 flatten(false), dontFlatten(false) {}
TIntermSelection(TIntermTyped * cond,TIntermNode * trueB,TIntermNode * falseB,const TType & type)1741 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
1742 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB),
1743 shortCircuit(true),
1744 flatten(false), dontFlatten(false) {}
1745 virtual void traverse(TIntermTraverser*);
getCondition()1746 virtual TIntermTyped* getCondition() const { return condition; }
setCondition(TIntermTyped * c)1747 virtual void setCondition(TIntermTyped* c) { condition = c; }
getTrueBlock()1748 virtual TIntermNode* getTrueBlock() const { return trueBlock; }
setTrueBlock(TIntermTyped * tb)1749 virtual void setTrueBlock(TIntermTyped* tb) { trueBlock = tb; }
getFalseBlock()1750 virtual TIntermNode* getFalseBlock() const { return falseBlock; }
setFalseBlock(TIntermTyped * fb)1751 virtual void setFalseBlock(TIntermTyped* fb) { falseBlock = fb; }
getAsSelectionNode()1752 virtual TIntermSelection* getAsSelectionNode() { return this; }
getAsSelectionNode()1753 virtual const TIntermSelection* getAsSelectionNode() const { return this; }
1754
setNoShortCircuit()1755 void setNoShortCircuit() { shortCircuit = false; }
getShortCircuit()1756 bool getShortCircuit() const { return shortCircuit; }
1757
setFlatten()1758 void setFlatten() { flatten = true; }
setDontFlatten()1759 void setDontFlatten() { dontFlatten = true; }
getFlatten()1760 bool getFlatten() const { return flatten; }
getDontFlatten()1761 bool getDontFlatten() const { return dontFlatten; }
1762
1763 protected:
1764 TIntermTyped* condition;
1765 TIntermNode* trueBlock;
1766 TIntermNode* falseBlock;
1767 bool shortCircuit; // normally all if-then-else and all GLSL ?: short-circuit, but HLSL ?: does not
1768 bool flatten; // true if flatten requested
1769 bool dontFlatten; // true if requested to not flatten
1770 };
1771
1772 //
1773 // For switch statements. Designed use is that a switch will have sequence of nodes
1774 // that are either case/default nodes or a *single* node that represents all the code
1775 // in between (if any) consecutive case/defaults. So, a traversal need only deal with
1776 // 0 or 1 nodes per case/default statement.
1777 //
1778 class TIntermSwitch : public TIntermNode {
1779 public:
TIntermSwitch(TIntermTyped * cond,TIntermAggregate * b)1780 TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b),
1781 flatten(false), dontFlatten(false) {}
1782 virtual void traverse(TIntermTraverser*);
getCondition()1783 virtual TIntermNode* getCondition() const { return condition; }
getBody()1784 virtual TIntermAggregate* getBody() const { return body; }
getAsSwitchNode()1785 virtual TIntermSwitch* getAsSwitchNode() { return this; }
getAsSwitchNode()1786 virtual const TIntermSwitch* getAsSwitchNode() const { return this; }
1787
setFlatten()1788 void setFlatten() { flatten = true; }
setDontFlatten()1789 void setDontFlatten() { dontFlatten = true; }
getFlatten()1790 bool getFlatten() const { return flatten; }
getDontFlatten()1791 bool getDontFlatten() const { return dontFlatten; }
1792
1793 protected:
1794 TIntermTyped* condition;
1795 TIntermAggregate* body;
1796 bool flatten; // true if flatten requested
1797 bool dontFlatten; // true if requested to not flatten
1798 };
1799
1800 enum TVisit
1801 {
1802 EvPreVisit,
1803 EvInVisit,
1804 EvPostVisit
1805 };
1806
1807 //
1808 // For traversing the tree. User should derive from this,
1809 // put their traversal specific data in it, and then pass
1810 // it to a Traverse method.
1811 //
1812 // When using this, just fill in the methods for nodes you want visited.
1813 // Return false from a pre-visit to skip visiting that node's subtree.
1814 //
1815 // Explicitly set postVisit to true if you want post visiting, otherwise,
1816 // filled in methods will only be called at pre-visit time (before processing
1817 // the subtree). Similarly for inVisit for in-order visiting of nodes with
1818 // multiple children.
1819 //
1820 // If you only want post-visits, explicitly turn off preVisit (and inVisit)
1821 // and turn on postVisit.
1822 //
1823 // In general, for the visit*() methods, return true from interior nodes
1824 // to have the traversal continue on to children.
1825 //
1826 // If you process children yourself, or don't want them processed, return false.
1827 //
1828 class TIntermTraverser {
1829 public:
POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator ())1830 POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
1831 TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
1832 preVisit(preVisit),
1833 inVisit(inVisit),
1834 postVisit(postVisit),
1835 rightToLeft(rightToLeft),
1836 depth(0),
1837 maxDepth(0) { }
~TIntermTraverser()1838 virtual ~TIntermTraverser() { }
1839
visitSymbol(TIntermSymbol *)1840 virtual void visitSymbol(TIntermSymbol*) { }
visitConstantUnion(TIntermConstantUnion *)1841 virtual void visitConstantUnion(TIntermConstantUnion*) { }
visitBinary(TVisit,TIntermBinary *)1842 virtual bool visitBinary(TVisit, TIntermBinary*) { return true; }
visitUnary(TVisit,TIntermUnary *)1843 virtual bool visitUnary(TVisit, TIntermUnary*) { return true; }
visitSelection(TVisit,TIntermSelection *)1844 virtual bool visitSelection(TVisit, TIntermSelection*) { return true; }
visitAggregate(TVisit,TIntermAggregate *)1845 virtual bool visitAggregate(TVisit, TIntermAggregate*) { return true; }
visitLoop(TVisit,TIntermLoop *)1846 virtual bool visitLoop(TVisit, TIntermLoop*) { return true; }
visitBranch(TVisit,TIntermBranch *)1847 virtual bool visitBranch(TVisit, TIntermBranch*) { return true; }
visitSwitch(TVisit,TIntermSwitch *)1848 virtual bool visitSwitch(TVisit, TIntermSwitch*) { return true; }
1849
getMaxDepth()1850 int getMaxDepth() const { return maxDepth; }
1851
incrementDepth(TIntermNode * current)1852 void incrementDepth(TIntermNode *current)
1853 {
1854 depth++;
1855 maxDepth = (std::max)(maxDepth, depth);
1856 path.push_back(current);
1857 }
1858
decrementDepth()1859 void decrementDepth()
1860 {
1861 depth--;
1862 path.pop_back();
1863 }
1864
getParentNode()1865 TIntermNode *getParentNode()
1866 {
1867 return path.size() == 0 ? nullptr : path.back();
1868 }
1869
1870 const bool preVisit;
1871 const bool inVisit;
1872 const bool postVisit;
1873 const bool rightToLeft;
1874
1875 protected:
1876 TIntermTraverser& operator=(TIntermTraverser&);
1877
1878 int depth;
1879 int maxDepth;
1880
1881 // All the nodes from root to the current node's parent during traversing.
1882 TVector<TIntermNode *> path;
1883 };
1884
1885 // KHR_vulkan_glsl says "Two arrays sized with specialization constants are the same type only if
1886 // sized with the same symbol, involving no operations"
SameSpecializationConstants(TIntermTyped * node1,TIntermTyped * node2)1887 inline bool SameSpecializationConstants(TIntermTyped* node1, TIntermTyped* node2)
1888 {
1889 return node1->getAsSymbolNode() && node2->getAsSymbolNode() &&
1890 node1->getAsSymbolNode()->getId() == node2->getAsSymbolNode()->getId();
1891 }
1892
1893 } // end namespace glslang
1894
1895 #endif // __INTERMEDIATE_H
1896