Add layout binding qualifier for blocks and samplers (atomics are not yet in, nor link validation).
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@23590 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
8f13e1322d
commit
ab3080353a
@ -62,3 +62,12 @@ void bar(in highp volatile vec4 v)
|
||||
f.xxxxx; // ERROR
|
||||
f.xxy; // ERROR
|
||||
}
|
||||
|
||||
layout(binding = 3) uniform; // ERROR
|
||||
layout(binding = 3) uniform boundblock { int aoeu; } boundInst;
|
||||
layout(binding = 7) uniform anonblock { int aoeu; } ;
|
||||
layout(location = 1) in; // ERROR
|
||||
layout(binding = 1) in inblock { int aoeua; }; // ERROR
|
||||
layout(binding = 100000) uniform anonblock2 { int aooeu; } ;
|
||||
layout(binding = 4) uniform sampler2D sampb1;
|
||||
layout(binding = 5) uniform sampler2D sampb2[10];
|
||||
|
@ -1,4 +1,4 @@
|
||||
ERROR: 0:4: 'color' : can only use location layout qualifier on a vertex input or fragment output
|
||||
ERROR: 0:4: 'input location layout qualifier' : not supported in this stage: fragment
|
||||
ERROR: 1 compilation errors. No code generated.
|
||||
|
||||
ERROR: node is still EOpNull!
|
||||
|
@ -7,7 +7,7 @@ ERROR: 0:19: 'badf' : member of uniform block cannot have an auxiliary or interp
|
||||
ERROR: 0:20: 'badg' : member storage qualifier cannot contradict block storage qualifier
|
||||
ERROR: 0:28: 'T3' : nameless block contains a member that already has a name at global scope
|
||||
ERROR: 0:35: 'output block' : not supported with this profile: es
|
||||
ERROR: 0:39: 'badoutA' : can only use location layout qualifier on a vertex input or fragment output
|
||||
ERROR: 0:39: 'output location layout qualifier' : not supported in this stage: vertex
|
||||
ERROR: 0:47: 'shared' : not supported with this profile: es
|
||||
ERROR: 0:47: 'shared' : not supported in this stage: vertex
|
||||
ERROR: 12 compilation errors. No code generated.
|
||||
@ -33,11 +33,11 @@ ERROR: node is still EOpNull!
|
||||
0:43 Constant:
|
||||
0:43 1 (const int)
|
||||
0:43 M4: direct index for structure (layout(row_major shared ) highp 4X4 matrix of float)
|
||||
0:43 '__anon__1' (layout(shared ) uniform block)
|
||||
0:43 '__anon__1' (layout(column_major shared ) uniform block)
|
||||
0:43 Constant:
|
||||
0:43 1 (const uint)
|
||||
0:43 M3: direct index for structure (layout(column_major shared ) highp 4X4 matrix of float)
|
||||
0:43 '__anon__1' (layout(shared ) uniform block)
|
||||
0:43 '__anon__1' (layout(column_major shared ) uniform block)
|
||||
0:43 Constant:
|
||||
0:43 0 (const uint)
|
||||
0:43 t2m: direct index for structure (layout(row_major shared ) highp 4X4 matrix of float)
|
||||
|
@ -20,7 +20,11 @@ ERROR: 0:44: '=' : cannot convert from 'float' to 'int'
|
||||
ERROR: 0:54: 'y' : vector field selection out of range
|
||||
ERROR: 0:62: 'xxxxx' : illegal vector field selection
|
||||
ERROR: 0:63: 'xxy' : vector field selection out of range
|
||||
ERROR: 20 compilation errors. No code generated.
|
||||
ERROR: 0:66: 'binding' : cannot declare a default, include a type or full declaration
|
||||
ERROR: 0:69: 'location' : cannot declare a default, use a full declaration
|
||||
ERROR: 0:70: 'binding' : requires uniform or buffer storage qualifier
|
||||
ERROR: 0:71: 'binding' : binding is too large
|
||||
ERROR: 24 compilation errors. No code generated.
|
||||
|
||||
ERROR: node is still EOpNull!
|
||||
0:20 Function Definition: foo( (const int)
|
||||
@ -112,6 +116,12 @@ ERROR: node is still EOpNull!
|
||||
0:? 4.200000
|
||||
0:? 'dx' (const float)
|
||||
0:? 4.200000
|
||||
0:? 'boundInst' (layout(binding=3 shared ) uniform block)
|
||||
0:? '__anon__0' (layout(binding=7 shared ) uniform block)
|
||||
0:? '__anon__1' (layout(binding=1 ) in block)
|
||||
0:? '__anon__2' (layout(shared ) uniform block)
|
||||
0:? 'sampb1' (layout(binding=4 ) uniform sampler2D)
|
||||
0:? 'sampb2' (layout(binding=5 ) uniform 10-element array of sampler2D)
|
||||
0:? 'gl_VertexID' (gl_VertexId int)
|
||||
0:? 'gl_InstanceID' (gl_InstanceId int)
|
||||
|
||||
|
@ -15,23 +15,20 @@ ERROR: 0:46: 'stream' : there is no such layout identifier taking an assigned va
|
||||
ERROR: 0:47: 'stream' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:50: 'stream' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:55: 'stream' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:77: 'binding' : not supported
|
||||
ERROR: 0:80: 's17' : redefinition
|
||||
ERROR: 0:85: 'binding' : not supported
|
||||
ERROR: 0:85: 'offset' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:87: 'binding' : not supported
|
||||
ERROR: 0:89: 'binding' : not supported
|
||||
ERROR: 0:85: 'binding' : requires block, or sampler/image, or atomic-counter type
|
||||
ERROR: 0:87: 'binding' : requires block, or sampler/image, or atomic-counter type
|
||||
ERROR: 0:89: 'offset' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:91: 'binding' : not supported
|
||||
WARNING: 0:89: '' : cannot set qualifier defaults when using a type and no identifier
|
||||
ERROR: 0:91: 'bar' : redefinition
|
||||
ERROR: 0:92: 'offset' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:92: 'bar' : redefinition
|
||||
ERROR: 0:94: 'binding' : not supported
|
||||
ERROR: 0:94: 'offset' : there is no such layout identifier taking an assigned value
|
||||
ERROR: 0:94: 'a2' : redefinition
|
||||
ERROR: 0:95: 'binding' : not supported
|
||||
ERROR: 0:96: 'binding' : not supported
|
||||
ERROR: 0:97: 'binding' : not supported
|
||||
ERROR: 0:95: 'binding' : requires block, or sampler/image, or atomic-counter type
|
||||
ERROR: 0:96: 'binding' : requires block, or sampler/image, or atomic-counter type
|
||||
ERROR: 0:97: 'binding' : requires block, or sampler/image, or atomic-counter type
|
||||
ERROR: 0:106: '' : vertex input cannot be further qualified
|
||||
ERROR: 0:112: 'ColorIvn' : identifier not previously declared
|
||||
ERROR: 0:132: 'shared' : not supported in this stage: vertex
|
||||
@ -43,7 +40,7 @@ ERROR: 0:153: '' : function does not return a value: func3
|
||||
ERROR: 0:192: 'constructor' : constructing from a non-dereferenced array
|
||||
ERROR: 0:193: 'constructor' : constructing from a non-dereferenced array
|
||||
ERROR: 0:194: 'constructor' : constructing from a non-dereferenced array
|
||||
ERROR: 44 compilation errors. No code generated.
|
||||
ERROR: 40 compilation errors. No code generated.
|
||||
|
||||
ERROR: node is still EOpNull!
|
||||
0:134 Function Definition: funcA(I21; (4-component vector of float)
|
||||
@ -289,13 +286,13 @@ ERROR: node is still EOpNull!
|
||||
0:? '__anon__2' (out block)
|
||||
0:? 'var7' (smooth out 4-component vector of float)
|
||||
0:? '__anon__3' (layout(std140 ) uniform block)
|
||||
0:? '__anon__4' (layout(shared ) uniform block)
|
||||
0:? 's17' (uniform sampler2D)
|
||||
0:? 'a2' (uniform int)
|
||||
0:? 'bar' (uniform int)
|
||||
0:? 'b2' (uniform int)
|
||||
0:? 'c2' (uniform int)
|
||||
0:? 'd2' (uniform int)
|
||||
0:? '__anon__4' (layout(column_major shared ) uniform block)
|
||||
0:? 's17' (layout(binding=3 ) uniform sampler2D)
|
||||
0:? 'a2' (layout(binding=2 ) uniform int)
|
||||
0:? 'bar' (layout(binding=2 ) uniform int)
|
||||
0:? 'b2' (layout(binding=2 ) uniform int)
|
||||
0:? 'c2' (layout(binding=3 ) uniform int)
|
||||
0:? 'd2' (layout(binding=2 ) uniform int)
|
||||
0:? '__anon__5' (out block)
|
||||
0:? 'ColorInv' (smooth out 3-component vector of float)
|
||||
0:? 'Color4' (invariant centroid smooth out 3-component vector of float)
|
||||
@ -306,7 +303,7 @@ ERROR: node is still EOpNull!
|
||||
0:? 'c' (in 4-component vector of float)
|
||||
0:? 'd' (in 4-component vector of float)
|
||||
0:? 'v' (smooth out 4-component vector of float)
|
||||
0:? '__anon__6' (layout(shared ) uniform block)
|
||||
0:? '__anon__6' (layout(shared ) coherent uniform block)
|
||||
0:? '__anon__7' (layout(shared ) uniform block)
|
||||
0:? 'shv' (shared 4-component vector of float)
|
||||
0:? 'img1' (uniform image2D)
|
||||
|
@ -297,21 +297,29 @@ public:
|
||||
layoutMatrix = ElmNone;
|
||||
layoutPacking = ElpNone;
|
||||
layoutSlotLocation = layoutLocationEnd;
|
||||
layoutBinding = layoutBindingEnd;
|
||||
}
|
||||
bool hasLayout() const
|
||||
{
|
||||
return layoutMatrix != ElmNone ||
|
||||
layoutPacking != ElpNone ||
|
||||
layoutSlotLocation != layoutLocationEnd;
|
||||
hasLocation() ||
|
||||
hasBinding();
|
||||
}
|
||||
TLayoutMatrix layoutMatrix : 3;
|
||||
TLayoutPacking layoutPacking : 4;
|
||||
unsigned int layoutSlotLocation : 7; // ins/outs should have small numbers, buffer offsets could be large
|
||||
static const unsigned int layoutLocationEnd = 0x3F;
|
||||
unsigned int layoutBinding : 8;
|
||||
static const unsigned int layoutBindingEnd = 0xFF;
|
||||
bool hasLocation() const
|
||||
{
|
||||
return layoutSlotLocation != layoutLocationEnd;
|
||||
}
|
||||
bool hasBinding() const
|
||||
{
|
||||
return layoutBinding != layoutBindingEnd;
|
||||
}
|
||||
static const char* getLayoutPackingString(TLayoutPacking packing)
|
||||
{
|
||||
switch (packing) {
|
||||
@ -430,17 +438,20 @@ public:
|
||||
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
|
||||
}
|
||||
}
|
||||
TType(TTypeList* userDef, const TString& n, TStorageQualifier blockQualifier = EvqGlobal) :
|
||||
basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), arraySizes(0),
|
||||
structure(userDef), fieldName(0)
|
||||
TType(TTypeList* userDef, const TString& n) :
|
||||
basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0),
|
||||
arraySizes(0), structure(userDef), fieldName(0)
|
||||
{
|
||||
sampler.clear();
|
||||
qualifier.clear();
|
||||
// is it an interface block?
|
||||
if (blockQualifier != EvqGlobal) {
|
||||
qualifier.storage = blockQualifier;
|
||||
basicType = EbtBlock;
|
||||
}
|
||||
typeName = NewPoolTString(n.c_str());
|
||||
}
|
||||
// For interface blocks
|
||||
TType(TTypeList* userDef, const TString& n, const TQualifier& q) :
|
||||
basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0),
|
||||
qualifier(q), arraySizes(0), structure(userDef), fieldName(0)
|
||||
{
|
||||
sampler.clear();
|
||||
typeName = NewPoolTString(n.c_str());
|
||||
}
|
||||
virtual ~TType() {}
|
||||
@ -628,6 +639,8 @@ public:
|
||||
p += snprintf(p, end - p, "layout(");
|
||||
if (qualifier.hasLocation())
|
||||
p += snprintf(p, end - p, "location=%d ", qualifier.layoutSlotLocation);
|
||||
if (qualifier.hasBinding())
|
||||
p += snprintf(p, end - p, "binding=%d ", qualifier.layoutBinding);
|
||||
if (qualifier.layoutMatrix != ElmNone)
|
||||
p += snprintf(p, end - p, "%s ", TQualifier::getLayoutMatrixString(qualifier.layoutMatrix));
|
||||
if (qualifier.layoutPacking != ElpNone)
|
||||
|
@ -2086,7 +2086,8 @@ void TParseContext::finalize()
|
||||
// Layout qualifier stuff.
|
||||
//
|
||||
|
||||
// Put the id's layout qualification into the public type.
|
||||
// Put the id's layout qualification into the public type. This is before we know any
|
||||
// type information for error checking.
|
||||
void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id)
|
||||
{
|
||||
std::transform(id.begin(), id.end(), id.begin(), ::tolower);
|
||||
@ -2100,28 +2101,38 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
|
||||
publicType.qualifier.layoutPacking = ElpShared;
|
||||
else if (id == TQualifier::getLayoutPackingString(ElpStd140))
|
||||
publicType.qualifier.layoutPacking = ElpStd140;
|
||||
else if (id == TQualifier::getLayoutPackingString(ElpStd430))
|
||||
else if (id == TQualifier::getLayoutPackingString(ElpStd430)) {
|
||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "std430");
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, 0, "std430");
|
||||
publicType.qualifier.layoutPacking = ElpStd430;
|
||||
else if (id == "location")
|
||||
} else if (id == "location")
|
||||
error(loc, "requires an integer assignment (e.g., location = 4)", "location", "");
|
||||
else if (id == "binding")
|
||||
else if (id == "binding") {
|
||||
error(loc, "requires an integer assignment (e.g., binding = 4)", "binding", "");
|
||||
else
|
||||
} else
|
||||
error(loc, "unrecognized layout identifier", id.c_str(), "");
|
||||
}
|
||||
|
||||
// Put the id's layout qualifier value into the public type.
|
||||
// Put the id's layout qualifier value into the public type. This is before we know any
|
||||
// type information for error checking.
|
||||
void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id, int value)
|
||||
{
|
||||
std::transform(id.begin(), id.end(), id.begin(), ::tolower);
|
||||
if (id == "location") {
|
||||
requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "location");
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 330, 0, "location");
|
||||
if ((unsigned int)value >= TQualifier::layoutLocationEnd)
|
||||
error(loc, "value is too large", id.c_str(), "");
|
||||
error(loc, "location is too large", id.c_str(), "");
|
||||
else
|
||||
publicType.qualifier.layoutSlotLocation = value;
|
||||
} else if (id == "binding")
|
||||
error(loc, "not supported", "binding", "");
|
||||
else
|
||||
} else if (id == "binding") {
|
||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "binding");
|
||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 420, GL_ARB_shading_language_420pack, "binding");
|
||||
if ((unsigned int)value >= TQualifier::layoutBindingEnd)
|
||||
error(loc, "binding is too large", id.c_str(), "");
|
||||
else
|
||||
publicType.qualifier.layoutBinding = value;
|
||||
} else
|
||||
error(loc, "there is no such layout identifier taking an assigned value", id.c_str(), "");
|
||||
|
||||
// TODO: semantics: error check: make sure locations are non-overlapping across the whole stage
|
||||
@ -2139,6 +2150,37 @@ void TParseContext::mergeLayoutQualifiers(TSourceLoc loc, TQualifier& dst, const
|
||||
|
||||
if (src.hasLocation())
|
||||
dst.layoutSlotLocation = src.layoutSlotLocation;
|
||||
|
||||
if (src.hasBinding())
|
||||
dst.layoutBinding = src.layoutBinding;
|
||||
}
|
||||
|
||||
// Do error layout error checking given a full variable/block declaration.
|
||||
void TParseContext::layoutCheck(TSourceLoc loc, const TSymbol& symbol)
|
||||
{
|
||||
const TType& type = symbol.getType();
|
||||
const TQualifier& qualifier = type.getQualifier();
|
||||
|
||||
if (qualifier.hasLocation()) {
|
||||
// TODO: location = functionality, when is it allowed?
|
||||
}
|
||||
if (qualifier.hasBinding()) {
|
||||
// Binding checking, from the spec:
|
||||
//
|
||||
// "If the binding point for any uniform or shader storage block instance is less than zero, or greater than or
|
||||
// equal to the implementation-dependent maximum number of uniform buffer bindings, a compile-time
|
||||
// error will occur. When the binding identifier is used with a uniform or shader storage block instanced as
|
||||
// an array of size N, all elements of the array from binding through binding + N – 1 must be within this
|
||||
// range."
|
||||
//
|
||||
// TODO: binding error checking against limits, arrays
|
||||
//
|
||||
if (qualifier.storage != EvqUniform && qualifier.storage != EvqBuffer)
|
||||
error(loc, "requires uniform or buffer storage qualifier", "binding", "");
|
||||
if (type.getBasicType() != EbtSampler && type.getBasicType() != EbtBlock)
|
||||
error(loc, "requires block, or sampler/image, or atomic-counter type", "binding", "");
|
||||
// TODO: atomic counter functionality: include in test above
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
@ -2229,6 +2271,10 @@ TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier,
|
||||
initNode = executeInitializer(loc, identifier, initializer, variable);
|
||||
}
|
||||
|
||||
// look for errors in layout qualifier use
|
||||
if (symbol)
|
||||
layoutCheck(loc, *symbol);
|
||||
|
||||
// see if it's a linker-level object to track
|
||||
if (symbol && newDeclaration && symbolTable.atGlobalLevel())
|
||||
intermediate.addSymbolLinkageNode(linkage, *symbol);
|
||||
@ -2648,7 +2694,7 @@ void TParseContext::addBlock(TSourceLoc loc, TTypeList& typeList, const TString*
|
||||
|
||||
arrayDimCheck(loc, arraySizes, 0);
|
||||
|
||||
// fix and check for qualifiers and types that don't belong within a block
|
||||
// fix and check for member qualifiers and types that don't belong within a block
|
||||
for (unsigned int member = 0; member < typeList.size(); ++member) {
|
||||
TQualifier& memberQualifier = typeList[member].type->getQualifier();
|
||||
TSourceLoc memberLoc = typeList[member].loc;
|
||||
@ -2683,7 +2729,7 @@ void TParseContext::addBlock(TSourceLoc loc, TTypeList& typeList, const TString*
|
||||
|
||||
// Build and add the interface block as a new type named blockName
|
||||
|
||||
TType blockType(&typeList, *blockName, currentBlockDefaults.storage);
|
||||
TType blockType(&typeList, *blockName, currentBlockDefaults);
|
||||
if (arraySizes)
|
||||
blockType.setArraySizes(arraySizes);
|
||||
blockType.getQualifier().layoutPacking = defaultQualification.layoutPacking;
|
||||
@ -2717,18 +2763,21 @@ void TParseContext::addBlock(TSourceLoc loc, TTypeList& typeList, const TString*
|
||||
if (! instanceName)
|
||||
instanceName = NewPoolTString("");
|
||||
|
||||
TVariable* variable = new TVariable(instanceName, blockType);
|
||||
if (! symbolTable.insert(*variable)) {
|
||||
TVariable& variable = *new TVariable(instanceName, blockType);
|
||||
if (! symbolTable.insert(variable)) {
|
||||
if (*instanceName == "")
|
||||
error(loc, "nameless block contains a member that already has a name at global scope", blockName->c_str(), "");
|
||||
else
|
||||
error(loc, "block instance name redefinition", variable->getName().c_str(), "");
|
||||
error(loc, "block instance name redefinition", variable.getName().c_str(), "");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for general layout qualifier errors
|
||||
layoutCheck(loc, variable);
|
||||
|
||||
// Save it in the AST for linker use.
|
||||
intermediate.addSymbolLinkageNode(linkage, *variable);
|
||||
intermediate.addSymbolLinkageNode(linkage, variable);
|
||||
}
|
||||
|
||||
// For an identifier that is already declared, add more qualification to it.
|
||||
@ -2769,6 +2818,10 @@ void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier,
|
||||
addQualifierToExisting(loc, qualifier, *identifiers[i]);
|
||||
}
|
||||
|
||||
//
|
||||
// Update qualifier defaults for all forms of declarations, which
|
||||
// must error check for their form before calling here.
|
||||
//
|
||||
void TParseContext::updateQualifierDefaults(TQualifier qualifier)
|
||||
{
|
||||
switch (qualifier.storage) {
|
||||
@ -2798,27 +2851,41 @@ void TParseContext::updateQualifierDefaults(TQualifier qualifier)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Update defaults for qualifiers. This is called directly for the case
|
||||
// of a declaration with just a qualifier.
|
||||
//
|
||||
void TParseContext::updateQualifierDefaults(TSourceLoc loc, TQualifier qualifier)
|
||||
{
|
||||
if (qualifier.isAuxiliary() ||
|
||||
qualifier.isMemory() ||
|
||||
qualifier.isInterpolation() ||
|
||||
qualifier.precision != EpqNone)
|
||||
error(loc, "cannot use auxiliary, memory, interpolation, or precision qualifier in a standalone qualifier", "", "");
|
||||
error(loc, "cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type)", "", "");
|
||||
|
||||
switch (qualifier.storage) {
|
||||
case EvqUniform:
|
||||
case EvqBuffer:
|
||||
case EvqVaryingIn:
|
||||
case EvqVaryingOut:
|
||||
break;
|
||||
default:
|
||||
error(loc, "standalone qualifier requires 'uniform', 'in', or 'out' storage qualification", "", "");
|
||||
error(loc, "default qualifier requires 'uniform', 'buffer', 'in', or 'out' storage qualification", "", "");
|
||||
return;
|
||||
}
|
||||
|
||||
if (qualifier.hasBinding())
|
||||
error(loc, "cannot declare a default, include a type or full declaration", "binding", "");
|
||||
if (qualifier.hasLocation())
|
||||
error(loc, "cannot declare a default, use a full declaration", "location", "");
|
||||
|
||||
updateQualifierDefaults(qualifier);
|
||||
}
|
||||
|
||||
//
|
||||
// Update defaults for qualifiers when declared with a type, and optionally an id.
|
||||
// (But, not the case of just a qualifier; this is called when a type is present.)
|
||||
//
|
||||
void TParseContext::updateTypedDefaults(TSourceLoc loc, TQualifier qualifier, const TString* id)
|
||||
{
|
||||
bool cantHaveId = false;
|
||||
@ -2836,11 +2903,15 @@ void TParseContext::updateTypedDefaults(TSourceLoc loc, TQualifier qualifier, co
|
||||
if (qualifier.layoutPacking != ElpNone)
|
||||
error(loc, "cannot specify packing on a variable declaration", id->c_str(), "");
|
||||
} else if (qualifier.storage == EvqVaryingIn) {
|
||||
if (qualifier.hasLayout() && language != EShLangVertex)
|
||||
error(loc, "can only use location layout qualifier on a vertex input or fragment output", id->c_str(), "");
|
||||
if (qualifier.hasLocation()) {
|
||||
if (profile == EEsProfile)
|
||||
requireStage(loc, EShLangVertex, "input location layout qualifier");
|
||||
}
|
||||
} else if (qualifier.storage == EvqVaryingOut) {
|
||||
if (qualifier.hasLayout() && language != EShLangFragment)
|
||||
error(loc, "can only use location layout qualifier on a vertex input or fragment output", id->c_str(), "");
|
||||
if (qualifier.hasLocation()) {
|
||||
if (profile == EEsProfile)
|
||||
requireStage(loc, EShLangFragment, "output location layout qualifier");
|
||||
}
|
||||
} else {
|
||||
if (qualifier.layoutMatrix != ElmNone ||
|
||||
qualifier.layoutPacking != ElpNone)
|
||||
|
@ -126,6 +126,7 @@ public:
|
||||
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&);
|
||||
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&, int);
|
||||
void mergeLayoutQualifiers(TSourceLoc, TQualifier& dest, const TQualifier& src);
|
||||
void layoutCheck(TSourceLoc, const TSymbol&);
|
||||
|
||||
const TFunction* findFunction(TSourceLoc, TFunction* pfnCall, bool *builtIn = 0);
|
||||
TIntermNode* declareVariable(TSourceLoc, TString& identifier, TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user