D3D11: fix invalidation of depth/stencil attachments

This caused a crash when invalidating the depth/stencil attachments of
the default framebuffer. But for non-default framebuffers, discarding
depth/stencil just did nothing because "rtv.valid()" would be false.

Bug: angleproject:8228
Change-Id: Ic22a29f521256af0ed4fc9c203cd6d750fcc00e6
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/4639494
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Commit-Queue: Kenneth Russell <kbr@chromium.org>
Auto-Submit: Steven Noonan <steven@uplinklabs.net>
This commit is contained in:
Steven Noonan
2023-06-23 03:28:14 -07:00
committed by Angle LUCI CQ
parent 179924cbfa
commit 613eefa3a7
2 changed files with 97 additions and 5 deletions

View File

@@ -247,14 +247,26 @@ angle::Result Framebuffer11::invalidateAttachment(const gl::Context *context,
RenderTarget11 *renderTarget = nullptr;
ANGLE_TRY(attachment->getRenderTarget(context, 0, &renderTarget));
const auto &rtv = renderTarget->getRenderTargetView();
if (rtv.valid())
if (attachment->getDepthSize() > 0 || attachment->getStencilSize() > 0)
{
deviceContext1->DiscardView(rtv.get());
const auto &dsv = renderTarget->getDepthStencilView();
if (dsv.valid())
{
deviceContext1->DiscardView(dsv.get());
}
return angle::Result::Continue;
}
else
{
const auto &rtv = renderTarget->getRenderTargetView();
return angle::Result::Continue;
if (rtv.valid())
{
deviceContext1->DiscardView(rtv.get());
}
return angle::Result::Continue;
}
}
angle::Result Framebuffer11::readPixelsImpl(const gl::Context *context,

View File

@@ -479,6 +479,86 @@ TEST_P(FramebufferTest_ES3, SubInvalidatePartial)
EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::red);
}
// Test that invalidating depth/stencil of the default framebuffer doesn't crash.
TEST_P(FramebufferTest_ES3, InvalidateDefaultFramebufferDepthStencil)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
std::array<GLenum, 2> attachments = {GL_DEPTH, GL_STENCIL};
// Invalidate default framebuffer depth/stencil attachments
glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, attachments.data());
EXPECT_GL_NO_ERROR();
}
// Test that invalidating color of the default framebuffer doesn't crash.
TEST_P(FramebufferTest_ES3, InvalidateDefaultFramebufferColor)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
std::array<GLenum, 1> attachments = {GL_COLOR};
// Invalidate default framebuffer color attachment.
glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments.data());
EXPECT_GL_NO_ERROR();
}
// Test that invalidating all attachments on the default framebuffer doesn't crash.
TEST_P(FramebufferTest_ES3, InvalidateDefaultFramebuffer)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
std::array<GLenum, 3> attachments = {GL_COLOR, GL_DEPTH, GL_STENCIL};
// Invalidate all default framebuffer attachments.
glInvalidateFramebuffer(GL_FRAMEBUFFER, 3, attachments.data());
EXPECT_GL_NO_ERROR();
}
// Test that invalidating combined depth/stencil attachment doesn't crash.
TEST_P(FramebufferTest_ES3, InvalidateDepthStencil)
{
// Create the framebuffer that will be invalidated
GLRenderbuffer depthStencil;
glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 2, 2);
GLFramebuffer fbo;
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencil);
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
EXPECT_GL_NO_ERROR();
std::array<GLenum, 2> attachments = {GL_STENCIL_ATTACHMENT, GL_DEPTH_ATTACHMENT};
// Invalidate both depth and stencil.
glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, attachments.data());
EXPECT_GL_NO_ERROR();
}
// Test that invalidating stencil-only attachment doesn't crash.
TEST_P(FramebufferTest_ES3, InvalidateStencilOnly)
{
// Create the framebuffer that will be invalidated
GLRenderbuffer stencil;
glBindRenderbuffer(GL_RENDERBUFFER, stencil);
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 2, 2);
GLFramebuffer fbo;
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil);
ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
EXPECT_GL_NO_ERROR();
std::array<GLenum, 1> attachments = {GL_STENCIL_ATTACHMENT};
// Invalidate both depth and stencil.
glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments.data());
EXPECT_GL_NO_ERROR();
}
// Test that invalidating stencil of a depth-only attachment doesn't crash.
TEST_P(FramebufferTest_ES3, DepthOnlyAttachmentInvalidateStencil)
{