Bind all elements of unbound image arrays to unit zero
Spec GLSL ES 3.10, section 4.4.5, Any uniform sampler, image or atomic
counter variable declared without a binding qualifier is initially bound
to unit zero. If the binding qualifier is used with an array, the first
element of the array takes the specified unit and each subsequent element
takes the next consecutive unit.
BUG=angleproject:1987
TEST=angle_end2end_tests:ComputeShaderTest
Change-Id: I6a8188449a91bf3e8ded37e067205dcae4e47fa7
Reviewed-on: https://chromium-review.googlesource.com/547977
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/tests/gl_tests/ComputeShaderTest.cpp b/src/tests/gl_tests/ComputeShaderTest.cpp
index 150d3a7..7e071c2 100644
--- a/src/tests/gl_tests/ComputeShaderTest.cpp
+++ b/src/tests/gl_tests/ComputeShaderTest.cpp
@@ -246,11 +246,7 @@
// Use image uniform to write texture in compute shader, and verify the content is expected.
TEST_P(ComputeShaderTest, BindImageTexture)
{
- if (IsD3D11())
- {
- std::cout << "Test skipped on D3D11 because it is not implemented yet." << std::endl;
- return;
- }
+ ANGLE_SKIP_TEST_IF(IsD3D11());
GLTexture mTexture[2];
GLFramebuffer mFramebuffer;
@@ -316,6 +312,58 @@
}
}
+// When declare a image array without a binding qualifier, all elements are bound to unit zero.
+TEST_P(ComputeShaderTest, ImageArrayWithoutBindingQualifier)
+{
+ ANGLE_SKIP_TEST_IF(IsD3D11());
+
+ // TODO(xinghua.cao@intel.com): On AMD desktop OpenGL, bind two image variables to unit 0,
+ // only one variable is valid.
+ ANGLE_SKIP_TEST_IF(IsAMD() && IsDesktopOpenGL() && IsWindows());
+
+ GLTexture mTexture;
+ GLFramebuffer mFramebuffer;
+ const std::string csSource =
+ "#version 310 es\n"
+ "layout(local_size_x=2, local_size_y=2, local_size_z=1) in;\n"
+ "layout(r32ui) writeonly uniform highp uimage2D uImage[2];"
+ "void main()\n"
+ "{\n"
+ " imageStore(uImage[0], ivec2(gl_LocalInvocationIndex, 0), uvec4(100, 0, 0, 0));"
+ " imageStore(uImage[1], ivec2(gl_LocalInvocationIndex, 1), uvec4(100, 0, 0, 0));"
+ "}\n";
+
+ ANGLE_GL_COMPUTE_PROGRAM(program, csSource);
+ glUseProgram(program.get());
+ constexpr int kTextureWidth = 4, kTextureHeight = 2;
+ GLuint inputValues[] = {200, 200, 200, 200, 200, 200, 200, 200};
+
+ glBindTexture(GL_TEXTURE_2D, mTexture);
+ glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, kTextureWidth, kTextureHeight);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureWidth, kTextureHeight, GL_RED_INTEGER,
+ GL_UNSIGNED_INT, inputValues);
+ EXPECT_GL_NO_ERROR();
+
+ glBindImageTexture(0, mTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI);
+ glDispatchCompute(1, 1, 1);
+ EXPECT_GL_NO_ERROR();
+
+ glUseProgram(0);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
+
+ glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
+ GLuint outputValues[8];
+ glReadPixels(0, 0, kTextureWidth, kTextureHeight, GL_RED_INTEGER, GL_UNSIGNED_INT,
+ outputValues);
+ EXPECT_GL_NO_ERROR();
+
+ GLuint expectedValue = 100;
+ for (int i = 0; i < kTextureWidth * kTextureHeight; i++)
+ {
+ EXPECT_EQ(expectedValue, outputValues[i]);
+ }
+}
+
// Check that it is not possible to create a compute shader when the context does not support ES
// 3.10
TEST_P(ComputeShaderTestES3, NotSupported)