Commit d4fff506 by Geoff Lang Committed by Commit Bot

Reorder state synchronization for resource init.

Some backends may change state while initializing resources. Make sure that all resources are initialized before synchronizing the backend state for the given operation. BUG=angleproject:2107 Change-Id: Ie75ac3eee986e41dfe3dd11a94a706e19df7497e Reviewed-on: https://chromium-review.googlesource.com/678481 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 33140409
...@@ -2907,7 +2907,7 @@ void Context::initWorkarounds() ...@@ -2907,7 +2907,7 @@ void Context::initWorkarounds()
Error Context::prepareForDraw() Error Context::prepareForDraw()
{ {
ANGLE_TRY(syncRendererState()); ANGLE_TRY(syncRendererDirtyObjects());
if (isRobustResourceInitEnabled()) if (isRobustResourceInitEnabled())
{ {
...@@ -2915,28 +2915,68 @@ Error Context::prepareForDraw() ...@@ -2915,28 +2915,68 @@ Error Context::prepareForDraw()
ANGLE_TRY(mGLState.getDrawFramebuffer()->ensureDrawAttachmentsInitialized(this)); ANGLE_TRY(mGLState.getDrawFramebuffer()->ensureDrawAttachmentsInitialized(this));
} }
ANGLE_TRY(syncRendererDirtyBits());
return NoError();
}
Error Context::prepareForClear(GLbitfield mask)
{
ANGLE_TRY(syncRendererDirtyObjects(mClearDirtyObjects));
ANGLE_TRY(mGLState.getDrawFramebuffer()->ensureClearAttachmentsInitialized(this, mask));
ANGLE_TRY(syncRendererDirtyBits(mClearDirtyBits));
return NoError();
}
Error Context::prepareForClearBuffer(GLenum buffer, GLint drawbuffer)
{
ANGLE_TRY(syncRendererDirtyObjects(mClearDirtyObjects));
ANGLE_TRY(mGLState.getDrawFramebuffer()->ensureClearBufferAttachmentsInitialized(this, buffer,
drawbuffer));
ANGLE_TRY(syncRendererDirtyBits(mClearDirtyBits));
return NoError(); return NoError();
} }
Error Context::syncRendererState() Error Context::syncRendererState()
{ {
ANGLE_TRY(mGLState.syncDirtyObjects(this)); ANGLE_TRY(syncRendererDirtyObjects());
ANGLE_TRY(syncRendererDirtyBits());
return NoError();
}
Error Context::syncRendererState(const State::DirtyBits &bitMask,
const State::DirtyObjects &objectMask)
{
ANGLE_TRY(syncRendererDirtyObjects(objectMask));
ANGLE_TRY(syncRendererDirtyBits(bitMask));
return NoError();
}
Error Context::syncRendererDirtyBits()
{
const State::DirtyBits &dirtyBits = mGLState.getDirtyBits(); const State::DirtyBits &dirtyBits = mGLState.getDirtyBits();
mImplementation->syncState(this, dirtyBits); mImplementation->syncState(this, dirtyBits);
mGLState.clearDirtyBits(); mGLState.clearDirtyBits();
return NoError(); return NoError();
} }
Error Context::syncRendererState(const State::DirtyBits &bitMask, Error Context::syncRendererDirtyBits(const State::DirtyBits &bitMask)
const State::DirtyObjects &objectMask)
{ {
ANGLE_TRY(mGLState.syncDirtyObjects(this, objectMask));
const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask); const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
mImplementation->syncState(this, dirtyBits); mImplementation->syncState(this, dirtyBits);
mGLState.clearDirtyBits(dirtyBits); mGLState.clearDirtyBits(dirtyBits);
return NoError(); return NoError();
} }
Error Context::syncRendererDirtyObjects()
{
return mGLState.syncDirtyObjects(this);
}
Error Context::syncRendererDirtyObjects(const State::DirtyObjects &objectMask)
{
return mGLState.syncDirtyObjects(this, objectMask);
}
void Context::blitFramebuffer(GLint srcX0, void Context::blitFramebuffer(GLint srcX0,
GLint srcY0, GLint srcY0,
GLint srcX1, GLint srcX1,
...@@ -2968,26 +3008,29 @@ void Context::blitFramebuffer(GLint srcX0, ...@@ -2968,26 +3008,29 @@ void Context::blitFramebuffer(GLint srcX0,
void Context::clear(GLbitfield mask) void Context::clear(GLbitfield mask)
{ {
ANGLE_CONTEXT_TRY(syncStateForClear()); ANGLE_CONTEXT_TRY(prepareForClear(mask));
handleError(mGLState.getDrawFramebuffer()->clear(this, mask)); ANGLE_CONTEXT_TRY(mGLState.getDrawFramebuffer()->clear(this, mask));
} }
void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values) void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
{ {
ANGLE_CONTEXT_TRY(syncStateForClear()); ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values)); ANGLE_CONTEXT_TRY(
mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
} }
void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values) void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
{ {
ANGLE_CONTEXT_TRY(syncStateForClear()); ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values)); ANGLE_CONTEXT_TRY(
mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
} }
void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values) void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
{ {
ANGLE_CONTEXT_TRY(syncStateForClear()); ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values)); ANGLE_CONTEXT_TRY(
mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
} }
void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
...@@ -3002,8 +3045,8 @@ void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLin ...@@ -3002,8 +3045,8 @@ void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLin
return; return;
} }
ANGLE_CONTEXT_TRY(syncStateForClear()); ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil)); ANGLE_CONTEXT_TRY(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
} }
void Context::readPixels(GLint x, void Context::readPixels(GLint x,
...@@ -3637,11 +3680,6 @@ Error Context::syncStateForTexImage() ...@@ -3637,11 +3680,6 @@ Error Context::syncStateForTexImage()
return syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects); return syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
} }
Error Context::syncStateForClear()
{
return syncRendererState(mClearDirtyBits, mClearDirtyObjects);
}
Error Context::syncStateForBlit() Error Context::syncStateForBlit()
{ {
return syncRendererState(mBlitDirtyBits, mBlitDirtyObjects); return syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
......
...@@ -1169,12 +1169,18 @@ class Context final : public ValidationContext ...@@ -1169,12 +1169,18 @@ class Context final : public ValidationContext
private: private:
Error prepareForDraw(); Error prepareForDraw();
Error prepareForClear(GLbitfield mask);
Error prepareForClearBuffer(GLenum buffer, GLint drawbuffer);
Error syncRendererState(); Error syncRendererState();
Error syncRendererState(const State::DirtyBits &bitMask, const State::DirtyObjects &objectMask); Error syncRendererState(const State::DirtyBits &bitMask, const State::DirtyObjects &objectMask);
Error syncRendererDirtyBits();
Error syncRendererDirtyBits(const State::DirtyBits &bitMask);
Error syncRendererDirtyObjects();
Error syncRendererDirtyObjects(const State::DirtyObjects &objectMask);
Error syncStateForReadPixels(); Error syncStateForReadPixels();
Error syncStateForTexImage(); Error syncStateForTexImage();
Error syncStateForClear();
Error syncStateForBlit(); Error syncStateForBlit();
VertexArray *checkVertexArrayAllocation(GLuint vertexArrayHandle); VertexArray *checkVertexArrayAllocation(GLuint vertexArrayHandle);
TransformFeedback *checkTransformFeedbackAllocation(GLuint transformFeedback); TransformFeedback *checkTransformFeedbackAllocation(GLuint transformFeedback);
......
...@@ -1288,25 +1288,8 @@ Error Framebuffer::clear(const Context *context, GLbitfield mask) ...@@ -1288,25 +1288,8 @@ Error Framebuffer::clear(const Context *context, GLbitfield mask)
return NoError(); return NoError();
} }
const auto &blend = glState.getBlendState();
const auto &depthStencil = glState.getDepthStencilState();
bool color = (mask & GL_COLOR_BUFFER_BIT) != 0 && !IsColorMaskedOut(blend);
bool depth = (mask & GL_DEPTH_BUFFER_BIT) != 0 && !IsDepthMaskedOut(depthStencil);
bool stencil = (mask & GL_STENCIL_BUFFER_BIT) != 0 && !IsStencilMaskedOut(depthStencil);
if (partialClearNeedsInit(context, color, depth, stencil))
{
ANGLE_TRY(ensureDrawAttachmentsInitialized(context));
}
ANGLE_TRY(mImpl->clear(context, mask)); ANGLE_TRY(mImpl->clear(context, mask));
if (glState.isRobustResourceInitEnabled())
{
markDrawAttachmentsInitialized(color, depth, stencil);
}
return NoError(); return NoError();
} }
...@@ -1321,17 +1304,8 @@ Error Framebuffer::clearBufferfv(const Context *context, ...@@ -1321,17 +1304,8 @@ Error Framebuffer::clearBufferfv(const Context *context,
return NoError(); return NoError();
} }
if (partialBufferClearNeedsInit(context, buffer))
{
ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer));
}
ANGLE_TRY(mImpl->clearBufferfv(context, buffer, drawbuffer, values)); ANGLE_TRY(mImpl->clearBufferfv(context, buffer, drawbuffer, values));
if (context->isRobustResourceInitEnabled())
{
markBufferInitialized(buffer, drawbuffer);
}
return NoError(); return NoError();
} }
...@@ -1346,17 +1320,8 @@ Error Framebuffer::clearBufferuiv(const Context *context, ...@@ -1346,17 +1320,8 @@ Error Framebuffer::clearBufferuiv(const Context *context,
return NoError(); return NoError();
} }
if (partialBufferClearNeedsInit(context, buffer))
{
ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer));
}
ANGLE_TRY(mImpl->clearBufferuiv(context, buffer, drawbuffer, values)); ANGLE_TRY(mImpl->clearBufferuiv(context, buffer, drawbuffer, values));
if (context->isRobustResourceInitEnabled())
{
markBufferInitialized(buffer, drawbuffer);
}
return NoError(); return NoError();
} }
...@@ -1371,17 +1336,8 @@ Error Framebuffer::clearBufferiv(const Context *context, ...@@ -1371,17 +1336,8 @@ Error Framebuffer::clearBufferiv(const Context *context,
return NoError(); return NoError();
} }
if (partialBufferClearNeedsInit(context, buffer))
{
ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer));
}
ANGLE_TRY(mImpl->clearBufferiv(context, buffer, drawbuffer, values)); ANGLE_TRY(mImpl->clearBufferiv(context, buffer, drawbuffer, values));
if (context->isRobustResourceInitEnabled())
{
markBufferInitialized(buffer, drawbuffer);
}
return NoError(); return NoError();
} }
...@@ -1397,17 +1353,8 @@ Error Framebuffer::clearBufferfi(const Context *context, ...@@ -1397,17 +1353,8 @@ Error Framebuffer::clearBufferfi(const Context *context,
return NoError(); return NoError();
} }
if (partialBufferClearNeedsInit(context, buffer))
{
ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer));
}
ANGLE_TRY(mImpl->clearBufferfi(context, buffer, drawbuffer, depth, stencil)); ANGLE_TRY(mImpl->clearBufferfi(context, buffer, drawbuffer, depth, stencil));
if (context->isRobustResourceInitEnabled())
{
markBufferInitialized(buffer, drawbuffer);
}
return NoError(); return NoError();
} }
...@@ -2008,6 +1955,63 @@ GLenum Framebuffer::getMultiviewLayout() const ...@@ -2008,6 +1955,63 @@ GLenum Framebuffer::getMultiviewLayout() const
return mState.getMultiviewLayout(); return mState.getMultiviewLayout();
} }
Error Framebuffer::ensureClearAttachmentsInitialized(const Context *context, GLbitfield mask)
{
const auto &glState = context->getGLState();
if (!context->isRobustResourceInitEnabled() || glState.isRasterizerDiscardEnabled())
{
return NoError();
}
const auto &blend = glState.getBlendState();
const auto &depthStencil = glState.getDepthStencilState();
bool color = (mask & GL_COLOR_BUFFER_BIT) != 0 && !IsColorMaskedOut(blend);
bool depth = (mask & GL_DEPTH_BUFFER_BIT) != 0 && !IsDepthMaskedOut(depthStencil);
bool stencil = (mask & GL_STENCIL_BUFFER_BIT) != 0 && !IsStencilMaskedOut(depthStencil);
if (!color && !depth && !stencil)
{
return NoError();
}
if (partialClearNeedsInit(context, color, depth, stencil))
{
ANGLE_TRY(ensureDrawAttachmentsInitialized(context));
}
// If the impl encounters an error during a a full (non-partial) clear, the attachments will
// still be marked initialized. This simplifies design, allowing this method to be called before
// the clear.
markDrawAttachmentsInitialized(color, depth, stencil);
return NoError();
}
Error Framebuffer::ensureClearBufferAttachmentsInitialized(const Context *context,
GLenum buffer,
GLint drawbuffer)
{
if (!context->isRobustResourceInitEnabled() ||
context->getGLState().isRasterizerDiscardEnabled() ||
IsClearBufferMaskedOut(context, buffer))
{
return NoError();
}
if (partialBufferClearNeedsInit(context, buffer))
{
ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer));
}
// If the impl encounters an error during a a full (non-partial) clear, the attachments will
// still be marked initialized. This simplifies design, allowing this method to be called before
// the clear.
markBufferInitialized(buffer, drawbuffer);
return NoError();
}
Error Framebuffer::ensureDrawAttachmentsInitialized(const Context *context) Error Framebuffer::ensureDrawAttachmentsInitialized(const Context *context)
{ {
if (!context->isRobustResourceInitEnabled()) if (!context->isRobustResourceInitEnabled())
......
...@@ -317,6 +317,10 @@ class Framebuffer final : public angle::ObserverInterface, public LabeledObject ...@@ -317,6 +317,10 @@ class Framebuffer final : public angle::ObserverInterface, public LabeledObject
GLint copyTextureLevel, GLint copyTextureLevel,
GLint copyTextureLayer) const; GLint copyTextureLayer) const;
Error ensureClearAttachmentsInitialized(const Context *context, GLbitfield mask);
Error ensureClearBufferAttachmentsInitialized(const Context *context,
GLenum buffer,
GLint drawbuffer);
Error ensureDrawAttachmentsInitialized(const Context *context); Error ensureDrawAttachmentsInitialized(const Context *context);
Error ensureReadAttachmentInitialized(const Context *context, GLbitfield blitMask); Error ensureReadAttachmentInitialized(const Context *context, GLbitfield blitMask);
Box getDimensions() const; Box getDimensions() const;
......
...@@ -2531,6 +2531,8 @@ Error State::clearUnclearedActiveTextures(const Context *context) ...@@ -2531,6 +2531,8 @@ Error State::clearUnclearedActiveTextures(const Context *context)
return NoError(); return NoError();
} }
ASSERT(!mDirtyObjects.any());
for (auto textureIndex : mActiveTexturesMask) for (auto textureIndex : mActiveTexturesMask)
{ {
Texture *texture = mCompleteTextureCache[textureIndex]; Texture *texture = mCompleteTextureCache[textureIndex];
......
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