1 // 2 //Copyright (C) 2002-2005 3Dlabs Inc. Ltd. 3 //Copyright (C) 2012-2016 LunarG, Inc. 4 // 5 //All rights reserved. 6 // 7 //Redistribution and use in source and binary forms, with or without 8 //modification, are permitted provided that the following conditions 9 //are met: 10 // 11 // Redistributions of source code must retain the above copyright 12 // notice, this list of conditions and the following disclaimer. 13 // 14 // Redistributions in binary form must reproduce the above 15 // copyright notice, this list of conditions and the following 16 // disclaimer in the documentation and/or other materials provided 17 // with the distribution. 18 // 19 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its 20 // contributors may be used to endorse or promote products derived 21 // from this software without specific prior written permission. 22 // 23 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 //"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 //FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 //COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 //INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 //CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 //LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 //ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 //POSSIBILITY OF SUCH DAMAGE. 35 // 36 37 // 38 // Definition of the in-memory high-level intermediate representation 39 // of shaders. This is a tree that parser creates. 40 // 41 // Nodes in the tree are defined as a hierarchy of classes derived from 42 // TIntermNode. Each is a node in a tree. There is no preset branching factor; 43 // each node can have it's own type of list of children. 44 // 45 46 #ifndef __INTERMEDIATE_H 47 #define __INTERMEDIATE_H 48 49 #include "../Include/Common.h" 50 #include "../Include/Types.h" 51 #include "../Include/ConstantUnion.h" 52 53 namespace glslang { 54 55 // 56 // Operators used by the high-level (parse tree) representation. 57 // 58 enum TOperator { 59 EOpNull, // if in a node, should only mean a node is still being built 60 EOpSequence, // denotes a list of statements, or parameters, etc. 61 EOpLinkerObjects, // for aggregate node of objects the linker may need, if not reference by the rest of the AST 62 EOpFunctionCall, 63 EOpFunction, // For function definition 64 EOpParameters, // an aggregate listing the parameters to a function 65 66 // 67 // Unary operators 68 // 69 70 EOpNegative, 71 EOpLogicalNot, 72 EOpVectorLogicalNot, 73 EOpBitwiseNot, 74 75 EOpPostIncrement, 76 EOpPostDecrement, 77 EOpPreIncrement, 78 EOpPreDecrement, 79 80 EOpConvIntToBool, 81 EOpConvUintToBool, 82 EOpConvFloatToBool, 83 EOpConvDoubleToBool, 84 EOpConvInt64ToBool, 85 EOpConvUint64ToBool, 86 EOpConvBoolToFloat, 87 EOpConvIntToFloat, 88 EOpConvUintToFloat, 89 EOpConvDoubleToFloat, 90 EOpConvInt64ToFloat, 91 EOpConvUint64ToFloat, 92 EOpConvUintToInt, 93 EOpConvFloatToInt, 94 EOpConvBoolToInt, 95 EOpConvDoubleToInt, 96 EOpConvInt64ToInt, 97 EOpConvUint64ToInt, 98 EOpConvIntToUint, 99 EOpConvFloatToUint, 100 EOpConvBoolToUint, 101 EOpConvDoubleToUint, 102 EOpConvInt64ToUint, 103 EOpConvUint64ToUint, 104 EOpConvIntToDouble, 105 EOpConvUintToDouble, 106 EOpConvFloatToDouble, 107 EOpConvBoolToDouble, 108 EOpConvInt64ToDouble, 109 EOpConvUint64ToDouble, 110 EOpConvBoolToInt64, 111 EOpConvIntToInt64, 112 EOpConvUintToInt64, 113 EOpConvFloatToInt64, 114 EOpConvDoubleToInt64, 115 EOpConvUint64ToInt64, 116 EOpConvBoolToUint64, 117 EOpConvIntToUint64, 118 EOpConvUintToUint64, 119 EOpConvFloatToUint64, 120 EOpConvDoubleToUint64, 121 EOpConvInt64ToUint64, 122 123 // 124 // binary operations 125 // 126 127 EOpAdd, 128 EOpSub, 129 EOpMul, 130 EOpDiv, 131 EOpMod, 132 EOpRightShift, 133 EOpLeftShift, 134 EOpAnd, 135 EOpInclusiveOr, 136 EOpExclusiveOr, 137 EOpEqual, 138 EOpNotEqual, 139 EOpVectorEqual, 140 EOpVectorNotEqual, 141 EOpLessThan, 142 EOpGreaterThan, 143 EOpLessThanEqual, 144 EOpGreaterThanEqual, 145 EOpComma, 146 147 EOpVectorTimesScalar, 148 EOpVectorTimesMatrix, 149 EOpMatrixTimesVector, 150 EOpMatrixTimesScalar, 151 152 EOpLogicalOr, 153 EOpLogicalXor, 154 EOpLogicalAnd, 155 156 EOpIndexDirect, 157 EOpIndexIndirect, 158 EOpIndexDirectStruct, 159 160 EOpVectorSwizzle, 161 162 EOpMethod, 163 164 // 165 // Built-in functions mapped to operators 166 // 167 168 EOpRadians, 169 EOpDegrees, 170 EOpSin, 171 EOpCos, 172 EOpTan, 173 EOpAsin, 174 EOpAcos, 175 EOpAtan, 176 EOpSinh, 177 EOpCosh, 178 EOpTanh, 179 EOpAsinh, 180 EOpAcosh, 181 EOpAtanh, 182 183 EOpPow, 184 EOpExp, 185 EOpLog, 186 EOpExp2, 187 EOpLog2, 188 EOpSqrt, 189 EOpInverseSqrt, 190 191 EOpAbs, 192 EOpSign, 193 EOpFloor, 194 EOpTrunc, 195 EOpRound, 196 EOpRoundEven, 197 EOpCeil, 198 EOpFract, 199 EOpModf, 200 EOpMin, 201 EOpMax, 202 EOpClamp, 203 EOpMix, 204 EOpStep, 205 EOpSmoothStep, 206 207 EOpIsNan, 208 EOpIsInf, 209 210 EOpFma, 211 212 EOpFrexp, 213 EOpLdexp, 214 215 EOpFloatBitsToInt, 216 EOpFloatBitsToUint, 217 EOpIntBitsToFloat, 218 EOpUintBitsToFloat, 219 EOpDoubleBitsToInt64, 220 EOpDoubleBitsToUint64, 221 EOpInt64BitsToDouble, 222 EOpUint64BitsToDouble, 223 EOpPackSnorm2x16, 224 EOpUnpackSnorm2x16, 225 EOpPackUnorm2x16, 226 EOpUnpackUnorm2x16, 227 EOpPackSnorm4x8, 228 EOpUnpackSnorm4x8, 229 EOpPackUnorm4x8, 230 EOpUnpackUnorm4x8, 231 EOpPackHalf2x16, 232 EOpUnpackHalf2x16, 233 EOpPackDouble2x32, 234 EOpUnpackDouble2x32, 235 EOpPackInt2x32, 236 EOpUnpackInt2x32, 237 EOpPackUint2x32, 238 EOpUnpackUint2x32, 239 240 EOpLength, 241 EOpDistance, 242 EOpDot, 243 EOpCross, 244 EOpNormalize, 245 EOpFaceForward, 246 EOpReflect, 247 EOpRefract, 248 249 EOpDPdx, // Fragment only 250 EOpDPdy, // Fragment only 251 EOpFwidth, // Fragment only 252 EOpDPdxFine, // Fragment only 253 EOpDPdyFine, // Fragment only 254 EOpFwidthFine, // Fragment only 255 EOpDPdxCoarse, // Fragment only 256 EOpDPdyCoarse, // Fragment only 257 EOpFwidthCoarse, // Fragment only 258 259 EOpInterpolateAtCentroid, // Fragment only 260 EOpInterpolateAtSample, // Fragment only 261 EOpInterpolateAtOffset, // Fragment only 262 263 EOpMatrixTimesMatrix, 264 EOpOuterProduct, 265 EOpDeterminant, 266 EOpMatrixInverse, 267 EOpTranspose, 268 269 EOpFtransform, 270 271 EOpNoise, 272 273 EOpEmitVertex, // geometry only 274 EOpEndPrimitive, // geometry only 275 EOpEmitStreamVertex, // geometry only 276 EOpEndStreamPrimitive, // geometry only 277 278 EOpBarrier, 279 EOpMemoryBarrier, 280 EOpMemoryBarrierAtomicCounter, 281 EOpMemoryBarrierBuffer, 282 EOpMemoryBarrierImage, 283 EOpMemoryBarrierShared, // compute only 284 EOpGroupMemoryBarrier, // compute only 285 286 EOpBallot, 287 EOpReadInvocation, 288 EOpReadFirstInvocation, 289 290 EOpAnyInvocation, 291 EOpAllInvocations, 292 EOpAllInvocationsEqual, 293 294 EOpAtomicAdd, 295 EOpAtomicMin, 296 EOpAtomicMax, 297 EOpAtomicAnd, 298 EOpAtomicOr, 299 EOpAtomicXor, 300 EOpAtomicExchange, 301 EOpAtomicCompSwap, 302 303 EOpAtomicCounterIncrement, 304 EOpAtomicCounterDecrement, 305 EOpAtomicCounter, 306 307 EOpAny, 308 EOpAll, 309 310 // 311 // Branch 312 // 313 314 EOpKill, // Fragment only 315 EOpReturn, 316 EOpBreak, 317 EOpContinue, 318 EOpCase, 319 EOpDefault, 320 321 // 322 // Constructors 323 // 324 325 EOpConstructGuardStart, 326 EOpConstructInt, // these first scalar forms also identify what implicit conversion is needed 327 EOpConstructUint, 328 EOpConstructInt64, 329 EOpConstructUint64, 330 EOpConstructBool, 331 EOpConstructFloat, 332 EOpConstructDouble, 333 EOpConstructVec2, 334 EOpConstructVec3, 335 EOpConstructVec4, 336 EOpConstructDVec2, 337 EOpConstructDVec3, 338 EOpConstructDVec4, 339 EOpConstructBVec2, 340 EOpConstructBVec3, 341 EOpConstructBVec4, 342 EOpConstructIVec2, 343 EOpConstructIVec3, 344 EOpConstructIVec4, 345 EOpConstructUVec2, 346 EOpConstructUVec3, 347 EOpConstructUVec4, 348 EOpConstructI64Vec2, 349 EOpConstructI64Vec3, 350 EOpConstructI64Vec4, 351 EOpConstructU64Vec2, 352 EOpConstructU64Vec3, 353 EOpConstructU64Vec4, 354 EOpConstructMat2x2, 355 EOpConstructMat2x3, 356 EOpConstructMat2x4, 357 EOpConstructMat3x2, 358 EOpConstructMat3x3, 359 EOpConstructMat3x4, 360 EOpConstructMat4x2, 361 EOpConstructMat4x3, 362 EOpConstructMat4x4, 363 EOpConstructDMat2x2, 364 EOpConstructDMat2x3, 365 EOpConstructDMat2x4, 366 EOpConstructDMat3x2, 367 EOpConstructDMat3x3, 368 EOpConstructDMat3x4, 369 EOpConstructDMat4x2, 370 EOpConstructDMat4x3, 371 EOpConstructDMat4x4, 372 EOpConstructStruct, 373 EOpConstructTextureSampler, 374 EOpConstructGuardEnd, 375 376 // 377 // moves 378 // 379 380 EOpAssign, 381 EOpAddAssign, 382 EOpSubAssign, 383 EOpMulAssign, 384 EOpVectorTimesMatrixAssign, 385 EOpVectorTimesScalarAssign, 386 EOpMatrixTimesScalarAssign, 387 EOpMatrixTimesMatrixAssign, 388 EOpDivAssign, 389 EOpModAssign, 390 EOpAndAssign, 391 EOpInclusiveOrAssign, 392 EOpExclusiveOrAssign, 393 EOpLeftShiftAssign, 394 EOpRightShiftAssign, 395 396 // 397 // Array operators 398 // 399 400 EOpArrayLength, // "Array" distinguishes from length(v) built-in function, but it applies to vectors and matrices as well. 401 402 // 403 // Image operations 404 // 405 406 EOpImageGuardBegin, 407 408 EOpImageQuerySize, 409 EOpImageQuerySamples, 410 EOpImageLoad, 411 EOpImageStore, 412 EOpImageAtomicAdd, 413 EOpImageAtomicMin, 414 EOpImageAtomicMax, 415 EOpImageAtomicAnd, 416 EOpImageAtomicOr, 417 EOpImageAtomicXor, 418 EOpImageAtomicExchange, 419 EOpImageAtomicCompSwap, 420 421 EOpSubpassLoad, 422 EOpSubpassLoadMS, 423 EOpSparseImageLoad, 424 425 EOpImageGuardEnd, 426 427 // 428 // Texture operations 429 // 430 431 EOpTextureGuardBegin, 432 433 EOpTextureQuerySize, 434 EOpTextureQueryLod, 435 EOpTextureQueryLevels, 436 EOpTextureQuerySamples, 437 EOpTexture, 438 EOpTextureProj, 439 EOpTextureLod, 440 EOpTextureOffset, 441 EOpTextureFetch, 442 EOpTextureFetchOffset, 443 EOpTextureProjOffset, 444 EOpTextureLodOffset, 445 EOpTextureProjLod, 446 EOpTextureProjLodOffset, 447 EOpTextureGrad, 448 EOpTextureGradOffset, 449 EOpTextureProjGrad, 450 EOpTextureProjGradOffset, 451 EOpTextureGather, 452 EOpTextureGatherOffset, 453 EOpTextureGatherOffsets, 454 EOpTextureClamp, 455 EOpTextureOffsetClamp, 456 EOpTextureGradClamp, 457 EOpTextureGradOffsetClamp, 458 459 EOpSparseTextureGuardBegin, 460 461 EOpSparseTexture, 462 EOpSparseTextureLod, 463 EOpSparseTextureOffset, 464 EOpSparseTextureFetch, 465 EOpSparseTextureFetchOffset, 466 EOpSparseTextureLodOffset, 467 EOpSparseTextureGrad, 468 EOpSparseTextureGradOffset, 469 EOpSparseTextureGather, 470 EOpSparseTextureGatherOffset, 471 EOpSparseTextureGatherOffsets, 472 EOpSparseTexelsResident, 473 EOpSparseTextureClamp, 474 EOpSparseTextureOffsetClamp, 475 EOpSparseTextureGradClamp, 476 EOpSparseTextureGradOffsetClamp, 477 478 EOpSparseTextureGuardEnd, 479 480 EOpTextureGuardEnd, 481 482 // 483 // Integer operations 484 // 485 486 EOpAddCarry, 487 EOpSubBorrow, 488 EOpUMulExtended, 489 EOpIMulExtended, 490 EOpBitfieldExtract, 491 EOpBitfieldInsert, 492 EOpBitFieldReverse, 493 EOpBitCount, 494 EOpFindLSB, 495 EOpFindMSB, 496 497 // 498 // HLSL operations 499 // 500 501 EOpClip, // discard if input value < 0 502 EOpIsFinite, 503 EOpLog10, // base 10 log 504 EOpRcp, // 1/x 505 EOpSaturate, // clamp from 0 to 1 506 EOpSinCos, // sin and cos in out parameters 507 EOpGenMul, // mul(x,y) on any of mat/vec/scalars 508 EOpDst, // x = 1, y=src0.y * src1.y, z=src0.z, w=src1.w 509 EOpInterlockedAdd, // atomic ops, but uses [optional] out arg instead of return 510 EOpInterlockedAnd, // ... 511 EOpInterlockedCompareExchange, // ... 512 EOpInterlockedCompareStore, // ... 513 EOpInterlockedExchange, // ... 514 EOpInterlockedMax, // ... 515 EOpInterlockedMin, // ... 516 EOpInterlockedOr, // ... 517 EOpInterlockedXor, // ... 518 EOpAllMemoryBarrierWithGroupSync, // memory barriers without non-hlsl AST equivalents 519 EOpGroupMemoryBarrierWithGroupSync, // ... 520 EOpWorkgroupMemoryBarrier, // ... 521 EOpWorkgroupMemoryBarrierWithGroupSync, // ... 522 EOpEvaluateAttributeSnapped, // InterpolateAtOffset with int position on 16x16 grid 523 EOpF32tof16, // HLSL conversion: half of a PackHalf2x16 524 EOpF16tof32, // HLSL conversion: half of an UnpackHalf2x16 525 EOpLit, // HLSL lighting coefficient vector 526 EOpTextureBias, // HLSL texture bias: will be lowered to EOpTexture 527 EOpAsDouble, // slightly different from EOpUint64BitsToDouble 528 529 EOpMethodSample, // Texture object methods. These are translated to existing 530 EOpMethodSampleBias, // AST methods, and exist to represent HLSL semantics until that 531 EOpMethodSampleCmp, // translation is performed. See HlslParseContext::decomposeSampleMethods(). 532 EOpMethodSampleCmpLevelZero, // ... 533 EOpMethodSampleGrad, // ... 534 EOpMethodSampleLevel, // ... 535 EOpMethodLoad, // ... 536 EOpMethodGetDimensions, // ... 537 EOpMethodGetSamplePosition, // ... 538 EOpMethodGather, // ... 539 EOpMethodCalculateLevelOfDetail, // ... 540 EOpMethodCalculateLevelOfDetailUnclamped, // ... 541 }; 542 543 class TIntermTraverser; 544 class TIntermOperator; 545 class TIntermAggregate; 546 class TIntermUnary; 547 class TIntermBinary; 548 class TIntermConstantUnion; 549 class TIntermSelection; 550 class TIntermSwitch; 551 class TIntermBranch; 552 class TIntermTyped; 553 class TIntermMethod; 554 class TIntermSymbol; 555 556 } // end namespace glslang 557 558 // 559 // Base class for the tree nodes 560 // 561 // (Put outside the glslang namespace, as it's used as part of the external interface.) 562 // 563 class TIntermNode { 564 public: 565 POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator()) 566 567 TIntermNode() { loc.init(); } 568 virtual const glslang::TSourceLoc& getLoc() const { return loc; } 569 virtual void setLoc(const glslang::TSourceLoc& l) { loc = l; } 570 virtual void traverse(glslang::TIntermTraverser*) = 0; 571 virtual glslang::TIntermTyped* getAsTyped() { return 0; } 572 virtual glslang::TIntermOperator* getAsOperator() { return 0; } 573 virtual glslang::TIntermConstantUnion* getAsConstantUnion() { return 0; } 574 virtual glslang::TIntermAggregate* getAsAggregate() { return 0; } 575 virtual glslang::TIntermUnary* getAsUnaryNode() { return 0; } 576 virtual glslang::TIntermBinary* getAsBinaryNode() { return 0; } 577 virtual glslang::TIntermSelection* getAsSelectionNode() { return 0; } 578 virtual glslang::TIntermSwitch* getAsSwitchNode() { return 0; } 579 virtual glslang::TIntermMethod* getAsMethodNode() { return 0; } 580 virtual glslang::TIntermSymbol* getAsSymbolNode() { return 0; } 581 virtual glslang::TIntermBranch* getAsBranchNode() { return 0; } 582 583 virtual const glslang::TIntermTyped* getAsTyped() const { return 0; } 584 virtual const glslang::TIntermOperator* getAsOperator() const { return 0; } 585 virtual const glslang::TIntermConstantUnion* getAsConstantUnion() const { return 0; } 586 virtual const glslang::TIntermAggregate* getAsAggregate() const { return 0; } 587 virtual const glslang::TIntermUnary* getAsUnaryNode() const { return 0; } 588 virtual const glslang::TIntermBinary* getAsBinaryNode() const { return 0; } 589 virtual const glslang::TIntermSelection* getAsSelectionNode() const { return 0; } 590 virtual const glslang::TIntermSwitch* getAsSwitchNode() const { return 0; } 591 virtual const glslang::TIntermMethod* getAsMethodNode() const { return 0; } 592 virtual const glslang::TIntermSymbol* getAsSymbolNode() const { return 0; } 593 virtual const glslang::TIntermBranch* getAsBranchNode() const { return 0; } 594 virtual ~TIntermNode() { } 595 596 protected: 597 TIntermNode(const TIntermNode&); 598 TIntermNode& operator=(const TIntermNode&); 599 glslang::TSourceLoc loc; 600 }; 601 602 namespace glslang { 603 604 // 605 // This is just to help yacc. 606 // 607 struct TIntermNodePair { 608 TIntermNode* node1; 609 TIntermNode* node2; 610 }; 611 612 // 613 // Intermediate class for nodes that have a type. 614 // 615 class TIntermTyped : public TIntermNode { 616 public: 617 TIntermTyped(const TType& t) { type.shallowCopy(t); } 618 TIntermTyped(TBasicType basicType) { TType bt(basicType); type.shallowCopy(bt); } 619 virtual TIntermTyped* getAsTyped() { return this; } 620 virtual const TIntermTyped* getAsTyped() const { return this; } 621 virtual void setType(const TType& t) { type.shallowCopy(t); } 622 virtual const TType& getType() const { return type; } 623 virtual TType& getWritableType() { return type; } 624 625 virtual TBasicType getBasicType() const { return type.getBasicType(); } 626 virtual TQualifier& getQualifier() { return type.getQualifier(); } 627 virtual const TQualifier& getQualifier() const { return type.getQualifier(); } 628 virtual void propagatePrecision(TPrecisionQualifier); 629 virtual int getVectorSize() const { return type.getVectorSize(); } 630 virtual int getMatrixCols() const { return type.getMatrixCols(); } 631 virtual int getMatrixRows() const { return type.getMatrixRows(); } 632 virtual bool isMatrix() const { return type.isMatrix(); } 633 virtual bool isArray() const { return type.isArray(); } 634 virtual bool isVector() const { return type.isVector(); } 635 virtual bool isScalar() const { return type.isScalar(); } 636 virtual bool isStruct() const { return type.isStruct(); } 637 TString getCompleteString() const { return type.getCompleteString(); } 638 639 protected: 640 TIntermTyped& operator=(const TIntermTyped&); 641 TType type; 642 }; 643 644 // 645 // Handle for, do-while, and while loops. 646 // 647 class TIntermLoop : public TIntermNode { 648 public: 649 TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) : 650 body(aBody), 651 test(aTest), 652 terminal(aTerminal), 653 first(testFirst) { } 654 virtual void traverse(TIntermTraverser*); 655 TIntermNode* getBody() const { return body; } 656 TIntermTyped* getTest() const { return test; } 657 TIntermTyped* getTerminal() const { return terminal; } 658 bool testFirst() const { return first; } 659 protected: 660 TIntermNode* body; // code to loop over 661 TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops 662 TIntermTyped* terminal; // exists for for-loops 663 bool first; // true for while and for, not for do-while 664 }; 665 666 // 667 // Handle case, break, continue, return, and kill. 668 // 669 class TIntermBranch : public TIntermNode { 670 public: 671 TIntermBranch(TOperator op, TIntermTyped* e) : 672 flowOp(op), 673 expression(e) { } 674 virtual TIntermBranch* getAsBranchNode() { return this; } 675 virtual const TIntermBranch* getAsBranchNode() const { return this; } 676 virtual void traverse(TIntermTraverser*); 677 TOperator getFlowOp() const { return flowOp; } 678 TIntermTyped* getExpression() const { return expression; } 679 protected: 680 TOperator flowOp; 681 TIntermTyped* expression; 682 }; 683 684 // 685 // Represent method names before seeing their calling signature 686 // or resolving them to operations. Just an expression as the base object 687 // and a textural name. 688 // 689 class TIntermMethod : public TIntermTyped { 690 public: 691 TIntermMethod(TIntermTyped* o, const TType& t, const TString& m) : TIntermTyped(t), object(o), method(m) { } 692 virtual TIntermMethod* getAsMethodNode() { return this; } 693 virtual const TIntermMethod* getAsMethodNode() const { return this; } 694 virtual const TString& getMethodName() const { return method; } 695 virtual TIntermTyped* getObject() const { return object; } 696 virtual void traverse(TIntermTraverser*); 697 protected: 698 TIntermTyped* object; 699 TString method; 700 }; 701 702 // 703 // Nodes that correspond to symbols or constants in the source code. 704 // 705 class TIntermSymbol : public TIntermTyped { 706 public: 707 // if symbol is initialized as symbol(sym), the memory comes from the pool allocator of sym. If sym comes from 708 // per process threadPoolAllocator, then it causes increased memory usage per compile 709 // it is essential to use "symbol = sym" to assign to symbol 710 TIntermSymbol(int i, const TString& n, const TType& t) 711 : TIntermTyped(t), id(i), constSubtree(nullptr) 712 { name = n; } 713 virtual int getId() const { return id; } 714 virtual const TString& getName() const { return name; } 715 virtual void traverse(TIntermTraverser*); 716 virtual TIntermSymbol* getAsSymbolNode() { return this; } 717 virtual const TIntermSymbol* getAsSymbolNode() const { return this; } 718 void setConstArray(const TConstUnionArray& c) { constArray = c; } 719 const TConstUnionArray& getConstArray() const { return constArray; } 720 void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; } 721 TIntermTyped* getConstSubtree() const { return constSubtree; } 722 723 protected: 724 int id; // the unique id of the symbol this node represents 725 TString name; // the name of the symbol this node represents 726 TConstUnionArray constArray; // if the symbol is a front-end compile-time constant, this is its value 727 TIntermTyped* constSubtree; 728 }; 729 730 class TIntermConstantUnion : public TIntermTyped { 731 public: 732 TIntermConstantUnion(const TConstUnionArray& ua, const TType& t) : TIntermTyped(t), constArray(ua), literal(false) { } 733 const TConstUnionArray& getConstArray() const { return constArray; } 734 virtual TIntermConstantUnion* getAsConstantUnion() { return this; } 735 virtual const TIntermConstantUnion* getAsConstantUnion() const { return this; } 736 virtual void traverse(TIntermTraverser*); 737 virtual TIntermTyped* fold(TOperator, const TIntermTyped*) const; 738 virtual TIntermTyped* fold(TOperator, const TType&) const; 739 void setLiteral() { literal = true; } 740 void setExpression() { literal = false; } 741 bool isLiteral() const { return literal; } 742 743 protected: 744 TIntermConstantUnion& operator=(const TIntermConstantUnion&); 745 746 const TConstUnionArray constArray; 747 bool literal; // true if node represents a literal in the source code 748 }; 749 750 // Represent the independent aspects of a texturing TOperator 751 struct TCrackedTextureOp { 752 bool query; 753 bool proj; 754 bool lod; 755 bool fetch; 756 bool offset; 757 bool offsets; 758 bool gather; 759 bool grad; 760 bool subpass; 761 bool lodClamp; 762 }; 763 764 // 765 // Intermediate class for node types that hold operators. 766 // 767 class TIntermOperator : public TIntermTyped { 768 public: 769 virtual TIntermOperator* getAsOperator() { return this; } 770 virtual const TIntermOperator* getAsOperator() const { return this; } 771 TOperator getOp() const { return op; } 772 virtual bool promote() { return true; } 773 bool modifiesState() const; 774 bool isConstructor() const; 775 bool isTexture() const { return op > EOpTextureGuardBegin && op < EOpTextureGuardEnd; } 776 bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; } 777 bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; } 778 bool isSparseImage() const { return op == EOpSparseImageLoad; } 779 780 // Crack the op into the individual dimensions of texturing operation. 781 void crackTexture(TSampler sampler, TCrackedTextureOp& cracked) const 782 { 783 cracked.query = false; 784 cracked.proj = false; 785 cracked.lod = false; 786 cracked.fetch = false; 787 cracked.offset = false; 788 cracked.offsets = false; 789 cracked.gather = false; 790 cracked.grad = false; 791 cracked.subpass = false; 792 cracked.lodClamp = false; 793 794 switch (op) { 795 case EOpImageQuerySize: 796 case EOpImageQuerySamples: 797 case EOpTextureQuerySize: 798 case EOpTextureQueryLod: 799 case EOpTextureQueryLevels: 800 case EOpTextureQuerySamples: 801 case EOpSparseTexelsResident: 802 cracked.query = true; 803 break; 804 case EOpTexture: 805 case EOpSparseTexture: 806 break; 807 case EOpTextureClamp: 808 case EOpSparseTextureClamp: 809 cracked.lodClamp = true; 810 break; 811 case EOpTextureProj: 812 cracked.proj = true; 813 break; 814 case EOpTextureLod: 815 case EOpSparseTextureLod: 816 cracked.lod = true; 817 break; 818 case EOpTextureOffset: 819 case EOpSparseTextureOffset: 820 cracked.offset = true; 821 break; 822 case EOpTextureOffsetClamp: 823 case EOpSparseTextureOffsetClamp: 824 cracked.offset = true; 825 cracked.lodClamp = true; 826 break; 827 case EOpTextureFetch: 828 case EOpSparseTextureFetch: 829 cracked.fetch = true; 830 if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D) 831 cracked.lod = true; 832 break; 833 case EOpTextureFetchOffset: 834 case EOpSparseTextureFetchOffset: 835 cracked.fetch = true; 836 cracked.offset = true; 837 if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D) 838 cracked.lod = true; 839 break; 840 case EOpTextureProjOffset: 841 cracked.offset = true; 842 cracked.proj = true; 843 break; 844 case EOpTextureLodOffset: 845 case EOpSparseTextureLodOffset: 846 cracked.offset = true; 847 cracked.lod = true; 848 break; 849 case EOpTextureProjLod: 850 cracked.lod = true; 851 cracked.proj = true; 852 break; 853 case EOpTextureProjLodOffset: 854 cracked.offset = true; 855 cracked.lod = true; 856 cracked.proj = true; 857 break; 858 case EOpTextureGrad: 859 case EOpSparseTextureGrad: 860 cracked.grad = true; 861 break; 862 case EOpTextureGradClamp: 863 case EOpSparseTextureGradClamp: 864 cracked.grad = true; 865 cracked.lodClamp = true; 866 break; 867 case EOpTextureGradOffset: 868 case EOpSparseTextureGradOffset: 869 cracked.grad = true; 870 cracked.offset = true; 871 break; 872 case EOpTextureProjGrad: 873 cracked.grad = true; 874 cracked.proj = true; 875 break; 876 case EOpTextureProjGradOffset: 877 cracked.grad = true; 878 cracked.offset = true; 879 cracked.proj = true; 880 break; 881 case EOpTextureGradOffsetClamp: 882 case EOpSparseTextureGradOffsetClamp: 883 cracked.grad = true; 884 cracked.offset = true; 885 cracked.lodClamp = true; 886 break; 887 case EOpTextureGather: 888 case EOpSparseTextureGather: 889 cracked.gather = true; 890 break; 891 case EOpTextureGatherOffset: 892 case EOpSparseTextureGatherOffset: 893 cracked.gather = true; 894 cracked.offset = true; 895 break; 896 case EOpTextureGatherOffsets: 897 case EOpSparseTextureGatherOffsets: 898 cracked.gather = true; 899 cracked.offsets = true; 900 break; 901 case EOpSubpassLoad: 902 case EOpSubpassLoadMS: 903 cracked.subpass = true; 904 break; 905 default: 906 break; 907 } 908 } 909 910 protected: 911 TIntermOperator(TOperator o) : TIntermTyped(EbtFloat), op(o) {} 912 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {} 913 TOperator op; 914 }; 915 916 // 917 // Nodes for all the basic binary math operators. 918 // 919 class TIntermBinary : public TIntermOperator { 920 public: 921 TIntermBinary(TOperator o) : TIntermOperator(o) {} 922 virtual void traverse(TIntermTraverser*); 923 virtual void setLeft(TIntermTyped* n) { left = n; } 924 virtual void setRight(TIntermTyped* n) { right = n; } 925 virtual TIntermTyped* getLeft() const { return left; } 926 virtual TIntermTyped* getRight() const { return right; } 927 virtual TIntermBinary* getAsBinaryNode() { return this; } 928 virtual const TIntermBinary* getAsBinaryNode() const { return this; } 929 virtual bool promote(); 930 virtual void updatePrecision(); 931 protected: 932 TIntermTyped* left; 933 TIntermTyped* right; 934 }; 935 936 // 937 // Nodes for unary math operators. 938 // 939 class TIntermUnary : public TIntermOperator { 940 public: 941 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {} 942 TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {} 943 virtual void traverse(TIntermTraverser*); 944 virtual void setOperand(TIntermTyped* o) { operand = o; } 945 virtual TIntermTyped* getOperand() { return operand; } 946 virtual const TIntermTyped* getOperand() const { return operand; } 947 virtual TIntermUnary* getAsUnaryNode() { return this; } 948 virtual const TIntermUnary* getAsUnaryNode() const { return this; } 949 virtual bool promote(); 950 virtual void updatePrecision(); 951 protected: 952 TIntermTyped* operand; 953 }; 954 955 typedef TVector<TIntermNode*> TIntermSequence; 956 typedef TVector<int> TQualifierList; 957 // 958 // Nodes that operate on an arbitrary sized set of children. 959 // 960 class TIntermAggregate : public TIntermOperator { 961 public: 962 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0) { } 963 TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { } 964 ~TIntermAggregate() { delete pragmaTable; } 965 virtual TIntermAggregate* getAsAggregate() { return this; } 966 virtual const TIntermAggregate* getAsAggregate() const { return this; } 967 virtual void setOperator(TOperator o) { op = o; } 968 virtual TIntermSequence& getSequence() { return sequence; } 969 virtual const TIntermSequence& getSequence() const { return sequence; } 970 virtual void setName(const TString& n) { name = n; } 971 virtual const TString& getName() const { return name; } 972 virtual void traverse(TIntermTraverser*); 973 virtual void setUserDefined() { userDefined = true; } 974 virtual bool isUserDefined() { return userDefined; } 975 virtual TQualifierList& getQualifierList() { return qualifier; } 976 virtual const TQualifierList& getQualifierList() const { return qualifier; } 977 void setOptimize(bool o) { optimize = o; } 978 void setDebug(bool d) { debug = d; } 979 bool getOptimize() const { return optimize; } 980 bool getDebug() const { return debug; } 981 void addToPragmaTable(const TPragmaTable& pTable); 982 const TPragmaTable& getPragmaTable() const { return *pragmaTable; } 983 protected: 984 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor 985 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator 986 TIntermSequence sequence; 987 TQualifierList qualifier; 988 TString name; 989 bool userDefined; // used for user defined function names 990 bool optimize; 991 bool debug; 992 TPragmaTable* pragmaTable; 993 }; 994 995 // 996 // For if tests. 997 // 998 class TIntermSelection : public TIntermTyped { 999 public: 1000 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) : 1001 TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB) {} 1002 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) : 1003 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {} 1004 virtual void traverse(TIntermTraverser*); 1005 virtual TIntermTyped* getCondition() const { return condition; } 1006 virtual TIntermNode* getTrueBlock() const { return trueBlock; } 1007 virtual TIntermNode* getFalseBlock() const { return falseBlock; } 1008 virtual TIntermSelection* getAsSelectionNode() { return this; } 1009 virtual const TIntermSelection* getAsSelectionNode() const { return this; } 1010 protected: 1011 TIntermTyped* condition; 1012 TIntermNode* trueBlock; 1013 TIntermNode* falseBlock; 1014 }; 1015 1016 // 1017 // For switch statements. Designed use is that a switch will have sequence of nodes 1018 // that are either case/default nodes or a *single* node that represents all the code 1019 // in between (if any) consecutive case/defaults. So, a traversal need only deal with 1020 // 0 or 1 nodes per case/default statement. 1021 // 1022 class TIntermSwitch : public TIntermNode { 1023 public: 1024 TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b) { } 1025 virtual void traverse(TIntermTraverser*); 1026 virtual TIntermNode* getCondition() const { return condition; } 1027 virtual TIntermAggregate* getBody() const { return body; } 1028 virtual TIntermSwitch* getAsSwitchNode() { return this; } 1029 virtual const TIntermSwitch* getAsSwitchNode() const { return this; } 1030 protected: 1031 TIntermTyped* condition; 1032 TIntermAggregate* body; 1033 }; 1034 1035 enum TVisit 1036 { 1037 EvPreVisit, 1038 EvInVisit, 1039 EvPostVisit 1040 }; 1041 1042 // 1043 // For traversing the tree. User should derive from this, 1044 // put their traversal specific data in it, and then pass 1045 // it to a Traverse method. 1046 // 1047 // When using this, just fill in the methods for nodes you want visited. 1048 // Return false from a pre-visit to skip visiting that node's subtree. 1049 // 1050 // Explicitly set postVisit to true if you want post visiting, otherwise, 1051 // filled in methods will only be called at pre-visit time (before processing 1052 // the subtree). Similarly for inVisit for in-order visiting of nodes with 1053 // multiple children. 1054 // 1055 // If you only want post-visits, explicitly turn off preVisit (and inVisit) 1056 // and turn on postVisit. 1057 // 1058 // In general, for the visit*() methods, return true from interior nodes 1059 // to have the traversal continue on to children. 1060 // 1061 // If you process children yourself, or don't want them processed, return false. 1062 // 1063 class TIntermTraverser { 1064 public: 1065 POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator()) 1066 TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) : 1067 preVisit(preVisit), 1068 inVisit(inVisit), 1069 postVisit(postVisit), 1070 rightToLeft(rightToLeft), 1071 depth(0), 1072 maxDepth(0) { } 1073 virtual ~TIntermTraverser() { } 1074 1075 virtual void visitSymbol(TIntermSymbol*) { } 1076 virtual void visitConstantUnion(TIntermConstantUnion*) { } 1077 virtual bool visitBinary(TVisit, TIntermBinary*) { return true; } 1078 virtual bool visitUnary(TVisit, TIntermUnary*) { return true; } 1079 virtual bool visitSelection(TVisit, TIntermSelection*) { return true; } 1080 virtual bool visitAggregate(TVisit, TIntermAggregate*) { return true; } 1081 virtual bool visitLoop(TVisit, TIntermLoop*) { return true; } 1082 virtual bool visitBranch(TVisit, TIntermBranch*) { return true; } 1083 virtual bool visitSwitch(TVisit, TIntermSwitch*) { return true; } 1084 1085 int getMaxDepth() const { return maxDepth; } 1086 1087 void incrementDepth(TIntermNode *current) 1088 { 1089 depth++; 1090 maxDepth = (std::max)(maxDepth, depth); 1091 path.push_back(current); 1092 } 1093 1094 void decrementDepth() 1095 { 1096 depth--; 1097 path.pop_back(); 1098 } 1099 1100 TIntermNode *getParentNode() 1101 { 1102 return path.size() == 0 ? NULL : path.back(); 1103 } 1104 1105 const bool preVisit; 1106 const bool inVisit; 1107 const bool postVisit; 1108 const bool rightToLeft; 1109 1110 protected: 1111 TIntermTraverser& operator=(TIntermTraverser&); 1112 1113 int depth; 1114 int maxDepth; 1115 1116 // All the nodes from root to the current node's parent during traversing. 1117 TVector<TIntermNode *> path; 1118 }; 1119 1120 // KHR_vulkan_glsl says "Two arrays sized with specialization constants are the same type only if 1121 // sized with the same symbol, involving no operations" 1122 inline bool SameSpecializationConstants(TIntermTyped* node1, TIntermTyped* node2) 1123 { 1124 return node1->getAsSymbolNode() && node2->getAsSymbolNode() && 1125 node1->getAsSymbolNode()->getId() == node2->getAsSymbolNode()->getId(); 1126 } 1127 1128 } // end namespace glslang 1129 1130 #endif // __INTERMEDIATE_H 1131