зеркало из https://github.com/AvaloniaUI/angle.git
Fix invalidation of GL_FRAMEBUFFER invalidating READ FBO
Per spec, GL_FRAMEBUFFER means GL_DRAW_FRAMEBUFFER for glInvalidateFramebuffer. Bug: chromium:1267424 Change-Id: I8c9ab61ecdbd4ccee4262dc8559b2feb02b4837c Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3266176 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
This commit is contained in:
Родитель
517ff22004
Коммит
91d3647325
|
@ -4144,8 +4144,14 @@ ANGLE_INLINE angle::Result Context::prepareForDispatch()
|
|||
|
||||
angle::Result Context::prepareForInvalidate(GLenum target)
|
||||
{
|
||||
// Only sync the FBO that's being invalidated
|
||||
ANGLE_TRY(mState.syncDirtyObject(this, target));
|
||||
// Only sync the FBO that's being invalidated. Per the GLES3 spec, GL_FRAMEBUFFER is equivalent
|
||||
// to GL_DRAW_FRAMEBUFFER for the purposes of invalidation.
|
||||
GLenum effectiveTarget = target;
|
||||
if (effectiveTarget == GL_FRAMEBUFFER)
|
||||
{
|
||||
effectiveTarget = GL_DRAW_FRAMEBUFFER;
|
||||
}
|
||||
ANGLE_TRY(mState.syncDirtyObject(this, effectiveTarget));
|
||||
return syncDirtyBits(mInvalidateDirtyBits, Command::Invalidate);
|
||||
}
|
||||
|
||||
|
@ -4790,13 +4796,9 @@ void Context::readBuffer(GLenum mode)
|
|||
|
||||
void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
|
||||
{
|
||||
Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
|
||||
ASSERT(framebuffer);
|
||||
|
||||
// The specification isn't clear what should be done when the framebuffer isn't complete.
|
||||
// We leave it up to the framebuffer implementation to decide what to do.
|
||||
ANGLE_CONTEXT_TRY(prepareForInvalidate(target));
|
||||
ANGLE_CONTEXT_TRY(framebuffer->discard(this, numAttachments, attachments));
|
||||
// We threat it the same way as GLES3 glInvalidateFramebuffer.
|
||||
invalidateFramebuffer(target, numAttachments, attachments);
|
||||
}
|
||||
|
||||
void Context::invalidateFramebuffer(GLenum target,
|
||||
|
|
|
@ -744,6 +744,42 @@ TEST_P(FramebufferTest_ES3, AttachmentWith3DLayers)
|
|||
EXPECT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
// Check that invalid layer is detected in framebuffer completeness check.
|
||||
TEST_P(FramebufferTest_ES3, 3DAttachmentInvalidLayer)
|
||||
{
|
||||
GLTexture tex;
|
||||
glBindTexture(GL_TEXTURE_3D, tex);
|
||||
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 4, 4, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
|
||||
GLFramebuffer framebuffer;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 2);
|
||||
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
|
||||
glCheckFramebufferStatus(GL_FRAMEBUFFER));
|
||||
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 1);
|
||||
EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
|
||||
EXPECT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
// Check that invalid layer is detected in framebuffer completeness check.
|
||||
TEST_P(FramebufferTest_ES3, 2DArrayInvalidLayer)
|
||||
{
|
||||
GLTexture tex;
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 4, 4, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
|
||||
GLFramebuffer framebuffer;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 2);
|
||||
EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
|
||||
glCheckFramebufferStatus(GL_FRAMEBUFFER));
|
||||
|
||||
glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 1);
|
||||
EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
|
||||
EXPECT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
// Test that clearing the stencil buffer when the framebuffer only has a color attachment does not
|
||||
// crash.
|
||||
TEST_P(FramebufferTest_ES3, ClearNonexistentStencil)
|
||||
|
|
|
@ -7208,6 +7208,27 @@ TEST_P(SimpleStateChangeTestES3, ClearColorInvalidateDepthClearColor)
|
|||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
ASSERT_GL_NO_ERROR();
|
||||
}
|
||||
|
||||
// Regression test for a bug where glInvalidateFramebuffer(GL_FRAMEBUFFER, ...) was invalidating
|
||||
// both the draw and read framebuffers.
|
||||
TEST_P(SimpleStateChangeTestES3, InvalidateFramebufferShouldntInvalidateReadFramebuffer)
|
||||
{
|
||||
// Create an invalid read framebuffer.
|
||||
GLFramebuffer fbo;
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
|
||||
|
||||
GLTexture tex;
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
|
||||
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_R8, 1, 1, 1);
|
||||
glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, tex, 0, 5);
|
||||
|
||||
// Invalidate using GL_FRAMEBUFFER. If GL_READ_FRAMEBUFFER was used, validation would fail due
|
||||
// to the framebuffer not being complete. A bug here was attempting to invalidate the read
|
||||
// framebuffer given GL_FRAMEBUFFER anyway.
|
||||
constexpr std::array<GLenum, 2> kAttachments = {GL_DEPTH, GL_STENCIL};
|
||||
glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, kAttachments.data());
|
||||
EXPECT_GL_NO_ERROR();
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
ANGLE_INSTANTIATE_TEST_ES2(StateChangeTest);
|
||||
|
|
Загрузка…
Ссылка в новой задаче