Commit 454c34cb by Olli Etuaho Committed by Commit Bot

Accept valid geometry shader inputs regardless of syntax

Before, only the following style of declarations were accepted: in float f[]; Now also these styles are accepted: in float[] f; in float f[], g[]; BUG=angleproject:2201 TEST=angle_unittests Change-Id: I0af7d355a5e06a67ceef2d6bd69af7e23c180a04 Reviewed-on: https://chromium-review.googlesource.com/738234 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 335d8bf2
...@@ -2264,6 +2264,43 @@ void TParseContext::checkAtomicCounterOffsetIsNotOverlapped(TPublicType &publicT ...@@ -2264,6 +2264,43 @@ void TParseContext::checkAtomicCounterOffsetIsNotOverlapped(TPublicType &publicT
type.setLayoutQualifier(qualifier); type.setLayoutQualifier(qualifier);
} }
void TParseContext::checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location,
const char *token,
TType *type)
{
if (IsGeometryShaderInput(mShaderType, type->getQualifier()))
{
if (type->isArray() && type->getOutermostArraySize() == 0u)
{
// Set size for the unsized geometry shader inputs if they are declared after a valid
// input primitive declaration.
if (mGeometryShaderInputPrimitiveType != EptUndefined)
{
ASSERT(mGeometryShaderInputArraySize > 0u);
type->sizeOutermostUnsizedArray(mGeometryShaderInputArraySize);
}
else
{
// [GLSL ES 3.2 SPEC Chapter 4.4.1.2]
// An input can be declared without an array size if there is a previous layout
// which specifies the size.
error(location,
"Missing a valid input primitive declaration before declaring an unsized "
"array input",
token);
}
}
else if (type->isArray())
{
setGeometryShaderInputArraySize(type->getOutermostArraySize(), location);
}
else
{
error(location, "Geometry shader input variable must be declared as an array", token);
}
}
}
TIntermDeclaration *TParseContext::parseSingleDeclaration( TIntermDeclaration *TParseContext::parseSingleDeclaration(
TPublicType &publicType, TPublicType &publicType,
const TSourceLoc &identifierOrTypeLocation, const TSourceLoc &identifierOrTypeLocation,
...@@ -2297,12 +2334,7 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration( ...@@ -2297,12 +2334,7 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration(
} }
} }
if (IsGeometryShaderInput(mShaderType, type.getQualifier())) checkGeometryShaderInputAndSetArraySize(identifierOrTypeLocation, identifier.c_str(), &type);
{
error(identifierOrTypeLocation,
"Geometry shader input varying variable must be declared as an array",
identifier.c_str());
}
declarationQualifierErrorCheck(publicType.qualifier, publicType.layoutQualifier, declarationQualifierErrorCheck(publicType.qualifier, publicType.layoutQualifier,
identifierOrTypeLocation); identifierOrTypeLocation);
...@@ -2375,33 +2407,7 @@ TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(TPublicType &elem ...@@ -2375,33 +2407,7 @@ TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(TPublicType &elem
TType arrayType(elementType); TType arrayType(elementType);
arrayType.makeArray(arraySize); arrayType.makeArray(arraySize);
if (IsGeometryShaderInput(mShaderType, elementType.qualifier)) checkGeometryShaderInputAndSetArraySize(indexLocation, identifier.c_str(), &arrayType);
{
if (arrayType.isUnsizedArray())
{
// Set size for the unsized geometry shader inputs if they are declared after a valid
// input primitive declaration.
if (mGeometryShaderInputPrimitiveType != EptUndefined)
{
ASSERT(mGeometryShaderInputArraySize > 0u);
arrayType.sizeOutermostUnsizedArray(mGeometryShaderInputArraySize);
}
else
{
// [GLSL ES 3.2 SPEC Chapter 4.4.1.2]
// An input can be declared without an array size if there is a previous layout
// which specifies the size.
error(indexLocation,
"Missing a valid input primitive declaration before declaring an unsized "
"array input",
"");
}
}
else
{
setGeometryShaderInputArraySize(arrayType.getOutermostArraySize(), indexLocation);
}
}
checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &arrayType); checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &arrayType);
...@@ -2566,6 +2572,9 @@ void TParseContext::parseDeclarator(TPublicType &publicType, ...@@ -2566,6 +2572,9 @@ void TParseContext::parseDeclarator(TPublicType &publicType,
TVariable *variable = nullptr; TVariable *variable = nullptr;
TType type(publicType); TType type(publicType);
checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier.c_str(), &type);
checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &type); checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &type);
if (IsAtomicCounter(publicType.getBasicType())) if (IsAtomicCounter(publicType.getBasicType()))
...@@ -2605,6 +2614,8 @@ void TParseContext::parseArrayDeclarator(TPublicType &elementType, ...@@ -2605,6 +2614,8 @@ void TParseContext::parseArrayDeclarator(TPublicType &elementType,
TType arrayType(elementType); TType arrayType(elementType);
arrayType.makeArray(arraySize); arrayType.makeArray(arraySize);
checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier.c_str(), &arrayType);
checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &arrayType); checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &arrayType);
if (IsAtomicCounter(elementType.getBasicType())) if (IsAtomicCounter(elementType.getBasicType()))
......
...@@ -507,6 +507,11 @@ class TParseContext : angle::NonCopyable ...@@ -507,6 +507,11 @@ class TParseContext : angle::NonCopyable
TType type, TType type,
const TSourceLoc &line); const TSourceLoc &line);
// Will set the size of the outermost array according to geometry shader input layout.
void checkGeometryShaderInputAndSetArraySize(const TSourceLoc &location,
const char *token,
TType *type);
// Will size any unsized array type so unsized arrays won't need to be taken into account // Will size any unsized array type so unsized arrays won't need to be taken into account
// further along the line in parsing. // further along the line in parsing.
void checkIsNotUnsizedArray(const TSourceLoc &line, void checkIsNotUnsizedArray(const TSourceLoc &line,
......
...@@ -580,6 +580,7 @@ void TType::sizeUnsizedArrays(const TVector<unsigned int> &arraySizes) ...@@ -580,6 +580,7 @@ void TType::sizeUnsizedArrays(const TVector<unsigned int> &arraySizes)
void TType::sizeOutermostUnsizedArray(unsigned int arraySize) void TType::sizeOutermostUnsizedArray(unsigned int arraySize)
{ {
ASSERT(isArray()); ASSERT(isArray());
ASSERT(mArraySizes.back() == 0u);
mArraySizes.back() = arraySize; mArraySizes.back() = arraySize;
} }
......
...@@ -1271,17 +1271,16 @@ TEST_F(GeometryShaderTest, DeclareUnsizedInputWithoutInputPrimitive) ...@@ -1271,17 +1271,16 @@ TEST_F(GeometryShaderTest, DeclareUnsizedInputWithoutInputPrimitive)
TEST_F(GeometryShaderTest, IndexingUnsizedInputDeclaredAfterInputPrimitive) TEST_F(GeometryShaderTest, IndexingUnsizedInputDeclaredAfterInputPrimitive)
{ {
const std::string &shaderString = const std::string &shaderString =
"#version 310 es\n" R"(#version 310 es
"#extension GL_OES_geometry_shader : require\n" #extension GL_OES_geometry_shader : require
"layout (points) in;\n" layout (points) in;
"layout (points, max_vertices = 1) out;\n" layout (points, max_vertices = 1) out;
"in vec4 texcoord[];\n" in vec4 texcoord[], texcoord2[];
"void main()\n" in vec4[] texcoord3, texcoord4;
"{\n" void main()
" int index = 0;\n" {
" vec4 coord1 = texcoord[0];\n" vec4 coord = texcoord[0] + texcoord2[0] + texcoord3[0] + texcoord4[0];
" vec4 coord2 = texcoord[index];\n" })";
"}\n";
if (!compile(shaderString)) if (!compile(shaderString))
{ {
...@@ -1535,4 +1534,4 @@ TEST_F(GeometryShaderTest, InvariantOutput) ...@@ -1535,4 +1534,4 @@ TEST_F(GeometryShaderTest, InvariantOutput)
{ {
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog; FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
} }
} }
\ No newline at end of file
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