Commit e181f2f7 by Shahbaz Youssefi Committed by Commit Bot

Validate that image array indices are constant

Also adds compiler tests for dynamic indexing of SSBOs and images. Bug: angleproject:3569 Change-Id: I84b90813840ffad5a9a3cd8e7f12bd637a57b327 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1961095Reviewed-by: 's avatarJiajia Qin <jiajia.qin@intel.com> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent bf47a17e
...@@ -4044,27 +4044,27 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression, ...@@ -4044,27 +4044,27 @@ TIntermTyped *TParseContext::addIndexExpression(TIntermTyped *baseExpression,
} }
else if (baseExpression->isArray()) else if (baseExpression->isArray())
{ {
TType elementType; TBasicType elementType = baseExpression->getType().getBasicType();
switch (mShaderVersion)
// Note: In Section 12.30 of the ESSL 3.00 spec on p143-144:
//
// Indexing of arrays of samplers by constant-index-expressions is
// supported in GLSL ES 1.00. A constant-index-expression is an
// expression formed from constant-expressions and certain loop indices,
// defined for a subset of loop constructs. Should this functionality be
// included in GLSL ES 3.00?
//
// RESOLUTION: No. Arrays of samplers may only be indexed by constant-
// integral-expressions.
if (IsSampler(elementType) && !allowUniformIndices && mShaderVersion > 100)
{ {
case 100: error(location, "array index for samplers must be constant integral expressions",
break; "[");
case 300: }
case 310: else if (IsImage(elementType))
elementType = baseExpression->getType(); {
elementType.toArrayElementType(); error(location,
if (elementType.isSampler() && !allowUniformIndices) "array indexes for image arrays must be constant integral expressions", "[");
{
error(location,
"array index for samplers must be constant integral expressions",
"[");
}
break;
case 320:
break;
default:
UNREACHABLE();
break;
} }
} }
} }
......
...@@ -1281,24 +1281,48 @@ TEST_F(FragmentShaderValidationTest, DynamicallyIndexedFragmentOutput) ...@@ -1281,24 +1281,48 @@ TEST_F(FragmentShaderValidationTest, DynamicallyIndexedFragmentOutput)
} }
} }
// Test that indexing an interface block array with a non-constant expression is forbidden, even if // Test that indexing a uniform buffer 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. // ANGLE is able to constant fold the index expression. ESSL 3.00 section 4.3.7.
TEST_F(FragmentShaderValidationTest, DynamicallyIndexedInterfaceBlock) TEST_F(FragmentShaderValidationTest, DynamicallyIndexedUniformBuffer)
{ {
const std::string &shaderString = const std::string &shaderString =
"#version 300 es\n" R"(#version 300 es
"precision mediump float;\n" precision mediump float;
"uniform int a;\n" uniform int a;
"uniform B\n" uniform B
"{\n" {
" vec4 f;\n" vec4 f;
"}\n" }
"blocks[2];\n" blocks[2];
"out vec4 my_FragColor;\n" out vec4 my_FragColor;
"void main()\n" void main()
"{\n" {
" my_FragColor = blocks[true ? 0 : a].f;\n" my_FragColor = blocks[true ? 0 : a].f;
"}\n"; })";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
}
}
// Test that indexing a storage buffer array with a non-constant expression is forbidden, even if
// ANGLE is able to constant fold the index expression. ESSL 3.10 section 4.3.9.
TEST_F(FragmentShaderValidationTest, DynamicallyIndexedStorageBuffer)
{
const std::string &shaderString =
R"(#version 310 es
precision mediump float;
uniform int a;
layout(std140) buffer B
{
vec4 f;
}
blocks[2];
out vec4 my_FragColor;
void main()
{
my_FragColor = blocks[true ? 0 : a].f;
})";
if (compile(shaderString)) if (compile(shaderString))
{ {
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog; FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
...@@ -1310,15 +1334,35 @@ TEST_F(FragmentShaderValidationTest, DynamicallyIndexedInterfaceBlock) ...@@ -1310,15 +1334,35 @@ TEST_F(FragmentShaderValidationTest, DynamicallyIndexedInterfaceBlock)
TEST_F(FragmentShaderValidationTest, DynamicallyIndexedSampler) TEST_F(FragmentShaderValidationTest, DynamicallyIndexedSampler)
{ {
const std::string &shaderString = const std::string &shaderString =
"#version 300 es\n" R"(#version 300 es
"precision mediump float;\n" precision mediump float;
"uniform int a;\n" uniform int a;
"uniform sampler2D s[2];\n" uniform sampler2D s[2];
"out vec4 my_FragColor;\n" out vec4 my_FragColor;
"void main()\n" void main()
"{\n" {
" my_FragColor = texture(s[true ? 0 : a], vec2(0));\n" my_FragColor = texture(s[true ? 0 : a], vec2(0));
"}\n"; })";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
}
}
// Test that indexing an image array with a non-constant expression is forbidden, even if ANGLE is
// able to constant fold the index expression. ESSL 3.10 section 4.1.7.2.
TEST_F(FragmentShaderValidationTest, DynamicallyIndexedImage)
{
const std::string &shaderString =
R"(#version 310 es
precision mediump float;
uniform int a;
layout(rgba32f) uniform highp readonly image2D image[2];
out vec4 my_FragColor;
void main()
{
my_FragColor = imageLoad(image[true ? 0 : a], ivec2(0));
})";
if (compile(shaderString)) if (compile(shaderString))
{ {
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog; FAIL() << "Shader compilation succeeded, expecting failure:\n" << 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