Commit bcd79fe5 by John Kessenich

Implement default layout qualifiers at global and block levels with proper…

Implement default layout qualifiers at global and block levels with proper inheritance. Also add more error checking of qualifiers. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@21107 e7fa87d3-cd2b-0410-9028-fcbf551c1848
parent ba042100
...@@ -12,6 +12,8 @@ layout(std140) uniform Transform { // layout of this block is std140 ...@@ -12,6 +12,8 @@ layout(std140) uniform Transform { // layout of this block is std140
mat4 M1; // row_major mat4 M1; // row_major
layout(column_major) mat4 M2; // column major layout(column_major) mat4 M2; // column major
mat3 N1; // row_major mat3 N1; // row_major
centroid float badf; // ERROR
in float badg; // ERROR
} tblock; } tblock;
uniform T2 { // layout of this block is shared uniform T2 { // layout of this block is shared
...@@ -26,6 +28,10 @@ layout(column_major) uniform T3 { // shared and column_major ...@@ -26,6 +28,10 @@ layout(column_major) uniform T3 { // shared and column_major
int b; // ERROR, redefinition (needs to be last member of block for testing, following members are skipped) int b; // ERROR, redefinition (needs to be last member of block for testing, following members are skipped)
}; };
out badout { // ERROR
float f;
};
void main() void main()
{ {
pos = p * (tblock.M1 + tblock.M2 + M4 + M3 + t2m); pos = p * (tblock.M1 + tblock.M2 + M4 + M3 + t2m);
......
...@@ -70,6 +70,11 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, int v, E ...@@ -70,6 +70,11 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, int v, E
error(1, "INTERNAL ERROR", "unexpected language", ""); error(1, "INTERNAL ERROR", "unexpected language", "");
} }
} }
defaultGlobalQualification.clear();
defaultGlobalQualification.layoutMatrix = ElmColumnMajor;
defaultGlobalQualification.layoutPacking = ElpShared;
defaultGlobalQualification.layoutSlotLocation = 0;
} }
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
...@@ -750,7 +755,7 @@ bool TParseContext::mergeQualifiersErrorCheck(int line, TPublicType& dst, const ...@@ -750,7 +755,7 @@ bool TParseContext::mergeQualifiersErrorCheck(int line, TPublicType& dst, const
dst.qualifier.precision = src.qualifier.precision; dst.qualifier.precision = src.qualifier.precision;
// Layout qualifiers // Layout qualifiers
mergeLayoutQualifiers(line, dst, src); mergeLayoutQualifiers(line, dst.qualifier, src.qualifier);
// other qualifiers // other qualifiers
#define MERGE_SINGLETON(field) bad |= dst.qualifier.field && src.qualifier.field; dst.qualifier.field |= src.qualifier.field; #define MERGE_SINGLETON(field) bad |= dst.qualifier.field && src.qualifier.field; dst.qualifier.field |= src.qualifier.field;
...@@ -1133,16 +1138,16 @@ void TParseContext::setLayoutQualifier(int line, TPublicType& publicType, TStrin ...@@ -1133,16 +1138,16 @@ void TParseContext::setLayoutQualifier(int line, TPublicType& publicType, TStrin
} }
// Merge any layout qualifier information from src into dst, leaving everything else in dst alone // Merge any layout qualifier information from src into dst, leaving everything else in dst alone
void TParseContext::mergeLayoutQualifiers(int line, TPublicType& dst, const TPublicType& src) void TParseContext::mergeLayoutQualifiers(int line, TQualifier& dst, const TQualifier& src)
{ {
if (src.qualifier.layoutMatrix != ElmNone) if (src.layoutMatrix != ElmNone)
dst.qualifier.layoutMatrix = src.qualifier.layoutMatrix; dst.layoutMatrix = src.layoutMatrix;
if (src.qualifier.layoutPacking != ElpNone) if (src.layoutPacking != ElpNone)
dst.qualifier.layoutPacking = src.qualifier.layoutPacking; dst.layoutPacking = src.layoutPacking;
if (src.qualifier.hasLocation()) if (src.hasLocation())
dst.qualifier.layoutSlotLocation = src.qualifier.layoutSlotLocation; dst.layoutSlotLocation = src.layoutSlotLocation;
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
...@@ -1464,7 +1469,7 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& typ ...@@ -1464,7 +1469,7 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& typ
// //
// Do everything needed to add an interface block. // Do everything needed to add an interface block.
// //
void TParseContext::addBlock(int line, TPublicType& qualifier, const TString& blockName, TTypeList& typeList, const TString* instanceName, TArraySizes arraySizes) void TParseContext::addBlock(int line, TPublicType& publicType, const TString& blockName, TTypeList& typeList, const TString* instanceName, TArraySizes arraySizes)
{ {
// First, error checks // First, error checks
...@@ -1478,13 +1483,13 @@ void TParseContext::addBlock(int line, TPublicType& qualifier, const TString& bl ...@@ -1478,13 +1483,13 @@ void TParseContext::addBlock(int line, TPublicType& qualifier, const TString& bl
return; return;
} }
if (qualifier.basicType != EbtVoid) { if (publicType.basicType != EbtVoid) {
error(line, "interface blocks cannot be declared with a type", blockName.c_str(), ""); error(line, "interface blocks cannot be declared with a type", blockName.c_str(), "");
recover(); recover();
return; return;
} }
if (qualifier.qualifier.storage == EvqUniform) { if (publicType.qualifier.storage == EvqUniform) {
requireProfile(line, (EProfileMask)(~ENoProfileMask), "uniform block"); requireProfile(line, (EProfileMask)(~ENoProfileMask), "uniform block");
profileRequires(line, EEsProfile, 300, 0, "uniform block"); profileRequires(line, EEsProfile, 300, 0, "uniform block");
} else { } else {
...@@ -1494,9 +1499,36 @@ void TParseContext::addBlock(int line, TPublicType& qualifier, const TString& bl ...@@ -1494,9 +1499,36 @@ void TParseContext::addBlock(int line, TPublicType& qualifier, const TString& bl
return; return;
} }
// check for qualifiers that don't belong within a block
for (unsigned int member = 0; member < typeList.size(); ++member) {
TQualifier memberQualifier = typeList[member].type->getQualifier();
if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal &&
memberQualifier.storage != publicType.qualifier.storage) {
error(line, "member storage qualifier cannot contradict block storage qualifier", typeList[member].type->getFieldName().c_str(), "");
recover();
}
if (publicType.qualifier.storage == EvqUniform) {
if (memberQualifier.isInterpolation() || memberQualifier.isAuxillary()) {
error(line, "member of uniform block cannot have an auxillary or interpolation qualifier", typeList[member].type->getFieldName().c_str(), "");
recover();
}
}
}
// Make default block qualification, and adjust the member qualifications
TQualifier defaultQualification = defaultGlobalQualification;
mergeLayoutQualifiers(line, defaultQualification, publicType.qualifier);
for (unsigned int member = 0; member < typeList.size(); ++member) {
TQualifier memberQualification = defaultQualification;
mergeLayoutQualifiers(line, memberQualification, typeList[member].type->getQualifier());
typeList[member].type->getQualifier() = memberQualification;
}
// Build and add the interface block as a new type named blockName // Build and add the interface block as a new type named blockName
TType blockType(&typeList, blockName, qualifier.qualifier.storage); TType blockType(&typeList, blockName, publicType.qualifier.storage);
blockType.getQualifier().layoutPacking = defaultQualification.layoutPacking;
TVariable* userTypeDef = new TVariable(&blockName, blockType, true); TVariable* userTypeDef = new TVariable(&blockName, blockType, true);
if (! symbolTable.insert(*userTypeDef)) { if (! symbolTable.insert(*userTypeDef)) {
error(line, "redefinition", blockName.c_str(), "block name"); error(line, "redefinition", blockName.c_str(), "block name");
...@@ -1505,11 +1537,6 @@ void TParseContext::addBlock(int line, TPublicType& qualifier, const TString& bl ...@@ -1505,11 +1537,6 @@ void TParseContext::addBlock(int line, TPublicType& qualifier, const TString& bl
return; return;
} }
// TODO: semantics: check for qualifiers that don't belong within a block
for (unsigned int member = 0; member < typeList.size(); ++member) {
//printf("%s: %s\n", typeList[member].type->getFieldName().c_str(), typeList[member].type->getCompleteString().c_str());
}
// Add the variable, as anonymous or named instanceName // Add the variable, as anonymous or named instanceName
// make an anonymous variable if no name was provided // make an anonymous variable if no name was provided
...@@ -1528,6 +1555,28 @@ void TParseContext::addBlock(int line, TPublicType& qualifier, const TString& bl ...@@ -1528,6 +1555,28 @@ void TParseContext::addBlock(int line, TPublicType& qualifier, const TString& bl
} }
} }
void TParseContext::updateDefaults(int line, const TPublicType& publicType, const TString* id)
{
bool cantHaveId = false;
TQualifier qualifier = publicType.qualifier;
if (qualifier.storage == EvqUniform) {
if (qualifier.layoutMatrix != ElmNone) {
cantHaveId = true;
defaultGlobalQualification.layoutMatrix = qualifier.layoutMatrix;
}
if (qualifier.layoutPacking != ElpNone) {
cantHaveId = true;
defaultGlobalQualification.layoutPacking = qualifier.layoutPacking;
}
}
if (cantHaveId && id) {
error(line, "cannot set global layout qualifiers on uniform variable, use just 'uniform' or a block", id->c_str(), "");
recover();
}
}
// //
// This function returns the tree representation for the vector field(s) being accessed from contant vector. // 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 // If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is
......
...@@ -91,6 +91,7 @@ struct TParseContext { ...@@ -91,6 +91,7 @@ struct TParseContext {
struct TPragma contextPragma; struct TPragma contextPragma;
TPrecisionQualifier defaultPrecision[EbtNumTypes]; TPrecisionQualifier defaultPrecision[EbtNumTypes];
TQualifier defaultGlobalQualification;
TString HashErrMsg; TString HashErrMsg;
bool AfterEOF; bool AfterEOF;
...@@ -132,7 +133,7 @@ struct TParseContext { ...@@ -132,7 +133,7 @@ struct TParseContext {
void setLayoutQualifier(int line, TPublicType&, TString&); void setLayoutQualifier(int line, TPublicType&, TString&);
void setLayoutQualifier(int line, TPublicType&, TString&, int); void setLayoutQualifier(int line, TPublicType&, TString&, int);
void mergeLayoutQualifiers(int line, TPublicType& dest, const TPublicType& src); void mergeLayoutQualifiers(int line, TQualifier& dest, const TQualifier& src);
const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0); const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType, bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
...@@ -141,6 +142,7 @@ struct TParseContext { ...@@ -141,6 +142,7 @@ struct TParseContext {
TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc); TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc);
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermNode*, TSourceLoc, bool subset); TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermNode*, TSourceLoc, bool subset);
void addBlock(int line, TPublicType& qualifier, const TString& blockName, TTypeList& typeList, const TString* instanceName = 0, TArraySizes arraySizes = 0); void addBlock(int line, TPublicType& qualifier, const TString& blockName, TTypeList& typeList, const TString* instanceName = 0, TArraySizes arraySizes = 0);
void updateDefaults(int line, const TPublicType&, const TString* id);
TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc); TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc);
TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc); TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc);
TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line); TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line);
......
...@@ -234,7 +234,7 @@ variable_identifier ...@@ -234,7 +234,7 @@ variable_identifier
unionArray->setUConst(anon->getMemberNumber()); unionArray->setUConst(anon->getMemberNumber());
TIntermTyped* constNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtUint, EvqConst), $1.line); TIntermTyped* constNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtUint, EvqConst), $1.line);
$$ = parseContext.intermediate.addIndex(EOpIndexDirect, container, constNode, $1.line); $$ = parseContext.intermediate.addIndex(EOpIndexDirectStruct, container, constNode, $1.line);
$$->setType(*(*variable->getType().getStruct())[anon->getMemberNumber()].type); $$->setType(*(*variable->getType().getStruct())[anon->getMemberNumber()].type);
} else { } else {
const TVariable* variable = symbol ? symbol->getAsVariable() : 0; const TVariable* variable = symbol ? symbol->getAsVariable() : 0;
...@@ -1494,6 +1494,7 @@ single_declaration ...@@ -1494,6 +1494,7 @@ single_declaration
: fully_specified_type { : fully_specified_type {
$$.type = $1; $$.type = $1;
$$.intermAggregate = 0; $$.intermAggregate = 0;
parseContext.updateDefaults($1.line, $$.type, 0);
} }
| fully_specified_type IDENTIFIER { | fully_specified_type IDENTIFIER {
$$.intermAggregate = 0; $$.intermAggregate = 0;
...@@ -1504,6 +1505,8 @@ single_declaration ...@@ -1504,6 +1505,8 @@ single_declaration
if (parseContext.nonInitErrorCheck($2.line, *$2.string, $$.type)) if (parseContext.nonInitErrorCheck($2.line, *$2.string, $$.type))
parseContext.recover(); parseContext.recover();
parseContext.updateDefaults($2.line, $$.type, $2.string);
} }
| fully_specified_type IDENTIFIER array_specifier { | fully_specified_type IDENTIFIER array_specifier {
$$.intermAggregate = 0; $$.intermAggregate = 0;
...@@ -1520,6 +1523,7 @@ single_declaration ...@@ -1520,6 +1523,7 @@ single_declaration
if (parseContext.arrayErrorCheck($3.line, *$2.string, $1, variable)) if (parseContext.arrayErrorCheck($3.line, *$2.string, $1, variable))
parseContext.recover(); parseContext.recover();
} }
parseContext.updateDefaults($2.line, $$.type, $2.string);
} }
| fully_specified_type IDENTIFIER array_specifier EQUAL initializer { | fully_specified_type IDENTIFIER array_specifier EQUAL initializer {
$$.intermAggregate = 0; $$.intermAggregate = 0;
...@@ -1647,7 +1651,7 @@ layout_qualifier_id_list ...@@ -1647,7 +1651,7 @@ layout_qualifier_id_list
} }
| layout_qualifier_id_list COMMA layout_qualifier_id { | layout_qualifier_id_list COMMA layout_qualifier_id {
$$ = $1; $$ = $1;
parseContext.mergeLayoutQualifiers($2.line, $$, $3); parseContext.mergeLayoutQualifiers($2.line, $$.qualifier, $3.qualifier);
} }
layout_qualifier_id layout_qualifier_id
......
...@@ -119,7 +119,9 @@ bool OutputBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it ...@@ -119,7 +119,9 @@ bool OutputBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it
case EOpIndexDirect: out.debug << "direct index"; break; case EOpIndexDirect: out.debug << "direct index"; break;
case EOpIndexIndirect: out.debug << "indirect index"; break; case EOpIndexIndirect: out.debug << "indirect index"; break;
case EOpIndexDirectStruct: out.debug << "direct index for structure"; break; case EOpIndexDirectStruct:
out.debug << (*node->getLeft()->getType().getStruct())[node->getRight()->getAsConstantUnion()->getUnionArrayPointer()->getIConst()].type->getFieldName();
out.debug << ": direct index for structure"; break;
case EOpVectorSwizzle: out.debug << "vector swizzle"; break; case EOpVectorSwizzle: out.debug << "vector swizzle"; break;
case EOpAdd: out.debug << "add"; break; case EOpAdd: out.debug << "add"; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment