Fix BlitFramebuffer validation for BGRA sources and targets.
It is legal to blit between GL_RGBA8 and GL_BGRA8 sources and
destinations when resolving multisampled renderbuffers. Expand
BlitFramebuffer's validation to handle this case.
Query GL_MAX_VERTEX_OUTPUT_COMPONENTS on the Core Profile to work
around an error generated on macOS when querying
GL_MAX_VARYING_COMPONENTS.
Expand the BlitFramebuffer tests to cover these cases and start
running them on the OpenGL backend.
Fix detectition of multisampled D3D11 rendertargets when the sample count
is 1.
BUG=angleproject:891
Change-Id: Ief5531756651caa66f612e647d3d5c05c8c51ff5
Reviewed-on: https://chromium-review.googlesource.com/587459
Reviewed-by: Kenneth Russell <kbr@chromium.org>
diff --git a/src/tests/gl_tests/BlitFramebufferANGLETest.cpp b/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
index c2d7d44..31e91cd 100644
--- a/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
+++ b/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
@@ -52,7 +52,11 @@
mRGBAColorbuffer = 0;
mRGBAFBO = 0;
+ mRGBAMultisampledRenderbuffer = 0;
+ mRGBAMultisampledFBO = 0;
+ mBGRAColorbuffer = 0;
+ mBGRAFBO = 0;
mBGRAMultisampledRenderbuffer = 0;
mBGRAMultisampledFBO = 0;
}
@@ -205,9 +209,10 @@
ASSERT_GL_NO_ERROR();
}
- if (extensionEnabled("GL_ANGLE_framebuffer_multisample"))
+ if (extensionEnabled("GL_ANGLE_framebuffer_multisample") &&
+ extensionEnabled("GL_OES_rgb8_rgba8"))
{
- // Test blit between RGBA and multisampled BGRA
+ // RGBA single-sampled framebuffer
glGenTextures(1, &mRGBAColorbuffer);
glBindTexture(GL_TEXTURE_2D, mRGBAColorbuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
@@ -220,16 +225,50 @@
ASSERT_GL_NO_ERROR();
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
- glGenRenderbuffers(1, &mBGRAMultisampledRenderbuffer);
- glBindRenderbuffer(GL_RENDERBUFFER, mBGRAMultisampledRenderbuffer);
- glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 1, GL_BGRA8_EXT, getWindowWidth(), getWindowHeight());
+ // RGBA multisampled framebuffer
+ glGenRenderbuffers(1, &mRGBAMultisampledRenderbuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, mRGBAMultisampledRenderbuffer);
+ glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 1, GL_RGBA8, getWindowWidth(),
+ getWindowHeight());
- glGenFramebuffers(1, &mBGRAMultisampledFBO);
- glBindFramebuffer(GL_FRAMEBUFFER, mBGRAMultisampledFBO);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mBGRAMultisampledRenderbuffer);
+ glGenFramebuffers(1, &mRGBAMultisampledFBO);
+ glBindFramebuffer(GL_FRAMEBUFFER, mRGBAMultisampledFBO);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
+ mRGBAMultisampledRenderbuffer);
ASSERT_GL_NO_ERROR();
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+ if (extensionEnabled("GL_EXT_texture_format_BGRA8888"))
+ {
+ // BGRA single-sampled framebuffer
+ glGenTextures(1, &mBGRAColorbuffer);
+ glBindTexture(GL_TEXTURE_2D, mBGRAColorbuffer);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, getWindowWidth(), getWindowHeight(), 0,
+ GL_BGRA_EXT, GL_UNSIGNED_BYTE, nullptr);
+
+ glGenFramebuffers(1, &mBGRAFBO);
+ glBindFramebuffer(GL_FRAMEBUFFER, mBGRAFBO);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ mBGRAColorbuffer, 0);
+
+ ASSERT_GL_NO_ERROR();
+ ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+ // BGRA multisampled framebuffer
+ glGenRenderbuffers(1, &mBGRAMultisampledRenderbuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, mBGRAMultisampledRenderbuffer);
+ glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 1, GL_BGRA8_EXT,
+ getWindowWidth(), getWindowHeight());
+
+ glGenFramebuffers(1, &mBGRAMultisampledFBO);
+ glBindFramebuffer(GL_FRAMEBUFFER, mBGRAMultisampledFBO);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
+ mBGRAMultisampledRenderbuffer);
+
+ ASSERT_GL_NO_ERROR();
+ ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+ }
}
glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
@@ -271,7 +310,27 @@
if (mRGBAFBO != 0)
{
- glDeleteFramebuffers(1, &mBGRAMultisampledFBO);
+ glDeleteFramebuffers(1, &mRGBAFBO);
+ }
+
+ if (mRGBAMultisampledRenderbuffer != 0)
+ {
+ glDeleteRenderbuffers(1, &mRGBAMultisampledRenderbuffer);
+ }
+
+ if (mRGBAMultisampledFBO != 0)
+ {
+ glDeleteFramebuffers(1, &mRGBAMultisampledFBO);
+ }
+
+ if (mBGRAColorbuffer != 0)
+ {
+ glDeleteTextures(1, &mBGRAColorbuffer);
+ }
+
+ if (mBGRAFBO != 0)
+ {
+ glDeleteFramebuffers(1, &mBGRAFBO);
}
if (mBGRAMultisampledRenderbuffer != 0)
@@ -287,6 +346,37 @@
ANGLETest::TearDown();
}
+ void multisampleTestHelper(GLuint readFramebuffer, GLuint drawFramebuffer)
+ {
+ glClearColor(0.0, 1.0, 0.0, 1.0);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, readFramebuffer);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ EXPECT_GL_NO_ERROR();
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, readFramebuffer);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFramebuffer);
+ glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
+ getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ EXPECT_GL_NO_ERROR();
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFramebuffer);
+ EXPECT_PIXEL_EQ(getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
+ EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
+ EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
+ EXPECT_PIXEL_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
+ }
+
+ bool checkExtension(const std::string &extension)
+ {
+ if (!extensionEnabled(extension))
+ {
+ std::cout << "Test skipped because " << extension << " not supported." << std::endl;
+ return false;
+ }
+
+ return true;
+ }
+
GLuint mCheckerProgram;
GLuint mBlueProgram;
@@ -315,7 +405,11 @@
GLuint mRGBAColorbuffer;
GLuint mRGBAFBO;
+ GLuint mRGBAMultisampledRenderbuffer;
+ GLuint mRGBAMultisampledFBO;
+ GLuint mBGRAColorbuffer;
+ GLuint mBGRAFBO;
GLuint mBGRAMultisampledRenderbuffer;
GLuint mBGRAMultisampledFBO;
};
@@ -824,6 +918,60 @@
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, mMRTColorBuffer1, 0);
}
+// Test multisampled framebuffer blits if supported
+TEST_P(BlitFramebufferANGLETest, MultisampledRGBAToRGBA)
+{
+ if (!checkExtension("GL_ANGLE_framebuffer_multisample"))
+ return;
+
+ if (!checkExtension("GL_OES_rgb8_rgba8"))
+ return;
+
+ multisampleTestHelper(mRGBAMultisampledFBO, mRGBAFBO);
+}
+
+TEST_P(BlitFramebufferANGLETest, MultisampledRGBAToBGRA)
+{
+ if (!checkExtension("GL_ANGLE_framebuffer_multisample"))
+ return;
+
+ if (!checkExtension("GL_OES_rgb8_rgba8"))
+ return;
+
+ if (!checkExtension("GL_EXT_texture_format_BGRA8888"))
+ return;
+
+ multisampleTestHelper(mRGBAMultisampledFBO, mBGRAFBO);
+}
+
+TEST_P(BlitFramebufferANGLETest, MultisampledBGRAToRGBA)
+{
+ if (!checkExtension("GL_ANGLE_framebuffer_multisample"))
+ return;
+
+ if (!checkExtension("GL_OES_rgb8_rgba8"))
+ return;
+
+ if (!checkExtension("GL_EXT_texture_format_BGRA8888"))
+ return;
+
+ multisampleTestHelper(mBGRAMultisampledFBO, mRGBAFBO);
+}
+
+TEST_P(BlitFramebufferANGLETest, MultisampledBGRAToBGRA)
+{
+ if (!checkExtension("GL_ANGLE_framebuffer_multisample"))
+ return;
+
+ if (!checkExtension("GL_OES_rgb8_rgba8"))
+ return;
+
+ if (!checkExtension("GL_EXT_texture_format_BGRA8888"))
+ return;
+
+ multisampleTestHelper(mBGRAMultisampledFBO, mBGRAFBO);
+}
+
// Make sure that attempts to stretch in a blit call issue an error
TEST_P(BlitFramebufferANGLETest, ErrorStretching)
{
@@ -888,18 +1036,6 @@
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
GL_COLOR_BUFFER_BIT, GL_NEAREST);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
-
- if (extensionEnabled("GL_ANGLE_framebuffer_multisample"))
- {
- glBindFramebuffer(GL_READ_FRAMEBUFFER, mBGRAMultisampledFBO);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mRGBAFBO);
- EXPECT_GL_NO_ERROR();
-
- glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
- GL_COLOR_BUFFER_BIT, GL_NEAREST);
- EXPECT_GL_ERROR(GL_INVALID_OPERATION);
- }
-
}
// TODO(geofflang): Fix the dependence on glBlitFramebufferANGLE without checks and assuming the
@@ -1070,6 +1206,8 @@
ANGLE_INSTANTIATE_TEST(BlitFramebufferANGLETest,
ES2_D3D9(),
ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE),
- ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE));
+ ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE),
+ ES2_OPENGL(),
+ ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(BlitFramebufferTest, ES3_D3D11());