| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- //
- // Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
- // 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.
- //
- //
- // Traverse a tree of constants to create a single folded constant.
- // It should only be used when the whole tree is known to be constant.
- //
- #include "ParseHelper.h"
- namespace glslang {
- class TConstTraverser : public TIntermTraverser {
- public:
- TConstTraverser(const TConstUnionArray& cUnion, bool singleConstParam, TOperator constructType, const TType& t)
- : unionArray(cUnion), type(t),
- constructorType(constructType), singleConstantParam(singleConstParam), error(false), isMatrix(false),
- matrixCols(0), matrixRows(0) { index = 0; tOp = EOpNull; }
- virtual void visitConstantUnion(TIntermConstantUnion* node);
- virtual bool visitAggregate(TVisit, TIntermAggregate* node);
- int index;
- TConstUnionArray unionArray;
- TOperator tOp;
- const TType& type;
- TOperator constructorType;
- bool singleConstantParam;
- bool error;
- int size; // size of the constructor ( 4 for vec4)
- bool isMatrix;
- int matrixCols;
- int matrixRows;
- protected:
- TConstTraverser(TConstTraverser&);
- TConstTraverser& operator=(TConstTraverser&);
- };
- bool TConstTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
- {
- if (! node->isConstructor() && node->getOp() != EOpComma) {
- error = true;
- return false;
- }
- bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
- if (flag) {
- singleConstantParam = true;
- constructorType = node->getOp();
- size = node->getType().computeNumComponents();
- if (node->getType().isMatrix()) {
- isMatrix = true;
- matrixCols = node->getType().getMatrixCols();
- matrixRows = node->getType().getMatrixRows();
- }
- }
- for (TIntermSequence::iterator p = node->getSequence().begin();
- p != node->getSequence().end(); p++) {
- if (node->getOp() == EOpComma)
- index = 0;
- (*p)->traverse(this);
- }
- if (flag)
- {
- singleConstantParam = false;
- constructorType = EOpNull;
- size = 0;
- isMatrix = false;
- matrixCols = 0;
- matrixRows = 0;
- }
- return false;
- }
- void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
- {
- TConstUnionArray leftUnionArray(unionArray);
- int instanceSize = type.computeNumComponents();
- if (index >= instanceSize)
- return;
- if (! singleConstantParam) {
- int rightUnionSize = node->getType().computeNumComponents();
- const TConstUnionArray& rightUnionArray = node->getConstArray();
- for (int i = 0; i < rightUnionSize; i++) {
- if (index >= instanceSize)
- return;
- leftUnionArray[index] = rightUnionArray[i];
- index++;
- }
- } else {
- int endIndex = index + size;
- const TConstUnionArray& rightUnionArray = node->getConstArray();
- if (! isMatrix) {
- int count = 0;
- int nodeComps = node->getType().computeNumComponents();
- for (int i = index; i < endIndex; i++) {
- if (i >= instanceSize)
- return;
- leftUnionArray[i] = rightUnionArray[count];
- (index)++;
- if (nodeComps > 1)
- count++;
- }
- } else {
- // constructing a matrix, but from what?
- if (node->isMatrix()) {
- // Matrix from a matrix; this has the outer matrix, node is the argument matrix.
- // Traverse the outer, potentially bigger matrix, fill in missing pieces with the
- // identity matrix.
- for (int c = 0; c < matrixCols; ++c) {
- for (int r = 0; r < matrixRows; ++r) {
- int targetOffset = index + c * matrixRows + r;
- if (r < node->getType().getMatrixRows() && c < node->getType().getMatrixCols()) {
- int srcOffset = c * node->getType().getMatrixRows() + r;
- leftUnionArray[targetOffset] = rightUnionArray[srcOffset];
- } else if (r == c)
- leftUnionArray[targetOffset].setDConst(1.0);
- else
- leftUnionArray[targetOffset].setDConst(0.0);
- }
- }
- } else {
- // matrix from vector or scalar
- int count = 0;
- const int startIndex = index;
- int nodeComps = node->getType().computeNumComponents();
- for (int i = startIndex; i < endIndex; i++) {
- if (i >= instanceSize)
- return;
- if (nodeComps == 1) {
- // If there is a single scalar parameter to a matrix
- // constructor, it is used to initialize all the
- // components on the matrix's diagonal, with the
- // remaining components initialized to 0.0.
- if (i == startIndex || (i - startIndex) % (matrixRows + 1) == 0 )
- leftUnionArray[i] = rightUnionArray[count];
- else
- leftUnionArray[i].setDConst(0.0);
- } else {
- // construct the matrix in column-major order, from
- // the components provided, in order
- leftUnionArray[i] = rightUnionArray[count];
- }
- index++;
- if (nodeComps > 1)
- count++;
- }
- }
- }
- }
- }
- bool TIntermediate::parseConstTree(TIntermNode* root, TConstUnionArray unionArray, TOperator constructorType, const TType& t, bool singleConstantParam)
- {
- if (root == 0)
- return false;
- TConstTraverser it(unionArray, singleConstantParam, constructorType, t);
- root->traverse(&it);
- if (it.error)
- return true;
- else
- return false;
- }
- } // end namespace glslang
|