本文整理汇总了C++中TIntermConstantUnion类的典型用法代码示例。如果您正苦于以下问题:C++ TIntermConstantUnion类的具体用法?C++ TIntermConstantUnion怎么用?C++ TIntermConstantUnion使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了TIntermConstantUnion类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: arraySizeErrorCheck
//
// Do size checking for an array type's size.
//
// Returns true if there was an error.
//
bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
{
TIntermConstantUnion* constant = expr->getAsConstantUnion();
if (constant == 0 || constant->getBasicType() != EbtInt) {
error(line, "array size must be a constant integer expression", "", "");
return true;
}
size = constant->getUnionArrayPointer()->getIConst();
if (size <= 0) {
error(line, "array size must be a positive integer", "", "");
size = 1;
return true;
}
return false;
}
示例2: addConstVectorNode
//
// This function returns the tree representation for the vector field(s) being accessed from contant vector.
// If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is
// returned, else an aggregate node is returned (for v.xy). The input to this function could either be the symbol
// node or it could be the intermediate tree representation of accessing fields in a constant structure or column of
// a constant matrix.
//
TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, TSourceLoc line)
{
TIntermTyped* typedNode;
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
ConstantUnion *unionArray;
if (tempConstantNode) {
unionArray = tempConstantNode->getUnionArrayPointer();
ASSERT(unionArray);
if (!unionArray) {
return node;
}
} else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
error(line, "Cannot offset into the vector", "Error");
recover();
return 0;
}
ConstantUnion* constArray = new ConstantUnion[fields.num];
for (int i = 0; i < fields.num; i++) {
if (fields.offsets[i] >= node->getType().getObjectSize()) {
std::stringstream extraInfoStream;
extraInfoStream << "vector field selection out of range '" << fields.offsets[i] << "'";
std::string extraInfo = extraInfoStream.str();
error(line, "", "[", extraInfo.c_str());
recover();
fields.offsets[i] = 0;
}
constArray[i] = unionArray[fields.offsets[i]];
}
typedNode = intermediate.addConstantUnion(constArray, node->getType(), line);
return typedNode;
}
示例3: addConstVectorNode
//
// This function returns the tree representation for the vector field(s) being accessed from contant vector.
// If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is
// returned, else an aggregate node is returned (for v.xy). The input to this function could either be the symbol
// node or it could be the intermediate tree representation of accessing fields in a constant structure or column of
// a constant matrix.
//
TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, TSourceLoc line)
{
TIntermTyped* typedNode;
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
ConstantUnion *unionArray;
if (tempConstantNode) {
unionArray = tempConstantNode->getUnionArrayPointer();
if (!unionArray) { // this error message should never be raised
infoSink.info.message(EPrefixInternalError, "ConstantUnion not initialized in addConstVectorNode function", line);
recover();
return node;
}
} else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
error(line, "Cannot offset into the vector", "Error", "");
recover();
return 0;
}
ConstantUnion* constArray = new ConstantUnion[fields.num];
for (int i = 0; i < fields.num; i++) {
if (fields.offsets[i] >= node->getType().getObjectSize()) {
error(line, "", "[", "vector field selection out of range '%d'", fields.offsets[i]);
recover();
fields.offsets[i] = 0;
}
constArray[i] = unionArray[fields.offsets[i]];
}
typedNode = intermediate.addConstantUnion(constArray, node->getType(), line);
return typedNode;
}
示例4: addConstMatrixNode
//
// This function returns the column being accessed from a constant matrix. The values are retrieved from
// the symbol table and parse-tree is built for a vector (each column of a matrix is a vector). The input
// to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a
// constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure)
//
TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, TSourceLoc line)
{
TIntermTyped* typedNode;
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
if (index >= node->getType().getNominalSize()) {
error(line, "", "[", "matrix field selection out of range '%d'", index);
recover();
index = 0;
}
if (tempConstantNode) {
ConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
int size = tempConstantNode->getType().getNominalSize();
typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
} else {
error(line, "Cannot offset into the matrix", "Error", "");
recover();
return 0;
}
return typedNode;
}
示例5: ASSERT
bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode)
{
if (binaryNode->getOp() == EOpIndexDirectInterfaceBlock)
{
// NOTE: we do not determine static use for individual blocks of an array
TIntermTyped *blockNode = binaryNode->getLeft()->getAsTyped();
ASSERT(blockNode);
TIntermConstantUnion *constantUnion = binaryNode->getRight()->getAsConstantUnion();
ASSERT(constantUnion);
const TInterfaceBlock *interfaceBlock = blockNode->getType().getInterfaceBlock();
InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks);
ASSERT(namedBlock);
namedBlock->staticUse = true;
unsigned int fieldIndex = constantUnion->getUConst(0);
ASSERT(fieldIndex < namedBlock->fields.size());
namedBlock->fields[fieldIndex].staticUse = true;
return false;
}
return true;
}
示例6: switch
//
// Connect two nodes with a new parent that does a binary operation on the nodes.
//
// Returns the added node.
//
TIntermTyped *TIntermediate::addBinaryMath(
TOperator op, TIntermTyped *left, TIntermTyped *right, const TSourceLoc &line)
{
switch (op)
{
case EOpEqual:
case EOpNotEqual:
if (left->isArray())
return NULL;
break;
case EOpLessThan:
case EOpGreaterThan:
case EOpLessThanEqual:
case EOpGreaterThanEqual:
if (left->isMatrix() || left->isArray() || left->isVector() ||
left->getBasicType() == EbtStruct)
{
return NULL;
}
break;
case EOpLogicalOr:
case EOpLogicalXor:
case EOpLogicalAnd:
if (left->getBasicType() != EbtBool ||
left->isMatrix() || left->isArray() || left->isVector())
{
return NULL;
}
break;
case EOpAdd:
case EOpSub:
case EOpDiv:
case EOpMul:
if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool)
return NULL;
default:
break;
}
if (left->getBasicType() != right->getBasicType())
{
return NULL;
}
//
// Need a new node holding things together then. Make
// one and promote it to the right type.
//
TIntermBinary *node = new TIntermBinary(op);
node->setLine(line);
node->setLeft(left);
node->setRight(right);
if (!node->promote(mInfoSink))
return NULL;
//
// See if we can fold constants.
//
TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
if (leftTempConstant && rightTempConstant)
{
TIntermTyped *typedReturnNode =
leftTempConstant->fold(node->getOp(), rightTempConstant, mInfoSink);
if (typedReturnNode)
return typedReturnNode;
}
return node;
}
示例7: OutputTreeText
//.........这里部分代码省略.........
case EOpBitShiftLeft:
out << "bit-wise shift left";
break;
case EOpBitShiftRight:
out << "bit-wise shift right";
break;
case EOpBitwiseAnd:
out << "bit-wise and";
break;
case EOpBitwiseXor:
out << "bit-wise xor";
break;
case EOpBitwiseOr:
out << "bit-wise or";
break;
case EOpEqual:
out << "Compare Equal";
break;
case EOpNotEqual:
out << "Compare Not Equal";
break;
case EOpLessThan:
out << "Compare Less Than";
break;
case EOpGreaterThan:
out << "Compare Greater Than";
break;
case EOpLessThanEqual:
out << "Compare Less Than or Equal";
break;
case EOpGreaterThanEqual:
out << "Compare Greater Than or Equal";
break;
case EOpVectorTimesScalar:
out << "vector-scale";
break;
case EOpVectorTimesMatrix:
out << "vector-times-matrix";
break;
case EOpMatrixTimesVector:
out << "matrix-times-vector";
break;
case EOpMatrixTimesScalar:
out << "matrix-scale";
break;
case EOpMatrixTimesMatrix:
out << "matrix-multiply";
break;
case EOpLogicalOr:
out << "logical-or";
break;
case EOpLogicalXor:
out << "logical-xor";
break;
case EOpLogicalAnd:
out << "logical-and";
break;
default:
out << "<unknown op>";
}
out << " (" << node->getCompleteString() << ")";
out << "\n";
// Special handling for direct indexes. Because constant
// unions are not aware they are struct indexes, treat them
// here where we have that contextual knowledge.
if (node->getOp() == EOpIndexDirectStruct ||
node->getOp() == EOpIndexDirectInterfaceBlock)
{
mDepth++;
node->getLeft()->traverse(this);
mDepth--;
TIntermConstantUnion *intermConstantUnion = node->getRight()->getAsConstantUnion();
ASSERT(intermConstantUnion);
OutputTreeText(out, intermConstantUnion, mDepth + 1);
// The following code finds the field name from the constant union
const ConstantUnion *constantUnion = intermConstantUnion->getUnionArrayPointer();
const TStructure *structure = node->getLeft()->getType().getStruct();
const TInterfaceBlock *interfaceBlock = node->getLeft()->getType().getInterfaceBlock();
ASSERT(structure || interfaceBlock);
const TFieldList &fields = structure ? structure->fields() : interfaceBlock->fields();
const TField *field = fields[constantUnion->getIConst()];
out << constantUnion->getIConst() << " (field '" << field->name() << "')";
return false;
}
return true;
}
示例8: switch
//
// Add one node as the parent of another that it operates on.
//
// Returns the added node.
//
TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc line, TSymbolTable& symbolTable)
{
TIntermUnary* node;
TIntermTyped* child = childNode->getAsTyped();
if (child == 0) {
infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line);
return 0;
}
switch (op) {
case EOpLogicalNot:
if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) {
return 0;
}
break;
case EOpPostIncrement:
case EOpPreIncrement:
case EOpPostDecrement:
case EOpPreDecrement:
case EOpNegative:
if (child->getType().getBasicType() == EbtStruct || child->getType().isArray())
return 0;
default: break;
}
//
// Do we need to promote the operand?
//
// Note: Implicit promotions were removed from the language.
//
TBasicType newType = EbtVoid;
switch (op) {
case EOpConstructInt: newType = EbtInt; break;
case EOpConstructBool: newType = EbtBool; break;
case EOpConstructFloat: newType = EbtFloat; break;
default: break;
}
if (newType != EbtVoid) {
child = addConversion(op, TType(newType, child->getPrecision(), EvqTemporary,
child->getNominalSize(),
child->isMatrix(),
child->isArray()),
child);
if (child == 0)
return 0;
}
//
// For constructors, we are now done, it's all in the conversion.
//
switch (op) {
case EOpConstructInt:
case EOpConstructBool:
case EOpConstructFloat:
return child;
default: break;
}
TIntermConstantUnion *childTempConstant = 0;
if (child->getAsConstantUnion())
childTempConstant = child->getAsConstantUnion();
//
// Make a new node for the operator.
//
node = new TIntermUnary(op);
if (line == 0)
line = child->getLine();
node->setLine(line);
node->setOperand(child);
if (! node->promote(infoSink))
return 0;
if (childTempConstant) {
TIntermTyped* newChild = childTempConstant->fold(op, 0, infoSink);
if (newChild)
return newChild;
}
return node;
}
示例9: getUnionArrayPointer
TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNode, TInfoSink& infoSink)
{
ConstantUnion *unionArray = getUnionArrayPointer();
int objectSize = getType().getObjectSize();
if (constantNode) { // binary operations
TIntermConstantUnion *node = constantNode->getAsConstantUnion();
ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
TType returnType = getType();
// for a case like float f = 1.2 + vec4(2,3,4,5);
if (constantNode->getType().getObjectSize() == 1 && objectSize > 1) {
rightUnionArray = new ConstantUnion[objectSize];
for (int i = 0; i < objectSize; ++i)
rightUnionArray[i] = *node->getUnionArrayPointer();
returnType = getType();
} else if (constantNode->getType().getObjectSize() > 1 && objectSize == 1) {
// for a case like float f = vec4(2,3,4,5) + 1.2;
unionArray = new ConstantUnion[constantNode->getType().getObjectSize()];
for (int i = 0; i < constantNode->getType().getObjectSize(); ++i)
unionArray[i] = *getUnionArrayPointer();
returnType = node->getType();
objectSize = constantNode->getType().getObjectSize();
}
ConstantUnion* tempConstArray = 0;
TIntermConstantUnion *tempNode;
bool boolNodeFlag = false;
switch(op) {
case EOpAdd:
tempConstArray = new ConstantUnion[objectSize];
{// support MSVC++6.0
for (int i = 0; i < objectSize; i++)
tempConstArray[i] = unionArray[i] + rightUnionArray[i];
}
break;
case EOpSub:
tempConstArray = new ConstantUnion[objectSize];
{// support MSVC++6.0
for (int i = 0; i < objectSize; i++)
tempConstArray[i] = unionArray[i] - rightUnionArray[i];
}
break;
case EOpMul:
case EOpVectorTimesScalar:
case EOpMatrixTimesScalar:
tempConstArray = new ConstantUnion[objectSize];
{// support MSVC++6.0
for (int i = 0; i < objectSize; i++)
tempConstArray[i] = unionArray[i] * rightUnionArray[i];
}
break;
case EOpMatrixTimesMatrix:
if (getType().getBasicType() != EbtFloat || node->getBasicType() != EbtFloat) {
infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix multiply", getLine());
return 0;
}
{// support MSVC++6.0
int size = getNominalSize();
tempConstArray = new ConstantUnion[size*size];
for (int row = 0; row < size; row++) {
for (int column = 0; column < size; column++) {
tempConstArray[size * column + row].setFConst(0.0f);
for (int i = 0; i < size; i++) {
tempConstArray[size * column + row].setFConst(tempConstArray[size * column + row].getFConst() + unionArray[i * size + row].getFConst() * (rightUnionArray[column * size + i].getFConst()));
}
}
}
}
break;
case EOpDiv:
tempConstArray = new ConstantUnion[objectSize];
{// support MSVC++6.0
for (int i = 0; i < objectSize; i++) {
switch (getType().getBasicType()) {
case EbtFloat:
if (rightUnionArray[i] == 0.0f) {
infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
tempConstArray[i].setFConst(FLT_MAX);
} else
tempConstArray[i].setFConst(unionArray[i].getFConst() / rightUnionArray[i].getFConst());
break;
case EbtInt:
if (rightUnionArray[i] == 0) {
infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
tempConstArray[i].setIConst(INT_MAX);
} else
tempConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst());
break;
default:
infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", getLine());
return 0;
}
}
}
break;
//.........这里部分代码省略.........
示例10: objSink
bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node)
{
bool visitChildren = true;
TInfoSinkBase& out = objSink();
switch (node->getOp())
{
case EOpInitialize:
if (visit == InVisit)
{
out << " = ";
// RHS of initialize is not being declared.
mDeclaringVariables = false;
}
break;
case EOpAssign: writeTriplet(visit, "(", " = ", ")"); break;
case EOpAddAssign: writeTriplet(visit, "(", " += ", ")"); break;
case EOpSubAssign: writeTriplet(visit, "(", " -= ", ")"); break;
case EOpDivAssign: writeTriplet(visit, "(", " /= ", ")"); break;
// Notice the fall-through.
case EOpMulAssign:
case EOpVectorTimesMatrixAssign:
case EOpVectorTimesScalarAssign:
case EOpMatrixTimesScalarAssign:
case EOpMatrixTimesMatrixAssign:
writeTriplet(visit, "(", " *= ", ")");
break;
case EOpIndexDirect:
writeTriplet(visit, NULL, "[", "]");
break;
case EOpIndexIndirect:
if (node->getAddIndexClamp())
{
if (visit == InVisit)
{
if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) {
out << "[int(clamp(float(";
} else {
out << "[webgl_int_clamp(";
}
}
else if (visit == PostVisit)
{
int maxSize;
TIntermTyped *left = node->getLeft();
TType leftType = left->getType();
if (left->isArray())
{
// The shader will fail validation if the array length is not > 0.
maxSize = leftType.getArraySize() - 1;
}
else
{
maxSize = leftType.getNominalSize() - 1;
}
if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) {
out << "), 0.0, float(" << maxSize << ")))]";
} else {
out << ", 0, " << maxSize << ")]";
}
}
}
else
{
writeTriplet(visit, NULL, "[", "]");
}
break;
case EOpIndexDirectStruct:
if (visit == InVisit)
{
out << ".";
// TODO(alokp): ASSERT
TString fieldName = node->getType().getFieldName();
const TType& structType = node->getLeft()->getType();
if (!mSymbolTable.findBuiltIn(structType.getTypeName()))
fieldName = hashName(fieldName);
out << fieldName;
visitChildren = false;
}
break;
case EOpVectorSwizzle:
if (visit == InVisit)
{
out << ".";
TIntermAggregate* rightChild = node->getRight()->getAsAggregate();
TIntermSequence& sequence = rightChild->getSequence();
for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); ++sit)
{
TIntermConstantUnion* element = (*sit)->getAsConstantUnion();
ASSERT(element->getBasicType() == EbtInt);
ASSERT(element->getNominalSize() == 1);
const ConstantUnion& data = element->getUnionArrayPointer()[0];
ASSERT(data.getType() == EbtInt);
switch (data.getIConst())
{
case 0: out << "x"; break;
//.........这里部分代码省略.........
示例11: foldConstructor
//.........这里部分代码省略.........
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;
}
示例12: objSink
//.........这里部分代码省略.........
TType leftType = left->getType();
if (left->isArray())
{
// The shader will fail validation if the array length is not > 0.
maxSize = leftType.getArraySize() - 1;
}
else
{
maxSize = leftType.getNominalSize() - 1;
}
if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC)
out << "), 0.0, float(" << maxSize << ")))]";
else
out << ", 0, " << maxSize << ")]";
}
}
else
{
writeTriplet(visit, NULL, "[", "]");
}
break;
case EOpIndexDirectStruct:
if (visit == InVisit)
{
// Here we are writing out "foo.bar", where "foo" is struct
// and "bar" is field. In AST, it is represented as a binary
// node, where left child represents "foo" and right child "bar".
// The node itself represents ".". The struct field "bar" is
// actually stored as an index into TStructure::fields.
out << ".";
const TStructure *structure = node->getLeft()->getType().getStruct();
const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
const TField *field = structure->fields()[index->getIConst(0)];
TString fieldName = field->name();
if (!mSymbolTable.findBuiltIn(structure->name(), mShaderVersion))
fieldName = hashName(fieldName);
out << fieldName;
visitChildren = false;
}
break;
case EOpIndexDirectInterfaceBlock:
if (visit == InVisit)
{
out << ".";
const TInterfaceBlock *interfaceBlock = node->getLeft()->getType().getInterfaceBlock();
const TIntermConstantUnion *index = node->getRight()->getAsConstantUnion();
const TField *field = interfaceBlock->fields()[index->getIConst(0)];
TString fieldName = field->name();
ASSERT(!mSymbolTable.findBuiltIn(interfaceBlock->name(), mShaderVersion));
fieldName = hashName(fieldName);
out << fieldName;
visitChildren = false;
}
break;
case EOpVectorSwizzle:
if (visit == InVisit)
{
out << ".";
TIntermAggregate *rightChild = node->getRight()->getAsAggregate();
TIntermSequence *sequence = rightChild->getSequence();
示例13: getUnionArrayPointer
//
// Do folding between a pair of nodes
//
TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNode)
{
TConstUnion *unionArray = getUnionArrayPointer();
int objectSize = getType().getObjectSize();
TConstUnion* newConstArray = 0;
// 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
//
TIntermConstantUnion *node = constantNode->getAsConstantUnion();
TConstUnion *rightUnionArray = node->getUnionArrayPointer();
if (constantNode->getType().getObjectSize() == 1 && objectSize > 1) {
// for a case like float f = vec4(2,3,4,5) + 1.2;
rightUnionArray = new TConstUnion[objectSize];
for (int i = 0; i < objectSize; ++i)
rightUnionArray[i] = *node->getUnionArrayPointer();
} else if (constantNode->getType().getObjectSize() > 1 && objectSize == 1) {
// for a case like float f = 1.2 + vec4(2,3,4,5);
rightUnionArray = node->getUnionArrayPointer();
unionArray = new TConstUnion[constantNode->getType().getObjectSize()];
for (int i = 0; i < constantNode->getType().getObjectSize(); ++i)
unionArray[i] = *getUnionArrayPointer();
returnType.shallowCopy(node->getType());
objectSize = constantNode->getType().getObjectSize();
}
int index = 0;
bool boolNodeFlag = false;
switch(op) {
case EOpAdd:
newConstArray = new TConstUnion[objectSize];
for (int i = 0; i < objectSize; i++)
newConstArray[i] = unionArray[i] + rightUnionArray[i];
break;
case EOpSub:
newConstArray = new TConstUnion[objectSize];
for (int i = 0; i < objectSize; i++)
newConstArray[i] = unionArray[i] - rightUnionArray[i];
break;
case EOpMul:
case EOpVectorTimesScalar:
case EOpMatrixTimesScalar:
newConstArray = new TConstUnion[objectSize];
for (int i = 0; i < objectSize; i++)
newConstArray[i] = unionArray[i] * rightUnionArray[i];
break;
case EOpMatrixTimesMatrix:
newConstArray = new TConstUnion[getMatrixRows() * node->getMatrixCols()];
for (int row = 0; row < getMatrixRows(); row++) {
for (int column = 0; column < node->getMatrixCols(); column++) {
double sum = 0.0f;
for (int i = 0; i < node->getMatrixRows(); i++)
sum += unionArray[i * getMatrixRows() + row].getDConst() * rightUnionArray[column * node->getMatrixRows() + i].getDConst();
newConstArray[column * getMatrixRows() + row].setDConst(sum);
}
}
returnType.shallowCopy(TType(getType().getBasicType(), EvqConst, 0, getMatrixRows(), node->getMatrixCols()));
break;
case EOpDiv:
newConstArray = new TConstUnion[objectSize];
for (int i = 0; i < objectSize; i++) {
switch (getType().getBasicType()) {
case EbtDouble:
case EbtFloat:
newConstArray[i].setDConst(unionArray[i].getDConst() / rightUnionArray[i].getDConst());
break;
case EbtInt:
if (rightUnionArray[i] == 0) {
newConstArray[i].setIConst(0xEFFFFFFF);
} else
newConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst());
break;
case EbtUint:
if (rightUnionArray[i] == 0) {
newConstArray[i].setUConst(0xFFFFFFFF);
} else
newConstArray[i].setUConst(unionArray[i].getUConst() / rightUnionArray[i].getUConst());
break;
default:
return 0;
}
}
break;
case EOpMatrixTimesVector:
newConstArray = new TConstUnion[getMatrixRows()];
for (int i = 0; i < getMatrixRows(); i++) {
//.........这里部分代码省略.........
示例14: getUnionArrayPointer
//
// 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.
//
TIntermTyped *TIntermConstantUnion::fold(
TOperator op, TIntermTyped *constantNode, TInfoSink &infoSink)
{
ConstantUnion *unionArray = getUnionArrayPointer();
if (!unionArray)
return NULL;
size_t objectSize = getType().getObjectSize();
if (constantNode)
{
// binary operations
TIntermConstantUnion *node = constantNode->getAsConstantUnion();
ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
TType returnType = getType();
if (!rightUnionArray)
return NULL;
// for a case like float f = 1.2 + vec4(2,3,4,5);
if (constantNode->getType().getObjectSize() == 1 && objectSize > 1)
{
rightUnionArray = new ConstantUnion[objectSize];
for (size_t i = 0; i < objectSize; ++i)
{
rightUnionArray[i] = *node->getUnionArrayPointer();
}
returnType = getType();
}
else if (constantNode->getType().getObjectSize() > 1 && objectSize == 1)
{
// for a case like float f = vec4(2,3,4,5) + 1.2;
unionArray = new ConstantUnion[constantNode->getType().getObjectSize()];
for (size_t i = 0; i < constantNode->getType().getObjectSize(); ++i)
{
unionArray[i] = *getUnionArrayPointer();
}
returnType = node->getType();
objectSize = constantNode->getType().getObjectSize();
}
ConstantUnion *tempConstArray = NULL;
TIntermConstantUnion *tempNode;
bool boolNodeFlag = false;
switch(op)
{
case EOpAdd:
tempConstArray = new ConstantUnion[objectSize];
for (size_t i = 0; i < objectSize; i++)
tempConstArray[i] = unionArray[i] + rightUnionArray[i];
break;
case EOpSub:
tempConstArray = new ConstantUnion[objectSize];
for (size_t i = 0; i < objectSize; i++)
tempConstArray[i] = unionArray[i] - rightUnionArray[i];
break;
case EOpMul:
case EOpVectorTimesScalar:
case EOpMatrixTimesScalar:
tempConstArray = new ConstantUnion[objectSize];
for (size_t i = 0; i < objectSize; i++)
tempConstArray[i] = unionArray[i] * rightUnionArray[i];
break;
case EOpMatrixTimesMatrix:
{
if (getType().getBasicType() != EbtFloat ||
node->getBasicType() != EbtFloat)
{
infoSink.info.message(
EPrefixInternalError, getLine(),
"Constant Folding cannot be done for matrix multiply");
return NULL;
}
const int leftCols = getCols();
const int leftRows = getRows();
const int rightCols = constantNode->getType().getCols();
const int rightRows = constantNode->getType().getRows();
const int resultCols = rightCols;
const int resultRows = leftRows;
tempConstArray = new ConstantUnion[resultCols*resultRows];
for (int row = 0; row < resultRows; row++)
{
for (int column = 0; column < resultCols; column++)
{
tempConstArray[resultRows * column + row].setFConst(0.0f);
for (int i = 0; i < leftCols; i++)
{
tempConstArray[resultRows * column + row].setFConst(
//.........这里部分代码省略.........
示例15: foldConstructor
//.........这里部分代码省略.........
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;
if (children.size() > 1)
arg1comp = std::min(comp, children[1]->getAsTyped()->getType().getVectorSize() - 1);
int arg2comp;
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 EOpMin:
if (isFloatingPoint)
newConstArray[comp].setDConst(std::min(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
else if (isSigned)
newConstArray[comp].setIConst(std::min(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()));
else
newConstArray[comp].setUConst(std::min(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()));
break;
case EOpMax:
if (isFloatingPoint)
newConstArray[comp].setDConst(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
else if (isSigned)
newConstArray[comp].setIConst(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()));
else
newConstArray[comp].setUConst(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()));
break;
case EOpClamp:
if (isFloatingPoint)
newConstArray[comp].setDConst(std::min(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()),
childConstUnions[2][arg2comp].getDConst()));
else if (isSigned)
newConstArray[comp].setIConst(std::min(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()),
childConstUnions[2][arg2comp].getIConst()));
else
newConstArray[comp].setUConst(std::min(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()),
childConstUnions[2][arg2comp].getUConst()));
break;
case EOpMix:
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...
switch (aggrNode->getOp()) {
// TODO: Functionality: constant folding: the rest of the ops have to be fleshed out
case EOpModf:
case EOpDistance:
case EOpDot:
case EOpCross:
case EOpFaceForward:
case EOpReflect:
case EOpRefract:
case EOpOuterProduct:
return aggrNode;
default:
return aggrNode;
}
}
TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, aggrNode->getType());
newNode->getWritableType().getQualifier().storage = EvqConst;
newNode->setLoc(aggrNode->getLoc());
return newNode;
}