Handle Clear* commands for side-by-side framebuffers
Clear* commands for side-by-side framebuffers require special handling
because only the scissor rectangle of the first viewport is used in the
scissor test as defined in the OpenGL 4.1+ specs.
To enable clearing of each view of a side-by-side framebuffer all views
are iterated over, the corresponding scissor rectangle is set as first,
and a Clear* call is made to the driver. Afterwards the scissor state is
restored.
BUG=angleproject:2062
TEST=angle_end2end_tests
Change-Id: I138663ea61b4f0c9302872108e7dfbadf451b3ec
Reviewed-on: https://chromium-review.googlesource.com/590233
Commit-Queue: Martin Radev <mradev@nvidia.com>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/tests/gl_tests/FramebufferMultiviewTest.cpp b/src/tests/gl_tests/FramebufferMultiviewTest.cpp
index f6c4a90..d65705a 100644
--- a/src/tests/gl_tests/FramebufferMultiviewTest.cpp
+++ b/src/tests/gl_tests/FramebufferMultiviewTest.cpp
@@ -14,15 +14,24 @@
namespace
{
-GLuint CreateTexture2D(GLenum internalFormat, GLenum format, GLenum type)
+GLuint CreateTexture2D(GLenum internalFormat,
+ GLenum format,
+ GLenum type,
+ GLsizei width,
+ GLsizei height)
{
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
- glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, nullptr);
+ glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, nullptr);
return tex;
}
+GLuint CreateTexture2D(GLenum internalFormat, GLenum format, GLenum type)
+{
+ return CreateTexture2D(internalFormat, format, type, 1, 1);
+}
+
} // namespace
class FramebufferMultiviewTest : public ANGLETest
@@ -481,4 +490,56 @@
EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
}
+// Test that glClear clears only the contents of each view.
+TEST_P(FramebufferMultiviewTest, SideBySideClear)
+{
+ if (!requestMultiviewExtension())
+ {
+ return;
+ }
+
+ mTexture2D = CreateTexture2D(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, 4, 2);
+ const GLint viewportOffsets[4] = {1, 0, 3, 0};
+ glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture2D,
+ 0, 2, &viewportOffsets[0]);
+
+ // Create and bind a normal framebuffer to access the 2D texture.
+ GLuint fbo;
+ glGenFramebuffers(1, &fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture2D, 0);
+
+ // Clear the contents of the texture.
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ // Bind and specify viewport/scissor dimensions for each view.
+ glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
+ glViewport(0, 0, 1, 2);
+ glScissor(0, 0, 1, 2);
+
+ glClearColor(1, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+ // column 0
+ EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 0);
+ EXPECT_PIXEL_EQ(0, 1, 0, 0, 0, 0);
+
+ // column 1
+ EXPECT_PIXEL_EQ(1, 0, 255, 0, 0, 0);
+ EXPECT_PIXEL_EQ(1, 1, 255, 0, 0, 0);
+
+ // column 2
+ EXPECT_PIXEL_EQ(2, 0, 0, 0, 0, 0);
+ EXPECT_PIXEL_EQ(2, 1, 0, 0, 0, 0);
+
+ // column 3
+ EXPECT_PIXEL_EQ(3, 0, 255, 0, 0, 0);
+ EXPECT_PIXEL_EQ(3, 1, 255, 0, 0, 0);
+
+ glDeleteFramebuffers(1, &fbo);
+}
+
ANGLE_INSTANTIATE_TEST(FramebufferMultiviewTest, ES3_OPENGL());
\ No newline at end of file