summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/tests/gl_tests/FramebufferTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/tests/gl_tests/FramebufferTest.cpp')
-rwxr-xr-xgfx/angle/src/tests/gl_tests/FramebufferTest.cpp379
1 files changed, 379 insertions, 0 deletions
diff --git a/gfx/angle/src/tests/gl_tests/FramebufferTest.cpp b/gfx/angle/src/tests/gl_tests/FramebufferTest.cpp
new file mode 100755
index 000000000..430ca8400
--- /dev/null
+++ b/gfx/angle/src/tests/gl_tests/FramebufferTest.cpp
@@ -0,0 +1,379 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Framebuffer tests:
+// Various tests related for Frambuffers.
+//
+
+#include "test_utils/ANGLETest.h"
+
+using namespace angle;
+
+class FramebufferFormatsTest : public ANGLETest
+{
+ protected:
+ FramebufferFormatsTest() : mFramebuffer(0), mTexture(0), mRenderbuffer(0), mProgram(0)
+ {
+ setWindowWidth(128);
+ setWindowHeight(128);
+ setConfigRedBits(8);
+ setConfigGreenBits(8);
+ setConfigBlueBits(8);
+ setConfigAlphaBits(8);
+ }
+
+ void checkBitCount(GLuint fbo, GLenum channel, GLint minBits)
+ {
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+ GLint bits = 0;
+ glGetIntegerv(channel, &bits);
+
+ if (minBits == 0)
+ {
+ EXPECT_EQ(minBits, bits);
+ }
+ else
+ {
+ EXPECT_GE(bits, minBits);
+ }
+ }
+
+ void testBitCounts(GLuint fbo,
+ GLint minRedBits,
+ GLint minGreenBits,
+ GLint minBlueBits,
+ GLint minAlphaBits,
+ GLint minDepthBits,
+ GLint minStencilBits)
+ {
+ checkBitCount(fbo, GL_RED_BITS, minRedBits);
+ checkBitCount(fbo, GL_GREEN_BITS, minGreenBits);
+ checkBitCount(fbo, GL_BLUE_BITS, minBlueBits);
+ checkBitCount(fbo, GL_ALPHA_BITS, minAlphaBits);
+ checkBitCount(fbo, GL_DEPTH_BITS, minDepthBits);
+ checkBitCount(fbo, GL_STENCIL_BITS, minStencilBits);
+ }
+
+ void testTextureFormat(GLenum internalFormat,
+ GLint minRedBits,
+ GLint minGreenBits,
+ GLint minBlueBits,
+ GLint minAlphaBits)
+ {
+ glGenTextures(1, &mTexture);
+ glBindTexture(GL_TEXTURE_2D, mTexture);
+ glTexStorage2DEXT(GL_TEXTURE_2D, 1, internalFormat, 1, 1);
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
+
+ testBitCounts(mFramebuffer, minRedBits, minGreenBits, minBlueBits, minAlphaBits, 0, 0);
+ }
+
+ void testRenderbufferMultisampleFormat(int minESVersion,
+ GLenum attachmentType,
+ GLenum internalFormat)
+ {
+ // TODO(geofflang): Figure out why this is broken on Intel OpenGL
+ if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
+ {
+ std::cout << "Test skipped on Intel OpenGL." << std::endl;
+ return;
+ }
+
+ int clientVersion = getClientMajorVersion();
+ if (clientVersion < minESVersion)
+ {
+ return;
+ }
+
+ // Check that multisample is supported with at least two samples (minimum required is 1)
+ bool supports2Samples = false;
+
+ if (clientVersion == 2)
+ {
+ if (extensionEnabled("ANGLE_framebuffer_multisample"))
+ {
+ int maxSamples;
+ glGetIntegerv(GL_MAX_SAMPLES_ANGLE, &maxSamples);
+ supports2Samples = maxSamples >= 2;
+ }
+ }
+ else
+ {
+ assert(clientVersion >= 3);
+ int maxSamples;
+ glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
+ supports2Samples = maxSamples >= 2;
+ }
+
+ if (!supports2Samples)
+ {
+ return;
+ }
+
+ glGenRenderbuffers(1, &mRenderbuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
+
+ EXPECT_GL_NO_ERROR();
+ glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 2, internalFormat, 128, 128);
+ EXPECT_GL_NO_ERROR();
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachmentType, GL_RENDERBUFFER, mRenderbuffer);
+ EXPECT_GL_NO_ERROR();
+ }
+
+ void testZeroHeightRenderbuffer()
+ {
+ glGenRenderbuffers(1, &mRenderbuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 0);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
+ mRenderbuffer);
+ EXPECT_GL_NO_ERROR();
+ }
+
+ void SetUp() override
+ {
+ ANGLETest::SetUp();
+
+ glGenFramebuffers(1, &mFramebuffer);
+ glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
+ }
+
+ void TearDown() override
+ {
+ ANGLETest::TearDown();
+
+ if (mTexture != 0)
+ {
+ glDeleteTextures(1, &mTexture);
+ mTexture = 0;
+ }
+
+ if (mRenderbuffer != 0)
+ {
+ glDeleteRenderbuffers(1, &mRenderbuffer);
+ mRenderbuffer = 0;
+ }
+
+ if (mFramebuffer != 0)
+ {
+ glDeleteFramebuffers(1, &mFramebuffer);
+ mFramebuffer = 0;
+ }
+
+ if (mProgram != 0)
+ {
+ glDeleteProgram(mProgram);
+ mProgram = 0;
+ }
+ }
+
+ GLuint mFramebuffer;
+ GLuint mTexture;
+ GLuint mRenderbuffer;
+ GLuint mProgram;
+};
+
+TEST_P(FramebufferFormatsTest, RGBA4)
+{
+ testTextureFormat(GL_RGBA4, 4, 4, 4, 4);
+}
+
+TEST_P(FramebufferFormatsTest, RGB565)
+{
+ testTextureFormat(GL_RGB565, 5, 6, 5, 0);
+}
+
+TEST_P(FramebufferFormatsTest, RGB8)
+{
+ if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_rgb8_rgba8"))
+ {
+ std::cout << "Test skipped due to missing ES3 or GL_OES_rgb8_rgba8." << std::endl;
+ return;
+ }
+
+ testTextureFormat(GL_RGB8_OES, 8, 8, 8, 0);
+}
+
+TEST_P(FramebufferFormatsTest, BGRA8)
+{
+ if (!extensionEnabled("GL_EXT_texture_format_BGRA8888"))
+ {
+ std::cout << "Test skipped due to missing GL_EXT_texture_format_BGRA8888." << std::endl;
+ return;
+ }
+
+ testTextureFormat(GL_BGRA8_EXT, 8, 8, 8, 8);
+}
+
+TEST_P(FramebufferFormatsTest, RGBA8)
+{
+ if (getClientMajorVersion() < 3 && !extensionEnabled("GL_OES_rgb8_rgba8"))
+ {
+ std::cout << "Test skipped due to missing ES3 or GL_OES_rgb8_rgba8." << std::endl;
+ return;
+ }
+
+ testTextureFormat(GL_RGBA8_OES, 8, 8, 8, 8);
+}
+
+TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH16)
+{
+ testRenderbufferMultisampleFormat(2, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT16);
+}
+
+TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH24)
+{
+ testRenderbufferMultisampleFormat(3, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24);
+}
+
+TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH32F)
+{
+ if (getClientMajorVersion() < 3)
+ {
+ std::cout << "Test skipped due to missing ES3." << std::endl;
+ return;
+ }
+
+ testRenderbufferMultisampleFormat(3, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT32F);
+}
+
+TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH24_STENCIL8)
+{
+ testRenderbufferMultisampleFormat(3, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH24_STENCIL8);
+}
+
+TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH32F_STENCIL8)
+{
+ if (getClientMajorVersion() < 3)
+ {
+ std::cout << "Test skipped due to missing ES3." << std::endl;
+ return;
+ }
+
+ testRenderbufferMultisampleFormat(3, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH32F_STENCIL8);
+}
+
+TEST_P(FramebufferFormatsTest, RenderbufferMultisample_STENCIL_INDEX8)
+{
+ // TODO(geofflang): Figure out how to support GLSTENCIL_INDEX8 on desktop GL
+ if (GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
+ {
+ std::cout << "Test skipped on Desktop OpenGL." << std::endl;
+ return;
+ }
+
+ testRenderbufferMultisampleFormat(2, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8);
+}
+
+// Test that binding an incomplete cube map is rejected by ANGLE.
+TEST_P(FramebufferFormatsTest, IncompleteCubeMap)
+{
+ // First make a complete CubeMap.
+ glGenTextures(1, &mTexture);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture);
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
+ mTexture, 0);
+
+ // Verify the framebuffer is complete.
+ ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+ // Make the CubeMap cube-incomplete.
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ nullptr);
+
+ // Verify the framebuffer is incomplete.
+ ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
+ glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+ // Verify drawing with the incomplete framebuffer produces a GL error
+ const std::string &vs = "attribute vec4 position; void main() { gl_Position = position; }";
+ const std::string &ps = "void main() { gl_FragColor = vec4(1, 0, 0, 1); }";
+ mProgram = CompileProgram(vs, ps);
+ ASSERT_NE(0u, mProgram);
+ drawQuad(mProgram, "position", 0.5f);
+ ASSERT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
+}
+
+// Test that a renderbuffer with zero height but nonzero width is handled without crashes/asserts.
+TEST_P(FramebufferFormatsTest, ZeroHeightRenderbuffer)
+{
+ if (getClientMajorVersion() < 3)
+ {
+ std::cout << "Test skipped due to missing ES3" << std::endl;
+ return;
+ }
+
+ testZeroHeightRenderbuffer();
+}
+
+// Use this to select which configurations (e.g. which renderer, which GLES major version) these
+// tests should be run against.
+ANGLE_INSTANTIATE_TEST(FramebufferFormatsTest,
+ ES2_D3D9(),
+ ES2_D3D11(),
+ ES3_D3D11(),
+ ES2_OPENGL(),
+ ES3_OPENGL(),
+ ES2_OPENGLES(),
+ ES3_OPENGLES());
+
+class FramebufferInvalidateTest : public ANGLETest
+{
+ protected:
+ FramebufferInvalidateTest() : mFramebuffer(0), mRenderbuffer(0) {}
+
+ void SetUp() override
+ {
+ ANGLETest::SetUp();
+
+ glGenFramebuffers(1, &mFramebuffer);
+ glGenRenderbuffers(1, &mRenderbuffer);
+ }
+
+ void TearDown() override
+ {
+ glDeleteFramebuffers(1, &mFramebuffer);
+ glDeleteRenderbuffers(1, &mRenderbuffer);
+ ANGLETest::TearDown();
+ }
+
+ GLuint mFramebuffer;
+ GLuint mRenderbuffer;
+};
+
+// Covers invalidating an incomplete framebuffer. This should be a no-op, but should not error.
+TEST_P(FramebufferInvalidateTest, Incomplete)
+{
+ glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mRenderbuffer);
+ EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
+ glCheckFramebufferStatus(GL_FRAMEBUFFER));
+
+ std::vector<GLenum> attachments;
+ attachments.push_back(GL_COLOR_ATTACHMENT0);
+
+ glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments.data());
+ EXPECT_GL_NO_ERROR();
+}
+
+ANGLE_INSTANTIATE_TEST(FramebufferInvalidateTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());