Commit 8170eab7 by Geoff Lang Committed by Commit Bot

D3D: Implement robust resource init for Surfaces.

BUG=angleproject:2107 BUG=angleproject:2317 Change-Id: I22260e1093dc6c09e4627c62a95ca4088c99e951 Reviewed-on: https://chromium-review.googlesource.com/678480 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 26403533
......@@ -1736,11 +1736,9 @@ void Framebuffer::setAttachmentImpl(const Context *context,
break;
case GL_BACK:
mState.mColorAttachments[0].attach(context, type, binding, textureIndex, resource,
numViews, baseViewIndex, multiviewLayout,
viewportOffsets);
mDirtyBits.set(DIRTY_BIT_COLOR_ATTACHMENT_0);
// No need for a resource binding for the default FBO, it's always complete.
updateAttachment(context, &mState.mColorAttachments[0], DIRTY_BIT_COLOR_ATTACHMENT_0,
&mDirtyColorAttachmentBindings[0], type, binding, textureIndex,
resource, numViews, baseViewIndex, multiviewLayout, viewportOffsets);
break;
default:
......@@ -1805,8 +1803,13 @@ void Framebuffer::syncState(const Context *context)
void Framebuffer::signal(size_t dirtyBit, InitState state)
{
// TOOD(jmadill): Make this only update individual attachments to do less work.
mCachedStatus.reset();
// Only reset the cached status if this is not the default framebuffer. The default framebuffer
// will still use this channel to mark itself dirty.
if (mId != 0)
{
// TOOD(jmadill): Make this only update individual attachments to do less work.
mCachedStatus.reset();
}
// Mark the appropriate init flag.
mState.mResourceNeedsInit.set(dirtyBit, state == InitState::MayNeedInit);
......
......@@ -62,7 +62,8 @@ Surface::Surface(EGLint surfaceType,
mOrientation(0),
mTexture(),
mColorFormat(config->renderTargetFormat),
mDSFormat(config->depthStencilFormat)
mDSFormat(config->depthStencilFormat),
mInitState(gl::InitState::Initialized)
{
mPostSubBufferRequested = (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE);
mFlexibleSurfaceCompatibilityRequested =
......@@ -84,6 +85,10 @@ Surface::Surface(EGLint surfaceType,
mRobustResourceInitialization =
(attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
if (mRobustResourceInitialization)
{
mInitState = gl::InitState::MayNeedInit;
}
mFixedSize = (attributes.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE);
if (mFixedSize)
......@@ -146,6 +151,15 @@ Error Surface::destroyImpl(const Display *display)
return NoError();
}
void Surface::postSwap()
{
if (mRobustResourceInitialization && mSwapBehavior != EGL_BUFFER_PRESERVED)
{
mInitState = gl::InitState::MayNeedInit;
mDirtyChannel.signal(mInitState);
}
}
Error Surface::initialize(const Display *display)
{
ANGLE_TRY(mImplementation->initialize(display));
......@@ -216,12 +230,16 @@ EGLint Surface::getType() const
Error Surface::swap(const gl::Context *context)
{
return mImplementation->swap(context);
ANGLE_TRY(mImplementation->swap(context));
postSwap();
return NoError();
}
Error Surface::swapWithDamage(const gl::Context *context, EGLint *rects, EGLint n_rects)
{
return mImplementation->swapWithDamage(context, rects, n_rects);
ANGLE_TRY(mImplementation->swapWithDamage(context, rects, n_rects));
postSwap();
return NoError();
}
Error Surface::postSubBuffer(const gl::Context *context,
......@@ -435,13 +453,12 @@ gl::Framebuffer *Surface::createDefaultFramebuffer(const Display *display)
gl::InitState Surface::initState(const gl::ImageIndex & /*imageIndex*/) const
{
// TODO(jmadill): Lazy surface init.
return gl::InitState::Initialized;
return mInitState;
}
void Surface::setInitState(const gl::ImageIndex & /*imageIndex*/, gl::InitState /*initState*/)
void Surface::setInitState(const gl::ImageIndex & /*imageIndex*/, gl::InitState initState)
{
// No-op.
mInitState = initState;
}
WindowSurface::WindowSurface(rx::EGLImplFactory *implFactory,
......
......@@ -186,6 +186,10 @@ class Surface : public gl::FramebufferAttachmentObject
private:
Error destroyImpl(const Display *display);
void postSwap();
gl::InitState mInitState;
};
class WindowSurface final : public Surface
......
......@@ -413,6 +413,20 @@ gl::Error SurfaceD3D::getAttachmentRenderTarget(const gl::Context *context,
return gl::NoError();
}
gl::Error SurfaceD3D::initializeContents(const gl::Context * /*context*/,
const gl::ImageIndex & /*imageIndex*/)
{
if (mState.config->renderTargetFormat != GL_NONE)
{
ANGLE_TRY(mRenderer->initRenderTarget(mSwapChain->getColorRenderTarget()));
}
if (mState.config->depthStencilFormat != GL_NONE)
{
ANGLE_TRY(mRenderer->initRenderTarget(mSwapChain->getDepthStencilRenderTarget()));
}
return gl::NoError();
}
WindowSurfaceD3D::WindowSurfaceD3D(const egl::SurfaceState &state,
RendererD3D *renderer,
egl::Display *display,
......
......@@ -60,6 +60,8 @@ class SurfaceD3D : public SurfaceImpl
GLenum binding,
const gl::ImageIndex &imageIndex,
FramebufferAttachmentRenderTarget **rtOut) override;
gl::Error initializeContents(const gl::Context *context,
const gl::ImageIndex &imageIndex) override;
const angle::Format *getD3DTextureColorFormat() const override;
......
......@@ -3996,8 +3996,10 @@ gl::Error Renderer11::clearRenderTarget(RenderTargetD3D *renderTarget,
{
RenderTarget11 *rt11 = GetAs<RenderTarget11>(renderTarget);
if (rt11->getDepthStencilView().valid())
if (rt11->getFormatSet().dsvFormat != DXGI_FORMAT_UNKNOWN)
{
ASSERT(rt11->getDepthStencilView().valid());
const auto &format = rt11->getFormatSet();
const UINT clearFlags = (format.format().depthBits > 0 ? D3D11_CLEAR_DEPTH : 0) |
(format.format().stencilBits ? D3D11_CLEAR_STENCIL : 0);
......
......@@ -190,20 +190,42 @@ class RobustResourceInitTest : public ANGLETest
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
setConfigDepthBits(24);
setConfigStencilBits(8);
setRobustResourceInit(true);
}
bool hasGLExtension()
bool isSkippedPlatform()
{
// Skip all tests on the OpenGL backend. It is not fully implemented but still needs to be
// exposed to test in Chromium.
if (IsDesktopOpenGL() || IsOpenGLES())
return IsDesktopOpenGL() || IsOpenGLES();
}
bool hasGLExtension()
{
return !isSkippedPlatform() && extensionEnabled("GL_ANGLE_robust_resource_initialization");
}
bool hasEGLExtension()
{
return !isSkippedPlatform() &&
eglDisplayExtensionEnabled(getEGLWindow()->getDisplay(),
"EGL_ANGLE_robust_resource_initialization");
}
bool hasRobustSurfaceInit()
{
if (!hasEGLExtension())
{
return false;
}
return extensionEnabled("GL_ANGLE_robust_resource_initialization");
EGLint robustSurfaceInit = EGL_FALSE;
eglQuerySurface(getEGLWindow()->getDisplay(), getEGLWindow()->getSurface(),
EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, &robustSurfaceInit);
return robustSurfaceInit;
}
void setupTexture(GLTexture *tex);
......@@ -292,6 +314,8 @@ TEST_P(RobustResourceInitTest, ExpectedRendererSupport)
{
bool shouldHaveSupport = IsD3D11() || IsD3D11_FL93() || IsD3D9();
EXPECT_EQ(shouldHaveSupport, hasGLExtension());
EXPECT_EQ(shouldHaveSupport, hasEGLExtension());
EXPECT_EQ(shouldHaveSupport, hasRobustSurfaceInit());
}
// Tests of the GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE query.
......@@ -1500,6 +1524,46 @@ TEST_P(RobustResourceInitTest, ClearWithScissor)
EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::transparentBlack);
}
// Tests that surfaces are initialized when they are created
TEST_P(RobustResourceInitTest, SurfaceInitialized)
{
ANGLE_SKIP_TEST_IF(!hasRobustSurfaceInit());
checkFramebufferNonZeroPixels(0, 0, 0, 0, GLColor::black);
}
// Tests that surfaces are initialized after swapping if they are not preserved
TEST_P(RobustResourceInitTest, SurfaceInitializedAfterSwap)
{
ANGLE_SKIP_TEST_IF(!hasRobustSurfaceInit());
EGLint swapBehaviour = 0;
ASSERT_TRUE(eglQuerySurface(getEGLWindow()->getDisplay(), getEGLWindow()->getSurface(),
EGL_SWAP_BEHAVIOR, &swapBehaviour));
const std::array<GLColor, 4> clearColors = {{
GLColor::blue, GLColor::cyan, GLColor::red, GLColor::yellow,
}};
for (size_t i = 0; i < clearColors.size(); i++)
{
if (swapBehaviour == EGL_BUFFER_PRESERVED && i > 0)
{
EXPECT_PIXEL_COLOR_EQ(0, 0, clearColors[i - 1]);
}
else
{
checkFramebufferNonZeroPixels(0, 0, 0, 0, GLColor::black);
}
angle::Vector4 clearColor = clearColors[i].toNormalizedVector();
glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
glClear(GL_COLOR_BUFFER_BIT);
EXPECT_GL_NO_ERROR();
swapBuffers();
}
}
ANGLE_INSTANTIATE_TEST(RobustResourceInitTest,
ES2_D3D9(),
ES2_D3D11(),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment