TIntermTyped* TIntermediate::foldConstructor(TIntermAggregate* aggrNode) { bool error = false; TConstUnion* unionArray = new TConstUnion[aggrNode->getType().getObjectSize()]; if (aggrNode->getSequence().size() == 1) error = parseConstTree(aggrNode->getLoc(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType(), true); else error = parseConstTree(aggrNode->getLoc(), aggrNode, unionArray, aggrNode->getOp(), aggrNode->getType()); if (error) return aggrNode; return addConstantUnion(unionArray, aggrNode->getType(), aggrNode->getLoc()); }
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()); }
// // Make a constant vector node or constant scalar node, representing a given // constant vector and constant swizzle into it. // TIntermTyped* TIntermediate::foldSwizzle(TIntermTyped* node, TVectorFields& fields, const TSourceLoc& loc) { const TConstUnionArray& unionArray = node->getAsConstantUnion()->getConstArray(); TConstUnionArray constArray(fields.num); for (int i = 0; i < fields.num; i++) constArray[i] = unionArray[fields.offsets[i]]; TIntermTyped* result = addConstantUnion(constArray, node->getType(), loc); if (result == 0) result = node; else result->setType(TType(node->getBasicType(), EvqConst, fields.num)); return result; }
TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line) { TIntermAggregate* node = new TIntermAggregate(EOpSequence); node->setLine(line); TIntermConstantUnion* constIntNode; TIntermSequence &sequenceVector = node->getSequence(); ConstantUnion* unionArray; for (int i = 0; i < fields.num; i++) { unionArray = new ConstantUnion[1]; unionArray->setIConst(fields.offsets[i]); constIntNode = addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), line); sequenceVector.push_back(constIntNode); } return node; }
// // Constant folding of a bracket (array-style) dereference or struct-like dot // dereference. Can handle any thing 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(); int start; if (node->isStruct()) { start = 0; for (int i = 0; i < index; ++i) start += (*node->getType().getStruct())[i].type->computeNumComponents(); } else start = size * index; result = addConstantUnion(TConstUnionArray(node->getAsConstantUnion()->getConstArray(), start, size), node->getType(), loc); if (result == 0) result = node; else result->setType(dereferencedType); return result; }
TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) { ConstantUnion *rightUnionArray = node->getUnionArrayPointer(); int size = node->getType().getObjectSize(); ConstantUnion *leftUnionArray = new ConstantUnion[size]; for (int i=0; i < size; i++) { switch (promoteTo) { case EbtFloat: switch (node->getType().getBasicType()) { case EbtInt: leftUnionArray[i].setFConst(static_cast<float>(rightUnionArray[i].getIConst())); break; case EbtBool: leftUnionArray[i].setFConst(static_cast<float>(rightUnionArray[i].getBConst())); break; case EbtFloat: leftUnionArray[i] = rightUnionArray[i]; break; default: infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine()); return 0; } break; case EbtInt: switch (node->getType().getBasicType()) { case EbtInt: leftUnionArray[i] = rightUnionArray[i]; break; case EbtBool: leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getBConst())); break; case EbtFloat: leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getFConst())); break; default: infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine()); return 0; } break; case EbtBool: switch (node->getType().getBasicType()) { case EbtInt: leftUnionArray[i].setBConst(rightUnionArray[i].getIConst() != 0); break; case EbtBool: leftUnionArray[i] = rightUnionArray[i]; break; case EbtFloat: leftUnionArray[i].setBConst(rightUnionArray[i].getFConst() != 0.0f); break; default: infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine()); return 0; } break; default: infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLine()); return 0; } } const TType& t = node->getType(); return addConstantUnion(leftUnionArray, TType(promoteTo, t.getPrecision(), t.getQualifier(), t.getNominalSize(), t.isMatrix(), t.isArray()), node->getLine()); }