Commit 36b0514a by Olli Etuaho

Fix ESSL3 indexing corner cases

Indexing interface blocks or fragment outputs with a non-constant expression is not valid even if ANGLE has been able to constant fold the expression. BUG=angleproject:1210 TEST=angle_unittests Change-Id: I2ccb67871b682976a31b8de306053b9b28c06437 Reviewed-on: https://chromium-review.googlesource.com/312044Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent b49c9bf9
...@@ -2698,6 +2698,27 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, ...@@ -2698,6 +2698,27 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion(); TIntermConstantUnion *indexConstantUnion = indexExpression->getAsConstantUnion();
// TODO(oetuaho@nvidia.com): Get rid of indexConstantUnion == nullptr below once ANGLE is able
// to constant fold all constant expressions. Right now we don't allow indexing interface blocks
// or fragment outputs with expressions that ANGLE is not able to constant fold, even if the
// index is a constant expression.
if (indexExpression->getQualifier() != EvqConst || indexConstantUnion == nullptr)
{
if (baseExpression->isInterfaceBlock())
{
error(
location, "", "[",
"array indexes for interface blocks arrays must be constant integral expressions");
recover();
}
else if (baseExpression->getQualifier() == EvqFragmentOut)
{
error(location, "", "[",
"array indexes for fragment outputs must be constant integral expressions");
recover();
}
}
if (indexConstantUnion) if (indexConstantUnion)
{ {
// If the index is not qualified as constant, the behavior in the spec is undefined. This // If the index is not qualified as constant, the behavior in the spec is undefined. This
...@@ -2790,20 +2811,6 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, ...@@ -2790,20 +2811,6 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
} }
else else
{ {
if (baseExpression->isInterfaceBlock())
{
error(
location, "", "[",
"array indexes for interface blocks arrays must be constant integral expressions");
recover();
}
else if (baseExpression->getQualifier() == EvqFragmentOut)
{
error(location, "", "[",
"array indexes for fragment outputs must be constant integral expressions");
recover();
}
indexedExpression = indexedExpression =
intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location); intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location);
} }
......
...@@ -1158,3 +1158,46 @@ TEST_F(MalformedShaderTest, EmptyArrayConstructor) ...@@ -1158,3 +1158,46 @@ TEST_F(MalformedShaderTest, EmptyArrayConstructor)
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog; FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
} }
} }
// Test that indexing fragment outputs with a non-constant expression is forbidden, even if ANGLE
// is able to constant fold the index expression. ESSL 3.00 section 4.3.6.
TEST_F(MalformedShaderTest, DynamicallyIndexedFragmentOutput)
{
const std::string &shaderString =
"#version 300 es"
"precision mediump float;\n"
"uniform int a;\n"
"out vec4[2] my_FragData;\n"
"void main()\n"
"{\n"
" my_FragData[true ? 0 : a] = vec4(0.0);\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// Test that indexing an interface block array with a non-constant expression is forbidden, even if
// ANGLE is able to constant fold the index expression. ESSL 3.00 section 4.3.7.
TEST_F(MalformedShaderTest, DynamicallyIndexedInterfaceBlock)
{
const std::string &shaderString =
"#version 300 es"
"precision mediump float;\n"
"uniform int a;\n"
"uniform B\n"
"{\n"
" vec4 f;\n"
"}\n"
"blocks[2];\n"
"out vec4 my_FragColor;\n"
"void main()\n"
"{\n"
" my_FragColor = blocks[true ? 0 : a].f;\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
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