Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit e794ddc

Browse files
Jiawei-ShaoCommit Bot
authored andcommitted
OpenGL: Remove all attachments before executing internal clear
This patch fixes a bug in BlitGL::clearRenderbuffer() by removing all the attachments of mScratchFBO before attaching the real target of clear to keep mScratchFBO always being incomplete. Without this fix, the WebGL CTS tests mentioned in issue 2760 will fail on Intel OpenGL drivers when Chromium is using pass through command buffer because when a multisampled depth renderbuffer is attached to mScratchFBO, mScratchFBO will sometimes become incomplete because it may already have a non-multisampled color attachment. Bug: angleproject:2760 Test: angle_end2end_tests Change-Id: Id206fb4b338545ab46aba118e80d288158dcd8ec Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1612305 Commit-Queue: Jiawei Shao <[email protected]> Reviewed-by: Geoff Lang <[email protected]>
1 parent d268345 commit e794ddc

File tree

2 files changed

+89
-2
lines changed

2 files changed

+89
-2
lines changed

src/libANGLE/renderer/gl/BlitGL.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ using ClearBindTargetVector = angle::FixedVector<GLenum, 3>;
159159
angle::Result PrepareForClear(StateManagerGL *stateManager,
160160
GLenum sizedInternalFormat,
161161
ClearBindTargetVector *outBindtargets,
162+
ClearBindTargetVector *outUnbindTargets,
162163
GLbitfield *outClearMask)
163164
{
164165
const gl::InternalFormat &internalFormatInfo =
@@ -172,14 +173,26 @@ angle::Result PrepareForClear(StateManagerGL *stateManager,
172173
{
173174
outBindtargets->push_back(GL_COLOR_ATTACHMENT0);
174175
}
176+
else
177+
{
178+
outUnbindTargets->push_back(GL_COLOR_ATTACHMENT0);
179+
}
175180
if (bindDepth)
176181
{
177182
outBindtargets->push_back(GL_DEPTH_ATTACHMENT);
178183
}
184+
else
185+
{
186+
outUnbindTargets->push_back(GL_DEPTH_ATTACHMENT);
187+
}
179188
if (bindStencil)
180189
{
181190
outBindtargets->push_back(GL_STENCIL_ATTACHMENT);
182191
}
192+
else
193+
{
194+
outUnbindTargets->push_back(GL_STENCIL_ATTACHMENT);
195+
}
183196

184197
ANGLE_TRY(SetClearState(stateManager, bindColor, bindDepth, bindStencil, outClearMask));
185198

@@ -718,10 +731,13 @@ angle::Result BlitGL::clearRenderableTexture(TextureGL *source,
718731
ANGLE_TRY(initializeResources());
719732

720733
ClearBindTargetVector bindTargets;
734+
ClearBindTargetVector unbindTargets;
721735
GLbitfield clearMask = 0;
722-
ANGLE_TRY(PrepareForClear(mStateManager, sizedInternalFormat, &bindTargets, &clearMask));
736+
ANGLE_TRY(PrepareForClear(mStateManager, sizedInternalFormat, &bindTargets, &unbindTargets,
737+
&clearMask));
723738

724739
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
740+
UnbindAttachments(mFunctions, GL_FRAMEBUFFER, unbindTargets);
725741

726742
if (nativegl::UseTexImage2D(source->getType()))
727743
{
@@ -814,10 +830,14 @@ angle::Result BlitGL::clearRenderbuffer(RenderbufferGL *source, GLenum sizedInte
814830
ANGLE_TRY(initializeResources());
815831

816832
ClearBindTargetVector bindTargets;
833+
ClearBindTargetVector unbindTargets;
817834
GLbitfield clearMask = 0;
818-
ANGLE_TRY(PrepareForClear(mStateManager, sizedInternalFormat, &bindTargets, &clearMask));
835+
ANGLE_TRY(PrepareForClear(mStateManager, sizedInternalFormat, &bindTargets, &unbindTargets,
836+
&clearMask));
819837

820838
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
839+
UnbindAttachments(mFunctions, GL_FRAMEBUFFER, unbindTargets);
840+
821841
for (GLenum bindTarget : bindTargets)
822842
{
823843
mFunctions->framebufferRenderbuffer(GL_FRAMEBUFFER, bindTarget, GL_RENDERBUFFER,

src/tests/gl_tests/RobustResourceInitTest.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1853,6 +1853,73 @@ TEST_P(RobustResourceInitTest, DynamicVertexArrayOffsetOutOfBounds)
18531853
// Either no error or invalid operation is okay.
18541854
}
18551855

1856+
// Test to cover a bug that the multisampled depth attachment of a framebuffer are not successfully
1857+
// initialized before it is used as the read framebuffer in blitFramebuffer.
1858+
// Referenced from the following WebGL CTS:
1859+
// conformance2/renderbuffers/multisampled-depth-renderbuffer-initialization.html
1860+
TEST_P(RobustResourceInitTestES3, InitializeMultisampledDepthRenderbufferAfterCopyTextureCHROMIUM)
1861+
{
1862+
ANGLE_SKIP_TEST_IF(!hasGLExtension());
1863+
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_CHROMIUM_copy_texture"));
1864+
1865+
// Call glCopyTextureCHROMIUM to set destTexture as the color attachment of the internal
1866+
// framebuffer mScratchFBO.
1867+
GLTexture sourceTexture;
1868+
glBindTexture(GL_TEXTURE_2D, sourceTexture);
1869+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1870+
GLTexture destTexture;
1871+
glBindTexture(GL_TEXTURE_2D, destTexture);
1872+
glCopyTextureCHROMIUM(sourceTexture, 0, GL_TEXTURE_2D, destTexture, 0, GL_RGBA,
1873+
GL_UNSIGNED_BYTE, GL_FALSE, GL_FALSE, GL_FALSE);
1874+
ASSERT_GL_NO_ERROR();
1875+
1876+
GLFramebuffer drawFbo;
1877+
glBindFramebuffer(GL_FRAMEBUFFER, drawFbo);
1878+
1879+
GLTexture colorTex;
1880+
glBindTexture(GL_TEXTURE_2D, colorTex);
1881+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1882+
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
1883+
GLRenderbuffer drawDepthRbo;
1884+
glBindRenderbuffer(GL_RENDERBUFFER, drawDepthRbo);
1885+
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, kWidth, kHeight);
1886+
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, drawDepthRbo);
1887+
1888+
// Clear drawDepthRbo to 0.0f
1889+
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1890+
glClearDepthf(0.0f);
1891+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1892+
1893+
constexpr uint32_t kReadDepthRboSampleCount = 4;
1894+
GLFramebuffer readFbo;
1895+
glBindFramebuffer(GL_FRAMEBUFFER, readFbo);
1896+
GLRenderbuffer readDepthRbo;
1897+
glBindRenderbuffer(GL_RENDERBUFFER, readDepthRbo);
1898+
glRenderbufferStorageMultisample(GL_RENDERBUFFER, kReadDepthRboSampleCount,
1899+
GL_DEPTH_COMPONENT16, kWidth, kHeight);
1900+
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, readDepthRbo);
1901+
1902+
glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
1903+
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFbo);
1904+
1905+
// Blit from readDepthRbo to drawDepthRbo. When robust resource init is enabled, readDepthRbo
1906+
// should be initialized to 1.0f by default, so the data in drawDepthRbo should also be 1.0f.
1907+
glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_DEPTH_BUFFER_BIT,
1908+
GL_NEAREST);
1909+
ASSERT_GL_NO_ERROR();
1910+
1911+
glDepthFunc(GL_LESS);
1912+
glEnable(GL_DEPTH_TEST);
1913+
1914+
glBindFramebuffer(GL_FRAMEBUFFER, drawFbo);
1915+
ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
1916+
1917+
// If drawDepthRbo is correctly set to 1.0f, the depth test can always pass, so the result
1918+
// should be green.
1919+
drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f, 1.0f, true);
1920+
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1921+
}
1922+
18561923
ANGLE_INSTANTIATE_TEST(RobustResourceInitTest,
18571924
ES2_D3D9(),
18581925
ES2_D3D11(),

0 commit comments

Comments
 (0)