Validate that fragment shader output matches the draw buffer type.
TEST=conformance2/rendering/fs-color-type-mismatch-color-buffer-type
BUG=angleproject:1688
Change-Id: I17848baf40b6d32b5adc1458fe2369b850164da3
Reviewed-on: https://chromium-review.googlesource.com/518246
Commit-Queue: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index 71f91fe..d0e87d1 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -2333,6 +2333,98 @@
ASSERT_GL_ERROR(GL_INVALID_OPERATION);
}
+// Verify that errors are generated when the fragment shader output doesn't match the bound color
+// buffer types
+TEST_P(WebGL2CompatibilityTest, FragmentShaderColorBufferTypeMissmatch)
+{
+ const std::string vertexShader =
+ "#version 300 es\n"
+ "void main() {\n"
+ " gl_Position = vec4(0, 0, 0, 1);\n"
+ "}\n";
+
+ const std::string fragmentShader =
+ "#version 300 es\n"
+ "precision mediump float;\n"
+ "layout(location = 0) out vec4 floatOutput;\n"
+ "layout(location = 1) out uvec4 uintOutput;\n"
+ "layout(location = 2) out ivec4 intOutput;\n"
+ "void main() {\n"
+ " floatOutput = vec4(0, 0, 0, 1);\n"
+ " uintOutput = uvec4(0, 0, 0, 1);\n"
+ " intOutput = ivec4(0, 0, 0, 1);\n"
+ "}\n";
+
+ ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
+ glUseProgram(program.get());
+
+ GLuint floatLocation = glGetFragDataLocation(program, "floatOutput");
+ GLuint uintLocation = glGetFragDataLocation(program, "uintOutput");
+ GLuint intLocation = glGetFragDataLocation(program, "intOutput");
+
+ GLFramebuffer fbo;
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+ GLRenderbuffer floatRenderbuffer;
+ glBindRenderbuffer(GL_RENDERBUFFER, floatRenderbuffer);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + floatLocation, GL_RENDERBUFFER,
+ floatRenderbuffer);
+
+ GLRenderbuffer uintRenderbuffer;
+ glBindRenderbuffer(GL_RENDERBUFFER, uintRenderbuffer);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8UI, 1, 1);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + uintLocation, GL_RENDERBUFFER,
+ uintRenderbuffer);
+
+ GLRenderbuffer intRenderbuffer;
+ glBindRenderbuffer(GL_RENDERBUFFER, intRenderbuffer);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8I, 1, 1);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + intLocation, GL_RENDERBUFFER,
+ intRenderbuffer);
+
+ ASSERT_GL_NO_ERROR();
+
+ GLint maxDrawBuffers = 0;
+ glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
+ std::vector<GLenum> drawBuffers(static_cast<size_t>(maxDrawBuffers), GL_NONE);
+ drawBuffers[floatLocation] = GL_COLOR_ATTACHMENT0 + floatLocation;
+ drawBuffers[uintLocation] = GL_COLOR_ATTACHMENT0 + uintLocation;
+ drawBuffers[intLocation] = GL_COLOR_ATTACHMENT0 + intLocation;
+
+ glDrawBuffers(maxDrawBuffers, drawBuffers.data());
+
+ // Check that the correct case generates no errors
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ EXPECT_GL_NO_ERROR();
+
+ // Unbind some buffers and verify that there are still no errors
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + uintLocation, GL_RENDERBUFFER,
+ 0);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + intLocation, GL_RENDERBUFFER,
+ 0);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ EXPECT_GL_NO_ERROR();
+
+ // Swap the int and uint buffers to and verify that an error is generated
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + uintLocation, GL_RENDERBUFFER,
+ intRenderbuffer);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + intLocation, GL_RENDERBUFFER,
+ uintRenderbuffer);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+ // Swap the float and uint buffers to and verify that an error is generated
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + uintLocation, GL_RENDERBUFFER,
+ floatRenderbuffer);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + floatLocation, GL_RENDERBUFFER,
+ uintRenderbuffer);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + intLocation, GL_RENDERBUFFER,
+ intRenderbuffer);
+ glDrawArrays(GL_TRIANGLES, 0, 6);
+ EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+}
+
// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST(WebGLCompatibilityTest,