зеркало из https://github.com/AvaloniaUI/angle.git
Improve test coverage of constant folding
Clean up some TODOs in the code as well as add tests to make sure that ANGLE treats expressions indexing into constant arrays as constant expressions in different contexts. This complements the existing tests in ConstantFoldingTest. BUG=angleproject:2298 TEST=angle_unittests Change-Id: I779bf03891f7d06f14d293e69101c05d7dbf57b6 Reviewed-on: https://chromium-review.googlesource.com/1254067 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
This commit is contained in:
Родитель
624fbdcf55
Коммит
1dfd8ae2e0
|
@ -975,9 +975,10 @@ unsigned int TParseContext::checkIsValidArraySize(const TSourceLoc &line, TInter
|
|||
{
|
||||
TIntermConstantUnion *constant = expr->getAsConstantUnion();
|
||||
|
||||
// TODO(oetuaho@nvidia.com): Get rid of the constant == nullptr check here once all constant
|
||||
// expressions can be folded. Right now we don't allow constant expressions that ANGLE can't
|
||||
// fold as array size.
|
||||
// ANGLE should be able to fold any EvqConst expressions resulting in an integer - but to be
|
||||
// safe against corner cases we still check for constant folding. Some interpretations of the
|
||||
// spec have allowed constant expressions with side effects - like array length() method on a
|
||||
// non-constant array.
|
||||
if (expr->getQualifier() != EvqConst || constant == nullptr || !constant->isScalarInt())
|
||||
{
|
||||
error(line, "array size must be a constant integer expression", "");
|
||||
|
@ -3945,10 +3946,10 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
|
|||
|
||||
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.
|
||||
// ANGLE should be able to fold any constant expressions resulting in an integer - but to be
|
||||
// safe we don't treat "EvqConst" that's evaluated according to the spec as being sufficient
|
||||
// for constness. Some interpretations of the spec have allowed constant expressions with side
|
||||
// effects - like array length() method on a non-constant array.
|
||||
if (indexExpression->getQualifier() != EvqConst || indexConstantUnion == nullptr)
|
||||
{
|
||||
if (baseExpression->isInterfaceBlock())
|
||||
|
@ -4903,9 +4904,10 @@ TIntermCase *TParseContext::addCase(TIntermTyped *condition, const TSourceLoc &l
|
|||
error(condition->getLine(), "case label must be a scalar integer", "case");
|
||||
}
|
||||
TIntermConstantUnion *conditionConst = condition->getAsConstantUnion();
|
||||
// TODO(oetuaho@nvidia.com): Get rid of the conditionConst == nullptr check once all constant
|
||||
// expressions can be folded. Right now we don't allow constant expressions that ANGLE can't
|
||||
// fold in case labels.
|
||||
// ANGLE should be able to fold any EvqConst expressions resulting in an integer - but to be
|
||||
// safe against corner cases we still check for conditionConst. Some interpretations of the
|
||||
// spec have allowed constant expressions with side effects - like array length() method on a
|
||||
// non-constant array.
|
||||
if (condition->getQualifier() != EvqConst || conditionConst == nullptr)
|
||||
{
|
||||
error(condition->getLine(), "case label must be constant", "case");
|
||||
|
|
|
@ -5967,3 +5967,70 @@ TEST_F(FragmentShaderValidationTest, CaseInsideBlock)
|
|||
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
|
||||
}
|
||||
}
|
||||
|
||||
// Test using a value from a constant array as a case label.
|
||||
TEST_F(FragmentShaderValidationTest, ValueFromConstantArrayAsCaseLabel)
|
||||
{
|
||||
const std::string &shaderString =
|
||||
R"(#version 300 es
|
||||
precision mediump float;
|
||||
uniform int u;
|
||||
const int[3] arr = int[3](2, 1, 0);
|
||||
out vec4 my_FragColor;
|
||||
void main()
|
||||
{
|
||||
switch (u)
|
||||
{
|
||||
case arr[1]:
|
||||
my_FragColor = vec4(0.0);
|
||||
case 2:
|
||||
case 0:
|
||||
default:
|
||||
my_FragColor = vec4(1.0);
|
||||
}
|
||||
})";
|
||||
if (!compile(shaderString))
|
||||
{
|
||||
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
|
||||
}
|
||||
}
|
||||
|
||||
// Test using a value from a constant array as a fragment output index.
|
||||
TEST_F(FragmentShaderValidationTest, ValueFromConstantArrayAsFragmentOutputIndex)
|
||||
{
|
||||
const std::string &shaderString =
|
||||
R"(#version 300 es
|
||||
precision mediump float;
|
||||
uniform int u;
|
||||
const int[3] arr = int[3](4, 1, 0);
|
||||
out vec4 my_FragData[2];
|
||||
void main()
|
||||
{
|
||||
my_FragData[arr[1]] = vec4(0.0);
|
||||
my_FragData[arr[2]] = vec4(0.0);
|
||||
})";
|
||||
if (!compile(shaderString))
|
||||
{
|
||||
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
|
||||
}
|
||||
}
|
||||
|
||||
// Test using a value from a constant array as an array size.
|
||||
TEST_F(FragmentShaderValidationTest, ValueFromConstantArrayAsArraySize)
|
||||
{
|
||||
const std::string &shaderString =
|
||||
R"(#version 300 es
|
||||
precision mediump float;
|
||||
uniform int u;
|
||||
const int[3] arr = int[3](0, 2, 0);
|
||||
const int[arr[1]] arr2 = int[2](2, 1);
|
||||
out vec4 my_FragColor;
|
||||
void main()
|
||||
{
|
||||
my_FragColor = vec4(arr2[1]);
|
||||
})";
|
||||
if (!compile(shaderString))
|
||||
{
|
||||
FAIL() << "Shader compilation failed, expecting success:\n" << mInfoLog;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче