diff options
Diffstat (limited to 'gfx/angle/src/tests/gl_tests/CopyTexImageTest.cpp')
-rwxr-xr-x | gfx/angle/src/tests/gl_tests/CopyTexImageTest.cpp | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/gfx/angle/src/tests/gl_tests/CopyTexImageTest.cpp b/gfx/angle/src/tests/gl_tests/CopyTexImageTest.cpp new file mode 100755 index 000000000..b3b74261b --- /dev/null +++ b/gfx/angle/src/tests/gl_tests/CopyTexImageTest.cpp @@ -0,0 +1,343 @@ +// +// 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. +// + +#include "test_utils/ANGLETest.h" + +namespace angle +{ + +class CopyTexImageTest : public ANGLETest +{ + protected: + CopyTexImageTest() + { + setWindowWidth(16); + setWindowHeight(16); + setConfigRedBits(8); + setConfigGreenBits(8); + setConfigBlueBits(8); + setConfigAlphaBits(8); + } + + GLuint createFramebuffer(GLenum format, GLenum type, GLfloat color[4]) const + { + GLuint fbo; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + GLuint texture = createTexture(format, type); + glBindTexture(GL_TEXTURE_2D, texture); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); + + glClearColor(color[0], color[1], color[2], color[3]); + glClear(GL_COLOR_BUFFER_BIT); + + return fbo; + } + + GLuint createTexture(GLenum format, GLenum type) const + { + GLuint tex; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + glTexImage2D(GL_TEXTURE_2D, 0, format, 16, 16, 0, format, type, nullptr); + + // Disable mipmapping + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + return tex; + } + + GLuint createTextureFromCopyTexImage(GLuint fbo, GLenum format) const + { + GLuint tex; + glGenTextures(1, &tex); + glBindTexture(GL_TEXTURE_2D, tex); + + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, 16, 16, 0); + + // Disable mipmapping + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + return tex; + } + + void copyTextureWithCopyTexSubImage(GLuint fbo, + GLuint texture, + GLint xoffset, + GLint yoffset, + GLint x, + GLint y, + GLsizei w, + GLsizei h) const + { + glBindTexture(GL_TEXTURE_2D, texture); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, x, y, w, h); + } + + void SetUp() override + { + ANGLETest::SetUp(); + + const std::string vsSource = + "precision highp float;\n" + "attribute vec4 position;\n" + "varying vec2 texcoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = position;\n" + " texcoord = (position.xy * 0.5) + 0.5;\n" + " texcoord.y = 1.0 - texcoord.y;\n" + "}\n"; + + const std::string textureFSSource = + "precision highp float;\n" + "uniform sampler2D tex;\n" + "varying vec2 texcoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_FragColor = texture2D(tex, texcoord);\n" + "}\n"; + + mTextureProgram = CompileProgram(vsSource, textureFSSource); + if (mTextureProgram == 0) + { + FAIL() << "shader compilation failed."; + } + + mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex"); + + ASSERT_GL_NO_ERROR(); + } + + void TearDown() override + { + glDeleteProgram(mTextureProgram); + + ANGLETest::TearDown(); + } + + void verifyResults(GLuint texture, GLubyte data[4], GLint x, GLint y) + { + glViewport(0, 0, 16, 16); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + // Draw a quad with the target texture + glUseProgram(mTextureProgram); + glBindTexture(GL_TEXTURE_2D, texture); + glUniform1i(mTextureUniformLocation, 0); + + drawQuad(mTextureProgram, "position", 0.5f); + + // Expect that the rendered quad has the same color as the source texture + EXPECT_PIXEL_NEAR(x, y, data[0], data[1], data[2], data[3], 1.0); + } + + GLuint mTextureProgram; + GLint mTextureUniformLocation; +}; + +TEST_P(CopyTexImageTest, RGBAToL) +{ + GLfloat color[] = { + 0.25f, 1.0f, 0.75f, 0.5f, + }; + + GLuint fbo = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color); + GLuint tex = createTextureFromCopyTexImage(fbo, GL_LUMINANCE); + + GLubyte expected[] = { + 64, 64, 64, 255, + }; + verifyResults(tex, expected, 0, 0); +} + +TEST_P(CopyTexImageTest, RGBToL) +{ + // TODO (geofflang): Figure out why CopyTex[Sub]Image doesn't work with + // RGB->L on older Intel chips + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + + GLfloat color[] = { + 0.25f, 1.0f, 0.75f, 0.5f, + }; + + GLuint fbo = createFramebuffer(GL_RGB, GL_UNSIGNED_BYTE, color); + GLuint tex = createTextureFromCopyTexImage(fbo, GL_LUMINANCE); + + GLubyte expected[] = { + 64, 64, 64, 255, + }; + verifyResults(tex, expected, 0, 0); +} + +TEST_P(CopyTexImageTest, RGBAToLA) +{ + GLfloat color[] = { + 0.25f, 1.0f, 0.75f, 0.5f, + }; + + GLuint fbo = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color); + GLuint tex = createTextureFromCopyTexImage(fbo, GL_LUMINANCE_ALPHA); + + GLubyte expected[] = { + 64, 64, 64, 127, + }; + verifyResults(tex, expected, 0, 0); +} + +TEST_P(CopyTexImageTest, RGBAToA) +{ + GLfloat color[] = { + 0.25f, 1.0f, 0.75f, 0.5f, + }; + + GLuint fbo = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color); + GLuint tex = createTextureFromCopyTexImage(fbo, GL_ALPHA); + + GLubyte expected[] = { + 0, 0, 0, 127, + }; + verifyResults(tex, expected, 0, 0); +} + +TEST_P(CopyTexImageTest, SubImageRGBAToL) +{ + GLfloat color0[] = { + 0.25f, 1.0f, 0.75f, 0.5f, + }; + GLuint fbo0 = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color0); + GLuint tex = createTextureFromCopyTexImage(fbo0, GL_LUMINANCE); + + GLfloat color1[] = { + 0.5f, 0.25f, 1.0f, 0.75f, + }; + GLuint fbo1 = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color1); + copyTextureWithCopyTexSubImage(fbo1, tex, 2, 4, 5, 6, 8, 8); + + GLubyte expected0[] = { + 64, 64, 64, 255, + }; + verifyResults(tex, expected0, 0, 0); + + GLubyte expected1[] = { + 127, 127, 127, 255, + }; + verifyResults(tex, expected1, 7, 7); +} + +TEST_P(CopyTexImageTest, SubImageRGBAToLA) +{ + GLfloat color0[] = { + 0.25f, 1.0f, 0.75f, 0.5f, + }; + GLuint fbo0 = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color0); + GLuint tex = createTextureFromCopyTexImage(fbo0, GL_LUMINANCE_ALPHA); + + GLfloat color1[] = { + 0.5f, 0.25f, 1.0f, 0.75f, + }; + GLuint fbo1 = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color1); + copyTextureWithCopyTexSubImage(fbo1, tex, 2, 4, 5, 6, 8, 8); + + GLubyte expected0[] = { + 64, 64, 64, 127, + }; + verifyResults(tex, expected0, 0, 0); + + GLubyte expected1[] = { + 127, 127, 127, 192, + }; + verifyResults(tex, expected1, 7, 7); +} + +TEST_P(CopyTexImageTest, SubImageRGBToL) +{ + // TODO (geofflang): Figure out why CopyTex[Sub]Image doesn't work with + // RGB->L on older Intel chips + if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE) + { + std::cout << "Test skipped on Intel OpenGL." << std::endl; + return; + } + + GLfloat color0[] = { + 0.25f, 1.0f, 0.75f, 0.5f, + }; + GLuint fbo0 = createFramebuffer(GL_RGB, GL_UNSIGNED_BYTE, color0); + GLuint tex = createTextureFromCopyTexImage(fbo0, GL_LUMINANCE); + + GLfloat color1[] = { + 0.5f, 0.25f, 1.0f, 0.75f, + }; + GLuint fbo1 = createFramebuffer(GL_RGB, GL_UNSIGNED_BYTE, color1); + copyTextureWithCopyTexSubImage(fbo1, tex, 2, 4, 5, 6, 8, 8); + + GLubyte expected0[] = { + 64, 64, 64, 255, + }; + verifyResults(tex, expected0, 0, 0); + + GLubyte expected1[] = { + 127, 127, 127, 255, + }; + verifyResults(tex, expected1, 7, 7); +} + +// specialization of CopyTexImageTest is added so that some tests can be explicitly run with an ES3 +// context +class CopyTexImageTestES3 : public CopyTexImageTest +{ +}; + +// The test verifies that glCopyTexSubImage2D generates a GL_INVALID_OPERATION error +// when the read buffer is GL_NONE. +// Reference: GLES 3.0.4, Section 3.8.5 Alternate Texture Image Specification Commands +TEST_P(CopyTexImageTestES3, ReadBufferIsNone) +{ + GLfloat color[] = { + 0.25f, 1.0f, 0.75f, 0.5f, + }; + + GLuint fbo = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color); + GLuint tex = createTextureFromCopyTexImage(fbo, GL_RGBA); + + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glBindTexture(GL_TEXTURE_2D, tex); + + glReadBuffer(GL_NONE); + + EXPECT_GL_NO_ERROR(); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 4, 4); + EXPECT_GL_ERROR(GL_INVALID_OPERATION); + + glDeleteFramebuffers(1, &fbo); + glDeleteTextures(1, &tex); +} + +// Use this to select which configurations (e.g. which renderer, which GLES major version) these +// tests should be run against. +ANGLE_INSTANTIATE_TEST(CopyTexImageTest, + ES2_D3D9(), + ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE), + ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE), + ES2_OPENGL(), + ES2_OPENGL(3, 3), + ES2_OPENGLES()); + +ANGLE_INSTANTIATE_TEST(CopyTexImageTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES()); +} |