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
mat4 M1; // row_major
layout(column_major) mat4 M2; // column major
mat3 N1; // row_major
centroid float badf; // ERROR
in float badg; // ERROR
} tblock;
uniform T2 { // layout of this block is shared
......@@ -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)
};
out badout { // ERROR
float f;
};
void main()
{
pos = p * (tblock.M1 + tblock.M2 + M4 + M3 + t2m);
......
......@@ -70,6 +70,11 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, int v, E
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
dst.qualifier.precision = src.qualifier.precision;
// Layout qualifiers
mergeLayoutQualifiers(line, dst, src);
mergeLayoutQualifiers(line, dst.qualifier, src.qualifier);
// other qualifiers
#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
}
// 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)
dst.qualifier.layoutMatrix = src.qualifier.layoutMatrix;
if (src.layoutMatrix != ElmNone)
dst.layoutMatrix = src.layoutMatrix;
if (src.qualifier.layoutPacking != ElpNone)
dst.qualifier.layoutPacking = src.qualifier.layoutPacking;
if (src.layoutPacking != ElpNone)
dst.layoutPacking = src.layoutPacking;
if (src.qualifier.hasLocation())
dst.qualifier.layoutSlotLocation = src.qualifier.layoutSlotLocation;
if (src.hasLocation())
dst.layoutSlotLocation = src.layoutSlotLocation;
}
/////////////////////////////////////////////////////////////////////////////////
......@@ -1464,7 +1469,7 @@ TIntermTyped* TParseContext::constructStruct(TIntermNode* node, const TType& typ
//
// 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
......@@ -1478,13 +1483,13 @@ void TParseContext::addBlock(int line, TPublicType& qualifier, const TString& bl
return;
}
if (qualifier.basicType != EbtVoid) {
if (publicType.basicType != EbtVoid) {
error(line, "interface blocks cannot be declared with a type", blockName.c_str(), "");
recover();
return;
}
if (qualifier.qualifier.storage == EvqUniform) {
if (publicType.qualifier.storage == EvqUniform) {
requireProfile(line, (EProfileMask)(~ENoProfileMask), "uniform block");
profileRequires(line, EEsProfile, 300, 0, "uniform block");
} else {
......@@ -1494,9 +1499,36 @@ void TParseContext::addBlock(int line, TPublicType& qualifier, const TString& bl
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
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);
if (! symbolTable.insert(*userTypeDef)) {
error(line, "redefinition", blockName.c_str(), "block name");
......@@ -1505,11 +1537,6 @@ void TParseContext::addBlock(int line, TPublicType& qualifier, const TString& bl
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
// make an anonymous variable if no name was provided
......@@ -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.
// 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 {
struct TPragma contextPragma;
TPrecisionQualifier defaultPrecision[EbtNumTypes];
TQualifier defaultGlobalQualification;
TString HashErrMsg;
bool AfterEOF;
......@@ -132,7 +133,7 @@ struct TParseContext {
void setLayoutQualifier(int line, TPublicType&, TString&);
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);
bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
......@@ -141,6 +142,7 @@ struct TParseContext {
TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc);
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 updateDefaults(int line, const TPublicType&, const TString* id);
TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc);
TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc);
TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line);
......
......@@ -234,7 +234,7 @@ variable_identifier
unionArray->setUConst(anon->getMemberNumber());
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);
} else {
const TVariable* variable = symbol ? symbol->getAsVariable() : 0;
......@@ -1494,6 +1494,7 @@ single_declaration
: fully_specified_type {
$$.type = $1;
$$.intermAggregate = 0;
parseContext.updateDefaults($1.line, $$.type, 0);
}
| fully_specified_type IDENTIFIER {
$$.intermAggregate = 0;
......@@ -1504,6 +1505,8 @@ single_declaration
if (parseContext.nonInitErrorCheck($2.line, *$2.string, $$.type))
parseContext.recover();
parseContext.updateDefaults($2.line, $$.type, $2.string);
}
| fully_specified_type IDENTIFIER array_specifier {
$$.intermAggregate = 0;
......@@ -1520,6 +1523,7 @@ single_declaration
if (parseContext.arrayErrorCheck($3.line, *$2.string, $1, variable))
parseContext.recover();
}
parseContext.updateDefaults($2.line, $$.type, $2.string);
}
| fully_specified_type IDENTIFIER array_specifier EQUAL initializer {
$$.intermAggregate = 0;
......@@ -1647,7 +1651,7 @@ layout_qualifier_id_list
}
| layout_qualifier_id_list COMMA layout_qualifier_id {
$$ = $1;
parseContext.mergeLayoutQualifiers($2.line, $$, $3);
parseContext.mergeLayoutQualifiers($2.line, $$.qualifier, $3.qualifier);
}
layout_qualifier_id
......
......@@ -119,7 +119,9 @@ bool OutputBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it
case EOpIndexDirect: out.debug << "direct 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 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