Commit 7881cfdf by Olli Etuaho Committed by Commit Bot

Add parsing of arrays of arrays

This changes the grammar so that multiple array sizes can be chained together, and adds arrays of arrays support to TPublicType. In TPublicType the array sizes are stored using a pointer to a vector, a plain vector won't work due to bison restrictions. A larger subset of program interface query tests now pass. Some are still failing due to unrelated bugs. BUG=angleproject:2125 TEST=angle_unittests, angle_end2end_tests, dEQP-GLES31.functional.shaders.arrays_of_arrays.* dEQP-GLES31.functional.uniform_location.nested_array.* dEQP-GLES31.functional.program_interface_query.* dEQP-GLES31.functional.ubo.*level*array.* Change-Id: Iee16477a3752b953f5068c0473a2ed62fead8155 Reviewed-on: https://chromium-review.googlesource.com/633944 Commit-Queue: Olli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 5d5253a3
...@@ -737,7 +737,7 @@ bool TParseContext::checkConstructorArguments(const TSourceLoc &line, ...@@ -737,7 +737,7 @@ bool TParseContext::checkConstructorArguments(const TSourceLoc &line,
for (TIntermNode *const &argNode : *arguments) for (TIntermNode *const &argNode : *arguments)
{ {
const TType &argType = argNode->getAsTyped()->getType(); const TType &argType = argNode->getAsTyped()->getType();
if (argType.isArray()) if (mShaderVersion < 310 && argType.isArray())
{ {
error(line, "constructing from a non-dereferenced array", "constructor"); error(line, "constructing from a non-dereferenced array", "constructor");
return false; return false;
...@@ -1028,7 +1028,7 @@ bool TParseContext::checkIsValidQualifierForArray(const TSourceLoc &line, ...@@ -1028,7 +1028,7 @@ bool TParseContext::checkIsValidQualifierForArray(const TSourceLoc &line,
bool TParseContext::checkArrayElementIsNotArray(const TSourceLoc &line, bool TParseContext::checkArrayElementIsNotArray(const TSourceLoc &line,
const TPublicType &elementType) const TPublicType &elementType)
{ {
if (elementType.array) if (mShaderVersion < 310 && elementType.isArray())
{ {
error(line, "cannot declare arrays of arrays", error(line, "cannot declare arrays of arrays",
TType(elementType).getCompleteString().c_str()); TType(elementType).getCompleteString().c_str());
...@@ -2138,7 +2138,7 @@ void TParseContext::addFullySpecifiedType(TPublicType *typeSpecifier) ...@@ -2138,7 +2138,7 @@ void TParseContext::addFullySpecifiedType(TPublicType *typeSpecifier)
checkPrecisionSpecified(typeSpecifier->getLine(), typeSpecifier->precision, checkPrecisionSpecified(typeSpecifier->getLine(), typeSpecifier->precision,
typeSpecifier->getBasicType()); typeSpecifier->getBasicType());
if (mShaderVersion < 300 && typeSpecifier->array) if (mShaderVersion < 300 && typeSpecifier->isArray())
{ {
error(typeSpecifier->getLine(), "not supported", "first-class array"); error(typeSpecifier->getLine(), "not supported", "first-class array");
typeSpecifier->clearArrayness(); typeSpecifier->clearArrayness();
...@@ -2172,7 +2172,7 @@ TPublicType TParseContext::addFullySpecifiedType(const TTypeQualifierBuilder &ty ...@@ -2172,7 +2172,7 @@ TPublicType TParseContext::addFullySpecifiedType(const TTypeQualifierBuilder &ty
if (mShaderVersion < 300) if (mShaderVersion < 300)
{ {
if (typeSpecifier.array) if (typeSpecifier.isArray())
{ {
error(typeSpecifier.getLine(), "not supported", "first-class array"); error(typeSpecifier.getLine(), "not supported", "first-class array");
returnType.clearArrayness(); returnType.clearArrayness();
...@@ -2229,7 +2229,7 @@ void TParseContext::checkInputOutputTypeIsValidES3(const TQualifier qualifier, ...@@ -2229,7 +2229,7 @@ void TParseContext::checkInputOutputTypeIsValidES3(const TQualifier qualifier,
{ {
case EvqVertexIn: case EvqVertexIn:
// ESSL 3.00 section 4.3.4 // ESSL 3.00 section 4.3.4
if (type.array) if (type.isArray())
{ {
error(qualifierLocation, "cannot be array", getQualifierString(qualifier)); error(qualifierLocation, "cannot be array", getQualifierString(qualifier));
} }
...@@ -2263,7 +2263,7 @@ void TParseContext::checkInputOutputTypeIsValidES3(const TQualifier qualifier, ...@@ -2263,7 +2263,7 @@ void TParseContext::checkInputOutputTypeIsValidES3(const TQualifier qualifier,
// ESSL 3.00 sections 4.3.4 and 4.3.6. // ESSL 3.00 sections 4.3.4 and 4.3.6.
// These restrictions are only implied by the ESSL 3.00 spec, but // These restrictions are only implied by the ESSL 3.00 spec, but
// the ESSL 3.10 spec lists these restrictions explicitly. // the ESSL 3.10 spec lists these restrictions explicitly.
if (type.array) if (type.isArray())
{ {
error(qualifierLocation, "cannot be an array of structures", error(qualifierLocation, "cannot be an array of structures",
getQualifierString(qualifier)); getQualifierString(qualifier));
...@@ -2483,11 +2483,12 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration( ...@@ -2483,11 +2483,12 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration(
return declaration; return declaration;
} }
TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(TPublicType &elementType, TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(
const TSourceLoc &identifierLocation, TPublicType &elementType,
const TString &identifier, const TSourceLoc &identifierLocation,
const TSourceLoc &indexLocation, const TString &identifier,
unsigned int arraySize) const TSourceLoc &indexLocation,
const TVector<unsigned int> &arraySizes)
{ {
mDeferredNonEmptyDeclarationErrorCheck = false; mDeferredNonEmptyDeclarationErrorCheck = false;
...@@ -2499,7 +2500,7 @@ TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(TPublicType &elem ...@@ -2499,7 +2500,7 @@ TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(TPublicType &elem
checkIsValidTypeAndQualifierForArray(indexLocation, elementType); checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
TType arrayType(elementType); TType arrayType(elementType);
arrayType.makeArray(arraySize); arrayType.makeArrays(arraySizes);
checkGeometryShaderInputAndSetArraySize(indexLocation, identifier.c_str(), &arrayType); checkGeometryShaderInputAndSetArraySize(indexLocation, identifier.c_str(), &arrayType);
...@@ -2556,7 +2557,7 @@ TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration( ...@@ -2556,7 +2557,7 @@ TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration(
const TSourceLoc &identifierLocation, const TSourceLoc &identifierLocation,
const TString &identifier, const TString &identifier,
const TSourceLoc &indexLocation, const TSourceLoc &indexLocation,
unsigned int arraySize, const TVector<unsigned int> &arraySizes,
const TSourceLoc &initLocation, const TSourceLoc &initLocation,
TIntermTyped *initializer) TIntermTyped *initializer)
{ {
...@@ -2570,7 +2571,7 @@ TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration( ...@@ -2570,7 +2571,7 @@ TIntermDeclaration *TParseContext::parseSingleArrayInitDeclaration(
checkIsValidTypeAndQualifierForArray(indexLocation, elementType); checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
TType arrayType(elementType); TType arrayType(elementType);
arrayType.makeArray(arraySize); arrayType.makeArrays(arraySizes);
TIntermDeclaration *declaration = new TIntermDeclaration(); TIntermDeclaration *declaration = new TIntermDeclaration();
declaration->setLine(identifierLocation); declaration->setLine(identifierLocation);
...@@ -2682,7 +2683,7 @@ void TParseContext::parseArrayDeclarator(TPublicType &elementType, ...@@ -2682,7 +2683,7 @@ void TParseContext::parseArrayDeclarator(TPublicType &elementType,
const TSourceLoc &identifierLocation, const TSourceLoc &identifierLocation,
const TString &identifier, const TString &identifier,
const TSourceLoc &arrayLocation, const TSourceLoc &arrayLocation,
unsigned int arraySize, const TVector<unsigned int> &arraySizes,
TIntermDeclaration *declarationOut) TIntermDeclaration *declarationOut)
{ {
// If the declaration starting this declarator list was empty (example: int,), some checks were // If the declaration starting this declarator list was empty (example: int,), some checks were
...@@ -2698,7 +2699,7 @@ void TParseContext::parseArrayDeclarator(TPublicType &elementType, ...@@ -2698,7 +2699,7 @@ void TParseContext::parseArrayDeclarator(TPublicType &elementType,
if (checkIsValidTypeAndQualifierForArray(arrayLocation, elementType)) if (checkIsValidTypeAndQualifierForArray(arrayLocation, elementType))
{ {
TType arrayType(elementType); TType arrayType(elementType);
arrayType.makeArray(arraySize); arrayType.makeArrays(arraySizes);
checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier.c_str(), &arrayType); checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier.c_str(), &arrayType);
...@@ -2754,7 +2755,7 @@ void TParseContext::parseArrayInitDeclarator(const TPublicType &elementType, ...@@ -2754,7 +2755,7 @@ void TParseContext::parseArrayInitDeclarator(const TPublicType &elementType,
const TSourceLoc &identifierLocation, const TSourceLoc &identifierLocation,
const TString &identifier, const TString &identifier,
const TSourceLoc &indexLocation, const TSourceLoc &indexLocation,
unsigned int arraySize, const TVector<unsigned int> &arraySizes,
const TSourceLoc &initLocation, const TSourceLoc &initLocation,
TIntermTyped *initializer, TIntermTyped *initializer,
TIntermDeclaration *declarationOut) TIntermDeclaration *declarationOut)
...@@ -2772,7 +2773,7 @@ void TParseContext::parseArrayInitDeclarator(const TPublicType &elementType, ...@@ -2772,7 +2773,7 @@ void TParseContext::parseArrayInitDeclarator(const TPublicType &elementType,
checkIsValidTypeAndQualifierForArray(indexLocation, elementType); checkIsValidTypeAndQualifierForArray(indexLocation, elementType);
TType arrayType(elementType); TType arrayType(elementType);
arrayType.makeArray(arraySize); arrayType.makeArrays(arraySizes);
// initNode will correspond to the whole of "b[n] = initializer". // initNode will correspond to the whole of "b[n] = initializer".
TIntermBinary *initNode = nullptr; TIntermBinary *initNode = nullptr;
...@@ -3440,7 +3441,7 @@ TFunction *TParseContext::parseFunctionHeader(const TPublicType &type, ...@@ -3440,7 +3441,7 @@ TFunction *TParseContext::parseFunctionHeader(const TPublicType &type,
{ {
// Array return values are forbidden, but there's also no valid syntax for declaring array // Array return values are forbidden, but there's also no valid syntax for declaring array
// return values in ESSL 1.00. // return values in ESSL 1.00.
ASSERT(type.arraySize == 0 || mDiagnostics->numErrors() > 0); ASSERT(!type.isArray() || mDiagnostics->numErrors() > 0);
if (type.isStructureContainingArrays()) if (type.isStructureContainingArrays())
{ {
...@@ -3462,7 +3463,7 @@ TFunction *TParseContext::addNonConstructorFunc(const TString *name, const TSour ...@@ -3462,7 +3463,7 @@ TFunction *TParseContext::addNonConstructorFunc(const TString *name, const TSour
TFunction *TParseContext::addConstructorFunc(const TPublicType &publicType) TFunction *TParseContext::addConstructorFunc(const TPublicType &publicType)
{ {
if (mShaderVersion < 300 && publicType.array) if (mShaderVersion < 300 && publicType.isArray())
{ {
error(publicType.getLine(), "array constructor supported in GLSL ES 3.00 and above only", error(publicType.getLine(), "array constructor supported in GLSL ES 3.00 and above only",
"[]"); "[]");
...@@ -3522,13 +3523,13 @@ TParameter TParseContext::parseParameterDeclarator(const TPublicType &publicType ...@@ -3522,13 +3523,13 @@ TParameter TParseContext::parseParameterDeclarator(const TPublicType &publicType
TParameter TParseContext::parseParameterArrayDeclarator(const TString *name, TParameter TParseContext::parseParameterArrayDeclarator(const TString *name,
const TSourceLoc &nameLoc, const TSourceLoc &nameLoc,
unsigned int arraySize, const TVector<unsigned int> &arraySizes,
const TSourceLoc &arrayLoc, const TSourceLoc &arrayLoc,
TPublicType *elementType) TPublicType *elementType)
{ {
checkArrayElementIsNotArray(arrayLoc, *elementType); checkArrayElementIsNotArray(arrayLoc, *elementType);
TType *arrayType = new TType(*elementType); TType *arrayType = new TType(*elementType);
arrayType->makeArray(arraySize); arrayType->makeArrays(arraySizes);
return parseParameterDeclarator(arrayType, name, nameLoc); return parseParameterDeclarator(arrayType, name, nameLoc);
} }
...@@ -4665,13 +4666,13 @@ TField *TParseContext::parseStructDeclarator(TString *identifier, const TSourceL ...@@ -4665,13 +4666,13 @@ TField *TParseContext::parseStructDeclarator(TString *identifier, const TSourceL
TField *TParseContext::parseStructArrayDeclarator(TString *identifier, TField *TParseContext::parseStructArrayDeclarator(TString *identifier,
const TSourceLoc &loc, const TSourceLoc &loc,
unsigned int arraySize, const TVector<unsigned int> &arraySizes,
const TSourceLoc &arraySizeLoc) const TSourceLoc &arraySizeLoc)
{ {
checkIsNotReserved(loc, *identifier); checkIsNotReserved(loc, *identifier);
TType *type = new TType(EbtVoid, EbpUndefined); TType *type = new TType(EbtVoid, EbpUndefined);
type->makeArray(arraySize); type->makeArrays(arraySizes);
return new TField(type, identifier, loc); return new TField(type, identifier, loc);
} }
...@@ -4746,7 +4747,7 @@ TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecif ...@@ -4746,7 +4747,7 @@ TFieldList *TParseContext::addStructDeclaratorList(const TPublicType &typeSpecif
for (TField *declarator : *declaratorList) for (TField *declarator : *declaratorList)
{ {
auto declaratorArraySizes = declarator->type()->getArraySizes(); auto declaratorArraySizes = declarator->type()->getArraySizes();
// don't allow arrays of arrays // Don't allow arrays of arrays in ESSL < 3.10.
if (!declaratorArraySizes.empty()) if (!declaratorArraySizes.empty())
{ {
checkArrayElementIsNotArray(typeSpecifier.getLine(), typeSpecifier); checkArrayElementIsNotArray(typeSpecifier.getLine(), typeSpecifier);
......
...@@ -221,7 +221,7 @@ class TParseContext : angle::NonCopyable ...@@ -221,7 +221,7 @@ class TParseContext : angle::NonCopyable
const TSourceLoc &identifierLocation, const TSourceLoc &identifierLocation,
const TString &identifier, const TString &identifier,
const TSourceLoc &indexLocation, const TSourceLoc &indexLocation,
unsigned int arraySize); const TVector<unsigned int> &arraySizes);
TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType, TIntermDeclaration *parseSingleInitDeclaration(const TPublicType &publicType,
const TSourceLoc &identifierLocation, const TSourceLoc &identifierLocation,
const TString &identifier, const TString &identifier,
...@@ -234,7 +234,7 @@ class TParseContext : angle::NonCopyable ...@@ -234,7 +234,7 @@ class TParseContext : angle::NonCopyable
const TSourceLoc &identifierLocation, const TSourceLoc &identifierLocation,
const TString &identifier, const TString &identifier,
const TSourceLoc &indexLocation, const TSourceLoc &indexLocation,
unsigned int arraySize, const TVector<unsigned int> &arraySizes,
const TSourceLoc &initLocation, const TSourceLoc &initLocation,
TIntermTyped *initializer); TIntermTyped *initializer);
...@@ -252,7 +252,7 @@ class TParseContext : angle::NonCopyable ...@@ -252,7 +252,7 @@ class TParseContext : angle::NonCopyable
const TSourceLoc &identifierLocation, const TSourceLoc &identifierLocation,
const TString &identifier, const TString &identifier,
const TSourceLoc &arrayLocation, const TSourceLoc &arrayLocation,
unsigned int arraySize, const TVector<unsigned int> &arraySizes,
TIntermDeclaration *declarationOut); TIntermDeclaration *declarationOut);
void parseInitDeclarator(const TPublicType &publicType, void parseInitDeclarator(const TPublicType &publicType,
const TSourceLoc &identifierLocation, const TSourceLoc &identifierLocation,
...@@ -266,7 +266,7 @@ class TParseContext : angle::NonCopyable ...@@ -266,7 +266,7 @@ class TParseContext : angle::NonCopyable
const TSourceLoc &identifierLocation, const TSourceLoc &identifierLocation,
const TString &identifier, const TString &identifier,
const TSourceLoc &indexLocation, const TSourceLoc &indexLocation,
unsigned int arraySize, const TVector<unsigned int> &arraySizes,
const TSourceLoc &initLocation, const TSourceLoc &initLocation,
TIntermTyped *initializer, TIntermTyped *initializer,
TIntermDeclaration *declarationOut); TIntermDeclaration *declarationOut);
...@@ -298,7 +298,7 @@ class TParseContext : angle::NonCopyable ...@@ -298,7 +298,7 @@ class TParseContext : angle::NonCopyable
TParameter parseParameterArrayDeclarator(const TString *name, TParameter parseParameterArrayDeclarator(const TString *name,
const TSourceLoc &nameLoc, const TSourceLoc &nameLoc,
unsigned int arraySize, const TVector<unsigned int> &arraySizes,
const TSourceLoc &arrayLoc, const TSourceLoc &arrayLoc,
TPublicType *elementType); TPublicType *elementType);
...@@ -314,7 +314,7 @@ class TParseContext : angle::NonCopyable ...@@ -314,7 +314,7 @@ class TParseContext : angle::NonCopyable
TField *parseStructDeclarator(TString *identifier, const TSourceLoc &loc); TField *parseStructDeclarator(TString *identifier, const TSourceLoc &loc);
TField *parseStructArrayDeclarator(TString *identifier, TField *parseStructArrayDeclarator(TString *identifier,
const TSourceLoc &loc, const TSourceLoc &loc,
unsigned int arraySize, const TVector<unsigned int> &arraySizes,
const TSourceLoc &arraySizeLoc); const TSourceLoc &arraySizeLoc);
void checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin, void checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
......
...@@ -178,9 +178,9 @@ TType::TType(const TPublicType &p) ...@@ -178,9 +178,9 @@ TType::TType(const TPublicType &p)
{ {
ASSERT(primarySize <= 4); ASSERT(primarySize <= 4);
ASSERT(secondarySize <= 4); ASSERT(secondarySize <= 4);
if (p.array) if (p.isArray())
{ {
makeArray(p.arraySize); mArraySizes = *p.arraySizes;
} }
if (p.getUserDef()) if (p.getUserDef())
{ {
...@@ -715,6 +715,12 @@ void TType::makeArray(unsigned int s) ...@@ -715,6 +715,12 @@ void TType::makeArray(unsigned int s)
invalidateMangledName(); invalidateMangledName();
} }
void TType::makeArrays(const TVector<unsigned int> &sizes)
{
mArraySizes.insert(mArraySizes.end(), sizes.begin(), sizes.end());
invalidateMangledName();
}
void TType::setArraySize(size_t arrayDimension, unsigned int s) void TType::setArraySize(size_t arrayDimension, unsigned int s)
{ {
ASSERT(arrayDimension < mArraySizes.size()); ASSERT(arrayDimension < mArraySizes.size());
...@@ -940,8 +946,7 @@ void TPublicType::initialize(const TTypeSpecifierNonArray &typeSpecifier, TQuali ...@@ -940,8 +946,7 @@ void TPublicType::initialize(const TTypeSpecifierNonArray &typeSpecifier, TQuali
qualifier = q; qualifier = q;
invariant = false; invariant = false;
precision = EbpUndefined; precision = EbpUndefined;
array = false; arraySizes = nullptr;
arraySize = 0;
} }
void TPublicType::initializeBasicType(TBasicType basicType) void TPublicType::initializeBasicType(TBasicType basicType)
...@@ -954,8 +959,7 @@ void TPublicType::initializeBasicType(TBasicType basicType) ...@@ -954,8 +959,7 @@ void TPublicType::initializeBasicType(TBasicType basicType)
qualifier = EvqTemporary; qualifier = EvqTemporary;
invariant = false; invariant = false;
precision = EbpUndefined; precision = EbpUndefined;
array = false; arraySizes = nullptr;
arraySize = 0;
} }
bool TPublicType::isStructureContainingArrays() const bool TPublicType::isStructureContainingArrays() const
...@@ -978,21 +982,24 @@ bool TPublicType::isStructureContainingType(TBasicType t) const ...@@ -978,21 +982,24 @@ bool TPublicType::isStructureContainingType(TBasicType t) const
return typeSpecifierNonArray.userDef->containsType(t); return typeSpecifierNonArray.userDef->containsType(t);
} }
void TPublicType::setArraySize(int s) void TPublicType::setArraySizes(TVector<unsigned int> *sizes)
{
arraySizes = sizes;
}
bool TPublicType::isArray() const
{ {
array = true; return arraySizes && !arraySizes->empty();
arraySize = s;
} }
void TPublicType::clearArrayness() void TPublicType::clearArrayness()
{ {
array = false; arraySizes = nullptr;
arraySize = 0;
} }
bool TPublicType::isAggregate() const bool TPublicType::isAggregate() const
{ {
return array || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector(); return isArray() || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector();
} }
} // namespace sh } // namespace sh
...@@ -247,8 +247,10 @@ class TType ...@@ -247,8 +247,10 @@ class TType
unsigned int getArraySizeProduct() const; unsigned int getArraySizeProduct() const;
bool isUnsizedArray() const; bool isUnsizedArray() const;
unsigned int getOutermostArraySize() const { return mArraySizes.back(); } unsigned int getOutermostArraySize() const { return mArraySizes.back(); }
void makeArray(unsigned int s);
void makeArray(unsigned int s);
// sizes contain new outermost array sizes.
void makeArrays(const TVector<unsigned int> &sizes);
// Here, the array dimension value 0 corresponds to the innermost array. // Here, the array dimension value 0 corresponds to the innermost array.
void setArraySize(size_t arrayDimension, unsigned int s); void setArraySize(size_t arrayDimension, unsigned int s);
...@@ -475,7 +477,8 @@ struct TPublicType ...@@ -475,7 +477,8 @@ struct TPublicType
bool isStructureContainingArrays() const; bool isStructureContainingArrays() const;
bool isStructureContainingType(TBasicType t) const; bool isStructureContainingType(TBasicType t) const;
void setArraySize(int s); void setArraySizes(TVector<unsigned int> *sizes);
bool isArray() const;
void clearArrayness(); void clearArrayness();
bool isAggregate() const; bool isAggregate() const;
...@@ -485,8 +488,11 @@ struct TPublicType ...@@ -485,8 +488,11 @@ struct TPublicType
TQualifier qualifier; TQualifier qualifier;
bool invariant; bool invariant;
TPrecision precision; TPrecision precision;
bool array;
int arraySize; // Either nullptr or empty in case the type is not an array. The last element is the outermost
// array size. Note that due to bison restrictions, copies of the public type created by the
// copy constructor share the same arraySizes pointer.
const TVector<unsigned int> *arraySizes;
}; };
} // namespace sh } // namespace sh
......
...@@ -86,7 +86,7 @@ using namespace sh; ...@@ -86,7 +86,7 @@ using namespace sh;
TIntermCase *intermCase; TIntermCase *intermCase;
}; };
union { union {
unsigned int arraySize; TVector<unsigned int> *arraySizes;
TTypeSpecifierNonArray typeSpecifierNonArray; TTypeSpecifierNonArray typeSpecifierNonArray;
TPublicType type; TPublicType type;
TPrecision precision; TPrecision precision;
...@@ -219,7 +219,8 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons ...@@ -219,7 +219,8 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons
%type <interm.param> parameter_declaration parameter_declarator parameter_type_specifier %type <interm.param> parameter_declaration parameter_declarator parameter_type_specifier
%type <interm.layoutQualifier> layout_qualifier_id_list layout_qualifier_id %type <interm.layoutQualifier> layout_qualifier_id_list layout_qualifier_id
%type <interm.arraySize> array_specifier // Note: array_specifier guaranteed to be non-null.
%type <interm.arraySizes> array_specifier
%type <interm.type> fully_specified_type type_specifier %type <interm.type> fully_specified_type type_specifier
...@@ -686,7 +687,7 @@ parameter_declarator ...@@ -686,7 +687,7 @@ parameter_declarator
$$ = context->parseParameterDeclarator($1, $2.string, @2); $$ = context->parseParameterDeclarator($1, $2.string, @2);
} }
| type_specifier identifier array_specifier { | type_specifier identifier array_specifier {
$$ = context->parseParameterArrayDeclarator($2.string, @2, $3, @3, &$1); $$ = context->parseParameterArrayDeclarator($2.string, @2, *($3), @3, &$1);
} }
; ;
...@@ -726,12 +727,12 @@ init_declarator_list ...@@ -726,12 +727,12 @@ init_declarator_list
} }
| init_declarator_list COMMA identifier array_specifier { | init_declarator_list COMMA identifier array_specifier {
$$ = $1; $$ = $1;
context->parseArrayDeclarator($$.type, @3, *$3.string, @4, $4, $$.intermDeclaration); context->parseArrayDeclarator($$.type, @3, *$3.string, @4, *($4), $$.intermDeclaration);
} }
| init_declarator_list COMMA identifier array_specifier EQUAL initializer { | init_declarator_list COMMA identifier array_specifier EQUAL initializer {
ES3_OR_NEWER("=", @5, "first-class arrays (array initializer)"); ES3_OR_NEWER("=", @5, "first-class arrays (array initializer)");
$$ = $1; $$ = $1;
context->parseArrayInitDeclarator($$.type, @3, *$3.string, @4, $4, @5, $6, $$.intermDeclaration); context->parseArrayInitDeclarator($$.type, @3, *$3.string, @4, *($4), @5, $6, $$.intermDeclaration);
} }
| init_declarator_list COMMA identifier EQUAL initializer { | init_declarator_list COMMA identifier EQUAL initializer {
$$ = $1; $$ = $1;
...@@ -750,12 +751,12 @@ single_declaration ...@@ -750,12 +751,12 @@ single_declaration
} }
| fully_specified_type identifier array_specifier { | fully_specified_type identifier array_specifier {
$$.type = $1; $$.type = $1;
$$.intermDeclaration = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, $3); $$.intermDeclaration = context->parseSingleArrayDeclaration($$.type, @2, *$2.string, @3, *($3));
} }
| fully_specified_type identifier array_specifier EQUAL initializer { | fully_specified_type identifier array_specifier EQUAL initializer {
ES3_OR_NEWER("[]", @3, "first-class arrays (array initializer)"); ES3_OR_NEWER("[]", @3, "first-class arrays (array initializer)");
$$.type = $1; $$.type = $1;
$$.intermDeclaration = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, $3, @4, $5); $$.intermDeclaration = context->parseSingleArrayInitDeclaration($$.type, @2, *$2.string, @3, *($3), @4, $5);
} }
| fully_specified_type identifier EQUAL initializer { | fully_specified_type identifier EQUAL initializer {
$$.type = $1; $$.type = $1;
...@@ -932,20 +933,35 @@ type_specifier_no_prec ...@@ -932,20 +933,35 @@ type_specifier_no_prec
} }
| type_specifier_nonarray array_specifier { | type_specifier_nonarray array_specifier {
$$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary)); $$.initialize($1, (context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary));
$$.setArraySize($2); $$.setArraySizes($2);
} }
; ;
array_specifier array_specifier
: LEFT_BRACKET RIGHT_BRACKET { : LEFT_BRACKET RIGHT_BRACKET {
ES3_OR_NEWER("[]", @1, "implicitly sized array"); ES3_OR_NEWER("[]", @1, "implicitly sized array");
$$ = 0u; $$ = new TVector<unsigned int>();
$$->push_back(0u);
} }
| LEFT_BRACKET constant_expression RIGHT_BRACKET { | LEFT_BRACKET constant_expression RIGHT_BRACKET {
$$ = new TVector<unsigned int>();
unsigned int size = context->checkIsValidArraySize(@1, $2); unsigned int size = context->checkIsValidArraySize(@1, $2);
// Make the type an array even if size check failed. // Make the type an array even if size check failed.
// This ensures useless error messages regarding a variable's non-arrayness won't follow. // This ensures useless error messages regarding a variable's non-arrayness won't follow.
$$ = size; $$->push_back(size);
}
| array_specifier LEFT_BRACKET RIGHT_BRACKET {
ES3_1_ONLY("[]", @2, "arrays of arrays");
$$ = $1;
$$->insert($$->begin(), 0u);
}
| array_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
ES3_1_ONLY("[]", @2, "arrays of arrays");
$$ = $1;
unsigned int size = context->checkIsValidArraySize(@2, $3);
// Make the type an array even if size check failed.
// This ensures useless error messages regarding a variable's non-arrayness won't follow.
$$->insert($$->begin(), size);
} }
; ;
...@@ -1226,7 +1242,7 @@ struct_declarator ...@@ -1226,7 +1242,7 @@ struct_declarator
$$ = context->parseStructDeclarator($1.string, @1); $$ = context->parseStructDeclarator($1.string, @1);
} }
| identifier array_specifier { | identifier array_specifier {
$$ = context->parseStructArrayDeclarator($1.string, @1, $2, @2); $$ = context->parseStructArrayDeclarator($1.string, @1, *($2), @2);
} }
; ;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -238,7 +238,7 @@ union YYSTYPE ...@@ -238,7 +238,7 @@ union YYSTYPE
TIntermCase *intermCase; TIntermCase *intermCase;
}; };
union { union {
unsigned int arraySize; TVector<unsigned int> *arraySizes;
TTypeSpecifierNonArray typeSpecifierNonArray; TTypeSpecifierNonArray typeSpecifierNonArray;
TPublicType type; TPublicType type;
TPrecision precision; TPrecision precision;
......
...@@ -111,10 +111,26 @@ ...@@ -111,10 +111,26 @@
1442 D3D11 : dEQP-GLES31.functional.debug.error_groups.case_10 = SKIP 1442 D3D11 : dEQP-GLES31.functional.debug.error_groups.case_10 = SKIP
1442 D3D11 : dEQP-GLES31.functional.state_query.program.active_atomic_counter_buffers_get_programiv = FAIL 1442 D3D11 : dEQP-GLES31.functional.state_query.program.active_atomic_counter_buffers_get_programiv = FAIL
1442 D3D11 : dEQP-GLES31.functional.layout_binding.ubo.* = FAIL 1442 D3D11 : dEQP-GLES31.functional.layout_binding.ubo.* = FAIL
1442 D3D11 : dEQP-GLES31.functional.program_interface_query.* = FAIL
// OPENGL Failing Tests // OPENGL Failing Tests
1665 WIN NVIDIA OPENGL : dEQP-GLES31.functional.draw_indirect.negative.command_offset_not_in_buffer_unsigned32_wrap = FAIL 1665 WIN NVIDIA OPENGL : dEQP-GLES31.functional.draw_indirect.negative.command_offset_not_in_buffer_unsigned32_wrap = FAIL
1442 NVIDIA OPENGL : dEQP-GLES31.functional.fbo.no_attachments.maximums.all = FAIL 1442 NVIDIA OPENGL : dEQP-GLES31.functional.fbo.no_attachments.maximums.all = FAIL
1442 OPENGL : dEQP-GLES31.functional.program_interface_query.atomic_counter_buffer.buffer_data_size = FAIL
1442 OPENGL : dEQP-GLES31.functional.program_interface_query.atomic_counter_buffer.referenced_by* = FAIL
1442 OPENGL : dEQP-GLES31.functional.program_interface_query.buffer_limited_query.* = FAIL
1442 OPENGL : dEQP-GLES31.functional.program_interface_query.buffer_variable.* = FAIL
1442 OPENGL : dEQP-GLES31.functional.program_interface_query.program_input.* = FAIL
1442 OPENGL : dEQP-GLES31.functional.program_interface_query.program_output.* = FAIL
1442 OPENGL : dEQP-GLES31.functional.program_interface_query.shader_storage_block.* = FAIL
1442 OPENGL : dEQP-GLES31.functional.program_interface_query.transform_feedback_varying.* = FAIL
1442 OPENGL : dEQP-GLES31.functional.program_interface_query.uniform.matrix_row_major.* = FAIL
1442 OPENGL : dEQP-GLES31.functional.program_interface_query.uniform.matrix_stride.* = FAIL
1442 OPENGL : dEQP-GLES31.functional.program_interface_query.uniform.referenced_by_shader.* = FAIL
1442 OPENGL : dEQP-GLES31.functional.program_interface_query.uniform.random.* = FAIL
1442 OPENGL : dEQP-GLES31.functional.program_interface_query.uniform_block.resource_list.block_array = FAIL
1442 OPENGL : dEQP-GLES31.functional.program_interface_query.uniform_block.resource_list.block_array_single_element = FAIL
1442 OPENGL : dEQP-GLES31.functional.program_interface_query.uniform_block.referenced_by.* = FAIL
// OpenGL and D3D11 Failing Tests // OpenGL and D3D11 Failing Tests
1663 OPENGL D3D11 : dEQP-GLES31.functional.draw_indirect.compute_interop.* = FAIL 1663 OPENGL D3D11 : dEQP-GLES31.functional.draw_indirect.compute_interop.* = FAIL
...@@ -1131,16 +1147,6 @@ ...@@ -1131,16 +1147,6 @@
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.frexp.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.frexp.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ldexp.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.builtin_functions.precision.ldexp.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.opaque_type_indexing.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.opaque_type_indexing.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.functions.overloading.arrays_of_arrays_size_vertex = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.functions.overloading.arrays_of_arrays_size_fragment = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.arrays_of_arrays.constructor.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.arrays_of_arrays.return.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.arrays_of_arrays.parameter.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.arrays_of_arrays.implicit_size.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.arrays_of_arrays.assignment.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.arrays_of_arrays.length.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.arrays_of_arrays.array_access.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.arrays_of_arrays.single_statement_multiple_declarations.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_number_of_declarations = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_number_of_declarations = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_order = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_order = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_type = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.shaders.linkage.shader_storage_block.mismatch_type = FAIL
...@@ -1197,9 +1203,6 @@ ...@@ -1197,9 +1203,6 @@
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.atomic_counter_multiple_groups = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.basic.atomic_counter_multiple_groups = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.indirect_dispatch.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.compute.indirect_dispatch.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.ssbo.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.ssbo.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.2_level_array.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.3_level_array.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.2_level_struct_array.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.basic_type_arrays.4 = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.basic_type_arrays.4 = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.basic_type_arrays.10 = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.basic_type_arrays.10 = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.1 = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.ubo.random.all_per_block_buffers.1 = FAIL
...@@ -1260,7 +1263,6 @@ ...@@ -1260,7 +1263,6 @@
1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.program_pipeline.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.state_query.program_pipeline.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.synchronization.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.synchronization.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.separate_shader.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.separate_shader.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.uniform_location.nested_array.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.error_filters.case_11 = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.error_filters.case_11 = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.error_groups.case_11 = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.error_groups.case_11 = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.buffer.bind_buffer_range = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.callbacks.buffer.bind_buffer_range = FAIL
...@@ -1298,7 +1300,6 @@ ...@@ -1298,7 +1300,6 @@
1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.primitive_bounding_box = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.primitive_bounding_box = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.tessellation_shader = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.tessellation_shader = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.object_labels.program_pipeline = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.debug.object_labels.program_pipeline = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.program_interface_query.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.image.image2d.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.image.image2d.* = FAIL
1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.image.image3d.* = FAIL 1442 OPENGL D3D11 : dEQP-GLES31.functional.layout_binding.image.image3d.* = FAIL
......
...@@ -652,6 +652,52 @@ TEST_P(BindUniformLocationES31Test, LocationLayoutQualifierConflictsWithAPIBindi ...@@ -652,6 +652,52 @@ TEST_P(BindUniformLocationES31Test, LocationLayoutQualifierConflictsWithAPIBindi
ASSERT_GL_FALSE(linked); ASSERT_GL_FALSE(linked);
} }
// Test for binding a location for an array of arrays uniform.
TEST_P(BindUniformLocationES31Test, ArrayOfArrays)
{
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_CHROMIUM_bind_uniform_location"));
const std::string vsSource =
R"(#version 310 es
in vec4 a_position;
void main()
{
gl_Position = a_position;
})";
const std::string fsSource =
R"(#version 310 es
precision highp float;
uniform vec4 sourceColor[2][1];
out highp vec4 my_FragColor;
void main()
{
my_FragColor = sourceColor[1][0];
})";
const GLuint location = 8;
GLuint vs = CompileShader(GL_VERTEX_SHADER, vsSource);
EXPECT_NE(0u, vs);
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fsSource);
EXPECT_NE(0u, fs);
linkProgramWithUniformLocation(vs, fs, "sourceColor[1]", location);
GLint linked = GL_FALSE;
glGetProgramiv(mProgram, GL_LINK_STATUS, &linked);
ASSERT_GL_TRUE(linked);
glUseProgram(mProgram);
glUniform4f(location, 0.0f, 1.0f, 0.0f, 1.0f);
drawQuad(mProgram, "a_position", 0.5f);
EXPECT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these // Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against. // tests should be run against.
ANGLE_INSTANTIATE_TEST(BindUniformLocationTest, ANGLE_INSTANTIATE_TEST(BindUniformLocationTest,
......
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