Add full support for uniforms with initializers, including intra-stage link validation of aggregate constant initializers.

This included 
 - encapsulating aggregate constants
 - removal of constant-aggregate comparison algorithms, instead using a flattened and direct std::vector comparison
 - adding structure type comparison for independently declared structures that still might match types



git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@23274 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2013-09-28 04:02:08 +00:00
parent b3345c422d
commit f2ee3dd46a
98 changed files with 3007 additions and 1715 deletions

View file

@ -464,8 +464,8 @@ TIntermTyped* TParseContext::handleVariable(TSourceLoc loc, TSymbol* symbol, TSt
// it was a member of an anonymous container, have to insert its dereference
const TVariable* variable = anon->getAnonContainer().getAsVariable();
TIntermTyped* container = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), loc);
TConstUnion* unionArray = new TConstUnion[1];
unionArray->setUConst(anon->getMemberNumber());
TConstUnionArray unionArray(1);
unionArray[0].setUConst(anon->getMemberNumber());
TIntermTyped* constNode = intermediate.addConstantUnion(unionArray, TType(EbtUint, EvqConst), loc);
node = intermediate.addIndex(EOpIndexDirectStruct, container, constNode, loc);
@ -483,10 +483,9 @@ TIntermTyped* TParseContext::handleVariable(TSourceLoc loc, TSymbol* symbol, TSt
// don't delete $1.string, it's used by error recovery, and the pool
// pop will reclaim the memory
if (variable->getType().getQualifier().storage == EvqConst ) {
TConstUnion* constArray = variable->getConstUnionPointer();
node = intermediate.addConstantUnion(constArray, variable->getType(), loc);
} else
if (variable->getType().getQualifier().storage == EvqConst)
node = intermediate.addConstantUnion(variable->getConstArray(), variable->getType(), loc);
else
node = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), loc);
}
@ -509,30 +508,30 @@ TIntermTyped* TParseContext::handleBracketDereference(TSourceLoc loc, TIntermTyp
} else if (base->getType().getQualifier().storage == EvqConst && index->getQualifier().storage == EvqConst) {
if (base->isArray()) {
// constant folding for arrays
result = addConstArrayNode(index->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), base, loc);
result = addConstArrayNode(index->getAsConstantUnion()->getConstArray()[0].getIConst(), base, loc);
} else if (base->isVector()) {
// constant folding for vectors
TVectorFields fields;
fields.num = 1;
fields.offsets[0] = index->getAsConstantUnion()->getUnionArrayPointer()->getIConst(); // need to do it this way because v.xy sends fields integer array
fields.offsets[0] = index->getAsConstantUnion()->getConstArray()[0].getIConst(); // need to do it this way because v.xy sends fields integer array
result = addConstVectorNode(fields, base, loc);
} else if (base->isMatrix()) {
// constant folding for matrices
result = addConstMatrixNode(index->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), base, loc);
result = addConstMatrixNode(index->getAsConstantUnion()->getConstArray()[0].getIConst(), base, loc);
}
} else {
if (index->getQualifier().storage == EvqConst) {
int indexValue = index->getAsConstantUnion()->getUnionArrayPointer()->getIConst();
int indexValue = index->getAsConstantUnion()->getConstArray()[0].getIConst();
if (! base->isArray() && (base->isVector() && base->getType().getVectorSize() <= indexValue ||
base->isMatrix() && base->getType().getMatrixCols() <= indexValue))
error(loc, "", "[", "index out of range '%d'", index->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
error(loc, "", "[", "index out of range '%d'", index->getAsConstantUnion()->getConstArray()[0].getIConst());
if (base->isArray()) {
if (base->getType().getArraySize() == 0) {
if (base->getType().getMaxArraySize() <= index->getAsConstantUnion()->getUnionArrayPointer()->getIConst())
arraySetMaxSize(loc, base->getAsSymbolNode(), index->getAsConstantUnion()->getUnionArrayPointer()->getIConst() + 1);
} else if ( index->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= base->getType().getArraySize() ||
index->getAsConstantUnion()->getUnionArrayPointer()->getIConst() < 0)
error(loc, "", "[", "array index out of range '%d'", index->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
if (base->getType().getMaxArraySize() <= index->getAsConstantUnion()->getConstArray()[0].getIConst())
arraySetMaxSize(loc, base->getAsSymbolNode(), index->getAsConstantUnion()->getConstArray()[0].getIConst() + 1);
} else if ( index->getAsConstantUnion()->getConstArray()[0].getIConst() >= base->getType().getArraySize() ||
index->getAsConstantUnion()->getConstArray()[0].getIConst() < 0)
error(loc, "", "[", "array index out of range '%d'", index->getAsConstantUnion()->getConstArray()[0].getIConst());
}
result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
} else {
@ -550,8 +549,8 @@ TIntermTyped* TParseContext::handleBracketDereference(TSourceLoc loc, TIntermTyp
}
if (result == 0) {
TConstUnion *unionArray = new TConstUnion[1];
unionArray->setDConst(0.0);
TConstUnionArray unionArray(1);
unionArray[0].setDConst(0.0);
result = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), loc);
} else {
TType newType;
@ -599,8 +598,8 @@ TIntermTyped* TParseContext::handleDotDereference(TSourceLoc loc, TIntermTyped*
result->setType(TType(base->getBasicType(), EvqConst, (int) (field).size()));
} else {
if (fields.num == 1) {
TConstUnion *unionArray = new TConstUnion[1];
unionArray->setIConst(fields.offsets[0]);
TConstUnionArray unionArray(1);
unionArray[0].setIConst(fields.offsets[0]);
TIntermTyped* index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), loc);
result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision));
@ -638,8 +637,8 @@ TIntermTyped* TParseContext::handleDotDereference(TSourceLoc loc, TIntermTyped*
result->getWritableType().getQualifier().storage = EvqConst;
}
} else {
TConstUnion *unionArray = new TConstUnion[1];
unionArray->setIConst(i);
TConstUnionArray unionArray(1);
unionArray[0].setIConst(i);
TIntermTyped* index = intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), loc);
result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc);
result->setType(*(*fields)[i].type);
@ -761,8 +760,8 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* fnCal
} else
length = intermNode->getAsTyped()->getType().getArraySize();
TConstUnion *unionArray = new TConstUnion[1];
unionArray->setIConst(length);
TConstUnionArray unionArray(1);
unionArray[0].setIConst(length);
result = intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), loc);
} else if (op != EOpNull) {
//
@ -836,8 +835,8 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* fnCal
} else {
// error message was put out by PaFindFunction()
// Put on a dummy node for error recovery
TConstUnion *unionArray = new TConstUnion[1];
unionArray->setDConst(0.0);
TConstUnionArray unionArray(1);
unionArray[0].setDConst(0.0);
result = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), loc);
}
}
@ -1074,7 +1073,7 @@ bool TParseContext::lValueErrorCheck(TSourceLoc loc, const char* op, TIntermType
for (TIntermSequence::iterator p = aggrNode->getSequence().begin();
p != aggrNode->getSequence().end(); p++) {
int value = (*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->getIConst();
int value = (*p)->getAsTyped()->getAsConstantUnion()->getConstArray()[0].getIConst();
offset[value]++;
if (offset[value] > 1) {
error(loc, " l-value of swizzle cannot have duplicate components", op, "", "");
@ -1631,7 +1630,7 @@ void TParseContext::arraySizeCheck(TSourceLoc loc, TIntermTyped* expr, int& size
return;
}
size = constant->getUnionArrayPointer()->getIConst();
size = constant->getConstArray()[0].getIConst();
if (size <= 0) {
error(loc, "array size must be a positive integer", "", "");
@ -1767,7 +1766,7 @@ bool TParseContext::arraySetMaxSize(TSourceLoc loc, TIntermSymbol *node, int siz
// return true;
// }
// int texCoordValue = texCoord->getAsVariable()->getConstUnionPointer()[0].getIConst();
// int texCoordValue = texCoord->getAsVariable()->getConstArray()[0].getIConst();
// if (texCoordValue <= size) {
// error(loc, "", "[", "gl_TexCoord can only have a max array size of up to gl_MaxTextureCoords", "");
// return true;
@ -2087,8 +2086,8 @@ TIntermNode* TParseContext::executeInitializer(TSourceLoc loc, TString& identifi
//
// test for and propagate constant
//
if (qualifier == EvqConst) {
if (qualifier != initializer->getType().getQualifier().storage) {
if (qualifier == EvqConst || qualifier == EvqUniform) {
if (initializer->getType().getQualifier().storage != EvqConst) {
error(loc, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str());
variable->getWritableType().getQualifier().storage = EvqTemporary;
return 0;
@ -2099,20 +2098,13 @@ TIntermNode* TParseContext::executeInitializer(TSourceLoc loc, TString& identifi
variable->getWritableType().getQualifier().storage = EvqTemporary;
return 0;
}
if (initializer->getAsConstantUnion()) {
TConstUnion* unionArray = variable->getConstUnionPointer();
if (type.getObjectSize() == 1 && type.getBasicType() != EbtStruct) {
*unionArray = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0];
} else {
variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
}
} else if (initializer->getAsSymbolNode()) {
if (initializer->getAsConstantUnion())
variable->setConstArray(initializer->getAsConstantUnion()->getConstArray());
else if (initializer->getAsSymbolNode()) {
TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getName());
if (const TVariable* tVar = symbol->getAsVariable()) {
TConstUnion* constArray = tVar->getConstUnionPointer();
variable->shareConstPointer(constArray);
} else {
if (const TVariable* tVar = symbol->getAsVariable())
variable->setConstArray(tVar->getConstArray());
else {
error(loc, "expected variable", initializer->getAsSymbolNode()->getName().c_str(), "");
return 0;
}
@ -2121,16 +2113,14 @@ TIntermNode* TParseContext::executeInitializer(TSourceLoc loc, TString& identifi
variable->getWritableType().getQualifier().storage = EvqTemporary;
return 0;
}
}
if (qualifier != EvqConst) {
} else {
TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), loc);
TIntermNode* initNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, loc);
if (! initNode)
assignError(loc, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
return initNode;
}
}
return 0;
}
@ -2559,8 +2549,8 @@ void TParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TInter
newExpression != 0 &&
prevExpression->getAsConstantUnion() &&
newExpression->getAsConstantUnion() &&
prevExpression->getAsConstantUnion()->getUnionArrayPointer()->getIConst() ==
newExpression->getAsConstantUnion()->getUnionArrayPointer()->getIConst())
prevExpression->getAsConstantUnion()->getConstArray()[0].getIConst() ==
newExpression->getAsConstantUnion()->getConstArray()[0].getIConst())
error(branchNode->getLoc(), "duplicated value", "case", "");
}
}
@ -2617,22 +2607,16 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy
TIntermTyped* typedNode;
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
TConstUnion *unionArray;
if (tempConstantNode) {
unionArray = tempConstantNode->getUnionArrayPointer();
if (!unionArray) { // this error message should never be raised
infoSink.info.message(EPrefixInternalError, "TConstUnion not initialized in addConstVectorNode function", loc);
return node;
}
} else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
TConstUnionArray unionArray;
if (tempConstantNode)
unionArray = tempConstantNode->getConstArray();
else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
error(loc, "Cannot offset into the vector", "Error", "");
return 0;
}
TConstUnion* constArray = new TConstUnion[fields.num];
TConstUnionArray constArray(fields.num);
for (int i = 0; i < fields.num; i++) {
if (fields.offsets[i] >= node->getType().getObjectSize()) {
@ -2664,10 +2648,10 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T
}
if (tempConstantNode) {
TConstUnion* unionArray = tempConstantNode->getUnionArrayPointer();
int size = tempConstantNode->getType().getMatrixRows();
// Note: the type is corrected (dereferenced) by the caller
typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), loc);
const TConstUnionArray& unionArray = tempConstantNode->getConstArray();
int size = tempConstantNode->getType().getMatrixRows();
// Note: the type is corrected (dereferenced) by the caller
typedNode = intermediate.addConstantUnion(TConstUnionArray(unionArray, size * index, size), tempConstantNode->getType(), loc);
} else {
error(loc, "Cannot offset into the matrix", "Error", "");
@ -2701,8 +2685,8 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
int arrayElementSize = arrayElementType.getObjectSize();
if (tempConstantNode) {
TConstUnion* unionArray = tempConstantNode->getUnionArrayPointer();
typedNode = intermediate.addConstantUnion(&unionArray[arrayElementSize * index], tempConstantNode->getType(), loc);
typedNode = intermediate.addConstantUnion(TConstUnionArray(tempConstantNode->getConstArray(), arrayElementSize * index, arrayElementSize),
tempConstantNode->getType(), loc);
} else {
error(loc, "Cannot offset into the array", "Error", "");
@ -2722,22 +2706,24 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n
{
TTypeList* fields = node->getType().getStruct();
TIntermTyped *typedNode;
int instanceSize = 0;
int instanceOffset = 0;
int instanceSize;
unsigned int index = 0;
TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
for ( index = 0; index < fields->size(); ++index) {
if ((*fields)[index].type->getFieldName() == identifier) {
instanceSize = (*fields)[index].type->getObjectSize();
if ((*fields)[index].type->getFieldName() == identifier)
break;
} else {
instanceSize += (*fields)[index].type->getObjectSize();
}
instanceOffset += instanceSize;
}
if (tempConstantNode) {
TConstUnion* constArray = tempConstantNode->getUnionArrayPointer();
typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), loc); // type will be changed in the calling function
typedNode = intermediate.addConstantUnion(TConstUnionArray(tempConstantNode->getConstArray(), instanceOffset, instanceSize),
tempConstantNode->getType(), loc);
// type will be changed in the calling function
} else {
error(loc, "Cannot offset into the structure", "Error", "");