// Test that unmultipying and premultiplying the alpha is the same as doing neither TEST_P(CopyTextureTest, UnmultiplyAndPremultplyAlpha) { if (!checkExtensions()) { return; } GLColor rgbaPixels[4] = {GLColor(255u, 255u, 255u, 255u), GLColor(127u, 127u, 127u, 127u), GLColor(63u, 63u, 63u, 127u), GLColor(255u, 255u, 255u, 0u)}; glBindTexture(GL_TEXTURE_2D, mTextures[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels); glCopyTextureCHROMIUM(mTextures[0], mTextures[1], GL_RGBA, GL_UNSIGNED_BYTE, GL_FALSE, GL_TRUE, GL_TRUE); EXPECT_GL_NO_ERROR(); // Check that FB is complete. EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(255, 255, 255, 255), 1.0); EXPECT_PIXEL_COLOR_NEAR(1, 0, GLColor(127, 127, 127, 127), 1.0); EXPECT_PIXEL_COLOR_NEAR(0, 1, GLColor(63, 63, 63, 127), 1.0); EXPECT_PIXEL_COLOR_NEAR(1, 1, GLColor(255, 255, 255, 0), 1.0); EXPECT_GL_NO_ERROR(); }
// Test that using an offset in CopySubTexture works correctly TEST_P(CopyTextureTest, CopySubTextureOffset) { if (!checkExtensions()) { return; } GLColor rgbaPixels[4 * 4] = {GLColor::red, GLColor::green, GLColor::blue, GLColor::black}; glBindTexture(GL_TEXTURE_2D, mTextures[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbaPixels); GLColor transparentPixels[4 * 4] = {GLColor::transparentBlack, GLColor::transparentBlack, GLColor::transparentBlack, GLColor::transparentBlack}; glBindTexture(GL_TEXTURE_2D, mTextures[1]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, transparentPixels); glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 1, 1, 0, 0, 1, 1, false, false, false); EXPECT_GL_NO_ERROR(); glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 1, 0, 1, 0, 1, 1, false, false, false); EXPECT_GL_NO_ERROR(); glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 0, 1, 0, 1, 1, 1, false, false, false); EXPECT_GL_NO_ERROR(); // Check that FB is complete. EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack); EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red); EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::green); EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor::blue); EXPECT_GL_NO_ERROR(); }
// Verify that GL_BIND_GENERATES_RESOURCE_CHROMIUM can be queried but not changed TEST_P(BindGeneratesResourceTest, QueryValidation) { GLint intValue = 2; glGetIntegerv(GL_BIND_GENERATES_RESOURCE_CHROMIUM, &intValue); EXPECT_GL_NO_ERROR(); EXPECT_GL_FALSE(intValue); float floatValue = 2.0f; glGetFloatv(GL_BIND_GENERATES_RESOURCE_CHROMIUM, &floatValue); EXPECT_GL_NO_ERROR(); EXPECT_EQ(floatValue, 0.0f); GLboolean boolValue = GL_TRUE; glGetBooleanv(GL_BIND_GENERATES_RESOURCE_CHROMIUM, &boolValue); EXPECT_GL_NO_ERROR(); EXPECT_GL_FALSE(boolValue); boolValue = glIsEnabled(GL_BIND_GENERATES_RESOURCE_CHROMIUM); EXPECT_GL_NO_ERROR(); EXPECT_GL_FALSE(boolValue); glEnable(GL_BIND_GENERATES_RESOURCE_CHROMIUM); EXPECT_GL_ERROR(GL_INVALID_ENUM); glDisable(GL_BIND_GENERATES_RESOURCE_CHROMIUM); EXPECT_GL_ERROR(GL_INVALID_ENUM); }
virtual void SetUp() { ANGLETest::SetUp(); glGenTextures(1, &mTexture2D); glGenTextures(1, &mTextureCube); glBindTexture(GL_TEXTURE_2D, mTexture2D); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); EXPECT_GL_NO_ERROR(); glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureCube); glTexStorage2DEXT(GL_TEXTURE_CUBE_MAP, 1, GL_RGBA8, 1, 1); EXPECT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR(); const std::string vertexShaderSource = SHADER_SOURCE ( precision highp float; attribute vec4 position; varying vec2 texcoord; uniform vec2 textureScale; void main() { gl_Position = vec4(position.xy * textureScale, 0.0, 1.0); texcoord = (position.xy * 0.5) + 0.5; }
TEST_F(SRGBTextureTest, srgba_validation) { bool supported = extensionEnabled("GL_EXT_sRGB") || getClientVersion() == 3; GLuint tex = 0; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); GLubyte pixel[4] = { 0 }; glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, pixel); if (supported) { EXPECT_GL_NO_ERROR(); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, pixel); EXPECT_GL_NO_ERROR(); glGenerateMipmap(GL_TEXTURE_2D); if (getClientVersion() == 2) { EXPECT_GL_ERROR(GL_INVALID_OPERATION); } else { EXPECT_GL_NO_ERROR(); } } else { EXPECT_GL_ERROR(GL_INVALID_ENUM); } glDeleteTextures(1, &tex); }
// Test to ensure that the basic functionality of the extension works. TEST_P(CopyTextureTest, BasicCopySubTexture) { if (!checkExtensions()) { return; } GLColor pixels = GLColor::red; glBindTexture(GL_TEXTURE_2D, mTextures[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels); glBindTexture(GL_TEXTURE_2D, mTextures[1]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 0, 0, 0, 0, 1, 1, false, false, false); EXPECT_GL_NO_ERROR(); // Check that FB is complete. EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); EXPECT_PIXEL_COLOR_EQ(0, 0, pixels); EXPECT_GL_NO_ERROR(); }
GLColor16 ReadColor16(GLint x, GLint y) { GLColor16 actual; glReadPixels((x), (y), 1, 1, GL_RGBA, GL_UNSIGNED_SHORT, &actual.R); EXPECT_GL_NO_ERROR(); return actual; }
void checkPixel(GLint x, GLint y, GLboolean renderedRed) { // By default, expect the pixel to be black. GLint expectedRedChannel = 0; GLint expectedGreenChannel = 0; GLint scissorSize[4]; glGetIntegerv(GL_SCISSOR_BOX, scissorSize); EXPECT_GL_NO_ERROR(); if (scissorSize[0] <= x && x < scissorSize[0] + scissorSize[2] && scissorSize[1] <= y && y < scissorSize[1] + scissorSize[3]) { // If the pixel lies within the scissor rect, then it should have been cleared to green. // If we rendered a red square on top of it, then the pixel should be red (the green channel will have been reset to 0). expectedRedChannel = renderedRed ? 255 : 0; expectedGreenChannel = renderedRed ? 0 : 255; } // If the pixel is within the bounds of the window, then we check it. Otherwise we skip it. if (0 <= x && x < getWindowWidth() && 0 <= y && y < getWindowHeight()) { EXPECT_PIXEL_EQ(x, y, expectedRedChannel, expectedGreenChannel, 0, 255); } }
// Test that invalid IDs in CopySubTexture are validated TEST_P(CopyTextureTest, CopySubTextureInvalidTextureIds) { if (!checkExtensions()) { return; } glBindTexture(GL_TEXTURE_2D, mTextures[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glBindTexture(GL_TEXTURE_2D, mTextures[1]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glCopySubTextureCHROMIUM(mTextures[0], 99993, 1, 1, 0, 0, 1, 1, false, false, false); EXPECT_GL_ERROR(GL_INVALID_VALUE); glCopySubTextureCHROMIUM(99994, mTextures[1], 1, 1, 0, 0, 1, 1, false, false, false); EXPECT_GL_ERROR(GL_INVALID_VALUE); glCopySubTextureCHROMIUM(99995, 99996, 1, 1, 0, 0, 1, 1, false, false, false); EXPECT_GL_ERROR(GL_INVALID_VALUE); glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 1, 1, 0, 0, 1, 1, false, false, false); EXPECT_GL_NO_ERROR(); }
// Test validation of texture IDs TEST_P(CopyCompressedTextureTest, InvalidTextureIds) { if (!checkExtensions()) { return; } glBindTexture(GL_TEXTURE_2D, mTextures[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0, sizeof(CompressedImageDXT1), CompressedImageDXT1); ASSERT_GL_NO_ERROR(); glBindTexture(GL_TEXTURE_2D, mTextures[1]); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); ASSERT_GL_NO_ERROR(); glCompressedCopyTextureCHROMIUM(mTextures[0], 99993); EXPECT_GL_ERROR(GL_INVALID_VALUE); glCompressedCopyTextureCHROMIUM(99994, mTextures[1]); EXPECT_GL_ERROR(GL_INVALID_VALUE); glCompressedCopyTextureCHROMIUM(99995, 99996); EXPECT_GL_ERROR(GL_INVALID_VALUE); glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]); EXPECT_GL_NO_ERROR(); }
// Test that invalid dimensions in CopySubTexture are validated TEST_P(CopyTextureTest, CopySubTextureDimension) { if (!checkExtensions()) { return; } glBindTexture(GL_TEXTURE_2D, mTextures[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glBindTexture(GL_TEXTURE_2D, mTextures[1]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 1, 1, 0, 0, 1, 1, false, false, false); EXPECT_GL_NO_ERROR(); // xoffset < 0 glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], -1, 1, 0, 0, 1, 1, false, false, false); EXPECT_GL_ERROR(GL_INVALID_VALUE); // x < 0 glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 1, 1, -1, 0, 1, 1, false, false, false); EXPECT_GL_ERROR(GL_INVALID_VALUE); // xoffset + width > dest_width glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 2, 2, 0, 0, 2, 2, false, false, false); EXPECT_GL_ERROR(GL_INVALID_VALUE); // x + width > source_width glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 0, 0, 1, 1, 2, 2, false, false, false); EXPECT_GL_ERROR(GL_INVALID_VALUE); }
GLColor ReadColor(GLint x, GLint y) { GLColor actual; glReadPixels((x), (y), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &actual.R); EXPECT_GL_NO_ERROR(); return actual; }
// Test that textures cannot be generated on bind TEST_P(BindGeneratesResourceTest, Textures) { glBindTexture(GL_TEXTURE_2D, 2); EXPECT_GL_ERROR(GL_INVALID_OPERATION); glBindTexture(GL_TEXTURE_2D, 0); EXPECT_GL_NO_ERROR(); }
// Test that framebuffers cannot be generated on bind TEST_P(BindGeneratesResourceTest, Framebuffers) { glBindFramebuffer(GL_FRAMEBUFFER, 2); EXPECT_GL_ERROR(GL_INVALID_OPERATION); glBindFramebuffer(GL_FRAMEBUFFER, 0); EXPECT_GL_NO_ERROR(); }
// Test that renderbuffer cannot be generated on bind TEST_P(BindGeneratesResourceTest, Renderbuffers) { glBindRenderbuffer(GL_RENDERBUFFER, 2); EXPECT_GL_ERROR(GL_INVALID_OPERATION); glBindRenderbuffer(GL_RENDERBUFFER, 0); EXPECT_GL_NO_ERROR(); }
// Test creating a pbuffer from a multisampled d3d surface and drawing with a program. TEST_P(D3DTextureTestMS, DrawProgram) { EGLWindow *window = getEGLWindow(); EGLDisplay display = window->getDisplay(); constexpr size_t bufferSize = 32; EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_NO_TEXTURE, EGL_NO_TEXTURE, 4, static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN)); ASSERT_EGL_SUCCESS(); ASSERT_NE(pbuffer, EGL_NO_SURFACE); // Apply the Pbuffer and clear it to magenta eglMakeCurrent(display, pbuffer, pbuffer, window->getContext()); ASSERT_EGL_SUCCESS(); glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize)); glClearColor(1.0f, 0.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); ASSERT_GL_NO_ERROR(); constexpr GLint testPoint = bufferSize / 2; EXPECT_PIXEL_COLOR_EQ(testPoint, testPoint, GLColor::magenta); // Apply the window surface eglMakeCurrent(display, window->getSurface(), window->getSurface(), window->getContext()); ASSERT_EGL_SUCCESS(); glViewport(0, 0, getWindowWidth(), getWindowHeight()); ASSERT_EGL_SUCCESS(); // Draw a quad and verify that it is magenta glUseProgram(mTextureProgramNoSampling); EXPECT_GL_NO_ERROR(); drawQuad(mTextureProgramNoSampling, "position", 0.5f); EXPECT_GL_NO_ERROR(); // Verify that magenta was drawn EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::magenta); // Make current with fixture EGL to ensure the Surface can be released immediately. getEGLWindow()->makeCurrent(); eglDestroySurface(display, pbuffer); }
TEST_F(SRGBTextureTest, srgba_renderbuffer) { bool supported = extensionEnabled("GL_EXT_sRGB") || getClientVersion() == 3; GLuint rbo = 0; glGenRenderbuffers(1, &rbo); glBindRenderbuffer(GL_RENDERBUFFER, rbo); glRenderbufferStorage(GL_RENDERBUFFER, GL_SRGB8_ALPHA8_EXT, 1, 1); if (supported) { EXPECT_GL_NO_ERROR(); } else { EXPECT_GL_ERROR(GL_INVALID_ENUM); // Make sure the rbo has a size for future tests glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, 1, 1); EXPECT_GL_NO_ERROR(); } GLuint fbo = 0; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo); EXPECT_GL_NO_ERROR(); GLint colorEncoding = 0; glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT, &colorEncoding); if (supported) { EXPECT_GL_NO_ERROR(); EXPECT_EQ(GL_SRGB_EXT, colorEncoding); } else { EXPECT_GL_ERROR(GL_INVALID_ENUM); } glDeleteFramebuffers(1, &fbo); glDeleteRenderbuffers(1, &rbo); }
// Test that CopyTexture cannot redefine an immutable texture and CopySubTexture can copy data to // immutable textures TEST_P(CopyTextureTest, ImmutableTexture) { if (!checkExtensions()) { return; } if (getClientMajorVersion() < 3 && (!extensionEnabled("GL_EXT_texture_storage") || !extensionEnabled("GL_OES_rgb8_rgba8"))) { std::cout << "Test skipped due to missing ES3 or GL_EXT_texture_storage or GL_OES_rgb8_rgba8" << std::endl; return; } GLColor pixels = GLColor::red; glBindTexture(GL_TEXTURE_2D, mTextures[0]); glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 1, 1); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixels); glBindTexture(GL_TEXTURE_2D, mTextures[1]); glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, 1, 1); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], 0); EXPECT_GL_NO_ERROR(); // Should generate an error when the texture is redefined glCopyTextureCHROMIUM(mTextures[0], mTextures[1], GL_RGBA, GL_UNSIGNED_BYTE, false, false, false); EXPECT_GL_ERROR(GL_INVALID_OPERATION); // Should succeed when using CopySubTexture glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 0, 0, 0, 0, 1, 1, false, false, false); EXPECT_GL_NO_ERROR(); // Check that FB is complete. EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); EXPECT_PIXEL_COLOR_EQ(0, 0, pixels); EXPECT_GL_NO_ERROR(); }
// Test to ensure that the destination texture is redefined if the properties are different. TEST_P(CopyTextureTest, RedefineDestinationTexture) { if (!checkExtensions()) { return; } GLColor pixels[4] = {GLColor::red, GLColor::red, GLColor::red, GLColor::red}; glBindTexture(GL_TEXTURE_2D, mTextures[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); glBindTexture(GL_TEXTURE_2D, mTextures[1]); glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, 1, 1, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels); EXPECT_GL_NO_ERROR(); // GL_INVALID_OPERATION due to "intrinsic format" != "internal format". glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels); EXPECT_GL_ERROR(GL_INVALID_OPERATION); // GL_INVALID_VALUE due to bad dimensions. glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels); EXPECT_GL_ERROR(GL_INVALID_VALUE); // If the dest texture has different properties, glCopyTextureCHROMIUM() // redefines them. glCopyTextureCHROMIUM(mTextures[0], mTextures[1], GL_RGBA, GL_UNSIGNED_BYTE, false, false, false); EXPECT_GL_NO_ERROR(); // glTexSubImage2D() succeeds because mTextures[1] is redefined into 2x2 // dimension and GL_RGBA format. glBindTexture(GL_TEXTURE_2D, mTextures[1]); glTexSubImage2D(GL_TEXTURE_2D, 0, 1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels); EXPECT_GL_NO_ERROR(); // Check that FB is complete. EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER)); EXPECT_PIXEL_COLOR_EQ(1, 1, pixels[3]); EXPECT_GL_NO_ERROR(); }
bool checkRenderbufferFormatSupport(GLenum internalFormat) { EXPECT_GL_NO_ERROR(); GLuint rb = 0; glGenRenderbuffers(1, &rb); glBindRenderbuffer(GL_RENDERBUFFER, rb); glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, 1, 1); glDeleteRenderbuffers(1, &rb); return (glGetError() == GL_NO_ERROR); }
bool checkTexStorageFormatSupport(GLenum internalFormat) { EXPECT_GL_NO_ERROR(); GLuint tex = 0; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexStorage2DEXT(GL_TEXTURE_2D, 1, internalFormat, 1, 1); glDeleteTextures(1, &tex); return (glGetError() == GL_NO_ERROR); }
bool checkTexImageFormatSupport(GLenum format, GLenum type) { EXPECT_GL_NO_ERROR(); GLuint tex = 0; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, type, NULL); glDeleteTextures(1, &tex); return (glGetError() == GL_NO_ERROR); }
// Read default framebuffer with glCopyTexSubImage2D(). TEST_P(CopyTexImageTest, SubDefaultFramebuffer) { // Seems to be a bug in Mesa with the GLX back end: cannot read framebuffer until we draw to it. // glCopyTexSubImage2D() below will fail without this clear. glClear(GL_COLOR_BUFFER_BIT); const GLint w = getWindowWidth(), h = getWindowHeight(); GLTexture tex; glBindTexture(GL_TEXTURE_2D, tex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, w, h); EXPECT_GL_NO_ERROR(); }
// Test that buffers cannot be generated on bind TEST_P(BindGeneratesResourceTest, Buffers) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 2); EXPECT_GL_ERROR(GL_INVALID_OPERATION); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); EXPECT_GL_NO_ERROR(); if (getClientMajorVersion() >= 3) { glBindBufferBase(GL_UNIFORM_BUFFER, 0, 3); EXPECT_GL_ERROR(GL_INVALID_OPERATION); glBindBufferBase(GL_UNIFORM_BUFFER, 0, 0); EXPECT_GL_NO_ERROR(); glBindBufferRange(GL_UNIFORM_BUFFER, 0, 4, 1, 2); EXPECT_GL_ERROR(GL_INVALID_OPERATION); glBindBufferRange(GL_UNIFORM_BUFFER, 0, 0, 1, 2); EXPECT_GL_NO_ERROR(); } }
void runTest() { // Firstly ensure that no errors have been hit. EXPECT_GL_NO_ERROR(); GLint viewportSize[4]; glGetIntegerv(GL_VIEWPORT, viewportSize); // Clear to green. Might be a scissored clear, if scissorSize != window size glClearColor(0, 1, 0, 1); glClear(GL_COLOR_BUFFER_BIT); // Draw a red quad centered in the middle of the viewport, with dimensions 25% of the size of the viewport. drawQuad(mProgram, "position", 0.5f, 0.25f); GLint centerViewportX = viewportSize[0] + (viewportSize[2] / 2); GLint centerViewportY = viewportSize[1] + (viewportSize[3] / 2); GLint redQuadLeftSideX = viewportSize[0] + viewportSize[2] * 3 / 8; GLint redQuadRightSideX = viewportSize[0] + viewportSize[2] * 5 / 8; GLint redQuadTopSideY = viewportSize[1] + viewportSize[3] * 3 / 8; GLint redQuadBottomSideY = viewportSize[1] + viewportSize[3] * 5 / 8; // The midpoint of the viewport should be red. checkPixel(centerViewportX, centerViewportY, true); // Pixels just inside the red quad should be red. checkPixel(redQuadLeftSideX, redQuadTopSideY, true); checkPixel(redQuadLeftSideX, redQuadBottomSideY - 1, true); checkPixel(redQuadRightSideX - 1, redQuadTopSideY, true); checkPixel(redQuadRightSideX - 1, redQuadBottomSideY - 1, true); // Pixels just outside the red quad shouldn't be red. checkPixel(redQuadLeftSideX - 1, redQuadTopSideY - 1, false); checkPixel(redQuadLeftSideX - 1, redQuadBottomSideY, false); checkPixel(redQuadRightSideX, redQuadTopSideY - 1, false); checkPixel(redQuadRightSideX, redQuadBottomSideY, false); // Pixels just within the viewport shouldn't be red. checkPixel(viewportSize[0], viewportSize[1], false); checkPixel(viewportSize[0], viewportSize[1] + viewportSize[3] - 1, false); checkPixel(viewportSize[0] + viewportSize[2] - 1, viewportSize[1], false); checkPixel(viewportSize[0] + viewportSize[2] - 1, viewportSize[1] + viewportSize[3] - 1, false); }
// Test to ensure that the basic functionality of the extension works. TEST_P(CopyTextureTest, BasicCopyTexture) { if (!checkExtensions()) { return; } GLColor pixels = GLColor::red; glBindTexture(GL_TEXTURE_2D, mTextures[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels); glCopyTextureCHROMIUM(mTextures[0], mTextures[1], GL_RGBA, GL_UNSIGNED_BYTE, false, false, false); EXPECT_GL_NO_ERROR(); EXPECT_PIXEL_COLOR_EQ(0, 0, pixels); }
// 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); }
// Check that invalid internal formats return errors. TEST_P(CopyTextureTest, InternalFormatNotSupported) { if (!checkExtensions()) { return; } glBindTexture(GL_TEXTURE_2D, mTextures[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); EXPECT_GL_NO_ERROR(); std::vector<GLint> unsupportedDestFormats; unsupportedDestFormats.push_back(GL_ALPHA); unsupportedDestFormats.push_back(GL_LUMINANCE); unsupportedDestFormats.push_back(GL_LUMINANCE_ALPHA); if (!extensionEnabled("GL_EXT_texture_format_BGRA8888")) { unsupportedDestFormats.push_back(GL_BGRA_EXT); } // Check unsupported format reports an error. for (GLint unsupportedDestFormat : unsupportedDestFormats) { glCopyTextureCHROMIUM(mTextures[0], mTextures[1], unsupportedDestFormat, GL_UNSIGNED_BYTE, false, false, false); EXPECT_GL_ERROR(GL_INVALID_OPERATION); } for (GLint unsupportedDestFormat : unsupportedDestFormats) { glBindTexture(GL_TEXTURE_2D, mTextures[1]); glTexImage2D(GL_TEXTURE_2D, 0, unsupportedDestFormat, 1, 1, 0, unsupportedDestFormat, GL_UNSIGNED_BYTE, nullptr); glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 0, 0, 0, 0, 1, 1, false, false, false); EXPECT_GL_ERROR(GL_INVALID_OPERATION); } }
// Test creating a pbuffer from a d3d surface and binding it to a texture TEST_P(D3DTextureTest, BindTexImage) { if (!valid()) { return; } EGLWindow *window = getEGLWindow(); EGLDisplay display = window->getDisplay(); const size_t bufferSize = 32; EGLSurface pbuffer = createPBuffer(bufferSize, bufferSize, EGL_TEXTURE_RGBA, EGL_TEXTURE_2D, 1, 0); ASSERT_EGL_SUCCESS(); ASSERT_NE(pbuffer, EGL_NO_SURFACE); // Apply the Pbuffer and clear it to purple eglMakeCurrent(display, pbuffer, pbuffer, window->getContext()); ASSERT_EGL_SUCCESS(); glViewport(0, 0, static_cast<GLsizei>(bufferSize), static_cast<GLsizei>(bufferSize)); glClearColor(1.0f, 0.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); ASSERT_GL_NO_ERROR(); EXPECT_PIXEL_EQ(static_cast<GLint>(bufferSize) / 2, static_cast<GLint>(bufferSize) / 2, 255, 0, 255, 255); // Apply the window surface eglMakeCurrent(display, window->getSurface(), window->getSurface(), window->getContext()); // Create a texture and bind the Pbuffer to it GLuint texture = 0; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); EXPECT_GL_NO_ERROR(); eglBindTexImage(display, pbuffer, EGL_BACK_BUFFER); glViewport(0, 0, getWindowWidth(), getWindowHeight()); ASSERT_EGL_SUCCESS(); // Draw a quad and verify that it is purple glUseProgram(mTextureProgram); glUniform1i(mTextureUniformLocation, 0); drawQuad(mTextureProgram, "position", 0.5f); EXPECT_GL_NO_ERROR(); // Unbind the texture eglReleaseTexImage(display, pbuffer, EGL_BACK_BUFFER); ASSERT_EGL_SUCCESS(); // Verify that purple was drawn EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 255, 255); glDeleteTextures(1, &texture); // Make current with fixture EGL to ensure the Surface can be released immediately. getEGLWindow()->makeCurrent(); eglDestroySurface(display, pbuffer); }
// Test validation of internal formats in CopyTexture and CopySubTexture TEST_P(CopyTextureTest, InternalFormat) { if (!checkExtensions()) { return; } std::vector<GLint> sourceFormats; sourceFormats.push_back(GL_ALPHA); sourceFormats.push_back(GL_RGB); sourceFormats.push_back(GL_RGBA); sourceFormats.push_back(GL_LUMINANCE); sourceFormats.push_back(GL_LUMINANCE_ALPHA); std::vector<GLint> destFormats; destFormats.push_back(GL_RGB); destFormats.push_back(GL_RGBA); if (extensionEnabled("GL_EXT_texture_format_BGRA8888")) { sourceFormats.push_back(GL_BGRA_EXT); destFormats.push_back(GL_BGRA_EXT); } // Test with glCopyTexture for (GLint sourceFormat : sourceFormats) { for (GLint destFormat : destFormats) { glBindTexture(GL_TEXTURE_2D, mTextures[0]); glTexImage2D(GL_TEXTURE_2D, 0, sourceFormat, 1, 1, 0, sourceFormat, GL_UNSIGNED_BYTE, nullptr); EXPECT_GL_NO_ERROR(); glCopyTextureCHROMIUM(mTextures[0], mTextures[1], destFormat, GL_UNSIGNED_BYTE, false, false, false); EXPECT_GL_NO_ERROR(); } } // Test with glCopySubTexture for (GLint sourceFormat : sourceFormats) { for (GLint destFormat : destFormats) { glBindTexture(GL_TEXTURE_2D, mTextures[0]); glTexImage2D(GL_TEXTURE_2D, 0, sourceFormat, 1, 1, 0, sourceFormat, GL_UNSIGNED_BYTE, nullptr); EXPECT_GL_NO_ERROR(); glBindTexture(GL_TEXTURE_2D, mTextures[1]); glTexImage2D(GL_TEXTURE_2D, 0, destFormat, 1, 1, 0, destFormat, GL_UNSIGNED_BYTE, nullptr); EXPECT_GL_NO_ERROR(); glCopySubTextureCHROMIUM(mTextures[0], mTextures[1], 0, 0, 0, 0, 1, 1, false, false, false); EXPECT_GL_NO_ERROR(); } } }