| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428 |
- //
- // Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
- // Copyright (C) 2012-2013 LunarG, Inc.
- // Copyright (C) 2017 ARM Limited.
- // Copyright (C) 2018-2020 Google, Inc.
- //
- // All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions
- // are met:
- //
- // Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- //
- // Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following
- // disclaimer in the documentation and/or other materials provided
- // with the distribution.
- //
- // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
- // contributors may be used to endorse or promote products derived
- // from this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- // POSSIBILITY OF SUCH DAMAGE.
- //
- #include "localintermediate.h"
- #include <cmath>
- #include <cfloat>
- #include <cstdlib>
- #include <climits>
- namespace {
- using namespace glslang;
- typedef union {
- double d;
- int i[2];
- } DoubleIntUnion;
- // Some helper functions
- bool isNan(double x)
- {
- DoubleIntUnion u;
- // tough to find a platform independent library function, do it directly
- u.d = x;
- int bitPatternL = u.i[0];
- int bitPatternH = u.i[1];
- return (bitPatternH & 0x7ff80000) == 0x7ff80000 &&
- ((bitPatternH & 0xFFFFF) != 0 || bitPatternL != 0);
- }
- bool isInf(double x)
- {
- DoubleIntUnion u;
- // tough to find a platform independent library function, do it directly
- u.d = x;
- int bitPatternL = u.i[0];
- int bitPatternH = u.i[1];
- return (bitPatternH & 0x7ff00000) == 0x7ff00000 &&
- (bitPatternH & 0xFFFFF) == 0 && bitPatternL == 0;
- }
- const double pi = 3.1415926535897932384626433832795;
- } // end anonymous namespace
- namespace glslang {
- //
- // The fold functions see if an operation on a constant can be done in place,
- // without generating run-time code.
- //
- // Returns the node to keep using, which may or may not be the node passed in.
- //
- // Note: As of version 1.2, all constant operations must be folded. It is
- // not opportunistic, but rather a semantic requirement.
- //
- //
- // Do folding between a pair of nodes.
- // 'this' is the left-hand operand and 'rightConstantNode' is the right-hand operand.
- //
- // Returns a new node representing the result.
- //
- TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* rightConstantNode) const
- {
- // For most cases, the return type matches the argument type, so set that
- // up and just code to exceptions below.
- TType returnType;
- returnType.shallowCopy(getType());
- //
- // A pair of nodes is to be folded together
- //
- const TIntermConstantUnion *rightNode = rightConstantNode->getAsConstantUnion();
- TConstUnionArray leftUnionArray = getConstArray();
- TConstUnionArray rightUnionArray = rightNode->getConstArray();
- // Figure out the size of the result
- int newComps;
- int constComps;
- switch(op) {
- case EOpMatrixTimesMatrix:
- newComps = rightNode->getMatrixCols() * getMatrixRows();
- break;
- case EOpMatrixTimesVector:
- newComps = getMatrixRows();
- break;
- case EOpVectorTimesMatrix:
- newComps = rightNode->getMatrixCols();
- break;
- default:
- newComps = getType().computeNumComponents();
- constComps = rightConstantNode->getType().computeNumComponents();
- if (constComps == 1 && newComps > 1) {
- // for a case like vec4 f = vec4(2,3,4,5) + 1.2;
- TConstUnionArray smearedArray(newComps, rightNode->getConstArray()[0]);
- rightUnionArray = smearedArray;
- } else if (constComps > 1 && newComps == 1) {
- // for a case like vec4 f = 1.2 + vec4(2,3,4,5);
- newComps = constComps;
- rightUnionArray = rightNode->getConstArray();
- TConstUnionArray smearedArray(newComps, getConstArray()[0]);
- leftUnionArray = smearedArray;
- returnType.shallowCopy(rightNode->getType());
- }
- break;
- }
- TConstUnionArray newConstArray(newComps);
- TType constBool(EbtBool, EvqConst);
- switch(op) {
- case EOpAdd:
- for (int i = 0; i < newComps; i++)
- newConstArray[i] = leftUnionArray[i] + rightUnionArray[i];
- break;
- case EOpSub:
- for (int i = 0; i < newComps; i++)
- newConstArray[i] = leftUnionArray[i] - rightUnionArray[i];
- break;
- case EOpMul:
- case EOpVectorTimesScalar:
- case EOpMatrixTimesScalar:
- for (int i = 0; i < newComps; i++)
- newConstArray[i] = leftUnionArray[i] * rightUnionArray[i];
- break;
- case EOpMatrixTimesMatrix:
- for (int row = 0; row < getMatrixRows(); row++) {
- for (int column = 0; column < rightNode->getMatrixCols(); column++) {
- double sum = 0.0f;
- for (int i = 0; i < rightNode->getMatrixRows(); i++)
- sum += leftUnionArray[i * getMatrixRows() + row].getDConst() * rightUnionArray[column * rightNode->getMatrixRows() + i].getDConst();
- newConstArray[column * getMatrixRows() + row].setDConst(sum);
- }
- }
- returnType.shallowCopy(TType(getType().getBasicType(), EvqConst, 0, rightNode->getMatrixCols(), getMatrixRows()));
- break;
- case EOpDiv:
- for (int i = 0; i < newComps; i++) {
- switch (getType().getBasicType()) {
- case EbtDouble:
- case EbtFloat:
- case EbtFloat16:
- if (rightUnionArray[i].getDConst() != 0.0)
- newConstArray[i].setDConst(leftUnionArray[i].getDConst() / rightUnionArray[i].getDConst());
- else if (leftUnionArray[i].getDConst() > 0.0)
- newConstArray[i].setDConst((double)INFINITY);
- else if (leftUnionArray[i].getDConst() < 0.0)
- newConstArray[i].setDConst(-(double)INFINITY);
- else
- newConstArray[i].setDConst((double)NAN);
- break;
- case EbtInt:
- if (rightUnionArray[i] == 0)
- newConstArray[i].setIConst(0x7FFFFFFF);
- else if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == (int)-0x80000000ll)
- newConstArray[i].setIConst((int)-0x80000000ll);
- else
- newConstArray[i].setIConst(leftUnionArray[i].getIConst() / rightUnionArray[i].getIConst());
- break;
- case EbtUint:
- if (rightUnionArray[i] == 0u)
- newConstArray[i].setUConst(0xFFFFFFFFu);
- else
- newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst());
- break;
- #ifndef GLSLANG_WEB
- case EbtInt8:
- if (rightUnionArray[i] == (signed char)0)
- newConstArray[i].setI8Const((signed char)0x7F);
- else if (rightUnionArray[i].getI8Const() == (signed char)-1 && leftUnionArray[i].getI8Const() == (signed char)-0x80)
- newConstArray[i].setI8Const((signed char)-0x80);
- else
- newConstArray[i].setI8Const(leftUnionArray[i].getI8Const() / rightUnionArray[i].getI8Const());
- break;
- case EbtUint8:
- if (rightUnionArray[i] == (unsigned char)0u)
- newConstArray[i].setU8Const((unsigned char)0xFFu);
- else
- newConstArray[i].setU8Const(leftUnionArray[i].getU8Const() / rightUnionArray[i].getU8Const());
- break;
- case EbtInt16:
- if (rightUnionArray[i] == (signed short)0)
- newConstArray[i].setI16Const((signed short)0x7FFF);
- else if (rightUnionArray[i].getI16Const() == (signed short)-1 && leftUnionArray[i].getI16Const() == (signed short)-0x8000)
- newConstArray[i].setI16Const((signed short)-0x8000);
- else
- newConstArray[i].setI16Const(leftUnionArray[i].getI16Const() / rightUnionArray[i].getI16Const());
- break;
- case EbtUint16:
- if (rightUnionArray[i] == (unsigned short)0u)
- newConstArray[i].setU16Const((unsigned short)0xFFFFu);
- else
- newConstArray[i].setU16Const(leftUnionArray[i].getU16Const() / rightUnionArray[i].getU16Const());
- break;
- case EbtInt64:
- if (rightUnionArray[i] == 0ll)
- newConstArray[i].setI64Const(0x7FFFFFFFFFFFFFFFll);
- else if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == (long long)-0x8000000000000000ll)
- newConstArray[i].setI64Const((long long)-0x8000000000000000ll);
- else
- newConstArray[i].setI64Const(leftUnionArray[i].getI64Const() / rightUnionArray[i].getI64Const());
- break;
- case EbtUint64:
- if (rightUnionArray[i] == 0ull)
- newConstArray[i].setU64Const(0xFFFFFFFFFFFFFFFFull);
- else
- newConstArray[i].setU64Const(leftUnionArray[i].getU64Const() / rightUnionArray[i].getU64Const());
- break;
- default:
- return 0;
- #endif
- }
- }
- break;
- case EOpMatrixTimesVector:
- for (int i = 0; i < getMatrixRows(); i++) {
- double sum = 0.0f;
- for (int j = 0; j < rightNode->getVectorSize(); j++) {
- sum += leftUnionArray[j*getMatrixRows() + i].getDConst() * rightUnionArray[j].getDConst();
- }
- newConstArray[i].setDConst(sum);
- }
- returnType.shallowCopy(TType(getBasicType(), EvqConst, getMatrixRows()));
- break;
- case EOpVectorTimesMatrix:
- for (int i = 0; i < rightNode->getMatrixCols(); i++) {
- double sum = 0.0f;
- for (int j = 0; j < getVectorSize(); j++)
- sum += leftUnionArray[j].getDConst() * rightUnionArray[i*rightNode->getMatrixRows() + j].getDConst();
- newConstArray[i].setDConst(sum);
- }
- returnType.shallowCopy(TType(getBasicType(), EvqConst, rightNode->getMatrixCols()));
- break;
- case EOpMod:
- for (int i = 0; i < newComps; i++) {
- if (rightUnionArray[i] == 0)
- newConstArray[i] = leftUnionArray[i];
- else {
- switch (getType().getBasicType()) {
- case EbtInt:
- if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == INT_MIN) {
- newConstArray[i].setIConst(0);
- break;
- } else goto modulo_default;
- #ifndef GLSLANG_WEB
- case EbtInt64:
- if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == LLONG_MIN) {
- newConstArray[i].setI64Const(0);
- break;
- } else goto modulo_default;
- case EbtInt16:
- if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == SHRT_MIN) {
- newConstArray[i].setIConst(0);
- break;
- } else goto modulo_default;
- #endif
- default:
- modulo_default:
- newConstArray[i] = leftUnionArray[i] % rightUnionArray[i];
- }
- }
- }
- break;
- case EOpRightShift:
- for (int i = 0; i < newComps; i++)
- newConstArray[i] = leftUnionArray[i] >> rightUnionArray[i];
- break;
- case EOpLeftShift:
- for (int i = 0; i < newComps; i++)
- newConstArray[i] = leftUnionArray[i] << rightUnionArray[i];
- break;
- case EOpAnd:
- for (int i = 0; i < newComps; i++)
- newConstArray[i] = leftUnionArray[i] & rightUnionArray[i];
- break;
- case EOpInclusiveOr:
- for (int i = 0; i < newComps; i++)
- newConstArray[i] = leftUnionArray[i] | rightUnionArray[i];
- break;
- case EOpExclusiveOr:
- for (int i = 0; i < newComps; i++)
- newConstArray[i] = leftUnionArray[i] ^ rightUnionArray[i];
- break;
- case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
- for (int i = 0; i < newComps; i++)
- newConstArray[i] = leftUnionArray[i] && rightUnionArray[i];
- break;
- case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
- for (int i = 0; i < newComps; i++)
- newConstArray[i] = leftUnionArray[i] || rightUnionArray[i];
- break;
- case EOpLogicalXor:
- for (int i = 0; i < newComps; i++) {
- switch (getType().getBasicType()) {
- case EbtBool: newConstArray[i].setBConst((leftUnionArray[i] == rightUnionArray[i]) ? false : true); break;
- default: assert(false && "Default missing");
- }
- }
- break;
- case EOpLessThan:
- newConstArray[0].setBConst(leftUnionArray[0] < rightUnionArray[0]);
- returnType.shallowCopy(constBool);
- break;
- case EOpGreaterThan:
- newConstArray[0].setBConst(leftUnionArray[0] > rightUnionArray[0]);
- returnType.shallowCopy(constBool);
- break;
- case EOpLessThanEqual:
- newConstArray[0].setBConst(! (leftUnionArray[0] > rightUnionArray[0]));
- returnType.shallowCopy(constBool);
- break;
- case EOpGreaterThanEqual:
- newConstArray[0].setBConst(! (leftUnionArray[0] < rightUnionArray[0]));
- returnType.shallowCopy(constBool);
- break;
- case EOpEqual:
- newConstArray[0].setBConst(rightNode->getConstArray() == leftUnionArray);
- returnType.shallowCopy(constBool);
- break;
- case EOpNotEqual:
- newConstArray[0].setBConst(rightNode->getConstArray() != leftUnionArray);
- returnType.shallowCopy(constBool);
- break;
- default:
- return 0;
- }
- TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, returnType);
- newNode->setLoc(getLoc());
- return newNode;
- }
- //
- // Do single unary node folding
- //
- // Returns a new node representing the result.
- //
- TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) const
- {
- // First, size the result, which is mostly the same as the argument's size,
- // but not always, and classify what is componentwise.
- // Also, eliminate cases that can't be compile-time constant.
- int resultSize;
- bool componentWise = true;
- int objectSize = getType().computeNumComponents();
- switch (op) {
- case EOpDeterminant:
- case EOpAny:
- case EOpAll:
- case EOpLength:
- componentWise = false;
- resultSize = 1;
- break;
- case EOpEmitStreamVertex:
- case EOpEndStreamPrimitive:
- // These don't fold
- return nullptr;
- case EOpPackSnorm2x16:
- case EOpPackUnorm2x16:
- case EOpPackHalf2x16:
- componentWise = false;
- resultSize = 1;
- break;
- case EOpUnpackSnorm2x16:
- case EOpUnpackUnorm2x16:
- case EOpUnpackHalf2x16:
- componentWise = false;
- resultSize = 2;
- break;
- case EOpPack16:
- case EOpPack32:
- case EOpPack64:
- case EOpUnpack32:
- case EOpUnpack16:
- case EOpUnpack8:
- case EOpNormalize:
- componentWise = false;
- resultSize = objectSize;
- break;
- default:
- resultSize = objectSize;
- break;
- }
- // Set up for processing
- TConstUnionArray newConstArray(resultSize);
- const TConstUnionArray& unionArray = getConstArray();
- // Process non-component-wise operations
- switch (op) {
- case EOpLength:
- case EOpNormalize:
- {
- double sum = 0;
- for (int i = 0; i < objectSize; i++)
- sum += unionArray[i].getDConst() * unionArray[i].getDConst();
- double length = sqrt(sum);
- if (op == EOpLength)
- newConstArray[0].setDConst(length);
- else {
- for (int i = 0; i < objectSize; i++)
- newConstArray[i].setDConst(unionArray[i].getDConst() / length);
- }
- break;
- }
- case EOpAny:
- {
- bool result = false;
- for (int i = 0; i < objectSize; i++) {
- if (unionArray[i].getBConst())
- result = true;
- }
- newConstArray[0].setBConst(result);
- break;
- }
- case EOpAll:
- {
- bool result = true;
- for (int i = 0; i < objectSize; i++) {
- if (! unionArray[i].getBConst())
- result = false;
- }
- newConstArray[0].setBConst(result);
- break;
- }
- case EOpPackSnorm2x16:
- case EOpPackUnorm2x16:
- case EOpPackHalf2x16:
- case EOpPack16:
- case EOpPack32:
- case EOpPack64:
- case EOpUnpack32:
- case EOpUnpack16:
- case EOpUnpack8:
- case EOpUnpackSnorm2x16:
- case EOpUnpackUnorm2x16:
- case EOpUnpackHalf2x16:
- case EOpDeterminant:
- case EOpMatrixInverse:
- case EOpTranspose:
- return nullptr;
- default:
- assert(componentWise);
- break;
- }
- // Turn off the componentwise loop
- if (! componentWise)
- objectSize = 0;
- // Process component-wise operations
- for (int i = 0; i < objectSize; i++) {
- switch (op) {
- case EOpNegative:
- switch (getType().getBasicType()) {
- case EbtDouble:
- case EbtFloat16:
- case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
- case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
- case EbtUint: newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break;
- #ifndef GLSLANG_WEB
- case EbtInt8: newConstArray[i].setI8Const(-unionArray[i].getI8Const()); break;
- case EbtUint8: newConstArray[i].setU8Const(static_cast<unsigned int>(-static_cast<signed int>(unionArray[i].getU8Const()))); break;
- case EbtInt16: newConstArray[i].setI16Const(-unionArray[i].getI16Const()); break;
- case EbtUint16:newConstArray[i].setU16Const(static_cast<unsigned int>(-static_cast<signed int>(unionArray[i].getU16Const()))); break;
- case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break;
- case EbtUint64: newConstArray[i].setU64Const(static_cast<unsigned long long>(-static_cast<long long>(unionArray[i].getU64Const()))); break;
- #endif
- default:
- return nullptr;
- }
- break;
- case EOpLogicalNot:
- case EOpVectorLogicalNot:
- switch (getType().getBasicType()) {
- case EbtBool: newConstArray[i].setBConst(!unionArray[i].getBConst()); break;
- default:
- return nullptr;
- }
- break;
- case EOpBitwiseNot:
- newConstArray[i] = ~unionArray[i];
- break;
- case EOpRadians:
- newConstArray[i].setDConst(unionArray[i].getDConst() * pi / 180.0);
- break;
- case EOpDegrees:
- newConstArray[i].setDConst(unionArray[i].getDConst() * 180.0 / pi);
- break;
- case EOpSin:
- newConstArray[i].setDConst(sin(unionArray[i].getDConst()));
- break;
- case EOpCos:
- newConstArray[i].setDConst(cos(unionArray[i].getDConst()));
- break;
- case EOpTan:
- newConstArray[i].setDConst(tan(unionArray[i].getDConst()));
- break;
- case EOpAsin:
- newConstArray[i].setDConst(asin(unionArray[i].getDConst()));
- break;
- case EOpAcos:
- newConstArray[i].setDConst(acos(unionArray[i].getDConst()));
- break;
- case EOpAtan:
- newConstArray[i].setDConst(atan(unionArray[i].getDConst()));
- break;
- case EOpDPdx:
- case EOpDPdy:
- case EOpFwidth:
- case EOpDPdxFine:
- case EOpDPdyFine:
- case EOpFwidthFine:
- case EOpDPdxCoarse:
- case EOpDPdyCoarse:
- case EOpFwidthCoarse:
- // The derivatives are all mandated to create a constant 0.
- newConstArray[i].setDConst(0.0);
- break;
- case EOpExp:
- newConstArray[i].setDConst(exp(unionArray[i].getDConst()));
- break;
- case EOpLog:
- newConstArray[i].setDConst(log(unionArray[i].getDConst()));
- break;
- case EOpExp2:
- {
- const double inv_log2_e = 0.69314718055994530941723212145818;
- newConstArray[i].setDConst(exp(unionArray[i].getDConst() * inv_log2_e));
- break;
- }
- case EOpLog2:
- {
- const double log2_e = 1.4426950408889634073599246810019;
- newConstArray[i].setDConst(log2_e * log(unionArray[i].getDConst()));
- break;
- }
- case EOpSqrt:
- newConstArray[i].setDConst(sqrt(unionArray[i].getDConst()));
- break;
- case EOpInverseSqrt:
- newConstArray[i].setDConst(1.0 / sqrt(unionArray[i].getDConst()));
- break;
- case EOpAbs:
- if (unionArray[i].getType() == EbtDouble)
- newConstArray[i].setDConst(fabs(unionArray[i].getDConst()));
- else if (unionArray[i].getType() == EbtInt)
- newConstArray[i].setIConst(abs(unionArray[i].getIConst()));
- else
- newConstArray[i] = unionArray[i];
- break;
- case EOpSign:
- #define SIGN(X) (X == 0 ? 0 : (X < 0 ? -1 : 1))
- if (unionArray[i].getType() == EbtDouble)
- newConstArray[i].setDConst(SIGN(unionArray[i].getDConst()));
- else
- newConstArray[i].setIConst(SIGN(unionArray[i].getIConst()));
- break;
- case EOpFloor:
- newConstArray[i].setDConst(floor(unionArray[i].getDConst()));
- break;
- case EOpTrunc:
- if (unionArray[i].getDConst() > 0)
- newConstArray[i].setDConst(floor(unionArray[i].getDConst()));
- else
- newConstArray[i].setDConst(ceil(unionArray[i].getDConst()));
- break;
- case EOpRound:
- newConstArray[i].setDConst(floor(0.5 + unionArray[i].getDConst()));
- break;
- case EOpRoundEven:
- {
- double flr = floor(unionArray[i].getDConst());
- bool even = flr / 2.0 == floor(flr / 2.0);
- double rounded = even ? ceil(unionArray[i].getDConst() - 0.5) : floor(unionArray[i].getDConst() + 0.5);
- newConstArray[i].setDConst(rounded);
- break;
- }
- case EOpCeil:
- newConstArray[i].setDConst(ceil(unionArray[i].getDConst()));
- break;
- case EOpFract:
- {
- double x = unionArray[i].getDConst();
- newConstArray[i].setDConst(x - floor(x));
- break;
- }
- case EOpIsNan:
- {
- newConstArray[i].setBConst(isNan(unionArray[i].getDConst()));
- break;
- }
- case EOpIsInf:
- {
- newConstArray[i].setBConst(isInf(unionArray[i].getDConst()));
- break;
- }
- case EOpConvIntToBool:
- newConstArray[i].setBConst(unionArray[i].getIConst() != 0); break;
- case EOpConvUintToBool:
- newConstArray[i].setBConst(unionArray[i].getUConst() != 0); break;
- case EOpConvBoolToInt:
- newConstArray[i].setIConst(unionArray[i].getBConst()); break;
- case EOpConvBoolToUint:
- newConstArray[i].setUConst(unionArray[i].getBConst()); break;
- case EOpConvIntToUint:
- newConstArray[i].setUConst(unionArray[i].getIConst()); break;
- case EOpConvUintToInt:
- newConstArray[i].setIConst(unionArray[i].getUConst()); break;
- case EOpConvFloatToBool:
- case EOpConvDoubleToBool:
- newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break;
- case EOpConvBoolToFloat:
- case EOpConvBoolToDouble:
- newConstArray[i].setDConst(unionArray[i].getBConst()); break;
- case EOpConvIntToFloat:
- case EOpConvIntToDouble:
- newConstArray[i].setDConst(unionArray[i].getIConst()); break;
- case EOpConvUintToFloat:
- case EOpConvUintToDouble:
- newConstArray[i].setDConst(unionArray[i].getUConst()); break;
- case EOpConvDoubleToFloat:
- case EOpConvFloatToDouble:
- newConstArray[i].setDConst(unionArray[i].getDConst()); break;
- case EOpConvFloatToUint:
- case EOpConvDoubleToUint:
- newConstArray[i].setUConst(static_cast<unsigned int>(unionArray[i].getDConst())); break;
- case EOpConvFloatToInt:
- case EOpConvDoubleToInt:
- newConstArray[i].setIConst(static_cast<int>(unionArray[i].getDConst())); break;
- #ifndef GLSLANG_WEB
- case EOpConvInt8ToBool:
- newConstArray[i].setBConst(unionArray[i].getI8Const() != 0); break;
- case EOpConvUint8ToBool:
- newConstArray[i].setBConst(unionArray[i].getU8Const() != 0); break;
- case EOpConvInt16ToBool:
- newConstArray[i].setBConst(unionArray[i].getI16Const() != 0); break;
- case EOpConvUint16ToBool:
- newConstArray[i].setBConst(unionArray[i].getU16Const() != 0); break;
- case EOpConvInt64ToBool:
- newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
- case EOpConvUint64ToBool:
- newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
- case EOpConvFloat16ToBool:
- newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break;
- case EOpConvBoolToInt8:
- newConstArray[i].setI8Const(unionArray[i].getBConst()); break;
- case EOpConvBoolToUint8:
- newConstArray[i].setU8Const(unionArray[i].getBConst()); break;
- case EOpConvBoolToInt16:
- newConstArray[i].setI16Const(unionArray[i].getBConst()); break;
- case EOpConvBoolToUint16:
- newConstArray[i].setU16Const(unionArray[i].getBConst()); break;
- case EOpConvBoolToInt64:
- newConstArray[i].setI64Const(unionArray[i].getBConst()); break;
- case EOpConvBoolToUint64:
- newConstArray[i].setU64Const(unionArray[i].getBConst()); break;
- case EOpConvBoolToFloat16:
- newConstArray[i].setDConst(unionArray[i].getBConst()); break;
- case EOpConvInt8ToInt16:
- newConstArray[i].setI16Const(unionArray[i].getI8Const()); break;
- case EOpConvInt8ToInt:
- newConstArray[i].setIConst(unionArray[i].getI8Const()); break;
- case EOpConvInt8ToInt64:
- newConstArray[i].setI64Const(unionArray[i].getI8Const()); break;
- case EOpConvInt8ToUint8:
- newConstArray[i].setU8Const(unionArray[i].getI8Const()); break;
- case EOpConvInt8ToUint16:
- newConstArray[i].setU16Const(unionArray[i].getI8Const()); break;
- case EOpConvInt8ToUint:
- newConstArray[i].setUConst(unionArray[i].getI8Const()); break;
- case EOpConvInt8ToUint64:
- newConstArray[i].setU64Const(unionArray[i].getI8Const()); break;
- case EOpConvUint8ToInt8:
- newConstArray[i].setI8Const(unionArray[i].getU8Const()); break;
- case EOpConvUint8ToInt16:
- newConstArray[i].setI16Const(unionArray[i].getU8Const()); break;
- case EOpConvUint8ToInt:
- newConstArray[i].setIConst(unionArray[i].getU8Const()); break;
- case EOpConvUint8ToInt64:
- newConstArray[i].setI64Const(unionArray[i].getU8Const()); break;
- case EOpConvUint8ToUint16:
- newConstArray[i].setU16Const(unionArray[i].getU8Const()); break;
- case EOpConvUint8ToUint:
- newConstArray[i].setUConst(unionArray[i].getU8Const()); break;
- case EOpConvUint8ToUint64:
- newConstArray[i].setU64Const(unionArray[i].getU8Const()); break;
- case EOpConvInt8ToFloat16:
- newConstArray[i].setDConst(unionArray[i].getI8Const()); break;
- case EOpConvInt8ToFloat:
- newConstArray[i].setDConst(unionArray[i].getI8Const()); break;
- case EOpConvInt8ToDouble:
- newConstArray[i].setDConst(unionArray[i].getI8Const()); break;
- case EOpConvUint8ToFloat16:
- newConstArray[i].setDConst(unionArray[i].getU8Const()); break;
- case EOpConvUint8ToFloat:
- newConstArray[i].setDConst(unionArray[i].getU8Const()); break;
- case EOpConvUint8ToDouble:
- newConstArray[i].setDConst(unionArray[i].getU8Const()); break;
- case EOpConvInt16ToInt8:
- newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getI16Const())); break;
- case EOpConvInt16ToInt:
- newConstArray[i].setIConst(unionArray[i].getI16Const()); break;
- case EOpConvInt16ToInt64:
- newConstArray[i].setI64Const(unionArray[i].getI16Const()); break;
- case EOpConvInt16ToUint8:
- newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getI16Const())); break;
- case EOpConvInt16ToUint16:
- newConstArray[i].setU16Const(unionArray[i].getI16Const()); break;
- case EOpConvInt16ToUint:
- newConstArray[i].setUConst(unionArray[i].getI16Const()); break;
- case EOpConvInt16ToUint64:
- newConstArray[i].setU64Const(unionArray[i].getI16Const()); break;
- case EOpConvUint16ToInt8:
- newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getU16Const())); break;
- case EOpConvUint16ToInt16:
- newConstArray[i].setI16Const(unionArray[i].getU16Const()); break;
- case EOpConvUint16ToInt:
- newConstArray[i].setIConst(unionArray[i].getU16Const()); break;
- case EOpConvUint16ToInt64:
- newConstArray[i].setI64Const(unionArray[i].getU16Const()); break;
- case EOpConvUint16ToUint8:
- newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getU16Const())); break;
- case EOpConvUint16ToUint:
- newConstArray[i].setUConst(unionArray[i].getU16Const()); break;
- case EOpConvUint16ToUint64:
- newConstArray[i].setU64Const(unionArray[i].getU16Const()); break;
- case EOpConvInt16ToFloat16:
- newConstArray[i].setDConst(unionArray[i].getI16Const()); break;
- case EOpConvInt16ToFloat:
- newConstArray[i].setDConst(unionArray[i].getI16Const()); break;
- case EOpConvInt16ToDouble:
- newConstArray[i].setDConst(unionArray[i].getI16Const()); break;
- case EOpConvUint16ToFloat16:
- newConstArray[i].setDConst(unionArray[i].getU16Const()); break;
- case EOpConvUint16ToFloat:
- newConstArray[i].setDConst(unionArray[i].getU16Const()); break;
- case EOpConvUint16ToDouble:
- newConstArray[i].setDConst(unionArray[i].getU16Const()); break;
- case EOpConvIntToInt8:
- newConstArray[i].setI8Const((signed char)unionArray[i].getIConst()); break;
- case EOpConvIntToInt16:
- newConstArray[i].setI16Const((signed short)unionArray[i].getIConst()); break;
- case EOpConvIntToInt64:
- newConstArray[i].setI64Const(unionArray[i].getIConst()); break;
- case EOpConvIntToUint8:
- newConstArray[i].setU8Const((unsigned char)unionArray[i].getIConst()); break;
- case EOpConvIntToUint16:
- newConstArray[i].setU16Const((unsigned char)unionArray[i].getIConst()); break;
- case EOpConvIntToUint64:
- newConstArray[i].setU64Const(unionArray[i].getIConst()); break;
- case EOpConvUintToInt8:
- newConstArray[i].setI8Const((signed char)unionArray[i].getUConst()); break;
- case EOpConvUintToInt16:
- newConstArray[i].setI16Const((signed short)unionArray[i].getUConst()); break;
- case EOpConvUintToInt64:
- newConstArray[i].setI64Const(unionArray[i].getUConst()); break;
- case EOpConvUintToUint8:
- newConstArray[i].setU8Const((unsigned char)unionArray[i].getUConst()); break;
- case EOpConvUintToUint16:
- newConstArray[i].setU16Const((unsigned short)unionArray[i].getUConst()); break;
- case EOpConvUintToUint64:
- newConstArray[i].setU64Const(unionArray[i].getUConst()); break;
- case EOpConvIntToFloat16:
- newConstArray[i].setDConst(unionArray[i].getIConst()); break;
- case EOpConvUintToFloat16:
- newConstArray[i].setDConst(unionArray[i].getUConst()); break;
- case EOpConvInt64ToInt8:
- newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getI64Const())); break;
- case EOpConvInt64ToInt16:
- newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getI64Const())); break;
- case EOpConvInt64ToInt:
- newConstArray[i].setIConst(static_cast<int>(unionArray[i].getI64Const())); break;
- case EOpConvInt64ToUint8:
- newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getI64Const())); break;
- case EOpConvInt64ToUint16:
- newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getI64Const())); break;
- case EOpConvInt64ToUint:
- newConstArray[i].setUConst(static_cast<unsigned int>(unionArray[i].getI64Const())); break;
- case EOpConvInt64ToUint64:
- newConstArray[i].setU64Const(unionArray[i].getI64Const()); break;
- case EOpConvUint64ToInt8:
- newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getU64Const())); break;
- case EOpConvUint64ToInt16:
- newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getU64Const())); break;
- case EOpConvUint64ToInt:
- newConstArray[i].setIConst(static_cast<int>(unionArray[i].getU64Const())); break;
- case EOpConvUint64ToInt64:
- newConstArray[i].setI64Const(unionArray[i].getU64Const()); break;
- case EOpConvUint64ToUint8:
- newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getU64Const())); break;
- case EOpConvUint64ToUint16:
- newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getU64Const())); break;
- case EOpConvUint64ToUint:
- newConstArray[i].setUConst(static_cast<unsigned int>(unionArray[i].getU64Const())); break;
- case EOpConvInt64ToFloat16:
- newConstArray[i].setDConst(static_cast<double>(unionArray[i].getI64Const())); break;
- case EOpConvInt64ToFloat:
- newConstArray[i].setDConst(static_cast<double>(unionArray[i].getI64Const())); break;
- case EOpConvInt64ToDouble:
- newConstArray[i].setDConst(static_cast<double>(unionArray[i].getI64Const())); break;
- case EOpConvUint64ToFloat16:
- newConstArray[i].setDConst(static_cast<double>(unionArray[i].getU64Const())); break;
- case EOpConvUint64ToFloat:
- newConstArray[i].setDConst(static_cast<double>(unionArray[i].getU64Const())); break;
- case EOpConvUint64ToDouble:
- newConstArray[i].setDConst(static_cast<double>(unionArray[i].getU64Const())); break;
- case EOpConvFloat16ToInt8:
- newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getDConst())); break;
- case EOpConvFloat16ToInt16:
- newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getDConst())); break;
- case EOpConvFloat16ToInt:
- newConstArray[i].setIConst(static_cast<int>(unionArray[i].getDConst())); break;
- case EOpConvFloat16ToInt64:
- newConstArray[i].setI64Const(static_cast<long long>(unionArray[i].getDConst())); break;
- case EOpConvFloat16ToUint8:
- newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getDConst())); break;
- case EOpConvFloat16ToUint16:
- newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getDConst())); break;
- case EOpConvFloat16ToUint:
- newConstArray[i].setUConst(static_cast<unsigned int>(unionArray[i].getDConst())); break;
- case EOpConvFloat16ToUint64:
- newConstArray[i].setU64Const(static_cast<unsigned long long>(unionArray[i].getDConst())); break;
- case EOpConvFloat16ToFloat:
- newConstArray[i].setDConst(unionArray[i].getDConst()); break;
- case EOpConvFloat16ToDouble:
- newConstArray[i].setDConst(unionArray[i].getDConst()); break;
- case EOpConvFloatToInt8:
- newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getDConst())); break;
- case EOpConvFloatToInt16:
- newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getDConst())); break;
- case EOpConvFloatToInt64:
- newConstArray[i].setI64Const(static_cast<long long>(unionArray[i].getDConst())); break;
- case EOpConvFloatToUint8:
- newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getDConst())); break;
- case EOpConvFloatToUint16:
- newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getDConst())); break;
- case EOpConvFloatToUint64:
- newConstArray[i].setU64Const(static_cast<unsigned long long>(unionArray[i].getDConst())); break;
- case EOpConvFloatToFloat16:
- newConstArray[i].setDConst(unionArray[i].getDConst()); break;
- case EOpConvDoubleToInt8:
- newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getDConst())); break;
- case EOpConvDoubleToInt16:
- newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getDConst())); break;
- case EOpConvDoubleToInt64:
- newConstArray[i].setI64Const(static_cast<long long>(unionArray[i].getDConst())); break;
- case EOpConvDoubleToUint8:
- newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getDConst())); break;
- case EOpConvDoubleToUint16:
- newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getDConst())); break;
- case EOpConvDoubleToUint64:
- newConstArray[i].setU64Const(static_cast<unsigned long long>(unionArray[i].getDConst())); break;
- case EOpConvDoubleToFloat16:
- newConstArray[i].setDConst(unionArray[i].getDConst()); break;
- case EOpConvPtrToUint64:
- case EOpConvUint64ToPtr:
- case EOpConstructReference:
- newConstArray[i].setU64Const(unionArray[i].getU64Const()); break;
- #endif
- // TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out
- case EOpSinh:
- case EOpCosh:
- case EOpTanh:
- case EOpAsinh:
- case EOpAcosh:
- case EOpAtanh:
- case EOpFloatBitsToInt:
- case EOpFloatBitsToUint:
- case EOpIntBitsToFloat:
- case EOpUintBitsToFloat:
- case EOpDoubleBitsToInt64:
- case EOpDoubleBitsToUint64:
- case EOpInt64BitsToDouble:
- case EOpUint64BitsToDouble:
- case EOpFloat16BitsToInt16:
- case EOpFloat16BitsToUint16:
- case EOpInt16BitsToFloat16:
- case EOpUint16BitsToFloat16:
- default:
- return nullptr;
- }
- }
- TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, returnType);
- newNode->getWritableType().getQualifier().storage = EvqConst;
- newNode->setLoc(getLoc());
- return newNode;
- }
- //
- // Do constant folding for an aggregate node that has all its children
- // as constants and an operator that requires constant folding.
- //
- TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
- {
- if (aggrNode == nullptr)
- return aggrNode;
- if (! areAllChildConst(aggrNode))
- return aggrNode;
- if (aggrNode->isConstructor())
- return foldConstructor(aggrNode);
- TIntermSequence& children = aggrNode->getSequence();
- // First, see if this is an operation to constant fold, kick out if not,
- // see what size the result is if so.
- bool componentwise = false; // will also say componentwise if a scalar argument gets repeated to make per-component results
- int objectSize;
- switch (aggrNode->getOp()) {
- case EOpAtan:
- case EOpPow:
- case EOpMin:
- case EOpMax:
- case EOpMix:
- case EOpMod:
- case EOpClamp:
- case EOpLessThan:
- case EOpGreaterThan:
- case EOpLessThanEqual:
- case EOpGreaterThanEqual:
- case EOpVectorEqual:
- case EOpVectorNotEqual:
- componentwise = true;
- objectSize = children[0]->getAsConstantUnion()->getType().computeNumComponents();
- break;
- case EOpCross:
- case EOpReflect:
- case EOpRefract:
- case EOpFaceForward:
- objectSize = children[0]->getAsConstantUnion()->getType().computeNumComponents();
- break;
- case EOpDistance:
- case EOpDot:
- objectSize = 1;
- break;
- case EOpOuterProduct:
- objectSize = children[0]->getAsTyped()->getType().getVectorSize() *
- children[1]->getAsTyped()->getType().getVectorSize();
- break;
- case EOpStep:
- componentwise = true;
- objectSize = std::max(children[0]->getAsTyped()->getType().getVectorSize(),
- children[1]->getAsTyped()->getType().getVectorSize());
- break;
- case EOpSmoothStep:
- componentwise = true;
- objectSize = std::max(children[0]->getAsTyped()->getType().getVectorSize(),
- children[2]->getAsTyped()->getType().getVectorSize());
- break;
- default:
- return aggrNode;
- }
- TConstUnionArray newConstArray(objectSize);
- TVector<TConstUnionArray> childConstUnions;
- for (unsigned int arg = 0; arg < children.size(); ++arg)
- childConstUnions.push_back(children[arg]->getAsConstantUnion()->getConstArray());
- if (componentwise) {
- for (int comp = 0; comp < objectSize; comp++) {
- // some arguments are scalars instead of matching vectors; simulate a smear
- int arg0comp = std::min(comp, children[0]->getAsTyped()->getType().getVectorSize() - 1);
- int arg1comp = 0;
- if (children.size() > 1)
- arg1comp = std::min(comp, children[1]->getAsTyped()->getType().getVectorSize() - 1);
- int arg2comp = 0;
- if (children.size() > 2)
- arg2comp = std::min(comp, children[2]->getAsTyped()->getType().getVectorSize() - 1);
- switch (aggrNode->getOp()) {
- case EOpAtan:
- newConstArray[comp].setDConst(atan2(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
- break;
- case EOpPow:
- newConstArray[comp].setDConst(pow(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
- break;
- case EOpMod:
- {
- double arg0 = childConstUnions[0][arg0comp].getDConst();
- double arg1 = childConstUnions[1][arg1comp].getDConst();
- double result = arg0 - arg1 * floor(arg0 / arg1);
- newConstArray[comp].setDConst(result);
- break;
- }
- case EOpMin:
- switch(children[0]->getAsTyped()->getBasicType()) {
- case EbtFloat16:
- case EbtFloat:
- case EbtDouble:
- newConstArray[comp].setDConst(std::min(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
- break;
- case EbtInt:
- newConstArray[comp].setIConst(std::min(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()));
- break;
- case EbtUint:
- newConstArray[comp].setUConst(std::min(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()));
- break;
- #ifndef GLSLANG_WEB
- case EbtInt8:
- newConstArray[comp].setI8Const(std::min(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()));
- break;
- case EbtUint8:
- newConstArray[comp].setU8Const(std::min(childConstUnions[0][arg0comp].getU8Const(), childConstUnions[1][arg1comp].getU8Const()));
- break;
- case EbtInt16:
- newConstArray[comp].setI16Const(std::min(childConstUnions[0][arg0comp].getI16Const(), childConstUnions[1][arg1comp].getI16Const()));
- break;
- case EbtUint16:
- newConstArray[comp].setU16Const(std::min(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const()));
- break;
- case EbtInt64:
- newConstArray[comp].setI64Const(std::min(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()));
- break;
- case EbtUint64:
- newConstArray[comp].setU64Const(std::min(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()));
- break;
- #endif
- default: assert(false && "Default missing");
- }
- break;
- case EOpMax:
- switch(children[0]->getAsTyped()->getBasicType()) {
- case EbtFloat16:
- case EbtFloat:
- case EbtDouble:
- newConstArray[comp].setDConst(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
- break;
- case EbtInt:
- newConstArray[comp].setIConst(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()));
- break;
- case EbtUint:
- newConstArray[comp].setUConst(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()));
- break;
- #ifndef GLSLANG_WEB
- case EbtInt8:
- newConstArray[comp].setI8Const(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()));
- break;
- case EbtUint8:
- newConstArray[comp].setU8Const(std::max(childConstUnions[0][arg0comp].getU8Const(), childConstUnions[1][arg1comp].getU8Const()));
- break;
- case EbtInt16:
- newConstArray[comp].setI16Const(std::max(childConstUnions[0][arg0comp].getI16Const(), childConstUnions[1][arg1comp].getI16Const()));
- break;
- case EbtUint16:
- newConstArray[comp].setU16Const(std::max(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const()));
- break;
- case EbtInt64:
- newConstArray[comp].setI64Const(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()));
- break;
- case EbtUint64:
- newConstArray[comp].setU64Const(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()));
- break;
- #endif
- default: assert(false && "Default missing");
- }
- break;
- case EOpClamp:
- switch(children[0]->getAsTyped()->getBasicType()) {
- case EbtFloat16:
- case EbtFloat:
- case EbtDouble:
- newConstArray[comp].setDConst(std::min(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()),
- childConstUnions[2][arg2comp].getDConst()));
- break;
- case EbtUint:
- newConstArray[comp].setUConst(std::min(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()),
- childConstUnions[2][arg2comp].getUConst()));
- break;
- #ifndef GLSLANG_WEB
- case EbtInt8:
- newConstArray[comp].setI8Const(std::min(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()),
- childConstUnions[2][arg2comp].getI8Const()));
- break;
- case EbtUint8:
- newConstArray[comp].setU8Const(std::min(std::max(childConstUnions[0][arg0comp].getU8Const(), childConstUnions[1][arg1comp].getU8Const()),
- childConstUnions[2][arg2comp].getU8Const()));
- break;
- case EbtInt16:
- newConstArray[comp].setI16Const(std::min(std::max(childConstUnions[0][arg0comp].getI16Const(), childConstUnions[1][arg1comp].getI16Const()),
- childConstUnions[2][arg2comp].getI16Const()));
- break;
- case EbtUint16:
- newConstArray[comp].setU16Const(std::min(std::max(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const()),
- childConstUnions[2][arg2comp].getU16Const()));
- break;
- case EbtInt:
- newConstArray[comp].setIConst(std::min(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()),
- childConstUnions[2][arg2comp].getIConst()));
- break;
- case EbtInt64:
- newConstArray[comp].setI64Const(std::min(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()),
- childConstUnions[2][arg2comp].getI64Const()));
- break;
- case EbtUint64:
- newConstArray[comp].setU64Const(std::min(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()),
- childConstUnions[2][arg2comp].getU64Const()));
- break;
- #endif
- default: assert(false && "Default missing");
- }
- break;
- case EOpLessThan:
- newConstArray[comp].setBConst(childConstUnions[0][arg0comp] < childConstUnions[1][arg1comp]);
- break;
- case EOpGreaterThan:
- newConstArray[comp].setBConst(childConstUnions[0][arg0comp] > childConstUnions[1][arg1comp]);
- break;
- case EOpLessThanEqual:
- newConstArray[comp].setBConst(! (childConstUnions[0][arg0comp] > childConstUnions[1][arg1comp]));
- break;
- case EOpGreaterThanEqual:
- newConstArray[comp].setBConst(! (childConstUnions[0][arg0comp] < childConstUnions[1][arg1comp]));
- break;
- case EOpVectorEqual:
- newConstArray[comp].setBConst(childConstUnions[0][arg0comp] == childConstUnions[1][arg1comp]);
- break;
- case EOpVectorNotEqual:
- newConstArray[comp].setBConst(childConstUnions[0][arg0comp] != childConstUnions[1][arg1comp]);
- break;
- case EOpMix:
- if (!children[0]->getAsTyped()->isFloatingDomain())
- return aggrNode;
- if (children[2]->getAsTyped()->getBasicType() == EbtBool) {
- newConstArray[comp].setDConst(childConstUnions[2][arg2comp].getBConst()
- ? childConstUnions[1][arg1comp].getDConst()
- : childConstUnions[0][arg0comp].getDConst());
- } else {
- newConstArray[comp].setDConst(
- childConstUnions[0][arg0comp].getDConst() * (1.0 - childConstUnions[2][arg2comp].getDConst()) +
- childConstUnions[1][arg1comp].getDConst() * childConstUnions[2][arg2comp].getDConst());
- }
- break;
- case EOpStep:
- newConstArray[comp].setDConst(childConstUnions[1][arg1comp].getDConst() < childConstUnions[0][arg0comp].getDConst() ? 0.0 : 1.0);
- break;
- case EOpSmoothStep:
- {
- double t = (childConstUnions[2][arg2comp].getDConst() - childConstUnions[0][arg0comp].getDConst()) /
- (childConstUnions[1][arg1comp].getDConst() - childConstUnions[0][arg0comp].getDConst());
- if (t < 0.0)
- t = 0.0;
- if (t > 1.0)
- t = 1.0;
- newConstArray[comp].setDConst(t * t * (3.0 - 2.0 * t));
- break;
- }
- default:
- return aggrNode;
- }
- }
- } else {
- // Non-componentwise...
- int numComps = children[0]->getAsConstantUnion()->getType().computeNumComponents();
- double dot;
- switch (aggrNode->getOp()) {
- case EOpDistance:
- {
- double sum = 0.0;
- for (int comp = 0; comp < numComps; ++comp) {
- double diff = childConstUnions[1][comp].getDConst() - childConstUnions[0][comp].getDConst();
- sum += diff * diff;
- }
- newConstArray[0].setDConst(sqrt(sum));
- break;
- }
- case EOpDot:
- newConstArray[0].setDConst(childConstUnions[0].dot(childConstUnions[1]));
- break;
- case EOpCross:
- newConstArray[0] = childConstUnions[0][1] * childConstUnions[1][2] - childConstUnions[0][2] * childConstUnions[1][1];
- newConstArray[1] = childConstUnions[0][2] * childConstUnions[1][0] - childConstUnions[0][0] * childConstUnions[1][2];
- newConstArray[2] = childConstUnions[0][0] * childConstUnions[1][1] - childConstUnions[0][1] * childConstUnions[1][0];
- break;
- case EOpFaceForward:
- // If dot(Nref, I) < 0 return N, otherwise return -N: Arguments are (N, I, Nref).
- dot = childConstUnions[1].dot(childConstUnions[2]);
- for (int comp = 0; comp < numComps; ++comp) {
- if (dot < 0.0)
- newConstArray[comp] = childConstUnions[0][comp];
- else
- newConstArray[comp].setDConst(-childConstUnions[0][comp].getDConst());
- }
- break;
- case EOpReflect:
- // I - 2 * dot(N, I) * N: Arguments are (I, N).
- dot = childConstUnions[0].dot(childConstUnions[1]);
- dot *= 2.0;
- for (int comp = 0; comp < numComps; ++comp)
- newConstArray[comp].setDConst(childConstUnions[0][comp].getDConst() - dot * childConstUnions[1][comp].getDConst());
- break;
- case EOpRefract:
- {
- // Arguments are (I, N, eta).
- // k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I))
- // if (k < 0.0)
- // return dvec(0.0)
- // else
- // return eta * I - (eta * dot(N, I) + sqrt(k)) * N
- dot = childConstUnions[0].dot(childConstUnions[1]);
- double eta = childConstUnions[2][0].getDConst();
- double k = 1.0 - eta * eta * (1.0 - dot * dot);
- if (k < 0.0) {
- for (int comp = 0; comp < numComps; ++comp)
- newConstArray[comp].setDConst(0.0);
- } else {
- for (int comp = 0; comp < numComps; ++comp)
- newConstArray[comp].setDConst(eta * childConstUnions[0][comp].getDConst() - (eta * dot + sqrt(k)) * childConstUnions[1][comp].getDConst());
- }
- break;
- }
- case EOpOuterProduct:
- {
- int numRows = numComps;
- int numCols = children[1]->getAsConstantUnion()->getType().computeNumComponents();
- for (int row = 0; row < numRows; ++row)
- for (int col = 0; col < numCols; ++col)
- newConstArray[col * numRows + row] = childConstUnions[0][row] * childConstUnions[1][col];
- break;
- }
- default:
- return aggrNode;
- }
- }
- TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, aggrNode->getType());
- newNode->getWritableType().getQualifier().storage = EvqConst;
- newNode->setLoc(aggrNode->getLoc());
- return newNode;
- }
- bool TIntermediate::areAllChildConst(TIntermAggregate* aggrNode)
- {
- bool allConstant = true;
- // check if all the child nodes are constants so that they can be inserted into
- // the parent node
- if (aggrNode) {
- TIntermSequence& childSequenceVector = aggrNode->getSequence();
- for (TIntermSequence::iterator p = childSequenceVector.begin();
- p != childSequenceVector.end(); p++) {
- if (!(*p)->getAsTyped()->getAsConstantUnion())
- return false;
- }
- }
- return allConstant;
- }
- TIntermTyped* TIntermediate::foldConstructor(TIntermAggregate* aggrNode)
- {
- bool error = false;
- TConstUnionArray unionArray(aggrNode->getType().computeNumComponents());
- if (aggrNode->getSequence().size() == 1)
- error = parseConstTree(aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType(), true);
- else
- error = parseConstTree(aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType());
- if (error)
- return aggrNode;
- return addConstantUnion(unionArray, aggrNode->getType(), aggrNode->getLoc());
- }
- //
- // Constant folding of a bracket (array-style) dereference or struct-like dot
- // dereference. Can handle anything except a multi-character swizzle, though
- // all swizzles may go to foldSwizzle().
- //
- TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, const TSourceLoc& loc)
- {
- TType dereferencedType(node->getType(), index);
- dereferencedType.getQualifier().storage = EvqConst;
- TIntermTyped* result = 0;
- int size = dereferencedType.computeNumComponents();
- // arrays, vectors, matrices, all use simple multiplicative math
- // while structures need to add up heterogeneous members
- int start;
- if (node->getType().isCoopMat())
- start = 0;
- else if (node->isArray() || ! node->isStruct())
- start = size * index;
- else {
- // it is a structure
- assert(node->isStruct());
- start = 0;
- for (int i = 0; i < index; ++i)
- start += (*node->getType().getStruct())[i].type->computeNumComponents();
- }
- result = addConstantUnion(TConstUnionArray(node->getAsConstantUnion()->getConstArray(), start, size), node->getType(), loc);
- if (result == 0)
- result = node;
- else
- result->setType(dereferencedType);
- return result;
- }
- //
- // Make a constant vector node or constant scalar node, representing a given
- // constant vector and constant swizzle into it.
- //
- TIntermTyped* TIntermediate::foldSwizzle(TIntermTyped* node, TSwizzleSelectors<TVectorSelector>& selectors, const TSourceLoc& loc)
- {
- const TConstUnionArray& unionArray = node->getAsConstantUnion()->getConstArray();
- TConstUnionArray constArray(selectors.size());
- for (int i = 0; i < selectors.size(); i++)
- constArray[i] = unionArray[selectors[i]];
- TIntermTyped* result = addConstantUnion(constArray, node->getType(), loc);
- if (result == 0)
- result = node;
- else
- result->setType(TType(node->getBasicType(), EvqConst, selectors.size()));
- return result;
- }
- } // end namespace glslang
|