зеркало из https://github.com/stride3d/xkslang.git
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
This commit is contained in:
Родитель
ba04210097
Коммит
bcd79fe5a3
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче