1 // 2 // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. 3 // Copyright (C) 2012-2015 LunarG, Inc. 4 // Copyright (C) 2015-2016 Google, Inc. 5 // 6 // All rights reserved. 7 // 8 // Redistribution and use in source and binary forms, with or without 9 // modification, are permitted provided that the following conditions 10 // are met: 11 // 12 // Redistributions of source code must retain the above copyright 13 // notice, this list of conditions and the following disclaimer. 14 // 15 // Redistributions in binary form must reproduce the above 16 // copyright notice, this list of conditions and the following 17 // disclaimer in the documentation and/or other materials provided 18 // with the distribution. 19 // 20 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its 21 // contributors may be used to endorse or promote products derived 22 // from this software without specific prior written permission. 23 // 24 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 27 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 28 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 29 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 30 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 34 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 // POSSIBILITY OF SUCH DAMAGE. 36 // 37 38 // 39 // Build the intermediate representation. 40 // 41 42 #include "localintermediate.h" 43 #include "RemoveTree.h" 44 #include "SymbolTable.h" 45 #include "propagateNoContraction.h" 46 47 #include <cfloat> 48 #include <utility> 49 50 namespace glslang { 51 52 //////////////////////////////////////////////////////////////////////////// 53 // 54 // First set of functions are to help build the intermediate representation. 55 // These functions are not member functions of the nodes. 56 // They are called from parser productions. 57 // 58 ///////////////////////////////////////////////////////////////////////////// 59 60 // 61 // Add a terminal node for an identifier in an expression. 62 // 63 // Returns the added node. 64 // 65 66 TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, const TConstUnionArray& constArray, 67 TIntermTyped* constSubtree, const TSourceLoc& loc) 68 { 69 TIntermSymbol* node = new TIntermSymbol(id, name, type); 70 node->setLoc(loc); 71 node->setConstArray(constArray); 72 node->setConstSubtree(constSubtree); 73 74 return node; 75 } 76 77 TIntermSymbol* TIntermediate::addSymbol(const TIntermSymbol& intermSymbol) 78 { 79 return addSymbol(intermSymbol.getId(), 80 intermSymbol.getName(), 81 intermSymbol.getType(), 82 intermSymbol.getConstArray(), 83 intermSymbol.getConstSubtree(), 84 intermSymbol.getLoc()); 85 } 86 87 TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable) 88 { 89 glslang::TSourceLoc loc; // just a null location 90 loc.init(); 91 92 return addSymbol(variable, loc); 93 } 94 95 TIntermSymbol* TIntermediate::addSymbol(const TVariable& variable, const TSourceLoc& loc) 96 { 97 return addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), variable.getConstArray(), variable.getConstSubtree(), loc); 98 } 99 100 TIntermSymbol* TIntermediate::addSymbol(const TType& type, const TSourceLoc& loc) 101 { 102 TConstUnionArray unionArray; // just a null constant 103 104 return addSymbol(0, "", type, unionArray, nullptr, loc); 105 } 106 107 // 108 // Connect two nodes with a new parent that does a binary operation on the nodes. 109 // 110 // Returns the added node. 111 // 112 // Returns nullptr if the working conversions and promotions could not be found. 113 // 114 TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) 115 { 116 // No operations work on blocks 117 if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock) 118 return nullptr; 119 120 // Try converting the children's base types to compatible types. 121 TIntermTyped* child = addConversion(op, left->getType(), right); 122 if (child) 123 right = child; 124 else { 125 child = addConversion(op, right->getType(), left); 126 if (child) 127 left = child; 128 else 129 return nullptr; 130 } 131 132 // Convert the children's type shape to be compatible. 133 addBiShapeConversion(op, left, right); 134 if (left == nullptr || right == nullptr) 135 return nullptr; 136 137 // 138 // Need a new node holding things together. Make 139 // one and promote it to the right type. 140 // 141 TIntermBinary* node = addBinaryNode(op, left, right, loc); 142 if (! promote(node)) 143 return nullptr; 144 145 node->updatePrecision(); 146 147 // 148 // If they are both (non-specialization) constants, they must be folded. 149 // (Unless it's the sequence (comma) operator, but that's handled in addComma().) 150 // 151 TIntermConstantUnion *leftTempConstant = node->getLeft()->getAsConstantUnion(); 152 TIntermConstantUnion *rightTempConstant = node->getRight()->getAsConstantUnion(); 153 if (leftTempConstant && rightTempConstant) { 154 TIntermTyped* folded = leftTempConstant->fold(node->getOp(), rightTempConstant); 155 if (folded) 156 return folded; 157 } 158 159 // If can propagate spec-constantness and if the operation is an allowed 160 // specialization-constant operation, make a spec-constant. 161 if (specConstantPropagates(*node->getLeft(), *node->getRight()) && isSpecializationOperation(*node)) 162 node->getWritableType().getQualifier().makeSpecConstant(); 163 164 return node; 165 } 166 167 // 168 // Low level: add binary node (no promotions or other argument modifications) 169 // 170 TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) const 171 { 172 // build the node 173 TIntermBinary* node = new TIntermBinary(op); 174 if (loc.line == 0) 175 loc = left->getLoc(); 176 node->setLoc(loc); 177 node->setLeft(left); 178 node->setRight(right); 179 180 return node; 181 } 182 183 // 184 // like non-type form, but sets node's type. 185 // 186 TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc, const TType& type) const 187 { 188 TIntermBinary* node = addBinaryNode(op, left, right, loc); 189 node->setType(type); 190 return node; 191 } 192 193 // 194 // Low level: add unary node (no promotions or other argument modifications) 195 // 196 TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc loc) const 197 { 198 TIntermUnary* node = new TIntermUnary(op); 199 if (loc.line == 0) 200 loc = child->getLoc(); 201 node->setLoc(loc); 202 node->setOperand(child); 203 204 return node; 205 } 206 207 // 208 // like non-type form, but sets node's type. 209 // 210 TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc loc, const TType& type) const 211 { 212 TIntermUnary* node = addUnaryNode(op, child, loc); 213 node->setType(type); 214 return node; 215 } 216 217 // 218 // Connect two nodes through an assignment. 219 // 220 // Returns the added node. 221 // 222 // Returns nullptr if the 'right' type could not be converted to match the 'left' type, 223 // or the resulting operation cannot be properly promoted. 224 // 225 TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) 226 { 227 // No block assignment 228 if (left->getType().getBasicType() == EbtBlock || right->getType().getBasicType() == EbtBlock) 229 return nullptr; 230 231 // 232 // Like adding binary math, except the conversion can only go 233 // from right to left. 234 // 235 236 // convert base types, nullptr return means not possible 237 right = addConversion(op, left->getType(), right); 238 if (right == nullptr) 239 return nullptr; 240 241 // convert shape 242 right = addUniShapeConversion(op, left->getType(), right); 243 244 // build the node 245 TIntermBinary* node = addBinaryNode(op, left, right, loc); 246 247 if (! promote(node)) 248 return nullptr; 249 250 node->updatePrecision(); 251 252 return node; 253 } 254 255 // 256 // Connect two nodes through an index operator, where the left node is the base 257 // of an array or struct, and the right node is a direct or indirect offset. 258 // 259 // Returns the added node. 260 // The caller should set the type of the returned node. 261 // 262 TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc loc) 263 { 264 // caller should set the type 265 return addBinaryNode(op, base, index, loc); 266 } 267 268 // 269 // Add one node as the parent of another that it operates on. 270 // 271 // Returns the added node. 272 // 273 TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSourceLoc loc) 274 { 275 if (child == 0) 276 return nullptr; 277 278 if (child->getType().getBasicType() == EbtBlock) 279 return nullptr; 280 281 switch (op) { 282 case EOpLogicalNot: 283 if (source == EShSourceHlsl) { 284 break; // HLSL can promote logical not 285 } 286 287 if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) { 288 return nullptr; 289 } 290 break; 291 292 case EOpPostIncrement: 293 case EOpPreIncrement: 294 case EOpPostDecrement: 295 case EOpPreDecrement: 296 case EOpNegative: 297 if (child->getType().getBasicType() == EbtStruct || child->getType().isArray()) 298 return nullptr; 299 default: break; // some compilers want this 300 } 301 302 // 303 // Do we need to promote the operand? 304 // 305 TBasicType newType = EbtVoid; 306 switch (op) { 307 case EOpConstructInt: newType = EbtInt; break; 308 case EOpConstructUint: newType = EbtUint; break; 309 case EOpConstructInt64: newType = EbtInt64; break; 310 case EOpConstructUint64: newType = EbtUint64; break; 311 #ifdef AMD_EXTENSIONS 312 case EOpConstructInt16: newType = EbtInt16; break; 313 case EOpConstructUint16: newType = EbtUint16; break; 314 #endif 315 case EOpConstructBool: newType = EbtBool; break; 316 case EOpConstructFloat: newType = EbtFloat; break; 317 case EOpConstructDouble: newType = EbtDouble; break; 318 #ifdef AMD_EXTENSIONS 319 case EOpConstructFloat16: newType = EbtFloat16; break; 320 #endif 321 default: break; // some compilers want this 322 } 323 324 if (newType != EbtVoid) { 325 child = addConversion(op, TType(newType, EvqTemporary, child->getVectorSize(), 326 child->getMatrixCols(), 327 child->getMatrixRows(), 328 child->isVector()), 329 child); 330 if (child == nullptr) 331 return nullptr; 332 } 333 334 // 335 // For constructors, we are now done, it was all in the conversion. 336 // TODO: but, did this bypass constant folding? 337 // 338 switch (op) { 339 case EOpConstructInt: 340 case EOpConstructUint: 341 case EOpConstructInt64: 342 case EOpConstructUint64: 343 #ifdef AMD_EXTENSIONS 344 case EOpConstructInt16: 345 case EOpConstructUint16: 346 #endif 347 case EOpConstructBool: 348 case EOpConstructFloat: 349 case EOpConstructDouble: 350 #ifdef AMD_EXTENSIONS 351 case EOpConstructFloat16: 352 #endif 353 return child; 354 default: break; // some compilers want this 355 } 356 357 // 358 // Make a new node for the operator. 359 // 360 TIntermUnary* node = addUnaryNode(op, child, loc); 361 362 if (! promote(node)) 363 return nullptr; 364 365 node->updatePrecision(); 366 367 // If it's a (non-specialization) constant, it must be folded. 368 if (node->getOperand()->getAsConstantUnion()) 369 return node->getOperand()->getAsConstantUnion()->fold(op, node->getType()); 370 371 // If it's a specialization constant, the result is too, 372 // if the operation is allowed for specialization constants. 373 if (node->getOperand()->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*node)) 374 node->getWritableType().getQualifier().makeSpecConstant(); 375 376 return node; 377 } 378 379 TIntermTyped* TIntermediate::addBuiltInFunctionCall(const TSourceLoc& loc, TOperator op, bool unary, TIntermNode* childNode, const TType& returnType) 380 { 381 if (unary) { 382 // 383 // Treat it like a unary operator. 384 // addUnaryMath() should get the type correct on its own; 385 // including constness (which would differ from the prototype). 386 // 387 TIntermTyped* child = childNode->getAsTyped(); 388 if (child == nullptr) 389 return nullptr; 390 391 if (child->getAsConstantUnion()) { 392 TIntermTyped* folded = child->getAsConstantUnion()->fold(op, returnType); 393 if (folded) 394 return folded; 395 } 396 397 return addUnaryNode(op, child, child->getLoc(), returnType); 398 } else { 399 // setAggregateOperater() calls fold() for constant folding 400 TIntermTyped* node = setAggregateOperator(childNode, op, returnType, loc); 401 402 return node; 403 } 404 } 405 406 // 407 // This is the safe way to change the operator on an aggregate, as it 408 // does lots of error checking and fixing. Especially for establishing 409 // a function call's operation on it's set of parameters. Sequences 410 // of instructions are also aggregates, but they just directly set 411 // their operator to EOpSequence. 412 // 413 // Returns an aggregate node, which could be the one passed in if 414 // it was already an aggregate. 415 // 416 TIntermTyped* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TType& type, TSourceLoc loc) 417 { 418 TIntermAggregate* aggNode; 419 420 // 421 // Make sure we have an aggregate. If not turn it into one. 422 // 423 if (node) { 424 aggNode = node->getAsAggregate(); 425 if (aggNode == nullptr || aggNode->getOp() != EOpNull) { 426 // 427 // Make an aggregate containing this node. 428 // 429 aggNode = new TIntermAggregate(); 430 aggNode->getSequence().push_back(node); 431 if (loc.line == 0) 432 loc = node->getLoc(); 433 } 434 } else 435 aggNode = new TIntermAggregate(); 436 437 // 438 // Set the operator. 439 // 440 aggNode->setOperator(op); 441 if (loc.line != 0) 442 aggNode->setLoc(loc); 443 444 aggNode->setType(type); 445 446 return fold(aggNode); 447 } 448 449 // 450 // Convert the node's type to the given type, as allowed by the operation involved: 'op'. 451 // For implicit conversions, 'op' is not the requested conversion, it is the explicit 452 // operation requiring the implicit conversion. 453 // 454 // Returns a node representing the conversion, which could be the same 455 // node passed in if no conversion was needed. 456 // 457 // Generally, this is focused on basic type conversion, not shape conversion. 458 // See addShapeConversion(). 459 // 460 // Return nullptr if a conversion can't be done. 461 // 462 TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node) const 463 { 464 // 465 // Does the base type even allow the operation? 466 // 467 switch (node->getBasicType()) { 468 case EbtVoid: 469 return nullptr; 470 case EbtAtomicUint: 471 case EbtSampler: 472 // opaque types can be passed to functions 473 if (op == EOpFunction) 474 break; 475 476 // HLSL can assign samplers directly (no constructor) 477 if (source == EShSourceHlsl && node->getBasicType() == EbtSampler) 478 break; 479 480 // samplers can get assigned via a sampler constructor 481 // (well, not yet, but code in the rest of this function is ready for it) 482 if (node->getBasicType() == EbtSampler && op == EOpAssign && 483 node->getAsOperator() != nullptr && node->getAsOperator()->getOp() == EOpConstructTextureSampler) 484 break; 485 486 // otherwise, opaque types can't even be operated on, let alone converted 487 return nullptr; 488 default: 489 break; 490 } 491 492 // Otherwise, if types are identical, no problem 493 if (type == node->getType()) 494 return node; 495 496 // If one's a structure, then no conversions. 497 if (type.isStruct() || node->isStruct()) 498 return nullptr; 499 500 // If one's an array, then no conversions. 501 if (type.isArray() || node->getType().isArray()) 502 return nullptr; 503 504 // Note: callers are responsible for other aspects of shape, 505 // like vector and matrix sizes. 506 507 TBasicType promoteTo; 508 509 switch (op) { 510 // 511 // Explicit conversions (unary operations) 512 // 513 case EOpConstructBool: 514 promoteTo = EbtBool; 515 break; 516 case EOpConstructFloat: 517 promoteTo = EbtFloat; 518 break; 519 case EOpConstructDouble: 520 promoteTo = EbtDouble; 521 break; 522 #ifdef AMD_EXTENSIONS 523 case EOpConstructFloat16: 524 promoteTo = EbtFloat16; 525 break; 526 #endif 527 case EOpConstructInt: 528 promoteTo = EbtInt; 529 break; 530 case EOpConstructUint: 531 promoteTo = EbtUint; 532 break; 533 case EOpConstructInt64: 534 promoteTo = EbtInt64; 535 break; 536 case EOpConstructUint64: 537 promoteTo = EbtUint64; 538 break; 539 #ifdef AMD_EXTENSIONS 540 case EOpConstructInt16: 541 promoteTo = EbtInt16; 542 break; 543 case EOpConstructUint16: 544 promoteTo = EbtUint16; 545 break; 546 #endif 547 548 // 549 // List all the binary ops that can implicitly convert one operand to the other's type; 550 // This implements the 'policy' for implicit type conversion. 551 // 552 case EOpLessThan: 553 case EOpGreaterThan: 554 case EOpLessThanEqual: 555 case EOpGreaterThanEqual: 556 case EOpEqual: 557 case EOpNotEqual: 558 559 case EOpAdd: 560 case EOpSub: 561 case EOpMul: 562 case EOpDiv: 563 case EOpMod: 564 565 case EOpVectorTimesScalar: 566 case EOpVectorTimesMatrix: 567 case EOpMatrixTimesVector: 568 case EOpMatrixTimesScalar: 569 570 case EOpAnd: 571 case EOpInclusiveOr: 572 case EOpExclusiveOr: 573 case EOpAndAssign: 574 case EOpInclusiveOrAssign: 575 case EOpExclusiveOrAssign: 576 case EOpLogicalNot: 577 case EOpLogicalAnd: 578 case EOpLogicalOr: 579 case EOpLogicalXor: 580 581 case EOpFunctionCall: 582 case EOpReturn: 583 case EOpAssign: 584 case EOpAddAssign: 585 case EOpSubAssign: 586 case EOpMulAssign: 587 case EOpVectorTimesScalarAssign: 588 case EOpMatrixTimesScalarAssign: 589 case EOpDivAssign: 590 case EOpModAssign: 591 592 case EOpAtan: 593 case EOpClamp: 594 case EOpCross: 595 case EOpDistance: 596 case EOpDot: 597 case EOpDst: 598 case EOpFaceForward: 599 case EOpFma: 600 case EOpFrexp: 601 case EOpLdexp: 602 case EOpMix: 603 case EOpLit: 604 case EOpMax: 605 case EOpMin: 606 case EOpModf: 607 case EOpPow: 608 case EOpReflect: 609 case EOpRefract: 610 case EOpSmoothStep: 611 case EOpStep: 612 613 case EOpSequence: 614 case EOpConstructStruct: 615 616 if (type.getBasicType() == node->getType().getBasicType()) 617 return node; 618 619 if (canImplicitlyPromote(node->getType().getBasicType(), type.getBasicType(), op)) 620 promoteTo = type.getBasicType(); 621 else 622 return nullptr; 623 624 break; 625 626 // Shifts can have mixed types as long as they are integer, without converting. 627 // It's the left operand's type that determines the resulting type, so no issue 628 // with assign shift ops either. 629 case EOpLeftShift: 630 case EOpRightShift: 631 case EOpLeftShiftAssign: 632 case EOpRightShiftAssign: 633 if ((type.getBasicType() == EbtInt || 634 type.getBasicType() == EbtUint || 635 #ifdef AMD_EXTENSIONS 636 type.getBasicType() == EbtInt16 || 637 type.getBasicType() == EbtUint16 || 638 #endif 639 type.getBasicType() == EbtInt64 || 640 type.getBasicType() == EbtUint64) && 641 (node->getType().getBasicType() == EbtInt || 642 node->getType().getBasicType() == EbtUint || 643 #ifdef AMD_EXTENSIONS 644 node->getType().getBasicType() == EbtInt16 || 645 node->getType().getBasicType() == EbtUint16 || 646 #endif 647 node->getType().getBasicType() == EbtInt64 || 648 node->getType().getBasicType() == EbtUint64)) 649 650 return node; 651 else if (source == EShSourceHlsl && node->getType().getBasicType() == EbtBool) { 652 promoteTo = type.getBasicType(); 653 break; 654 } else 655 return nullptr; 656 657 default: 658 // default is to require a match; all exceptions should have case statements above 659 660 if (type.getBasicType() == node->getType().getBasicType()) 661 return node; 662 else 663 return nullptr; 664 } 665 666 if (node->getAsConstantUnion()) 667 return promoteConstantUnion(promoteTo, node->getAsConstantUnion()); 668 669 // 670 // Add a new newNode for the conversion. 671 // 672 TIntermUnary* newNode = nullptr; 673 674 TOperator newOp = EOpNull; 675 676 // This is 'mechanism' here, it does any conversion told. The policy comes 677 // from the shader or the above code. 678 switch (promoteTo) { 679 case EbtDouble: 680 switch (node->getBasicType()) { 681 case EbtInt: newOp = EOpConvIntToDouble; break; 682 case EbtUint: newOp = EOpConvUintToDouble; break; 683 case EbtBool: newOp = EOpConvBoolToDouble; break; 684 case EbtFloat: newOp = EOpConvFloatToDouble; break; 685 #ifdef AMD_EXTENSIONS 686 case EbtFloat16: newOp = EOpConvFloat16ToDouble; break; 687 #endif 688 case EbtInt64: newOp = EOpConvInt64ToDouble; break; 689 case EbtUint64: newOp = EOpConvUint64ToDouble; break; 690 #ifdef AMD_EXTENSIONS 691 case EbtInt16: newOp = EOpConvInt16ToDouble; break; 692 case EbtUint16: newOp = EOpConvUint16ToDouble; break; 693 #endif 694 default: 695 return nullptr; 696 } 697 break; 698 case EbtFloat: 699 switch (node->getBasicType()) { 700 case EbtInt: newOp = EOpConvIntToFloat; break; 701 case EbtUint: newOp = EOpConvUintToFloat; break; 702 case EbtBool: newOp = EOpConvBoolToFloat; break; 703 case EbtDouble: newOp = EOpConvDoubleToFloat; break; 704 #ifdef AMD_EXTENSIONS 705 case EbtFloat16: newOp = EOpConvFloat16ToFloat; break; 706 #endif 707 case EbtInt64: newOp = EOpConvInt64ToFloat; break; 708 case EbtUint64: newOp = EOpConvUint64ToFloat; break; 709 #ifdef AMD_EXTENSIONS 710 case EbtInt16: newOp = EOpConvInt16ToFloat; break; 711 case EbtUint16: newOp = EOpConvUint16ToFloat; break; 712 #endif 713 default: 714 return nullptr; 715 } 716 break; 717 #ifdef AMD_EXTENSIONS 718 case EbtFloat16: 719 switch (node->getBasicType()) { 720 case EbtInt: newOp = EOpConvIntToFloat16; break; 721 case EbtUint: newOp = EOpConvUintToFloat16; break; 722 case EbtBool: newOp = EOpConvBoolToFloat16; break; 723 case EbtFloat: newOp = EOpConvFloatToFloat16; break; 724 case EbtDouble: newOp = EOpConvDoubleToFloat16; break; 725 case EbtInt64: newOp = EOpConvInt64ToFloat16; break; 726 case EbtUint64: newOp = EOpConvUint64ToFloat16; break; 727 case EbtInt16: newOp = EOpConvInt16ToFloat16; break; 728 case EbtUint16: newOp = EOpConvUint16ToFloat16; break; 729 default: 730 return nullptr; 731 } 732 break; 733 #endif 734 case EbtBool: 735 switch (node->getBasicType()) { 736 case EbtInt: newOp = EOpConvIntToBool; break; 737 case EbtUint: newOp = EOpConvUintToBool; break; 738 case EbtFloat: newOp = EOpConvFloatToBool; break; 739 case EbtDouble: newOp = EOpConvDoubleToBool; break; 740 #ifdef AMD_EXTENSIONS 741 case EbtFloat16: newOp = EOpConvFloat16ToBool; break; 742 #endif 743 case EbtInt64: newOp = EOpConvInt64ToBool; break; 744 case EbtUint64: newOp = EOpConvUint64ToBool; break; 745 #ifdef AMD_EXTENSIONS 746 case EbtInt16: newOp = EOpConvInt16ToBool; break; 747 case EbtUint16: newOp = EOpConvUint16ToBool; break; 748 #endif 749 default: 750 return nullptr; 751 } 752 break; 753 case EbtInt: 754 switch (node->getBasicType()) { 755 case EbtUint: newOp = EOpConvUintToInt; break; 756 case EbtBool: newOp = EOpConvBoolToInt; break; 757 case EbtFloat: newOp = EOpConvFloatToInt; break; 758 case EbtDouble: newOp = EOpConvDoubleToInt; break; 759 #ifdef AMD_EXTENSIONS 760 case EbtFloat16: newOp = EOpConvFloat16ToInt; break; 761 #endif 762 case EbtInt64: newOp = EOpConvInt64ToInt; break; 763 case EbtUint64: newOp = EOpConvUint64ToInt; break; 764 #ifdef AMD_EXTENSIONS 765 case EbtInt16: newOp = EOpConvInt16ToInt; break; 766 case EbtUint16: newOp = EOpConvUint16ToInt; break; 767 #endif 768 default: 769 return nullptr; 770 } 771 break; 772 case EbtUint: 773 switch (node->getBasicType()) { 774 case EbtInt: newOp = EOpConvIntToUint; break; 775 case EbtBool: newOp = EOpConvBoolToUint; break; 776 case EbtFloat: newOp = EOpConvFloatToUint; break; 777 case EbtDouble: newOp = EOpConvDoubleToUint; break; 778 #ifdef AMD_EXTENSIONS 779 case EbtFloat16: newOp = EOpConvFloat16ToUint; break; 780 #endif 781 case EbtInt64: newOp = EOpConvInt64ToUint; break; 782 case EbtUint64: newOp = EOpConvUint64ToUint; break; 783 #ifdef AMD_EXTENSIONS 784 case EbtInt16: newOp = EOpConvInt16ToUint; break; 785 case EbtUint16: newOp = EOpConvUint16ToUint; break; 786 #endif 787 default: 788 return nullptr; 789 } 790 break; 791 case EbtInt64: 792 switch (node->getBasicType()) { 793 case EbtInt: newOp = EOpConvIntToInt64; break; 794 case EbtUint: newOp = EOpConvUintToInt64; break; 795 case EbtBool: newOp = EOpConvBoolToInt64; break; 796 case EbtFloat: newOp = EOpConvFloatToInt64; break; 797 case EbtDouble: newOp = EOpConvDoubleToInt64; break; 798 #ifdef AMD_EXTENSIONS 799 case EbtFloat16: newOp = EOpConvFloat16ToInt64; break; 800 #endif 801 case EbtUint64: newOp = EOpConvUint64ToInt64; break; 802 #ifdef AMD_EXTENSIONS 803 case EbtInt16: newOp = EOpConvInt16ToInt64; break; 804 case EbtUint16: newOp = EOpConvUint16ToInt64; break; 805 #endif 806 default: 807 return nullptr; 808 } 809 break; 810 case EbtUint64: 811 switch (node->getBasicType()) { 812 case EbtInt: newOp = EOpConvIntToUint64; break; 813 case EbtUint: newOp = EOpConvUintToUint64; break; 814 case EbtBool: newOp = EOpConvBoolToUint64; break; 815 case EbtFloat: newOp = EOpConvFloatToUint64; break; 816 case EbtDouble: newOp = EOpConvDoubleToUint64; break; 817 #ifdef AMD_EXTENSIONS 818 case EbtFloat16: newOp = EOpConvFloat16ToUint64; break; 819 #endif 820 case EbtInt64: newOp = EOpConvInt64ToUint64; break; 821 #ifdef AMD_EXTENSIONS 822 case EbtInt16: newOp = EOpConvInt16ToUint64; break; 823 case EbtUint16: newOp = EOpConvUint16ToUint64; break; 824 #endif 825 default: 826 return nullptr; 827 } 828 break; 829 #ifdef AMD_EXTENSIONS 830 case EbtInt16: 831 switch (node->getBasicType()) { 832 case EbtInt: newOp = EOpConvIntToInt16; break; 833 case EbtUint: newOp = EOpConvUintToInt16; break; 834 case EbtBool: newOp = EOpConvBoolToInt16; break; 835 case EbtFloat: newOp = EOpConvFloatToInt16; break; 836 case EbtDouble: newOp = EOpConvDoubleToInt16; break; 837 case EbtFloat16: newOp = EOpConvFloat16ToInt16; break; 838 case EbtInt64: newOp = EOpConvInt64ToInt16; break; 839 case EbtUint64: newOp = EOpConvUint64ToInt16; break; 840 case EbtUint16: newOp = EOpConvUint16ToInt16; break; 841 default: 842 return nullptr; 843 } 844 break; 845 case EbtUint16: 846 switch (node->getBasicType()) { 847 case EbtInt: newOp = EOpConvIntToUint16; break; 848 case EbtUint: newOp = EOpConvUintToUint16; break; 849 case EbtBool: newOp = EOpConvBoolToUint16; break; 850 case EbtFloat: newOp = EOpConvFloatToUint16; break; 851 case EbtDouble: newOp = EOpConvDoubleToUint16; break; 852 case EbtFloat16: newOp = EOpConvFloat16ToUint16; break; 853 case EbtInt64: newOp = EOpConvInt64ToUint16; break; 854 case EbtUint64: newOp = EOpConvUint64ToUint16; break; 855 case EbtInt16: newOp = EOpConvInt16ToUint16; break; 856 default: 857 return nullptr; 858 } 859 break; 860 #endif 861 default: 862 return nullptr; 863 } 864 865 TType newType(promoteTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows()); 866 newNode = addUnaryNode(newOp, node, node->getLoc(), newType); 867 868 // TODO: it seems that some unary folding operations should occur here, but are not 869 870 // Propagate specialization-constant-ness, if allowed 871 if (node->getType().getQualifier().isSpecConstant() && isSpecializationOperation(*newNode)) 872 newNode->getWritableType().getQualifier().makeSpecConstant(); 873 874 return newNode; 875 } 876 877 // Convert the node's shape of type for the given type, as allowed by the 878 // operation involved: 'op'. This is for situations where there is only one 879 // direction to consider doing the shape conversion. 880 // 881 // This implements policy, it call addShapeConversion() for the mechanism. 882 // 883 // Generally, the AST represents allowed GLSL shapes, so this isn't needed 884 // for GLSL. Bad shapes are caught in conversion or promotion. 885 // 886 // Return 'node' if no conversion was done. Promotion handles final shape 887 // checking. 888 // 889 TIntermTyped* TIntermediate::addUniShapeConversion(TOperator op, const TType& type, TIntermTyped* node) 890 { 891 // some source languages don't do this 892 switch (source) { 893 case EShSourceHlsl: 894 break; 895 case EShSourceGlsl: 896 default: 897 return node; 898 } 899 900 // some operations don't do this 901 switch (op) { 902 case EOpFunctionCall: 903 case EOpReturn: 904 break; 905 906 case EOpMulAssign: 907 // want to support vector *= scalar native ops in AST and lower, not smear, similarly for 908 // matrix *= scalar, etc. 909 910 case EOpAddAssign: 911 case EOpSubAssign: 912 case EOpDivAssign: 913 case EOpAndAssign: 914 case EOpInclusiveOrAssign: 915 case EOpExclusiveOrAssign: 916 case EOpRightShiftAssign: 917 case EOpLeftShiftAssign: 918 if (node->getVectorSize() == 1) 919 return node; 920 break; 921 922 case EOpAssign: 923 break; 924 925 case EOpMix: 926 break; 927 928 default: 929 return node; 930 } 931 932 return addShapeConversion(type, node); 933 } 934 935 // Convert the nodes' shapes to be compatible for the operation 'op'. 936 // 937 // This implements policy, it call addShapeConversion() for the mechanism. 938 // 939 // Generally, the AST represents allowed GLSL shapes, so this isn't needed 940 // for GLSL. Bad shapes are caught in conversion or promotion. 941 // 942 void TIntermediate::addBiShapeConversion(TOperator op, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode) 943 { 944 // some source languages don't do this 945 switch (source) { 946 case EShSourceHlsl: 947 break; 948 case EShSourceGlsl: 949 default: 950 return; 951 } 952 953 // some operations don't do this 954 // 'break' will mean attempt bidirectional conversion 955 switch (op) { 956 case EOpMulAssign: 957 case EOpAssign: 958 case EOpAddAssign: 959 case EOpSubAssign: 960 case EOpDivAssign: 961 case EOpAndAssign: 962 case EOpInclusiveOrAssign: 963 case EOpExclusiveOrAssign: 964 case EOpRightShiftAssign: 965 case EOpLeftShiftAssign: 966 // switch to unidirectional conversion (the lhs can't change) 967 rhsNode = addUniShapeConversion(op, lhsNode->getType(), rhsNode); 968 return; 969 970 case EOpAdd: 971 case EOpSub: 972 case EOpMul: 973 case EOpDiv: 974 // want to support vector * scalar native ops in AST and lower, not smear, similarly for 975 // matrix * vector, etc. 976 if (lhsNode->getVectorSize() == 1 || rhsNode->getVectorSize() == 1) 977 return; 978 break; 979 980 case EOpRightShift: 981 case EOpLeftShift: 982 // can natively support the right operand being a scalar and the left a vector, 983 // but not the reverse 984 if (rhsNode->getVectorSize() == 1) 985 return; 986 break; 987 988 case EOpLessThan: 989 case EOpGreaterThan: 990 case EOpLessThanEqual: 991 case EOpGreaterThanEqual: 992 993 case EOpEqual: 994 case EOpNotEqual: 995 996 case EOpLogicalAnd: 997 case EOpLogicalOr: 998 case EOpLogicalXor: 999 1000 case EOpAnd: 1001 case EOpInclusiveOr: 1002 case EOpExclusiveOr: 1003 1004 case EOpMix: 1005 break; 1006 1007 default: 1008 return; 1009 } 1010 1011 // Do bidirectional conversions 1012 if (lhsNode->getType().isScalarOrVec1() || rhsNode->getType().isScalarOrVec1()) { 1013 if (lhsNode->getType().isScalarOrVec1()) 1014 lhsNode = addShapeConversion(rhsNode->getType(), lhsNode); 1015 else 1016 rhsNode = addShapeConversion(lhsNode->getType(), rhsNode); 1017 } 1018 lhsNode = addShapeConversion(rhsNode->getType(), lhsNode); 1019 rhsNode = addShapeConversion(lhsNode->getType(), rhsNode); 1020 } 1021 1022 // Convert the node's shape of type for the given type. It's not necessarily 1023 // an error if they are different and not converted, as some operations accept 1024 // mixed types. Promotion will do final shape checking. 1025 // 1026 // If there is a chance of two nodes, with conversions possible in each direction, 1027 // the policy for what to ask for must be in the caller; this will do what is asked. 1028 // 1029 // Return 'node' if no conversion was done. Promotion handles final shape 1030 // checking. 1031 // 1032 TIntermTyped* TIntermediate::addShapeConversion(const TType& type, TIntermTyped* node) 1033 { 1034 // no conversion needed 1035 if (node->getType() == type) 1036 return node; 1037 1038 // structures and arrays don't change shape, either to or from 1039 if (node->getType().isStruct() || node->getType().isArray() || 1040 type.isStruct() || type.isArray()) 1041 return node; 1042 1043 // The new node that handles the conversion 1044 TOperator constructorOp = mapTypeToConstructorOp(type); 1045 1046 // HLSL has custom semantics for scalar->mat shape conversions. 1047 if (source == EShSourceHlsl) { 1048 if (node->getType().isScalarOrVec1() && type.isMatrix()) { 1049 1050 // HLSL semantics: the scalar (or vec1) is replicated to every component of the matrix. Left to its 1051 // own devices, the constructor from a scalar would populate the diagonal. This forces replication 1052 // to every matrix element. 1053 1054 // Note that if the node is complex (e.g, a function call), we don't want to duplicate it here 1055 // repeatedly, so we copy it to a temp, then use the temp. 1056 const int matSize = type.getMatrixRows() * type.getMatrixCols(); 1057 TIntermAggregate* rhsAggregate = new TIntermAggregate(); 1058 1059 const bool isSimple = (node->getAsSymbolNode() != nullptr) || (node->getAsConstantUnion() != nullptr); 1060 1061 if (!isSimple) { 1062 assert(0); // TODO: use node replicator service when available. 1063 } 1064 1065 for (int x=0; x<matSize; ++x) 1066 rhsAggregate->getSequence().push_back(node); 1067 1068 return setAggregateOperator(rhsAggregate, constructorOp, type, node->getLoc()); 1069 } 1070 } 1071 1072 // scalar -> vector or vec1 -> vector or 1073 // vector -> scalar or 1074 // bigger vector -> smaller vector 1075 if ((node->getType().isScalarOrVec1() && type.isVector()) || 1076 (node->getType().isVector() && type.isScalar()) || 1077 (node->isVector() && type.isVector() && node->getVectorSize() > type.getVectorSize())) 1078 return setAggregateOperator(makeAggregate(node), constructorOp, type, node->getLoc()); 1079 1080 return node; 1081 } 1082 1083 // 1084 // See if the 'from' type is allowed to be implicitly converted to the 1085 // 'to' type. This is not about vector/array/struct, only about basic type. 1086 // 1087 bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op) const 1088 { 1089 if (profile == EEsProfile || version == 110) 1090 return false; 1091 1092 if (from == to) 1093 return true; 1094 1095 // TODO: Move more policies into language-specific handlers. 1096 // Some languages allow more general (or potentially, more specific) conversions under some conditions. 1097 if (source == EShSourceHlsl) { 1098 const bool fromConvertable = (from == EbtFloat || from == EbtDouble || from == EbtInt || from == EbtUint || from == EbtBool); 1099 const bool toConvertable = (to == EbtFloat || to == EbtDouble || to == EbtInt || to == EbtUint || to == EbtBool); 1100 1101 if (fromConvertable && toConvertable) { 1102 switch (op) { 1103 case EOpAndAssign: // assignments can perform arbitrary conversions 1104 case EOpInclusiveOrAssign: // ... 1105 case EOpExclusiveOrAssign: // ... 1106 case EOpAssign: // ... 1107 case EOpAddAssign: // ... 1108 case EOpSubAssign: // ... 1109 case EOpMulAssign: // ... 1110 case EOpVectorTimesScalarAssign: // ... 1111 case EOpMatrixTimesScalarAssign: // ... 1112 case EOpDivAssign: // ... 1113 case EOpModAssign: // ... 1114 case EOpReturn: // function returns can also perform arbitrary conversions 1115 case EOpFunctionCall: // conversion of a calling parameter 1116 case EOpLogicalNot: 1117 case EOpLogicalAnd: 1118 case EOpLogicalOr: 1119 case EOpLogicalXor: 1120 case EOpConstructStruct: 1121 return true; 1122 default: 1123 break; 1124 } 1125 } 1126 } 1127 1128 switch (to) { 1129 case EbtDouble: 1130 switch (from) { 1131 case EbtInt: 1132 case EbtUint: 1133 case EbtInt64: 1134 case EbtUint64: 1135 #ifdef AMD_EXTENSIONS 1136 case EbtInt16: 1137 case EbtUint16: 1138 #endif 1139 case EbtFloat: 1140 case EbtDouble: 1141 #ifdef AMD_EXTENSIONS 1142 case EbtFloat16: 1143 #endif 1144 return true; 1145 default: 1146 return false; 1147 } 1148 case EbtFloat: 1149 switch (from) { 1150 case EbtInt: 1151 case EbtUint: 1152 #ifdef AMD_EXTENSIONS 1153 case EbtInt16: 1154 case EbtUint16: 1155 #endif 1156 case EbtFloat: 1157 #ifdef AMD_EXTENSIONS 1158 case EbtFloat16: 1159 #endif 1160 return true; 1161 case EbtBool: 1162 return (source == EShSourceHlsl); 1163 default: 1164 return false; 1165 } 1166 case EbtUint: 1167 switch (from) { 1168 case EbtInt: 1169 return version >= 400 || (source == EShSourceHlsl); 1170 case EbtUint: 1171 #ifdef AMD_EXTENSIONS 1172 case EbtInt16: 1173 case EbtUint16: 1174 #endif 1175 return true; 1176 case EbtBool: 1177 return (source == EShSourceHlsl); 1178 default: 1179 return false; 1180 } 1181 case EbtInt: 1182 switch (from) { 1183 case EbtInt: 1184 #ifdef AMD_EXTENSIONS 1185 case EbtInt16: 1186 #endif 1187 return true; 1188 case EbtBool: 1189 return (source == EShSourceHlsl); 1190 default: 1191 return false; 1192 } 1193 case EbtUint64: 1194 switch (from) { 1195 case EbtInt: 1196 case EbtUint: 1197 case EbtInt64: 1198 case EbtUint64: 1199 #ifdef AMD_EXTENSIONS 1200 case EbtInt16: 1201 case EbtUint16: 1202 #endif 1203 return true; 1204 default: 1205 return false; 1206 } 1207 case EbtInt64: 1208 switch (from) { 1209 case EbtInt: 1210 case EbtInt64: 1211 #ifdef AMD_EXTENSIONS 1212 case EbtInt16: 1213 #endif 1214 return true; 1215 default: 1216 return false; 1217 } 1218 #ifdef AMD_EXTENSIONS 1219 case EbtFloat16: 1220 switch (from) { 1221 case EbtInt16: 1222 case EbtUint16: 1223 case EbtFloat16: 1224 return true; 1225 default: 1226 return false; 1227 } 1228 case EbtUint16: 1229 switch (from) { 1230 case EbtInt16: 1231 case EbtUint16: 1232 return true; 1233 default: 1234 return false; 1235 } 1236 #endif 1237 default: 1238 return false; 1239 } 1240 } 1241 1242 // 1243 // Given a type, find what operation would fully construct it. 1244 // 1245 TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const 1246 { 1247 TOperator op = EOpNull; 1248 1249 switch (type.getBasicType()) { 1250 case EbtStruct: 1251 op = EOpConstructStruct; 1252 break; 1253 case EbtSampler: 1254 if (type.getSampler().combined) 1255 op = EOpConstructTextureSampler; 1256 break; 1257 case EbtFloat: 1258 if (type.isMatrix()) { 1259 switch (type.getMatrixCols()) { 1260 case 2: 1261 switch (type.getMatrixRows()) { 1262 case 2: op = EOpConstructMat2x2; break; 1263 case 3: op = EOpConstructMat2x3; break; 1264 case 4: op = EOpConstructMat2x4; break; 1265 default: break; // some compilers want this 1266 } 1267 break; 1268 case 3: 1269 switch (type.getMatrixRows()) { 1270 case 2: op = EOpConstructMat3x2; break; 1271 case 3: op = EOpConstructMat3x3; break; 1272 case 4: op = EOpConstructMat3x4; break; 1273 default: break; // some compilers want this 1274 } 1275 break; 1276 case 4: 1277 switch (type.getMatrixRows()) { 1278 case 2: op = EOpConstructMat4x2; break; 1279 case 3: op = EOpConstructMat4x3; break; 1280 case 4: op = EOpConstructMat4x4; break; 1281 default: break; // some compilers want this 1282 } 1283 break; 1284 default: break; // some compilers want this 1285 } 1286 } else { 1287 switch(type.getVectorSize()) { 1288 case 1: op = EOpConstructFloat; break; 1289 case 2: op = EOpConstructVec2; break; 1290 case 3: op = EOpConstructVec3; break; 1291 case 4: op = EOpConstructVec4; break; 1292 default: break; // some compilers want this 1293 } 1294 } 1295 break; 1296 case EbtDouble: 1297 if (type.getMatrixCols()) { 1298 switch (type.getMatrixCols()) { 1299 case 2: 1300 switch (type.getMatrixRows()) { 1301 case 2: op = EOpConstructDMat2x2; break; 1302 case 3: op = EOpConstructDMat2x3; break; 1303 case 4: op = EOpConstructDMat2x4; break; 1304 default: break; // some compilers want this 1305 } 1306 break; 1307 case 3: 1308 switch (type.getMatrixRows()) { 1309 case 2: op = EOpConstructDMat3x2; break; 1310 case 3: op = EOpConstructDMat3x3; break; 1311 case 4: op = EOpConstructDMat3x4; break; 1312 default: break; // some compilers want this 1313 } 1314 break; 1315 case 4: 1316 switch (type.getMatrixRows()) { 1317 case 2: op = EOpConstructDMat4x2; break; 1318 case 3: op = EOpConstructDMat4x3; break; 1319 case 4: op = EOpConstructDMat4x4; break; 1320 default: break; // some compilers want this 1321 } 1322 break; 1323 } 1324 } else { 1325 switch(type.getVectorSize()) { 1326 case 1: op = EOpConstructDouble; break; 1327 case 2: op = EOpConstructDVec2; break; 1328 case 3: op = EOpConstructDVec3; break; 1329 case 4: op = EOpConstructDVec4; break; 1330 default: break; // some compilers want this 1331 } 1332 } 1333 break; 1334 #ifdef AMD_EXTENSIONS 1335 case EbtFloat16: 1336 if (type.getMatrixCols()) { 1337 switch (type.getMatrixCols()) { 1338 case 2: 1339 switch (type.getMatrixRows()) { 1340 case 2: op = EOpConstructF16Mat2x2; break; 1341 case 3: op = EOpConstructF16Mat2x3; break; 1342 case 4: op = EOpConstructF16Mat2x4; break; 1343 default: break; // some compilers want this 1344 } 1345 break; 1346 case 3: 1347 switch (type.getMatrixRows()) { 1348 case 2: op = EOpConstructF16Mat3x2; break; 1349 case 3: op = EOpConstructF16Mat3x3; break; 1350 case 4: op = EOpConstructF16Mat3x4; break; 1351 default: break; // some compilers want this 1352 } 1353 break; 1354 case 4: 1355 switch (type.getMatrixRows()) { 1356 case 2: op = EOpConstructF16Mat4x2; break; 1357 case 3: op = EOpConstructF16Mat4x3; break; 1358 case 4: op = EOpConstructF16Mat4x4; break; 1359 default: break; // some compilers want this 1360 } 1361 break; 1362 } 1363 } 1364 else { 1365 switch (type.getVectorSize()) { 1366 case 1: op = EOpConstructFloat16; break; 1367 case 2: op = EOpConstructF16Vec2; break; 1368 case 3: op = EOpConstructF16Vec3; break; 1369 case 4: op = EOpConstructF16Vec4; break; 1370 default: break; // some compilers want this 1371 } 1372 } 1373 break; 1374 #endif 1375 case EbtInt: 1376 if (type.getMatrixCols()) { 1377 switch (type.getMatrixCols()) { 1378 case 2: 1379 switch (type.getMatrixRows()) { 1380 case 2: op = EOpConstructIMat2x2; break; 1381 case 3: op = EOpConstructIMat2x3; break; 1382 case 4: op = EOpConstructIMat2x4; break; 1383 default: break; // some compilers want this 1384 } 1385 break; 1386 case 3: 1387 switch (type.getMatrixRows()) { 1388 case 2: op = EOpConstructIMat3x2; break; 1389 case 3: op = EOpConstructIMat3x3; break; 1390 case 4: op = EOpConstructIMat3x4; break; 1391 default: break; // some compilers want this 1392 } 1393 break; 1394 case 4: 1395 switch (type.getMatrixRows()) { 1396 case 2: op = EOpConstructIMat4x2; break; 1397 case 3: op = EOpConstructIMat4x3; break; 1398 case 4: op = EOpConstructIMat4x4; break; 1399 default: break; // some compilers want this 1400 } 1401 break; 1402 } 1403 } else { 1404 switch(type.getVectorSize()) { 1405 case 1: op = EOpConstructInt; break; 1406 case 2: op = EOpConstructIVec2; break; 1407 case 3: op = EOpConstructIVec3; break; 1408 case 4: op = EOpConstructIVec4; break; 1409 default: break; // some compilers want this 1410 } 1411 } 1412 break; 1413 case EbtUint: 1414 if (type.getMatrixCols()) { 1415 switch (type.getMatrixCols()) { 1416 case 2: 1417 switch (type.getMatrixRows()) { 1418 case 2: op = EOpConstructUMat2x2; break; 1419 case 3: op = EOpConstructUMat2x3; break; 1420 case 4: op = EOpConstructUMat2x4; break; 1421 default: break; // some compilers want this 1422 } 1423 break; 1424 case 3: 1425 switch (type.getMatrixRows()) { 1426 case 2: op = EOpConstructUMat3x2; break; 1427 case 3: op = EOpConstructUMat3x3; break; 1428 case 4: op = EOpConstructUMat3x4; break; 1429 default: break; // some compilers want this 1430 } 1431 break; 1432 case 4: 1433 switch (type.getMatrixRows()) { 1434 case 2: op = EOpConstructUMat4x2; break; 1435 case 3: op = EOpConstructUMat4x3; break; 1436 case 4: op = EOpConstructUMat4x4; break; 1437 default: break; // some compilers want this 1438 } 1439 break; 1440 } 1441 } else { 1442 switch(type.getVectorSize()) { 1443 case 1: op = EOpConstructUint; break; 1444 case 2: op = EOpConstructUVec2; break; 1445 case 3: op = EOpConstructUVec3; break; 1446 case 4: op = EOpConstructUVec4; break; 1447 default: break; // some compilers want this 1448 } 1449 } 1450 break; 1451 case EbtInt64: 1452 switch(type.getVectorSize()) { 1453 case 1: op = EOpConstructInt64; break; 1454 case 2: op = EOpConstructI64Vec2; break; 1455 case 3: op = EOpConstructI64Vec3; break; 1456 case 4: op = EOpConstructI64Vec4; break; 1457 default: break; // some compilers want this 1458 } 1459 break; 1460 case EbtUint64: 1461 switch(type.getVectorSize()) { 1462 case 1: op = EOpConstructUint64; break; 1463 case 2: op = EOpConstructU64Vec2; break; 1464 case 3: op = EOpConstructU64Vec3; break; 1465 case 4: op = EOpConstructU64Vec4; break; 1466 default: break; // some compilers want this 1467 } 1468 break; 1469 #ifdef AMD_EXTENSIONS 1470 case EbtInt16: 1471 switch(type.getVectorSize()) { 1472 case 1: op = EOpConstructInt16; break; 1473 case 2: op = EOpConstructI16Vec2; break; 1474 case 3: op = EOpConstructI16Vec3; break; 1475 case 4: op = EOpConstructI16Vec4; break; 1476 default: break; // some compilers want this 1477 } 1478 break; 1479 case EbtUint16: 1480 switch(type.getVectorSize()) { 1481 case 1: op = EOpConstructUint16; break; 1482 case 2: op = EOpConstructU16Vec2; break; 1483 case 3: op = EOpConstructU16Vec3; break; 1484 case 4: op = EOpConstructU16Vec4; break; 1485 default: break; // some compilers want this 1486 } 1487 break; 1488 #endif 1489 case EbtBool: 1490 if (type.getMatrixCols()) { 1491 switch (type.getMatrixCols()) { 1492 case 2: 1493 switch (type.getMatrixRows()) { 1494 case 2: op = EOpConstructBMat2x2; break; 1495 case 3: op = EOpConstructBMat2x3; break; 1496 case 4: op = EOpConstructBMat2x4; break; 1497 default: break; // some compilers want this 1498 } 1499 break; 1500 case 3: 1501 switch (type.getMatrixRows()) { 1502 case 2: op = EOpConstructBMat3x2; break; 1503 case 3: op = EOpConstructBMat3x3; break; 1504 case 4: op = EOpConstructBMat3x4; break; 1505 default: break; // some compilers want this 1506 } 1507 break; 1508 case 4: 1509 switch (type.getMatrixRows()) { 1510 case 2: op = EOpConstructBMat4x2; break; 1511 case 3: op = EOpConstructBMat4x3; break; 1512 case 4: op = EOpConstructBMat4x4; break; 1513 default: break; // some compilers want this 1514 } 1515 break; 1516 } 1517 } else { 1518 switch(type.getVectorSize()) { 1519 case 1: op = EOpConstructBool; break; 1520 case 2: op = EOpConstructBVec2; break; 1521 case 3: op = EOpConstructBVec3; break; 1522 case 4: op = EOpConstructBVec4; break; 1523 default: break; // some compilers want this 1524 } 1525 } 1526 break; 1527 default: 1528 break; 1529 } 1530 1531 return op; 1532 } 1533 1534 // 1535 // Safe way to combine two nodes into an aggregate. Works with null pointers, 1536 // a node that's not a aggregate yet, etc. 1537 // 1538 // Returns the resulting aggregate, unless nullptr was passed in for 1539 // both existing nodes. 1540 // 1541 TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right) 1542 { 1543 if (left == nullptr && right == nullptr) 1544 return nullptr; 1545 1546 TIntermAggregate* aggNode = nullptr; 1547 if (left != nullptr) 1548 aggNode = left->getAsAggregate(); 1549 if (aggNode == nullptr || aggNode->getOp() != EOpNull) { 1550 aggNode = new TIntermAggregate; 1551 if (left != nullptr) 1552 aggNode->getSequence().push_back(left); 1553 } 1554 1555 if (right != nullptr) 1556 aggNode->getSequence().push_back(right); 1557 1558 return aggNode; 1559 } 1560 1561 TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc& loc) 1562 { 1563 TIntermAggregate* aggNode = growAggregate(left, right); 1564 if (aggNode) 1565 aggNode->setLoc(loc); 1566 1567 return aggNode; 1568 } 1569 1570 // 1571 // Turn an existing node into an aggregate. 1572 // 1573 // Returns an aggregate, unless nullptr was passed in for the existing node. 1574 // 1575 TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node) 1576 { 1577 if (node == nullptr) 1578 return nullptr; 1579 1580 TIntermAggregate* aggNode = new TIntermAggregate; 1581 aggNode->getSequence().push_back(node); 1582 aggNode->setLoc(node->getLoc()); 1583 1584 return aggNode; 1585 } 1586 1587 TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, const TSourceLoc& loc) 1588 { 1589 if (node == nullptr) 1590 return nullptr; 1591 1592 TIntermAggregate* aggNode = new TIntermAggregate; 1593 aggNode->getSequence().push_back(node); 1594 aggNode->setLoc(loc); 1595 1596 return aggNode; 1597 } 1598 1599 // 1600 // Make an aggregate with an empty sequence. 1601 // 1602 TIntermAggregate* TIntermediate::makeAggregate(const TSourceLoc& loc) 1603 { 1604 TIntermAggregate* aggNode = new TIntermAggregate; 1605 aggNode->setLoc(loc); 1606 1607 return aggNode; 1608 } 1609 1610 // 1611 // For "if" test nodes. There are three children; a condition, 1612 // a true path, and a false path. The two paths are in the 1613 // nodePair. 1614 // 1615 // Returns the selection node created. 1616 // 1617 TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc, TSelectionControl control) 1618 { 1619 // 1620 // Don't prune the false path for compile-time constants; it's needed 1621 // for static access analysis. 1622 // 1623 1624 TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2); 1625 node->setLoc(loc); 1626 node->setSelectionControl(control); 1627 1628 return node; 1629 } 1630 1631 TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc& loc) 1632 { 1633 // However, the lowest precedence operators of the sequence operator ( , ) and the assignment operators 1634 // ... are not included in the operators that can create a constant expression. 1635 // 1636 // if (left->getType().getQualifier().storage == EvqConst && 1637 // right->getType().getQualifier().storage == EvqConst) { 1638 1639 // return right; 1640 //} 1641 1642 TIntermTyped *commaAggregate = growAggregate(left, right, loc); 1643 commaAggregate->getAsAggregate()->setOperator(EOpComma); 1644 commaAggregate->setType(right->getType()); 1645 commaAggregate->getWritableType().getQualifier().makeTemporary(); 1646 1647 return commaAggregate; 1648 } 1649 1650 TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type, const TString* name, const TSourceLoc& loc) 1651 { 1652 TIntermMethod* method = new TIntermMethod(object, type, *name); 1653 method->setLoc(loc); 1654 1655 return method; 1656 } 1657 1658 // 1659 // For "?:" test nodes. There are three children; a condition, 1660 // a true path, and a false path. The two paths are specified 1661 // as separate parameters. For vector 'cond', the true and false 1662 // are not paths, but vectors to mix. 1663 // 1664 // Specialization constant operations include 1665 // - The ternary operator ( ? : ) 1666 // 1667 // Returns the selection node created, or nullptr if one could not be. 1668 // 1669 TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& loc, TSelectionControl control) 1670 { 1671 // If it's void, go to the if-then-else selection() 1672 if (trueBlock->getBasicType() == EbtVoid && falseBlock->getBasicType() == EbtVoid) { 1673 TIntermNodePair pair = { trueBlock, falseBlock }; 1674 return addSelection(cond, pair, loc, control); 1675 } 1676 1677 // 1678 // Get compatible types. 1679 // 1680 TIntermTyped* child = addConversion(EOpSequence, trueBlock->getType(), falseBlock); 1681 if (child) 1682 falseBlock = child; 1683 else { 1684 child = addConversion(EOpSequence, falseBlock->getType(), trueBlock); 1685 if (child) 1686 trueBlock = child; 1687 else 1688 return nullptr; 1689 } 1690 1691 // Handle a vector condition as a mix 1692 if (!cond->getType().isScalarOrVec1()) { 1693 TType targetVectorType(trueBlock->getType().getBasicType(), EvqTemporary, 1694 cond->getType().getVectorSize()); 1695 // smear true/false operands as needed 1696 trueBlock = addUniShapeConversion(EOpMix, targetVectorType, trueBlock); 1697 falseBlock = addUniShapeConversion(EOpMix, targetVectorType, falseBlock); 1698 1699 // After conversion, types have to match. 1700 if (falseBlock->getType() != trueBlock->getType()) 1701 return nullptr; 1702 1703 // make the mix operation 1704 TIntermAggregate* mix = makeAggregate(loc); 1705 mix = growAggregate(mix, falseBlock); 1706 mix = growAggregate(mix, trueBlock); 1707 mix = growAggregate(mix, cond); 1708 mix->setType(targetVectorType); 1709 mix->setOp(EOpMix); 1710 1711 return mix; 1712 } 1713 1714 // Now have a scalar condition... 1715 1716 // Convert true and false expressions to matching types 1717 addBiShapeConversion(EOpMix, trueBlock, falseBlock); 1718 1719 // After conversion, types have to match. 1720 if (falseBlock->getType() != trueBlock->getType()) 1721 return nullptr; 1722 1723 // Eliminate the selection when the condition is a scalar and all operands are constant. 1724 if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) { 1725 if (cond->getAsConstantUnion()->getConstArray()[0].getBConst()) 1726 return trueBlock; 1727 else 1728 return falseBlock; 1729 } 1730 1731 // 1732 // Make a selection node. 1733 // 1734 TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType()); 1735 node->setLoc(loc); 1736 node->getQualifier().precision = std::max(trueBlock->getQualifier().precision, falseBlock->getQualifier().precision); 1737 1738 if ((cond->getQualifier().isConstant() && specConstantPropagates(*trueBlock, *falseBlock)) || 1739 (cond->getQualifier().isSpecConstant() && trueBlock->getQualifier().isConstant() && 1740 falseBlock->getQualifier().isConstant())) 1741 node->getQualifier().makeSpecConstant(); 1742 else 1743 node->getQualifier().makeTemporary(); 1744 1745 return node; 1746 } 1747 1748 // 1749 // Constant terminal nodes. Has a union that contains bool, float or int constants 1750 // 1751 // Returns the constant union node created. 1752 // 1753 1754 TIntermConstantUnion* TIntermediate::addConstantUnion(const TConstUnionArray& unionArray, const TType& t, const TSourceLoc& loc, bool literal) const 1755 { 1756 TIntermConstantUnion* node = new TIntermConstantUnion(unionArray, t); 1757 node->getQualifier().storage = EvqConst; 1758 node->setLoc(loc); 1759 if (literal) 1760 node->setLiteral(); 1761 1762 return node; 1763 } 1764 1765 TIntermConstantUnion* TIntermediate::addConstantUnion(int i, const TSourceLoc& loc, bool literal) const 1766 { 1767 TConstUnionArray unionArray(1); 1768 unionArray[0].setIConst(i); 1769 1770 return addConstantUnion(unionArray, TType(EbtInt, EvqConst), loc, literal); 1771 } 1772 1773 TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned int u, const TSourceLoc& loc, bool literal) const 1774 { 1775 TConstUnionArray unionArray(1); 1776 unionArray[0].setUConst(u); 1777 1778 return addConstantUnion(unionArray, TType(EbtUint, EvqConst), loc, literal); 1779 } 1780 1781 TIntermConstantUnion* TIntermediate::addConstantUnion(long long i64, const TSourceLoc& loc, bool literal) const 1782 { 1783 TConstUnionArray unionArray(1); 1784 unionArray[0].setI64Const(i64); 1785 1786 return addConstantUnion(unionArray, TType(EbtInt64, EvqConst), loc, literal); 1787 } 1788 1789 TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned long long u64, const TSourceLoc& loc, bool literal) const 1790 { 1791 TConstUnionArray unionArray(1); 1792 unionArray[0].setU64Const(u64); 1793 1794 return addConstantUnion(unionArray, TType(EbtUint64, EvqConst), loc, literal); 1795 } 1796 1797 #ifdef AMD_EXTENSIONS 1798 TIntermConstantUnion* TIntermediate::addConstantUnion(short i16, const TSourceLoc& loc, bool literal) const 1799 { 1800 TConstUnionArray unionArray(1); 1801 unionArray[0].setIConst(i16); 1802 1803 return addConstantUnion(unionArray, TType(EbtInt16, EvqConst), loc, literal); 1804 } 1805 1806 TIntermConstantUnion* TIntermediate::addConstantUnion(unsigned short u16, const TSourceLoc& loc, bool literal) const 1807 { 1808 TConstUnionArray unionArray(1); 1809 unionArray[0].setUConst(u16); 1810 1811 return addConstantUnion(unionArray, TType(EbtUint16, EvqConst), loc, literal); 1812 } 1813 #endif 1814 1815 TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, const TSourceLoc& loc, bool literal) const 1816 { 1817 TConstUnionArray unionArray(1); 1818 unionArray[0].setBConst(b); 1819 1820 return addConstantUnion(unionArray, TType(EbtBool, EvqConst), loc, literal); 1821 } 1822 1823 TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseType, const TSourceLoc& loc, bool literal) const 1824 { 1825 #ifdef AMD_EXTENSIONS 1826 assert(baseType == EbtFloat || baseType == EbtDouble || baseType == EbtFloat16); 1827 #else 1828 assert(baseType == EbtFloat || baseType == EbtDouble); 1829 #endif 1830 1831 TConstUnionArray unionArray(1); 1832 unionArray[0].setDConst(d); 1833 1834 return addConstantUnion(unionArray, TType(baseType, EvqConst), loc, literal); 1835 } 1836 1837 TIntermConstantUnion* TIntermediate::addConstantUnion(const TString* s, const TSourceLoc& loc, bool literal) const 1838 { 1839 TConstUnionArray unionArray(1); 1840 unionArray[0].setSConst(s); 1841 1842 return addConstantUnion(unionArray, TType(EbtString, EvqConst), loc, literal); 1843 } 1844 1845 // Put vector swizzle selectors onto the given sequence 1846 void TIntermediate::pushSelector(TIntermSequence& sequence, const TVectorSelector& selector, const TSourceLoc& loc) 1847 { 1848 TIntermConstantUnion* constIntNode = addConstantUnion(selector, loc); 1849 sequence.push_back(constIntNode); 1850 } 1851 1852 // Put matrix swizzle selectors onto the given sequence 1853 void TIntermediate::pushSelector(TIntermSequence& sequence, const TMatrixSelector& selector, const TSourceLoc& loc) 1854 { 1855 TIntermConstantUnion* constIntNode = addConstantUnion(selector.coord1, loc); 1856 sequence.push_back(constIntNode); 1857 constIntNode = addConstantUnion(selector.coord2, loc); 1858 sequence.push_back(constIntNode); 1859 } 1860 1861 // Make an aggregate node that has a sequence of all selectors. 1862 template TIntermTyped* TIntermediate::addSwizzle<TVectorSelector>(TSwizzleSelectors<TVectorSelector>& selector, const TSourceLoc& loc); 1863 template TIntermTyped* TIntermediate::addSwizzle<TMatrixSelector>(TSwizzleSelectors<TMatrixSelector>& selector, const TSourceLoc& loc); 1864 template<typename selectorType> 1865 TIntermTyped* TIntermediate::addSwizzle(TSwizzleSelectors<selectorType>& selector, const TSourceLoc& loc) 1866 { 1867 TIntermAggregate* node = new TIntermAggregate(EOpSequence); 1868 1869 node->setLoc(loc); 1870 TIntermSequence &sequenceVector = node->getSequence(); 1871 1872 for (int i = 0; i < selector.size(); i++) 1873 pushSelector(sequenceVector, selector[i], loc); 1874 1875 return node; 1876 } 1877 1878 // 1879 // Follow the left branches down to the root of an l-value 1880 // expression (just "." and []). 1881 // 1882 // Return the base of the l-value (where following indexing quits working). 1883 // Return nullptr if a chain following dereferences cannot be followed. 1884 // 1885 // 'swizzleOkay' says whether or not it is okay to consider a swizzle 1886 // a valid part of the dereference chain. 1887 // 1888 const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay) 1889 { 1890 do { 1891 const TIntermBinary* binary = node->getAsBinaryNode(); 1892 if (binary == nullptr) 1893 return node; 1894 TOperator op = binary->getOp(); 1895 if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle && op != EOpMatrixSwizzle) 1896 return nullptr; 1897 if (! swizzleOkay) { 1898 if (op == EOpVectorSwizzle || op == EOpMatrixSwizzle) 1899 return nullptr; 1900 if ((op == EOpIndexDirect || op == EOpIndexIndirect) && 1901 (binary->getLeft()->getType().isVector() || binary->getLeft()->getType().isScalar()) && 1902 ! binary->getLeft()->getType().isArray()) 1903 return nullptr; 1904 } 1905 node = node->getAsBinaryNode()->getLeft(); 1906 } while (true); 1907 } 1908 1909 // 1910 // Create while and do-while loop nodes. 1911 // 1912 TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TLoopControl control) 1913 { 1914 TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst); 1915 node->setLoc(loc); 1916 node->setLoopControl(control); 1917 1918 return node; 1919 } 1920 1921 // 1922 // Create a for-loop sequence. 1923 // 1924 TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* initializer, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TLoopControl control) 1925 { 1926 TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst); 1927 node->setLoc(loc); 1928 node->setLoopControl(control); 1929 1930 // make a sequence of the initializer and statement, but try to reuse the 1931 // aggregate already created for whatever is in the initializer, if there is one 1932 TIntermAggregate* loopSequence = (initializer == nullptr || 1933 initializer->getAsAggregate() == nullptr) ? makeAggregate(initializer, loc) 1934 : initializer->getAsAggregate(); 1935 if (loopSequence != nullptr && loopSequence->getOp() == EOpSequence) 1936 loopSequence->setOp(EOpNull); 1937 loopSequence = growAggregate(loopSequence, node); 1938 loopSequence->setOperator(EOpSequence); 1939 1940 return loopSequence; 1941 } 1942 1943 // 1944 // Add branches. 1945 // 1946 TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc& loc) 1947 { 1948 return addBranch(branchOp, nullptr, loc); 1949 } 1950 1951 TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, const TSourceLoc& loc) 1952 { 1953 TIntermBranch* node = new TIntermBranch(branchOp, expression); 1954 node->setLoc(loc); 1955 1956 return node; 1957 } 1958 1959 // 1960 // This is to be executed after the final root is put on top by the parsing 1961 // process. 1962 // 1963 bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/) 1964 { 1965 if (root == nullptr) 1966 return true; 1967 1968 // Finish off the top-level sequence 1969 TIntermAggregate* aggRoot = root->getAsAggregate(); 1970 if (aggRoot && aggRoot->getOp() == EOpNull) 1971 aggRoot->setOperator(EOpSequence); 1972 1973 // Propagate 'noContraction' label in backward from 'precise' variables. 1974 glslang::PropagateNoContraction(*this); 1975 1976 switch (textureSamplerTransformMode) { 1977 case EShTexSampTransKeep: 1978 break; 1979 case EShTexSampTransUpgradeTextureRemoveSampler: 1980 performTextureUpgradeAndSamplerRemovalTransformation(root); 1981 break; 1982 } 1983 1984 return true; 1985 } 1986 1987 void TIntermediate::addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage language, TSymbolTable& symbolTable) 1988 { 1989 // Add top-level nodes for declarations that must be checked cross 1990 // compilation unit by a linker, yet might not have been referenced 1991 // by the AST. 1992 // 1993 // Almost entirely, translation of symbols is driven by what's present 1994 // in the AST traversal, not by translating the symbol table. 1995 // 1996 // However, there are some special cases: 1997 // - From the specification: "Special built-in inputs gl_VertexID and 1998 // gl_InstanceID are also considered active vertex attributes." 1999 // - Linker-based type mismatch error reporting needs to see all 2000 // uniforms/ins/outs variables and blocks. 2001 // - ftransform() can make gl_Vertex and gl_ModelViewProjectionMatrix active. 2002 // 2003 2004 // if (ftransformUsed) { 2005 // TODO: 1.1 lowering functionality: track ftransform() usage 2006 // addSymbolLinkageNode(root, symbolTable, "gl_Vertex"); 2007 // addSymbolLinkageNode(root, symbolTable, "gl_ModelViewProjectionMatrix"); 2008 //} 2009 2010 if (language == EShLangVertex) { 2011 // the names won't be found in the symbol table unless the versions are right, 2012 // so version logic does not need to be repeated here 2013 addSymbolLinkageNode(linkage, symbolTable, "gl_VertexID"); 2014 addSymbolLinkageNode(linkage, symbolTable, "gl_InstanceID"); 2015 } 2016 2017 // Add a child to the root node for the linker objects 2018 linkage->setOperator(EOpLinkerObjects); 2019 treeRoot = growAggregate(treeRoot, linkage); 2020 } 2021 2022 // 2023 // Add the given name or symbol to the list of nodes at the end of the tree used 2024 // for link-time checking and external linkage. 2025 // 2026 2027 void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable& symbolTable, const TString& name) 2028 { 2029 TSymbol* symbol = symbolTable.find(name); 2030 if (symbol) 2031 addSymbolLinkageNode(linkage, *symbol->getAsVariable()); 2032 } 2033 2034 void TIntermediate::addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol& symbol) 2035 { 2036 const TVariable* variable = symbol.getAsVariable(); 2037 if (! variable) { 2038 // This must be a member of an anonymous block, and we need to add the whole block 2039 const TAnonMember* anon = symbol.getAsAnonMember(); 2040 variable = &anon->getAnonContainer(); 2041 } 2042 TIntermSymbol* node = addSymbol(*variable); 2043 linkage = growAggregate(linkage, node); 2044 } 2045 2046 // 2047 // Add a caller->callee relationship to the call graph. 2048 // Assumes the strings are unique per signature. 2049 // 2050 void TIntermediate::addToCallGraph(TInfoSink& /*infoSink*/, const TString& caller, const TString& callee) 2051 { 2052 // Duplicates are okay, but faster to not keep them, and they come grouped by caller, 2053 // as long as new ones are push on the same end we check on for duplicates 2054 for (TGraph::const_iterator call = callGraph.begin(); call != callGraph.end(); ++call) { 2055 if (call->caller != caller) 2056 break; 2057 if (call->callee == callee) 2058 return; 2059 } 2060 2061 callGraph.push_front(TCall(caller, callee)); 2062 } 2063 2064 // 2065 // This deletes the tree. 2066 // 2067 void TIntermediate::removeTree() 2068 { 2069 if (treeRoot) 2070 RemoveAllTreeNodes(treeRoot); 2071 } 2072 2073 // 2074 // Implement the part of KHR_vulkan_glsl that lists the set of operations 2075 // that can result in a specialization constant operation. 2076 // 2077 // "5.x Specialization Constant Operations" 2078 // 2079 // Only some operations discussed in this section may be applied to a 2080 // specialization constant and still yield a result that is as 2081 // specialization constant. The operations allowed are listed below. 2082 // When a specialization constant is operated on with one of these 2083 // operators and with another constant or specialization constant, the 2084 // result is implicitly a specialization constant. 2085 // 2086 // - int(), uint(), and bool() constructors for type conversions 2087 // from any of the following types to any of the following types: 2088 // * int 2089 // * uint 2090 // * bool 2091 // - vector versions of the above conversion constructors 2092 // - allowed implicit conversions of the above 2093 // - swizzles (e.g., foo.yx) 2094 // - The following when applied to integer or unsigned integer types: 2095 // * unary negative ( - ) 2096 // * binary operations ( + , - , * , / , % ) 2097 // * shift ( <<, >> ) 2098 // * bitwise operations ( & , | , ^ ) 2099 // - The following when applied to integer or unsigned integer scalar types: 2100 // * comparison ( == , != , > , >= , < , <= ) 2101 // - The following when applied to the Boolean scalar type: 2102 // * not ( ! ) 2103 // * logical operations ( && , || , ^^ ) 2104 // * comparison ( == , != )" 2105 // 2106 // This function just handles binary and unary nodes. Construction 2107 // rules are handled in construction paths that are not covered by the unary 2108 // and binary paths, while required conversions will still show up here 2109 // as unary converters in the from a construction operator. 2110 // 2111 bool TIntermediate::isSpecializationOperation(const TIntermOperator& node) const 2112 { 2113 // The operations resulting in floating point are quite limited 2114 // (However, some floating-point operations result in bool, like ">", 2115 // so are handled later.) 2116 if (node.getType().isFloatingDomain()) { 2117 switch (node.getOp()) { 2118 case EOpIndexDirect: 2119 case EOpIndexIndirect: 2120 case EOpIndexDirectStruct: 2121 case EOpVectorSwizzle: 2122 case EOpConvFloatToDouble: 2123 case EOpConvDoubleToFloat: 2124 #ifdef AMD_EXTENSIONS 2125 case EOpConvFloat16ToFloat: 2126 case EOpConvFloatToFloat16: 2127 case EOpConvFloat16ToDouble: 2128 case EOpConvDoubleToFloat16: 2129 #endif 2130 return true; 2131 default: 2132 return false; 2133 } 2134 } 2135 2136 // Check for floating-point arguments 2137 if (const TIntermBinary* bin = node.getAsBinaryNode()) 2138 if (bin->getLeft() ->getType().isFloatingDomain() || 2139 bin->getRight()->getType().isFloatingDomain()) 2140 return false; 2141 2142 // So, for now, we can assume everything left is non-floating-point... 2143 2144 // Now check for integer/bool-based operations 2145 switch (node.getOp()) { 2146 2147 // dereference/swizzle 2148 case EOpIndexDirect: 2149 case EOpIndexIndirect: 2150 case EOpIndexDirectStruct: 2151 case EOpVectorSwizzle: 2152 2153 // conversion constructors 2154 case EOpConvIntToBool: 2155 case EOpConvUintToBool: 2156 case EOpConvUintToInt: 2157 case EOpConvBoolToInt: 2158 case EOpConvIntToUint: 2159 case EOpConvBoolToUint: 2160 case EOpConvInt64ToBool: 2161 case EOpConvBoolToInt64: 2162 case EOpConvUint64ToBool: 2163 case EOpConvBoolToUint64: 2164 case EOpConvInt64ToInt: 2165 case EOpConvIntToInt64: 2166 case EOpConvUint64ToUint: 2167 case EOpConvUintToUint64: 2168 case EOpConvInt64ToUint64: 2169 case EOpConvUint64ToInt64: 2170 case EOpConvInt64ToUint: 2171 case EOpConvUintToInt64: 2172 case EOpConvUint64ToInt: 2173 case EOpConvIntToUint64: 2174 #ifdef AMD_EXTENSIONS 2175 case EOpConvInt16ToBool: 2176 case EOpConvBoolToInt16: 2177 case EOpConvInt16ToInt: 2178 case EOpConvIntToInt16: 2179 case EOpConvInt16ToUint: 2180 case EOpConvUintToInt16: 2181 case EOpConvInt16ToInt64: 2182 case EOpConvInt64ToInt16: 2183 case EOpConvInt16ToUint64: 2184 case EOpConvUint64ToInt16: 2185 case EOpConvUint16ToBool: 2186 case EOpConvBoolToUint16: 2187 case EOpConvUint16ToInt: 2188 case EOpConvIntToUint16: 2189 case EOpConvUint16ToUint: 2190 case EOpConvUintToUint16: 2191 case EOpConvUint16ToInt64: 2192 case EOpConvInt64ToUint16: 2193 case EOpConvUint16ToUint64: 2194 case EOpConvUint64ToUint16: 2195 case EOpConvInt16ToUint16: 2196 case EOpConvUint16ToInt16: 2197 #endif 2198 2199 // unary operations 2200 case EOpNegative: 2201 case EOpLogicalNot: 2202 case EOpBitwiseNot: 2203 2204 // binary operations 2205 case EOpAdd: 2206 case EOpSub: 2207 case EOpMul: 2208 case EOpVectorTimesScalar: 2209 case EOpDiv: 2210 case EOpMod: 2211 case EOpRightShift: 2212 case EOpLeftShift: 2213 case EOpAnd: 2214 case EOpInclusiveOr: 2215 case EOpExclusiveOr: 2216 case EOpLogicalOr: 2217 case EOpLogicalXor: 2218 case EOpLogicalAnd: 2219 case EOpEqual: 2220 case EOpNotEqual: 2221 case EOpLessThan: 2222 case EOpGreaterThan: 2223 case EOpLessThanEqual: 2224 case EOpGreaterThanEqual: 2225 return true; 2226 default: 2227 return false; 2228 } 2229 } 2230 2231 //////////////////////////////////////////////////////////////// 2232 // 2233 // Member functions of the nodes used for building the tree. 2234 // 2235 //////////////////////////////////////////////////////////////// 2236 2237 // 2238 // Say whether or not an operation node changes the value of a variable. 2239 // 2240 // Returns true if state is modified. 2241 // 2242 bool TIntermOperator::modifiesState() const 2243 { 2244 switch (op) { 2245 case EOpPostIncrement: 2246 case EOpPostDecrement: 2247 case EOpPreIncrement: 2248 case EOpPreDecrement: 2249 case EOpAssign: 2250 case EOpAddAssign: 2251 case EOpSubAssign: 2252 case EOpMulAssign: 2253 case EOpVectorTimesMatrixAssign: 2254 case EOpVectorTimesScalarAssign: 2255 case EOpMatrixTimesScalarAssign: 2256 case EOpMatrixTimesMatrixAssign: 2257 case EOpDivAssign: 2258 case EOpModAssign: 2259 case EOpAndAssign: 2260 case EOpInclusiveOrAssign: 2261 case EOpExclusiveOrAssign: 2262 case EOpLeftShiftAssign: 2263 case EOpRightShiftAssign: 2264 return true; 2265 default: 2266 return false; 2267 } 2268 } 2269 2270 // 2271 // returns true if the operator is for one of the constructors 2272 // 2273 bool TIntermOperator::isConstructor() const 2274 { 2275 return op > EOpConstructGuardStart && op < EOpConstructGuardEnd; 2276 } 2277 2278 // 2279 // Make sure the type of an operator is appropriate for its 2280 // combination of operation and operand type. This will invoke 2281 // promoteUnary, promoteBinary, etc as needed. 2282 // 2283 // Returns false if nothing makes sense. 2284 // 2285 bool TIntermediate::promote(TIntermOperator* node) 2286 { 2287 if (node == nullptr) 2288 return false; 2289 2290 if (node->getAsUnaryNode()) 2291 return promoteUnary(*node->getAsUnaryNode()); 2292 2293 if (node->getAsBinaryNode()) 2294 return promoteBinary(*node->getAsBinaryNode()); 2295 2296 if (node->getAsAggregate()) 2297 return promoteAggregate(*node->getAsAggregate()); 2298 2299 return false; 2300 } 2301 2302 // 2303 // See TIntermediate::promote 2304 // 2305 bool TIntermediate::promoteUnary(TIntermUnary& node) 2306 { 2307 const TOperator op = node.getOp(); 2308 TIntermTyped* operand = node.getOperand(); 2309 2310 switch (op) { 2311 case EOpLogicalNot: 2312 // Convert operand to a boolean type 2313 if (operand->getBasicType() != EbtBool) { 2314 // Add constructor to boolean type. If that fails, we can't do it, so return false. 2315 TIntermTyped* converted = convertToBasicType(op, EbtBool, operand); 2316 if (converted == nullptr) 2317 return false; 2318 2319 // Use the result of converting the node to a bool. 2320 node.setOperand(operand = converted); // also updates stack variable 2321 } 2322 break; 2323 case EOpBitwiseNot: 2324 if (operand->getBasicType() != EbtInt && 2325 operand->getBasicType() != EbtUint && 2326 #ifdef AMD_EXTENSIONS 2327 operand->getBasicType() != EbtInt16 && 2328 operand->getBasicType() != EbtUint16 && 2329 #endif 2330 operand->getBasicType() != EbtInt64 && 2331 operand->getBasicType() != EbtUint64) 2332 2333 return false; 2334 break; 2335 case EOpNegative: 2336 case EOpPostIncrement: 2337 case EOpPostDecrement: 2338 case EOpPreIncrement: 2339 case EOpPreDecrement: 2340 if (operand->getBasicType() != EbtInt && 2341 operand->getBasicType() != EbtUint && 2342 operand->getBasicType() != EbtInt64 && 2343 operand->getBasicType() != EbtUint64 && 2344 #ifdef AMD_EXTENSIONS 2345 operand->getBasicType() != EbtInt16 && 2346 operand->getBasicType() != EbtUint16 && 2347 #endif 2348 operand->getBasicType() != EbtFloat && 2349 #ifdef AMD_EXTENSIONS 2350 operand->getBasicType() != EbtFloat16 && 2351 #endif 2352 operand->getBasicType() != EbtDouble) 2353 2354 return false; 2355 break; 2356 2357 default: 2358 if (operand->getBasicType() != EbtFloat) 2359 2360 return false; 2361 } 2362 2363 node.setType(operand->getType()); 2364 node.getWritableType().getQualifier().makeTemporary(); 2365 2366 return true; 2367 } 2368 2369 void TIntermUnary::updatePrecision() 2370 { 2371 #ifdef AMD_EXTENSIONS 2372 if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat || getBasicType() == EbtFloat16) { 2373 #else 2374 if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat) { 2375 #endif 2376 if (operand->getQualifier().precision > getQualifier().precision) 2377 getQualifier().precision = operand->getQualifier().precision; 2378 } 2379 } 2380 2381 // If it is not already, convert this node to the given basic type. 2382 TIntermTyped* TIntermediate::convertToBasicType(TOperator op, TBasicType basicType, TIntermTyped* node) const 2383 { 2384 if (node == nullptr) 2385 return nullptr; 2386 2387 // It's already this basic type: nothing needs to be done, so use the node directly. 2388 if (node->getBasicType() == basicType) 2389 return node; 2390 2391 const TType& type = node->getType(); 2392 const TType newType(basicType, type.getQualifier().storage, 2393 type.getVectorSize(), type.getMatrixCols(), type.getMatrixRows(), type.isVector()); 2394 2395 // Add constructor to the right vectorness of the right type. If that fails, we can't do it, so return nullptr. 2396 return addConversion(op, newType, node); 2397 } 2398 2399 // 2400 // See TIntermediate::promote 2401 // 2402 bool TIntermediate::promoteBinary(TIntermBinary& node) 2403 { 2404 TOperator op = node.getOp(); 2405 TIntermTyped* left = node.getLeft(); 2406 TIntermTyped* right = node.getRight(); 2407 2408 // Arrays and structures have to be exact matches. 2409 if ((left->isArray() || right->isArray() || left->getBasicType() == EbtStruct || right->getBasicType() == EbtStruct) 2410 && left->getType() != right->getType()) 2411 return false; 2412 2413 // Base assumption: just make the type the same as the left 2414 // operand. Only deviations from this will be coded. 2415 node.setType(left->getType()); 2416 node.getWritableType().getQualifier().clear(); 2417 2418 // Composite and opaque types don't having pending operator changes, e.g., 2419 // array, structure, and samplers. Just establish final type and correctness. 2420 if (left->isArray() || left->getBasicType() == EbtStruct || left->getBasicType() == EbtSampler) { 2421 switch (op) { 2422 case EOpEqual: 2423 case EOpNotEqual: 2424 if (left->getBasicType() == EbtSampler) { 2425 // can't compare samplers 2426 return false; 2427 } else { 2428 // Promote to conditional 2429 node.setType(TType(EbtBool)); 2430 } 2431 2432 return true; 2433 2434 case EOpAssign: 2435 // Keep type from above 2436 2437 return true; 2438 2439 default: 2440 return false; 2441 } 2442 } 2443 2444 // 2445 // We now have only scalars, vectors, and matrices to worry about. 2446 // 2447 2448 // HLSL implicitly promotes bool -> int for numeric operations. 2449 // (Implicit conversions to make the operands match each other's types were already done.) 2450 if (getSource() == EShSourceHlsl && 2451 (left->getBasicType() == EbtBool || right->getBasicType() == EbtBool)) { 2452 switch (op) { 2453 case EOpLessThan: 2454 case EOpGreaterThan: 2455 case EOpLessThanEqual: 2456 case EOpGreaterThanEqual: 2457 2458 case EOpRightShift: 2459 case EOpLeftShift: 2460 2461 case EOpMod: 2462 2463 case EOpAnd: 2464 case EOpInclusiveOr: 2465 case EOpExclusiveOr: 2466 2467 case EOpAdd: 2468 case EOpSub: 2469 case EOpDiv: 2470 case EOpMul: 2471 left = addConversion(op, TType(EbtInt, EvqTemporary, left->getVectorSize()), left); 2472 right = addConversion(op, TType(EbtInt, EvqTemporary, right->getVectorSize()), right); 2473 if (left == nullptr || right == nullptr) 2474 return false; 2475 node.setLeft(left); 2476 node.setRight(right); 2477 break; 2478 2479 default: 2480 break; 2481 } 2482 } 2483 2484 // Do general type checks against individual operands (comparing left and right is coming up, checking mixed shapes after that) 2485 switch (op) { 2486 case EOpLessThan: 2487 case EOpGreaterThan: 2488 case EOpLessThanEqual: 2489 case EOpGreaterThanEqual: 2490 // Relational comparisons need numeric types and will promote to scalar Boolean. 2491 if (left->getBasicType() == EbtBool) 2492 return false; 2493 2494 node.setType(TType(EbtBool, EvqTemporary, left->getVectorSize())); 2495 break; 2496 2497 case EOpEqual: 2498 case EOpNotEqual: 2499 if (getSource() == EShSourceHlsl) { 2500 const int resultWidth = std::max(left->getVectorSize(), right->getVectorSize()); 2501 2502 // In HLSL, == or != on vectors means component-wise comparison. 2503 if (resultWidth > 1) { 2504 op = (op == EOpEqual) ? EOpVectorEqual : EOpVectorNotEqual; 2505 node.setOp(op); 2506 } 2507 2508 node.setType(TType(EbtBool, EvqTemporary, resultWidth)); 2509 } else { 2510 // All the above comparisons result in a bool (but not the vector compares) 2511 node.setType(TType(EbtBool)); 2512 } 2513 break; 2514 2515 case EOpLogicalAnd: 2516 case EOpLogicalOr: 2517 case EOpLogicalXor: 2518 if (getSource() == EShSourceHlsl) { 2519 TIntermTyped* convertedL = convertToBasicType(op, EbtBool, left); 2520 TIntermTyped* convertedR = convertToBasicType(op, EbtBool, right); 2521 if (convertedL == nullptr || convertedR == nullptr) 2522 return false; 2523 node.setLeft(left = convertedL); // also updates stack variable 2524 node.setRight(right = convertedR); // also updates stack variable 2525 } else { 2526 // logical ops operate only on scalar Booleans and will promote to scalar Boolean. 2527 if (left->getBasicType() != EbtBool || left->isVector() || left->isMatrix()) 2528 return false; 2529 } 2530 2531 node.setType(TType(EbtBool, EvqTemporary, left->getVectorSize())); 2532 2533 break; 2534 2535 case EOpRightShift: 2536 case EOpLeftShift: 2537 case EOpRightShiftAssign: 2538 case EOpLeftShiftAssign: 2539 2540 case EOpMod: 2541 case EOpModAssign: 2542 2543 case EOpAnd: 2544 case EOpInclusiveOr: 2545 case EOpExclusiveOr: 2546 case EOpAndAssign: 2547 case EOpInclusiveOrAssign: 2548 case EOpExclusiveOrAssign: 2549 if (getSource() == EShSourceHlsl) 2550 break; 2551 2552 // Check for integer-only operands. 2553 if ((left->getBasicType() != EbtInt && left->getBasicType() != EbtUint && 2554 #ifdef AMD_EXTENSIONS 2555 left->getBasicType() != EbtInt16 && left->getBasicType() != EbtUint16 && 2556 #endif 2557 left->getBasicType() != EbtInt64 && left->getBasicType() != EbtUint64) || 2558 (right->getBasicType() != EbtInt && right->getBasicType() != EbtUint && 2559 #ifdef AMD_EXTENSIONS 2560 right->getBasicType() != EbtInt16 && right->getBasicType() != EbtUint16 && 2561 #endif 2562 right->getBasicType() != EbtInt64 && right->getBasicType() != EbtUint64)) 2563 return false; 2564 if (left->isMatrix() || right->isMatrix()) 2565 return false; 2566 2567 break; 2568 2569 case EOpAdd: 2570 case EOpSub: 2571 case EOpDiv: 2572 case EOpMul: 2573 case EOpAddAssign: 2574 case EOpSubAssign: 2575 case EOpMulAssign: 2576 case EOpDivAssign: 2577 // check for non-Boolean operands 2578 if (left->getBasicType() == EbtBool || right->getBasicType() == EbtBool) 2579 return false; 2580 2581 default: 2582 break; 2583 } 2584 2585 // Compare left and right, and finish with the cases where the operand types must match 2586 switch (op) { 2587 case EOpLessThan: 2588 case EOpGreaterThan: 2589 case EOpLessThanEqual: 2590 case EOpGreaterThanEqual: 2591 2592 case EOpEqual: 2593 case EOpNotEqual: 2594 case EOpVectorEqual: 2595 case EOpVectorNotEqual: 2596 2597 case EOpLogicalAnd: 2598 case EOpLogicalOr: 2599 case EOpLogicalXor: 2600 return left->getType() == right->getType(); 2601 2602 case EOpMod: 2603 case EOpModAssign: 2604 2605 case EOpAnd: 2606 case EOpInclusiveOr: 2607 case EOpExclusiveOr: 2608 case EOpAndAssign: 2609 case EOpInclusiveOrAssign: 2610 case EOpExclusiveOrAssign: 2611 2612 case EOpAdd: 2613 case EOpSub: 2614 case EOpDiv: 2615 2616 case EOpAddAssign: 2617 case EOpSubAssign: 2618 case EOpDivAssign: 2619 // Quick out in case the types do match 2620 if (left->getType() == right->getType()) 2621 return true; 2622 2623 // Fall through 2624 2625 case EOpMul: 2626 case EOpMulAssign: 2627 // At least the basic type has to match 2628 if (left->getBasicType() != right->getBasicType()) 2629 return false; 2630 2631 default: 2632 break; 2633 } 2634 2635 // Finish handling the case, for all ops, where both operands are scalars. 2636 if (left->isScalar() && right->isScalar()) 2637 return true; 2638 2639 // Finish handling the case, for all ops, where there are two vectors of different sizes 2640 if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize() && right->getVectorSize() > 1) 2641 return false; 2642 2643 // 2644 // We now have a mix of scalars, vectors, or matrices, for non-relational operations. 2645 // 2646 2647 // Can these two operands be combined, what is the resulting type? 2648 TBasicType basicType = left->getBasicType(); 2649 switch (op) { 2650 case EOpMul: 2651 if (!left->isMatrix() && right->isMatrix()) { 2652 if (left->isVector()) { 2653 if (left->getVectorSize() != right->getMatrixRows()) 2654 return false; 2655 node.setOp(op = EOpVectorTimesMatrix); 2656 node.setType(TType(basicType, EvqTemporary, right->getMatrixCols())); 2657 } else { 2658 node.setOp(op = EOpMatrixTimesScalar); 2659 node.setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), right->getMatrixRows())); 2660 } 2661 } else if (left->isMatrix() && !right->isMatrix()) { 2662 if (right->isVector()) { 2663 if (left->getMatrixCols() != right->getVectorSize()) 2664 return false; 2665 node.setOp(op = EOpMatrixTimesVector); 2666 node.setType(TType(basicType, EvqTemporary, left->getMatrixRows())); 2667 } else { 2668 node.setOp(op = EOpMatrixTimesScalar); 2669 } 2670 } else if (left->isMatrix() && right->isMatrix()) { 2671 if (left->getMatrixCols() != right->getMatrixRows()) 2672 return false; 2673 node.setOp(op = EOpMatrixTimesMatrix); 2674 node.setType(TType(basicType, EvqTemporary, 0, right->getMatrixCols(), left->getMatrixRows())); 2675 } else if (! left->isMatrix() && ! right->isMatrix()) { 2676 if (left->isVector() && right->isVector()) { 2677 ; // leave as component product 2678 } else if (left->isVector() || right->isVector()) { 2679 node.setOp(op = EOpVectorTimesScalar); 2680 if (right->isVector()) 2681 node.setType(TType(basicType, EvqTemporary, right->getVectorSize())); 2682 } 2683 } else { 2684 return false; 2685 } 2686 break; 2687 case EOpMulAssign: 2688 if (! left->isMatrix() && right->isMatrix()) { 2689 if (left->isVector()) { 2690 if (left->getVectorSize() != right->getMatrixRows() || left->getVectorSize() != right->getMatrixCols()) 2691 return false; 2692 node.setOp(op = EOpVectorTimesMatrixAssign); 2693 } else { 2694 return false; 2695 } 2696 } else if (left->isMatrix() && !right->isMatrix()) { 2697 if (right->isVector()) { 2698 return false; 2699 } else { 2700 node.setOp(op = EOpMatrixTimesScalarAssign); 2701 } 2702 } else if (left->isMatrix() && right->isMatrix()) { 2703 if (left->getMatrixCols() != left->getMatrixRows() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixCols() != right->getMatrixRows()) 2704 return false; 2705 node.setOp(op = EOpMatrixTimesMatrixAssign); 2706 } else if (!left->isMatrix() && !right->isMatrix()) { 2707 if (left->isVector() && right->isVector()) { 2708 // leave as component product 2709 } else if (left->isVector() || right->isVector()) { 2710 if (! left->isVector()) 2711 return false; 2712 node.setOp(op = EOpVectorTimesScalarAssign); 2713 } 2714 } else { 2715 return false; 2716 } 2717 break; 2718 2719 case EOpRightShift: 2720 case EOpLeftShift: 2721 case EOpRightShiftAssign: 2722 case EOpLeftShiftAssign: 2723 if (right->isVector() && (! left->isVector() || right->getVectorSize() != left->getVectorSize())) 2724 return false; 2725 break; 2726 2727 case EOpAssign: 2728 if (left->getVectorSize() != right->getVectorSize() || left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows()) 2729 return false; 2730 // fall through 2731 2732 case EOpAdd: 2733 case EOpSub: 2734 case EOpDiv: 2735 case EOpMod: 2736 case EOpAnd: 2737 case EOpInclusiveOr: 2738 case EOpExclusiveOr: 2739 case EOpAddAssign: 2740 case EOpSubAssign: 2741 case EOpDivAssign: 2742 case EOpModAssign: 2743 case EOpAndAssign: 2744 case EOpInclusiveOrAssign: 2745 case EOpExclusiveOrAssign: 2746 2747 if ((left->isMatrix() && right->isVector()) || 2748 (left->isVector() && right->isMatrix()) || 2749 left->getBasicType() != right->getBasicType()) 2750 return false; 2751 if (left->isMatrix() && right->isMatrix() && (left->getMatrixCols() != right->getMatrixCols() || left->getMatrixRows() != right->getMatrixRows())) 2752 return false; 2753 if (left->isVector() && right->isVector() && left->getVectorSize() != right->getVectorSize()) 2754 return false; 2755 if (right->isVector() || right->isMatrix()) { 2756 node.getWritableType().shallowCopy(right->getType()); 2757 node.getWritableType().getQualifier().makeTemporary(); 2758 } 2759 break; 2760 2761 default: 2762 return false; 2763 } 2764 2765 // 2766 // One more check for assignment. 2767 // 2768 switch (op) { 2769 // The resulting type has to match the left operand. 2770 case EOpAssign: 2771 case EOpAddAssign: 2772 case EOpSubAssign: 2773 case EOpMulAssign: 2774 case EOpDivAssign: 2775 case EOpModAssign: 2776 case EOpAndAssign: 2777 case EOpInclusiveOrAssign: 2778 case EOpExclusiveOrAssign: 2779 case EOpLeftShiftAssign: 2780 case EOpRightShiftAssign: 2781 if (node.getType() != left->getType()) 2782 return false; 2783 break; 2784 default: 2785 break; 2786 } 2787 2788 return true; 2789 } 2790 2791 // 2792 // See TIntermediate::promote 2793 // 2794 bool TIntermediate::promoteAggregate(TIntermAggregate& node) 2795 { 2796 TOperator op = node.getOp(); 2797 TIntermSequence& args = node.getSequence(); 2798 const int numArgs = static_cast<int>(args.size()); 2799 2800 // Presently, only hlsl does intrinsic promotions. 2801 if (getSource() != EShSourceHlsl) 2802 return true; 2803 2804 // set of opcodes that can be promoted in this manner. 2805 switch (op) { 2806 case EOpAtan: 2807 case EOpClamp: 2808 case EOpCross: 2809 case EOpDistance: 2810 case EOpDot: 2811 case EOpDst: 2812 case EOpFaceForward: 2813 // case EOpFindMSB: TODO: 2814 // case EOpFindLSB: TODO: 2815 case EOpFma: 2816 case EOpMod: 2817 case EOpFrexp: 2818 case EOpLdexp: 2819 case EOpMix: 2820 case EOpLit: 2821 case EOpMax: 2822 case EOpMin: 2823 case EOpModf: 2824 // case EOpGenMul: TODO: 2825 case EOpPow: 2826 case EOpReflect: 2827 case EOpRefract: 2828 // case EOpSinCos: TODO: 2829 case EOpSmoothStep: 2830 case EOpStep: 2831 break; 2832 default: 2833 return true; 2834 } 2835 2836 // TODO: array and struct behavior 2837 2838 // Try converting all nodes to the given node's type 2839 TIntermSequence convertedArgs(numArgs, nullptr); 2840 2841 // Try to convert all types to the nonConvArg type. 2842 for (int nonConvArg = 0; nonConvArg < numArgs; ++nonConvArg) { 2843 // Try converting all args to this arg's type 2844 for (int convArg = 0; convArg < numArgs; ++convArg) { 2845 convertedArgs[convArg] = addConversion(op, args[nonConvArg]->getAsTyped()->getType(), 2846 args[convArg]->getAsTyped()); 2847 } 2848 2849 // If we successfully converted all the args, use the result. 2850 if (std::all_of(convertedArgs.begin(), convertedArgs.end(), 2851 [](const TIntermNode* node) { return node != nullptr; })) { 2852 2853 std::swap(args, convertedArgs); 2854 return true; 2855 } 2856 } 2857 2858 return false; 2859 } 2860 2861 void TIntermBinary::updatePrecision() 2862 { 2863 #ifdef AMD_EXTENSIONS 2864 if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat || getBasicType() == EbtFloat16) { 2865 #else 2866 if (getBasicType() == EbtInt || getBasicType() == EbtUint || getBasicType() == EbtFloat) { 2867 #endif 2868 getQualifier().precision = std::max(right->getQualifier().precision, left->getQualifier().precision); 2869 if (getQualifier().precision != EpqNone) { 2870 left->propagatePrecision(getQualifier().precision); 2871 right->propagatePrecision(getQualifier().precision); 2872 } 2873 } 2874 } 2875 2876 void TIntermTyped::propagatePrecision(TPrecisionQualifier newPrecision) 2877 { 2878 #ifdef AMD_EXTENSIONS 2879 if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtUint && getBasicType() != EbtFloat && getBasicType() != EbtFloat16)) 2880 #else 2881 if (getQualifier().precision != EpqNone || (getBasicType() != EbtInt && getBasicType() != EbtUint && getBasicType() != EbtFloat)) 2882 #endif 2883 return; 2884 2885 getQualifier().precision = newPrecision; 2886 2887 TIntermBinary* binaryNode = getAsBinaryNode(); 2888 if (binaryNode) { 2889 binaryNode->getLeft()->propagatePrecision(newPrecision); 2890 binaryNode->getRight()->propagatePrecision(newPrecision); 2891 2892 return; 2893 } 2894 2895 TIntermUnary* unaryNode = getAsUnaryNode(); 2896 if (unaryNode) { 2897 unaryNode->getOperand()->propagatePrecision(newPrecision); 2898 2899 return; 2900 } 2901 2902 TIntermAggregate* aggregateNode = getAsAggregate(); 2903 if (aggregateNode) { 2904 TIntermSequence operands = aggregateNode->getSequence(); 2905 for (unsigned int i = 0; i < operands.size(); ++i) { 2906 TIntermTyped* typedNode = operands[i]->getAsTyped(); 2907 if (! typedNode) 2908 break; 2909 typedNode->propagatePrecision(newPrecision); 2910 } 2911 2912 return; 2913 } 2914 2915 TIntermSelection* selectionNode = getAsSelectionNode(); 2916 if (selectionNode) { 2917 TIntermTyped* typedNode = selectionNode->getTrueBlock()->getAsTyped(); 2918 if (typedNode) { 2919 typedNode->propagatePrecision(newPrecision); 2920 typedNode = selectionNode->getFalseBlock()->getAsTyped(); 2921 if (typedNode) 2922 typedNode->propagatePrecision(newPrecision); 2923 } 2924 2925 return; 2926 } 2927 } 2928 2929 TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) const 2930 { 2931 const TConstUnionArray& rightUnionArray = node->getConstArray(); 2932 int size = node->getType().computeNumComponents(); 2933 2934 TConstUnionArray leftUnionArray(size); 2935 2936 for (int i=0; i < size; i++) { 2937 switch (promoteTo) { 2938 case EbtFloat: 2939 switch (node->getType().getBasicType()) { 2940 case EbtInt: 2941 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getIConst())); 2942 break; 2943 case EbtUint: 2944 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getUConst())); 2945 break; 2946 case EbtInt64: 2947 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getI64Const())); 2948 break; 2949 case EbtUint64: 2950 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getU64Const())); 2951 break; 2952 case EbtBool: 2953 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst())); 2954 break; 2955 case EbtFloat: 2956 case EbtDouble: 2957 #ifdef AMD_EXTENSIONS 2958 case EbtFloat16: 2959 #endif 2960 leftUnionArray[i] = rightUnionArray[i]; 2961 break; 2962 default: 2963 return node; 2964 } 2965 break; 2966 case EbtDouble: 2967 switch (node->getType().getBasicType()) { 2968 case EbtInt: 2969 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getIConst())); 2970 break; 2971 case EbtUint: 2972 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getUConst())); 2973 break; 2974 case EbtInt64: 2975 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getI64Const())); 2976 break; 2977 case EbtUint64: 2978 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getU64Const())); 2979 break; 2980 case EbtBool: 2981 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst())); 2982 break; 2983 case EbtFloat: 2984 case EbtDouble: 2985 #ifdef AMD_EXTENSIONS 2986 case EbtFloat16: 2987 #endif 2988 leftUnionArray[i] = rightUnionArray[i]; 2989 break; 2990 default: 2991 return node; 2992 } 2993 break; 2994 #ifdef AMD_EXTENSIONS 2995 case EbtFloat16: 2996 switch (node->getType().getBasicType()) { 2997 case EbtInt: 2998 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getIConst())); 2999 break; 3000 case EbtUint: 3001 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getUConst())); 3002 break; 3003 case EbtInt64: 3004 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getI64Const())); 3005 break; 3006 case EbtUint64: 3007 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getU64Const())); 3008 break; 3009 case EbtBool: 3010 leftUnionArray[i].setDConst(static_cast<double>(rightUnionArray[i].getBConst())); 3011 break; 3012 case EbtFloat: 3013 case EbtDouble: 3014 case EbtFloat16: 3015 leftUnionArray[i] = rightUnionArray[i]; 3016 break; 3017 default: 3018 return node; 3019 } 3020 break; 3021 #endif 3022 case EbtInt: 3023 switch (node->getType().getBasicType()) { 3024 case EbtInt: 3025 leftUnionArray[i] = rightUnionArray[i]; 3026 break; 3027 case EbtUint: 3028 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getUConst())); 3029 break; 3030 case EbtInt64: 3031 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getI64Const())); 3032 break; 3033 case EbtUint64: 3034 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getU64Const())); 3035 break; 3036 case EbtBool: 3037 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getBConst())); 3038 break; 3039 case EbtFloat: 3040 case EbtDouble: 3041 #ifdef AMD_EXTENSIONS 3042 case EbtFloat16: 3043 #endif 3044 leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getDConst())); 3045 break; 3046 default: 3047 return node; 3048 } 3049 break; 3050 case EbtUint: 3051 switch (node->getType().getBasicType()) { 3052 case EbtInt: 3053 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getIConst())); 3054 break; 3055 case EbtUint: 3056 leftUnionArray[i] = rightUnionArray[i]; 3057 break; 3058 case EbtInt64: 3059 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getI64Const())); 3060 break; 3061 case EbtUint64: 3062 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getU64Const())); 3063 break; 3064 case EbtBool: 3065 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getBConst())); 3066 break; 3067 case EbtFloat: 3068 case EbtDouble: 3069 #ifdef AMD_EXTENSIONS 3070 case EbtFloat16: 3071 #endif 3072 leftUnionArray[i].setUConst(static_cast<unsigned int>(rightUnionArray[i].getDConst())); 3073 break; 3074 default: 3075 return node; 3076 } 3077 break; 3078 case EbtBool: 3079 switch (node->getType().getBasicType()) { 3080 case EbtInt: 3081 leftUnionArray[i].setBConst(rightUnionArray[i].getIConst() != 0); 3082 break; 3083 case EbtUint: 3084 leftUnionArray[i].setBConst(rightUnionArray[i].getUConst() != 0); 3085 break; 3086 case EbtInt64: 3087 leftUnionArray[i].setBConst(rightUnionArray[i].getI64Const() != 0); 3088 break; 3089 case EbtUint64: 3090 leftUnionArray[i].setBConst(rightUnionArray[i].getU64Const() != 0); 3091 break; 3092 case EbtBool: 3093 leftUnionArray[i] = rightUnionArray[i]; 3094 break; 3095 case EbtFloat: 3096 case EbtDouble: 3097 #ifdef AMD_EXTENSIONS 3098 case EbtFloat16: 3099 #endif 3100 leftUnionArray[i].setBConst(rightUnionArray[i].getDConst() != 0.0); 3101 break; 3102 default: 3103 return node; 3104 } 3105 break; 3106 case EbtInt64: 3107 switch (node->getType().getBasicType()) { 3108 case EbtInt: 3109 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getIConst())); 3110 break; 3111 case EbtUint: 3112 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getUConst())); 3113 break; 3114 case EbtInt64: 3115 leftUnionArray[i] = rightUnionArray[i]; 3116 break; 3117 case EbtUint64: 3118 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getU64Const())); 3119 break; 3120 case EbtBool: 3121 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getBConst())); 3122 break; 3123 case EbtFloat: 3124 case EbtDouble: 3125 #ifdef AMD_EXTENSIONS 3126 case EbtFloat16: 3127 #endif 3128 leftUnionArray[i].setI64Const(static_cast<long long>(rightUnionArray[i].getDConst())); 3129 break; 3130 default: 3131 return node; 3132 } 3133 break; 3134 case EbtUint64: 3135 switch (node->getType().getBasicType()) { 3136 case EbtInt: 3137 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getIConst())); 3138 break; 3139 case EbtUint: 3140 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getUConst())); 3141 break; 3142 case EbtInt64: 3143 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getI64Const())); 3144 break; 3145 case EbtUint64: 3146 leftUnionArray[i] = rightUnionArray[i]; 3147 break; 3148 case EbtBool: 3149 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getBConst())); 3150 break; 3151 case EbtFloat: 3152 case EbtDouble: 3153 #ifdef AMD_EXTENSIONS 3154 case EbtFloat16: 3155 #endif 3156 leftUnionArray[i].setU64Const(static_cast<unsigned long long>(rightUnionArray[i].getDConst())); 3157 break; 3158 default: 3159 return node; 3160 } 3161 break; 3162 default: 3163 return node; 3164 } 3165 } 3166 3167 const TType& t = node->getType(); 3168 3169 return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier().storage, t.getVectorSize(), t.getMatrixCols(), t.getMatrixRows()), 3170 node->getLoc()); 3171 } 3172 3173 void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable) 3174 { 3175 assert(!pragmaTable); 3176 pragmaTable = new TPragmaTable(); 3177 *pragmaTable = pTable; 3178 } 3179 3180 // If either node is a specialization constant, while the other is 3181 // a constant (or specialization constant), the result is still 3182 // a specialization constant. 3183 bool TIntermediate::specConstantPropagates(const TIntermTyped& node1, const TIntermTyped& node2) 3184 { 3185 return (node1.getType().getQualifier().isSpecConstant() && node2.getType().getQualifier().isConstant()) || 3186 (node2.getType().getQualifier().isSpecConstant() && node1.getType().getQualifier().isConstant()); 3187 } 3188 3189 struct TextureUpgradeAndSamplerRemovalTransform : public TIntermTraverser { 3190 void visitSymbol(TIntermSymbol* symbol) override { 3191 if (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isTexture()) { 3192 symbol->getWritableType().getSampler().combined = true; 3193 } 3194 } 3195 bool visitAggregate(TVisit, TIntermAggregate* ag) override { 3196 using namespace std; 3197 TIntermSequence& seq = ag->getSequence(); 3198 // remove pure sampler variables 3199 TIntermSequence::iterator newEnd = remove_if(seq.begin(), seq.end(), [](TIntermNode* node) { 3200 TIntermSymbol* symbol = node->getAsSymbolNode(); 3201 if (!symbol) 3202 return false; 3203 3204 return (symbol->getBasicType() == EbtSampler && symbol->getType().getSampler().isPureSampler()); 3205 }); 3206 seq.erase(newEnd, seq.end()); 3207 // replace constructors with sampler/textures 3208 for_each(seq.begin(), seq.end(), [](TIntermNode*& node) { 3209 TIntermAggregate *constructor = node->getAsAggregate(); 3210 if (constructor && constructor->getOp() == EOpConstructTextureSampler) { 3211 if (!constructor->getSequence().empty()) 3212 node = constructor->getSequence()[0]; 3213 } 3214 }); 3215 return true; 3216 } 3217 }; 3218 3219 void TIntermediate::performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root) 3220 { 3221 TextureUpgradeAndSamplerRemovalTransform transform; 3222 root->traverse(&transform); 3223 } 3224 3225 } // end namespace glslang 3226