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
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(
TPublicType &publicType,
const TSourceLoc &identifierOrTypeLocation,
......@@ -2297,12 +2334,7 @@ TIntermDeclaration *TParseContext::parseSingleDeclaration(
}
}
if (IsGeometryShaderInput(mShaderType, type.getQualifier()))
{
error(identifierOrTypeLocation,
"Geometry shader input varying variable must be declared as an array",
identifier.c_str());
}
checkGeometryShaderInputAndSetArraySize(identifierOrTypeLocation, identifier.c_str(), &type);
declarationQualifierErrorCheck(publicType.qualifier, publicType.layoutQualifier,
identifierOrTypeLocation);
......@@ -2375,33 +2407,7 @@ TIntermDeclaration *TParseContext::parseSingleArrayDeclaration(TPublicType &elem
TType arrayType(elementType);
arrayType.makeArray(arraySize);
if (IsGeometryShaderInput(mShaderType, elementType.qualifier))
{
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);
}
}
checkGeometryShaderInputAndSetArraySize(indexLocation, identifier.c_str(), &arrayType);
checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &arrayType);
......@@ -2566,6 +2572,9 @@ void TParseContext::parseDeclarator(TPublicType &publicType,
TVariable *variable = nullptr;
TType type(publicType);
checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier.c_str(), &type);
checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &type);
if (IsAtomicCounter(publicType.getBasicType()))
......@@ -2605,6 +2614,8 @@ void TParseContext::parseArrayDeclarator(TPublicType &elementType,
TType arrayType(elementType);
arrayType.makeArray(arraySize);
checkGeometryShaderInputAndSetArraySize(identifierLocation, identifier.c_str(), &arrayType);
checkCanBeDeclaredWithoutInitializer(identifierLocation, identifier, &arrayType);
if (IsAtomicCounter(elementType.getBasicType()))
......
......@@ -507,6 +507,11 @@ class TParseContext : angle::NonCopyable
TType type,
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
// further along the line in parsing.
void checkIsNotUnsizedArray(const TSourceLoc &line,
......
......@@ -580,6 +580,7 @@ void TType::sizeUnsizedArrays(const TVector<unsigned int> &arraySizes)
void TType::sizeOutermostUnsizedArray(unsigned int arraySize)
{
ASSERT(isArray());
ASSERT(mArraySizes.back() == 0u);
mArraySizes.back() = arraySize;
}
......
......@@ -1271,17 +1271,16 @@ TEST_F(GeometryShaderTest, DeclareUnsizedInputWithoutInputPrimitive)
TEST_F(GeometryShaderTest, IndexingUnsizedInputDeclaredAfterInputPrimitive)
{
const std::string &shaderString =
"#version 310 es\n"
"#extension GL_OES_geometry_shader : require\n"
"layout (points) in;\n"
"layout (points, max_vertices = 1) out;\n"
"in vec4 texcoord[];\n"
"void main()\n"
"{\n"
" int index = 0;\n"
" vec4 coord1 = texcoord[0];\n"
" vec4 coord2 = texcoord[index];\n"
"}\n";
R"(#version 310 es
#extension GL_OES_geometry_shader : require
layout (points) in;
layout (points, max_vertices = 1) out;
in vec4 texcoord[], texcoord2[];
in vec4[] texcoord3, texcoord4;
void main()
{
vec4 coord = texcoord[0] + texcoord2[0] + texcoord3[0] + texcoord4[0];
})";
if (!compile(shaderString))
{
......
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