From a1e3abc06b91e04f896b7ec3e63332ccc3ca914e Mon Sep 17 00:00:00 2001 From: Christopher Cameron Date: Fri, 22 Sep 2023 10:14:43 +0200 Subject: [PATCH] Add ES2 support for copying GL_SRGB8_ALPHA8 to GL_RGBA8 Bug: angleproject:7907 Change-Id: I02ae9785ea1f942e85983c18155cfd75ec39b5c2 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4887271 Commit-Queue: ccameron chromium Reviewed-by: Geoff Lang --- src/libANGLE/validationES2.cpp | 1 + .../angle_end2end_tests_expectations.txt | 1 + src/tests/gl_tests/CopyTextureTest.cpp | 135 ++++++++++-------- 3 files changed, 78 insertions(+), 59 deletions(-) diff --git a/src/libANGLE/validationES2.cpp b/src/libANGLE/validationES2.cpp index 1e5dd9c2a..b1282d2eb 100644 --- a/src/libANGLE/validationES2.cpp +++ b/src/libANGLE/validationES2.cpp @@ -84,6 +84,7 @@ bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat) case GL_RGBA8: case GL_BGRA_EXT: case GL_BGRA8_EXT: + case GL_SRGB_ALPHA_EXT: return true; default: diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt index a3b316327..c98be49bd 100644 --- a/src/tests/angle_end2end_tests_expectations.txt +++ b/src/tests/angle_end2end_tests_expectations.txt @@ -1385,6 +1385,7 @@ b/266235549 D3D11 : ComputeShaderTest.SSBOAliasOverWrite/* = SKIP b/292285899 PIXEL4ORXL GLES : EGLSurfaceTest.DestroyAndRecreateWhileCurrent/* = SKIP // Work in progress. +7907 D3D11 : CopyTextureTest.NoConvertSRGBToRGB/ES2_D3D11 = SKIP 7907 D3D11 : CopyTextureTestES3.NoConvertSRGBToRGB/ES3_D3D11 = SKIP // Please do not add expectations below this line, diff --git a/src/tests/gl_tests/CopyTextureTest.cpp b/src/tests/gl_tests/CopyTextureTest.cpp index 323dcc113..7a904a7e4 100644 --- a/src/tests/gl_tests/CopyTextureTest.cpp +++ b/src/tests/gl_tests/CopyTextureTest.cpp @@ -107,6 +107,73 @@ class CopyTextureTest : public ANGLETest<> EXPECT_EQ(expectedUniqueValues[3], uniqueValues[3].size()); } + void testSrgbToRgb(GLenum internalformat, GLenum format) + { + const size_t kTestCount = 4; + const GLColor kSourceColor[kTestCount] = { + GLColor(89, 67, 45, 123), + GLColor(87, 69, 45, 123), + GLColor(180, 143, 93, 123), + GLColor(89, 67, 45, 123), + }; + const GLColor kExpectedColor[kTestCount] = { + GLColor(89, 67, 45, 123), + GLColor(180, 143, 93, 123), + GLColor(87, 69, 45, 123), + GLColor(89, 67, 45, 123), + }; + bool kPremultiply[kTestCount] = {false, false, true, true}; + bool kUnmultiply[kTestCount] = {false, true, false, true}; + + for (size_t test = 0; test < kTestCount; ++test) + { + // Create image as sRGB. + GLTexture sourceTexture; + glBindTexture(GL_TEXTURE_2D, sourceTexture); + glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 1, 1, 0, format, GL_UNSIGNED_BYTE, + &kSourceColor[test]); + ASSERT_GL_NO_ERROR(); + + GLTexture destTexture; + glBindTexture(GL_TEXTURE_2D, destTexture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + ASSERT_GL_NO_ERROR(); + + // Note: flipY is used to avoid direct transfer between textures and force a draw-based + // path. + glCopySubTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, // level, + 0, 0, // src x,y + 0, 0, // dst x,y + 1, 1, // width, height + true, // flip-y + kPremultiply[test], // premul + kUnmultiply[test]); // unmul + ASSERT_GL_NO_ERROR(); + + // Verify the copy. + ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), + essl1_shaders::fs::Texture2D()); + glUseProgram(program); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, destTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + GLint textureLocation = + glGetUniformLocation(program, essl1_shaders::Texture2DUniform()); + ASSERT_NE(-1, textureLocation); + glUniform1i(textureLocation, 0); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f); + ASSERT_GL_NO_ERROR(); + + EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpectedColor[test], 2); + } + } + GLuint mTextures[2] = { 0, 0, @@ -2744,69 +2811,19 @@ TEST_P(CopyTextureTestES3, InvalidateCopyThenBlend) EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::yellow); } +// Test that sRGB-to-RGB copy does not change pixel values. +// http://anglebug.com/7907 +TEST_P(CopyTextureTest, NoConvertSRGBToRGB) +{ + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_sRGB")); + testSrgbToRgb(GL_SRGB_ALPHA_EXT, GL_SRGB_ALPHA_EXT); +} + // Test that sRGB-to-RGB copy does not change pixel values. // http://anglebug.com/7907 TEST_P(CopyTextureTestES3, NoConvertSRGBToRGB) { - const size_t kTestCount = 4; - const GLColor kSourceColor[kTestCount] = { - GLColor(89, 67, 45, 123), - GLColor(87, 69, 45, 123), - GLColor(180, 143, 93, 123), - GLColor(89, 67, 45, 123), - }; - const GLColor kExpectedColor[kTestCount] = { - GLColor(89, 67, 45, 123), - GLColor(180, 143, 93, 123), - GLColor(87, 69, 45, 123), - GLColor(89, 67, 45, 123), - }; - bool kPremultiply[kTestCount] = {false, false, true, true}; - bool kUnmultiply[kTestCount] = {false, true, false, true}; - - for (size_t test = 0; test < kTestCount; ++test) - { - // Create image as sRGB. - GLTexture sourceTexture; - glBindTexture(GL_TEXTURE_2D, sourceTexture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, - &kSourceColor[test]); - - GLTexture destTexture; - glBindTexture(GL_TEXTURE_2D, destTexture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - - // Note: flipY is used to avoid direct transfer between textures and force a draw-based - // path. - glCopySubTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, // level, - 0, 0, // src x,y - 0, 0, // dst x,y - 1, 1, // width, height - true, // flip-y - kPremultiply[test], // premul - kUnmultiply[test]); // unmul - ASSERT_GL_NO_ERROR(); - - // Verify the copy. - ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D()); - glUseProgram(program); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, destTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - GLint textureLocation = glGetUniformLocation(program, essl1_shaders::Texture2DUniform()); - ASSERT_NE(-1, textureLocation); - glUniform1i(textureLocation, 0); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f); - ASSERT_GL_NO_ERROR(); - - EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpectedColor[test], 2); - } + testSrgbToRgb(GL_SRGB8_ALPHA8, GL_RGBA); } void CopyTextureTestES3::invalidateBlitThenBlendCommon(GLsizei layerCount)