GLSL: Fix #853: Only outer dimension of array can be specialization constant.
This commit is contained in:
parent
d314ecfbe3
commit
3fcb42cfa6
@ -22,7 +22,11 @@ ERROR: 0:32: 'initializer' : can't use with types containing arrays sized with a
|
|||||||
ERROR: 0:34: '=' : can't use with types containing arrays sized with a specialization constant
|
ERROR: 0:34: '=' : can't use with types containing arrays sized with a specialization constant
|
||||||
ERROR: 0:35: '==' : can't use with types containing arrays sized with a specialization constant
|
ERROR: 0:35: '==' : can't use with types containing arrays sized with a specialization constant
|
||||||
ERROR: 0:39: 'set' : cannot be used with push_constant
|
ERROR: 0:39: 'set' : cannot be used with push_constant
|
||||||
ERROR: 23 compilation errors. No code generated.
|
ERROR: 0:49: '[]' : only outermost dimension of an array of arrays can be a specialization constant
|
||||||
|
ERROR: 0:50: '[]' : only outermost dimension of an array of arrays can be a specialization constant
|
||||||
|
ERROR: 0:51: '[]' : only outermost dimension of an array of arrays can be a specialization constant
|
||||||
|
ERROR: 0:54: '[]' : only outermost dimension of an array of arrays can be a specialization constant
|
||||||
|
ERROR: 27 compilation errors. No code generated.
|
||||||
|
|
||||||
|
|
||||||
SPIR-V is not generated for failed compile or link
|
SPIR-V is not generated for failed compile or link
|
||||||
|
@ -45,3 +45,16 @@ layout(set = 1, push_constant) uniform badpc { int a; } badpcI; // ERROR, no de
|
|||||||
#if VULKAN != 100
|
#if VULKAN != 100
|
||||||
#error VULKAN should be 100
|
#error VULKAN should be 100
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
float AofA0[2][arraySize]; // ERROR, only outer dimension
|
||||||
|
float AofA1[arraySize][arraySize]; // ERROR, only outer dimension
|
||||||
|
float AofA2[arraySize][2 + arraySize]; // ERROR, only outer dimension
|
||||||
|
float AofA3[arraySize][2];
|
||||||
|
|
||||||
|
out ban1 { // ERROR, only outer dimension
|
||||||
|
float f;
|
||||||
|
} bai1[2][arraySize];
|
||||||
|
|
||||||
|
out ban2 {
|
||||||
|
float f;
|
||||||
|
} bai2[arraySize][2];
|
||||||
|
@ -1460,7 +1460,7 @@ public:
|
|||||||
|
|
||||||
virtual bool containsSpecializationSize() const
|
virtual bool containsSpecializationSize() const
|
||||||
{
|
{
|
||||||
return contains([](const TType* t) { return t->isArray() && t->arraySizes->containsNode(); } );
|
return contains([](const TType* t) { return t->isArray() && t->arraySizes->isOuterSpecialization(); } );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Array editing methods. Array descriptors can be shared across
|
// Array editing methods. Array descriptors can be shared across
|
||||||
|
@ -264,6 +264,20 @@ struct TArraySizes {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool isInnerSpecialization() const
|
||||||
|
{
|
||||||
|
for (int d = 1; d < sizes.size(); ++d) {
|
||||||
|
if (sizes.getDimNode(d) != nullptr)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool isOuterSpecialization()
|
||||||
|
{
|
||||||
|
return sizes.getDimNode(0) != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool isImplicit() const { return getOuterSize() == UnsizedArraySize || isInnerImplicit(); }
|
bool isImplicit() const { return getOuterSize() == UnsizedArraySize || isInnerImplicit(); }
|
||||||
void addOuterSizes(const TArraySizes& s) { sizes.push_front(s.sizes); }
|
void addOuterSizes(const TArraySizes& s) { sizes.push_front(s.sizes); }
|
||||||
void dereference() { sizes.pop_front(); }
|
void dereference() { sizes.pop_front(); }
|
||||||
@ -288,18 +302,6 @@ struct TArraySizes {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if any of the dimensions of the array is sized with a node
|
|
||||||
// instead of a front-end compile-time constant.
|
|
||||||
bool containsNode()
|
|
||||||
{
|
|
||||||
for (int d = 0; d < sizes.size(); ++d) {
|
|
||||||
if (sizes.getDimNode(d) != nullptr)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const TArraySizes& rhs) { return sizes == rhs.sizes; }
|
bool operator==(const TArraySizes& rhs) { return sizes == rhs.sizes; }
|
||||||
bool operator!=(const TArraySizes& rhs) { return sizes != rhs.sizes; }
|
bool operator!=(const TArraySizes& rhs) { return sizes != rhs.sizes; }
|
||||||
|
|
||||||
|
@ -2958,7 +2958,7 @@ void TParseContext::structArrayCheck(const TSourceLoc& /*loc*/, const TType& typ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TParseContext::arrayUnsizedCheck(const TSourceLoc& loc, const TQualifier& qualifier, const TArraySizes* arraySizes, bool initializer, bool lastMember)
|
void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qualifier, const TArraySizes* arraySizes, bool initializer, bool lastMember)
|
||||||
{
|
{
|
||||||
assert(arraySizes);
|
assert(arraySizes);
|
||||||
|
|
||||||
@ -2974,6 +2974,9 @@ void TParseContext::arrayUnsizedCheck(const TSourceLoc& loc, const TQualifier& q
|
|||||||
if (arraySizes->isInnerImplicit())
|
if (arraySizes->isInnerImplicit())
|
||||||
error(loc, "only outermost dimension of an array of arrays can be implicitly sized", "[]", "");
|
error(loc, "only outermost dimension of an array of arrays can be implicitly sized", "[]", "");
|
||||||
|
|
||||||
|
if (arraySizes->isInnerSpecialization())
|
||||||
|
error(loc, "only outermost dimension of an array of arrays can be a specialization constant", "[]", "");
|
||||||
|
|
||||||
// desktop always allows outer-dimension-unsized variable arrays,
|
// desktop always allows outer-dimension-unsized variable arrays,
|
||||||
if (profile != EEsProfile)
|
if (profile != EEsProfile)
|
||||||
return;
|
return;
|
||||||
@ -5081,7 +5084,7 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
|
|||||||
arrayDimMerge(type, arraySizes);
|
arrayDimMerge(type, arraySizes);
|
||||||
|
|
||||||
// Check that implicit sizing is only where allowed.
|
// Check that implicit sizing is only where allowed.
|
||||||
arrayUnsizedCheck(loc, type.getQualifier(), &type.getArraySizes(), initializer != nullptr, false);
|
arraySizesCheck(loc, type.getQualifier(), &type.getArraySizes(), initializer != nullptr, false);
|
||||||
|
|
||||||
if (! arrayQualifierError(loc, type.getQualifier()) && ! arrayError(loc, type))
|
if (! arrayQualifierError(loc, type.getQualifier()) && ! arrayError(loc, type))
|
||||||
declareArray(loc, identifier, type, symbol);
|
declareArray(loc, identifier, type, symbol);
|
||||||
@ -5633,7 +5636,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||||||
blockStageIoCheck(loc, currentBlockQualifier);
|
blockStageIoCheck(loc, currentBlockQualifier);
|
||||||
blockQualifierCheck(loc, currentBlockQualifier, instanceName != nullptr);
|
blockQualifierCheck(loc, currentBlockQualifier, instanceName != nullptr);
|
||||||
if (arraySizes) {
|
if (arraySizes) {
|
||||||
arrayUnsizedCheck(loc, currentBlockQualifier, arraySizes, false, false);
|
arraySizesCheck(loc, currentBlockQualifier, arraySizes, false, false);
|
||||||
arrayDimCheck(loc, arraySizes, 0);
|
arrayDimCheck(loc, arraySizes, 0);
|
||||||
if (arraySizes->getNumDims() > 1)
|
if (arraySizes->getNumDims() > 1)
|
||||||
requireProfile(loc, ~EEsProfile, "array-of-array of block");
|
requireProfile(loc, ~EEsProfile, "array-of-array of block");
|
||||||
@ -5651,7 +5654,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||||||
if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()))
|
if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()))
|
||||||
error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");
|
error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");
|
||||||
if (memberType.isArray())
|
if (memberType.isArray())
|
||||||
arrayUnsizedCheck(memberLoc, currentBlockQualifier, &memberType.getArraySizes(), false, member == typeList.size() - 1);
|
arraySizesCheck(memberLoc, currentBlockQualifier, &memberType.getArraySizes(), false, member == typeList.size() - 1);
|
||||||
if (memberQualifier.hasOffset()) {
|
if (memberQualifier.hasOffset()) {
|
||||||
if (spvVersion.spv == 0) {
|
if (spvVersion.spv == 0) {
|
||||||
requireProfile(memberLoc, ~EEsProfile, "offset on block member");
|
requireProfile(memberLoc, ~EEsProfile, "offset on block member");
|
||||||
|
@ -317,7 +317,7 @@ public:
|
|||||||
bool arrayError(const TSourceLoc&, const TType&);
|
bool arrayError(const TSourceLoc&, const TType&);
|
||||||
void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&);
|
void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&);
|
||||||
void structArrayCheck(const TSourceLoc&, const TType& structure);
|
void structArrayCheck(const TSourceLoc&, const TType& structure);
|
||||||
void arrayUnsizedCheck(const TSourceLoc&, const TQualifier&, const TArraySizes*, bool initializer, bool lastMember);
|
void arraySizesCheck(const TSourceLoc&, const TQualifier&, const TArraySizes*, bool initializer, bool lastMember);
|
||||||
void arrayOfArrayVersionCheck(const TSourceLoc&);
|
void arrayOfArrayVersionCheck(const TSourceLoc&);
|
||||||
void arrayDimCheck(const TSourceLoc&, const TArraySizes* sizes1, const TArraySizes* sizes2);
|
void arrayDimCheck(const TSourceLoc&, const TArraySizes* sizes1, const TArraySizes* sizes2);
|
||||||
void arrayDimCheck(const TSourceLoc&, const TType*, const TArraySizes*);
|
void arrayDimCheck(const TSourceLoc&, const TType*, const TArraySizes*);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user