Skip to content

Commit

Permalink
GL: Reset color mask before clearing textures
Browse files Browse the repository at this point in the history
Some OpenGL drivers may apply last used color
mask state to ClearTexImage operations.

Bug: angleproject:347047859
Change-Id: I0bbf103793857b96e50fae8d6dfafc96b8dfe224
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5854319
Reviewed-by: Geoff Lang <[email protected]>
Commit-Queue: Alexey Knyazev <[email protected]>
  • Loading branch information
lexaknyazev authored and Angle LUCI CQ committed Sep 11, 2024
1 parent 1a5fee1 commit f0919be
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/libANGLE/renderer/gl/TextureGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1499,6 +1499,9 @@ angle::Result TextureGL::clearImage(const gl::Context *context,
nativegl::TexSubImageFormat texSubImageFormat =
nativegl::GetTexSubImageFormat(functions, features, format, type);

// Some drivers may use color mask state when clearing textures.
contextGL->getStateManager()->setColorMask(true, true, true, true);

ANGLE_GL_TRY(context, functions->clearTexImage(mTextureID, level, texSubImageFormat.format,
texSubImageFormat.type, data));

Expand All @@ -1517,6 +1520,9 @@ angle::Result TextureGL::clearSubImage(const gl::Context *context,
const FunctionsGL *functions = GetFunctionsGL(context);
const angle::FeaturesGL &features = GetFeaturesGL(context);

// Some drivers may use color mask state when clearing textures.
contextGL->getStateManager()->setColorMask(true, true, true, true);

nativegl::TexSubImageFormat texSubImageFormat =
nativegl::GetTexSubImageFormat(functions, features, format, type);
ANGLE_GL_TRY(context, functions->clearTexSubImage(
Expand Down
32 changes: 32 additions & 0 deletions src/tests/gl_tests/ClearTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3925,6 +3925,38 @@ TEST_P(ClearTextureEXTTest, Validation)
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}

// Covers a driver bug that leaks color mask state into clear texture ops.
TEST_P(ClearTextureEXTTest, ClearTextureAfterMaskedClearBug)
{
ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));

// Perform a masked clear
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}

// Create a new texture with data, clear it, and sample
{
constexpr uint32_t kSize = 16;
std::vector<unsigned char> pixelData(kSize * kSize * 4, 255);

GLTexture tex;
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
pixelData.data());
glClearTexImageEXT(tex, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
}
}

ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(
ClearTest,
ES3_VULKAN().enable(Feature::ForceFallbackFormat),
Expand Down

0 comments on commit f0919be

Please sign in to comment.