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, ...@@ -1736,11 +1736,9 @@ void Framebuffer::setAttachmentImpl(const Context *context,
break; break;
case GL_BACK: case GL_BACK:
mState.mColorAttachments[0].attach(context, type, binding, textureIndex, resource, updateAttachment(context, &mState.mColorAttachments[0], DIRTY_BIT_COLOR_ATTACHMENT_0,
numViews, baseViewIndex, multiviewLayout, &mDirtyColorAttachmentBindings[0], type, binding, textureIndex,
viewportOffsets); 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.
break; break;
default: default:
...@@ -1805,8 +1803,13 @@ void Framebuffer::syncState(const Context *context) ...@@ -1805,8 +1803,13 @@ void Framebuffer::syncState(const Context *context)
void Framebuffer::signal(size_t dirtyBit, InitState state) void Framebuffer::signal(size_t dirtyBit, InitState state)
{ {
// TOOD(jmadill): Make this only update individual attachments to do less work. // Only reset the cached status if this is not the default framebuffer. The default framebuffer
mCachedStatus.reset(); // 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. // Mark the appropriate init flag.
mState.mResourceNeedsInit.set(dirtyBit, state == InitState::MayNeedInit); mState.mResourceNeedsInit.set(dirtyBit, state == InitState::MayNeedInit);
......
...@@ -62,7 +62,8 @@ Surface::Surface(EGLint surfaceType, ...@@ -62,7 +62,8 @@ Surface::Surface(EGLint surfaceType,
mOrientation(0), mOrientation(0),
mTexture(), mTexture(),
mColorFormat(config->renderTargetFormat), 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); mPostSubBufferRequested = (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE);
mFlexibleSurfaceCompatibilityRequested = mFlexibleSurfaceCompatibilityRequested =
...@@ -84,6 +85,10 @@ Surface::Surface(EGLint surfaceType, ...@@ -84,6 +85,10 @@ Surface::Surface(EGLint surfaceType,
mRobustResourceInitialization = mRobustResourceInitialization =
(attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE); (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); mFixedSize = (attributes.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE);
if (mFixedSize) if (mFixedSize)
...@@ -146,6 +151,15 @@ Error Surface::destroyImpl(const Display *display) ...@@ -146,6 +151,15 @@ Error Surface::destroyImpl(const Display *display)
return NoError(); return NoError();
} }
void Surface::postSwap()
{
if (mRobustResourceInitialization && mSwapBehavior != EGL_BUFFER_PRESERVED)
{
mInitState = gl::InitState::MayNeedInit;
mDirtyChannel.signal(mInitState);
}
}
Error Surface::initialize(const Display *display) Error Surface::initialize(const Display *display)
{ {
ANGLE_TRY(mImplementation->initialize(display)); ANGLE_TRY(mImplementation->initialize(display));
...@@ -216,12 +230,16 @@ EGLint Surface::getType() const ...@@ -216,12 +230,16 @@ EGLint Surface::getType() const
Error Surface::swap(const gl::Context *context) 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) 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, Error Surface::postSubBuffer(const gl::Context *context,
...@@ -435,13 +453,12 @@ gl::Framebuffer *Surface::createDefaultFramebuffer(const Display *display) ...@@ -435,13 +453,12 @@ gl::Framebuffer *Surface::createDefaultFramebuffer(const Display *display)
gl::InitState Surface::initState(const gl::ImageIndex & /*imageIndex*/) const gl::InitState Surface::initState(const gl::ImageIndex & /*imageIndex*/) const
{ {
// TODO(jmadill): Lazy surface init. return mInitState;
return gl::InitState::Initialized;
} }
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, WindowSurface::WindowSurface(rx::EGLImplFactory *implFactory,
......
...@@ -186,6 +186,10 @@ class Surface : public gl::FramebufferAttachmentObject ...@@ -186,6 +186,10 @@ class Surface : public gl::FramebufferAttachmentObject
private: private:
Error destroyImpl(const Display *display); Error destroyImpl(const Display *display);
void postSwap();
gl::InitState mInitState;
}; };
class WindowSurface final : public Surface class WindowSurface final : public Surface
......
...@@ -413,6 +413,20 @@ gl::Error SurfaceD3D::getAttachmentRenderTarget(const gl::Context *context, ...@@ -413,6 +413,20 @@ gl::Error SurfaceD3D::getAttachmentRenderTarget(const gl::Context *context,
return gl::NoError(); 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, WindowSurfaceD3D::WindowSurfaceD3D(const egl::SurfaceState &state,
RendererD3D *renderer, RendererD3D *renderer,
egl::Display *display, egl::Display *display,
......
...@@ -60,6 +60,8 @@ class SurfaceD3D : public SurfaceImpl ...@@ -60,6 +60,8 @@ class SurfaceD3D : public SurfaceImpl
GLenum binding, GLenum binding,
const gl::ImageIndex &imageIndex, const gl::ImageIndex &imageIndex,
FramebufferAttachmentRenderTarget **rtOut) override; FramebufferAttachmentRenderTarget **rtOut) override;
gl::Error initializeContents(const gl::Context *context,
const gl::ImageIndex &imageIndex) override;
const angle::Format *getD3DTextureColorFormat() const override; const angle::Format *getD3DTextureColorFormat() const override;
......
...@@ -3996,8 +3996,10 @@ gl::Error Renderer11::clearRenderTarget(RenderTargetD3D *renderTarget, ...@@ -3996,8 +3996,10 @@ gl::Error Renderer11::clearRenderTarget(RenderTargetD3D *renderTarget,
{ {
RenderTarget11 *rt11 = GetAs<RenderTarget11>(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 auto &format = rt11->getFormatSet();
const UINT clearFlags = (format.format().depthBits > 0 ? D3D11_CLEAR_DEPTH : 0) | const UINT clearFlags = (format.format().depthBits > 0 ? D3D11_CLEAR_DEPTH : 0) |
(format.format().stencilBits ? D3D11_CLEAR_STENCIL : 0); (format.format().stencilBits ? D3D11_CLEAR_STENCIL : 0);
......
...@@ -190,20 +190,42 @@ class RobustResourceInitTest : public ANGLETest ...@@ -190,20 +190,42 @@ class RobustResourceInitTest : public ANGLETest
setConfigGreenBits(8); setConfigGreenBits(8);
setConfigBlueBits(8); setConfigBlueBits(8);
setConfigAlphaBits(8); setConfigAlphaBits(8);
setConfigDepthBits(24);
setConfigStencilBits(8);
setRobustResourceInit(true); setRobustResourceInit(true);
} }
bool hasGLExtension() bool isSkippedPlatform()
{ {
// Skip all tests on the OpenGL backend. It is not fully implemented but still needs to be // Skip all tests on the OpenGL backend. It is not fully implemented but still needs to be
// exposed to test in Chromium. // 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 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); void setupTexture(GLTexture *tex);
...@@ -292,6 +314,8 @@ TEST_P(RobustResourceInitTest, ExpectedRendererSupport) ...@@ -292,6 +314,8 @@ TEST_P(RobustResourceInitTest, ExpectedRendererSupport)
{ {
bool shouldHaveSupport = IsD3D11() || IsD3D11_FL93() || IsD3D9(); bool shouldHaveSupport = IsD3D11() || IsD3D11_FL93() || IsD3D9();
EXPECT_EQ(shouldHaveSupport, hasGLExtension()); EXPECT_EQ(shouldHaveSupport, hasGLExtension());
EXPECT_EQ(shouldHaveSupport, hasEGLExtension());
EXPECT_EQ(shouldHaveSupport, hasRobustSurfaceInit());
} }
// Tests of the GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE query. // Tests of the GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE query.
...@@ -1500,6 +1524,46 @@ TEST_P(RobustResourceInitTest, ClearWithScissor) ...@@ -1500,6 +1524,46 @@ TEST_P(RobustResourceInitTest, ClearWithScissor)
EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::transparentBlack); 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, ANGLE_INSTANTIATE_TEST(RobustResourceInitTest,
ES2_D3D9(), ES2_D3D9(),
ES2_D3D11(), 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