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()
Error Context::prepareForDraw()
{
ANGLE_TRY(syncRendererState());
ANGLE_TRY(syncRendererDirtyObjects());
if (isRobustResourceInitEnabled())
{
......@@ -2915,28 +2915,68 @@ Error Context::prepareForDraw()
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();
}
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();
mImplementation->syncState(this, dirtyBits);
mGLState.clearDirtyBits();
return NoError();
}
Error Context::syncRendererState(const State::DirtyBits &bitMask,
const State::DirtyObjects &objectMask)
Error Context::syncRendererDirtyBits(const State::DirtyBits &bitMask)
{
ANGLE_TRY(mGLState.syncDirtyObjects(this, objectMask));
const State::DirtyBits &dirtyBits = (mGLState.getDirtyBits() & bitMask);
mImplementation->syncState(this, dirtyBits);
mGLState.clearDirtyBits(dirtyBits);
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,
GLint srcY0,
GLint srcX1,
......@@ -2968,26 +3008,29 @@ void Context::blitFramebuffer(GLint srcX0,
void Context::clear(GLbitfield mask)
{
ANGLE_CONTEXT_TRY(syncStateForClear());
handleError(mGLState.getDrawFramebuffer()->clear(this, mask));
ANGLE_CONTEXT_TRY(prepareForClear(mask));
ANGLE_CONTEXT_TRY(mGLState.getDrawFramebuffer()->clear(this, mask));
}
void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
{
ANGLE_CONTEXT_TRY(syncStateForClear());
handleError(mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
ANGLE_CONTEXT_TRY(
mGLState.getDrawFramebuffer()->clearBufferfv(this, buffer, drawbuffer, values));
}
void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
{
ANGLE_CONTEXT_TRY(syncStateForClear());
handleError(mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
ANGLE_CONTEXT_TRY(
mGLState.getDrawFramebuffer()->clearBufferuiv(this, buffer, drawbuffer, values));
}
void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
{
ANGLE_CONTEXT_TRY(syncStateForClear());
handleError(mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
ANGLE_CONTEXT_TRY(
mGLState.getDrawFramebuffer()->clearBufferiv(this, buffer, drawbuffer, values));
}
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
return;
}
ANGLE_CONTEXT_TRY(syncStateForClear());
handleError(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
ANGLE_CONTEXT_TRY(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
}
void Context::readPixels(GLint x,
......@@ -3637,11 +3680,6 @@ Error Context::syncStateForTexImage()
return syncRendererState(mTexImageDirtyBits, mTexImageDirtyObjects);
}
Error Context::syncStateForClear()
{
return syncRendererState(mClearDirtyBits, mClearDirtyObjects);
}
Error Context::syncStateForBlit()
{
return syncRendererState(mBlitDirtyBits, mBlitDirtyObjects);
......
......@@ -1169,12 +1169,18 @@ class Context final : public ValidationContext
private:
Error prepareForDraw();
Error prepareForClear(GLbitfield mask);
Error prepareForClearBuffer(GLenum buffer, GLint drawbuffer);
Error syncRendererState();
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 syncStateForTexImage();
Error syncStateForClear();
Error syncStateForBlit();
VertexArray *checkVertexArrayAllocation(GLuint vertexArrayHandle);
TransformFeedback *checkTransformFeedbackAllocation(GLuint transformFeedback);
......
......@@ -1288,25 +1288,8 @@ Error Framebuffer::clear(const Context *context, GLbitfield mask)
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));
if (glState.isRobustResourceInitEnabled())
{
markDrawAttachmentsInitialized(color, depth, stencil);
}
return NoError();
}
......@@ -1321,17 +1304,8 @@ Error Framebuffer::clearBufferfv(const Context *context,
return NoError();
}
if (partialBufferClearNeedsInit(context, buffer))
{
ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer));
}
ANGLE_TRY(mImpl->clearBufferfv(context, buffer, drawbuffer, values));
if (context->isRobustResourceInitEnabled())
{
markBufferInitialized(buffer, drawbuffer);
}
return NoError();
}
......@@ -1346,17 +1320,8 @@ Error Framebuffer::clearBufferuiv(const Context *context,
return NoError();
}
if (partialBufferClearNeedsInit(context, buffer))
{
ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer));
}
ANGLE_TRY(mImpl->clearBufferuiv(context, buffer, drawbuffer, values));
if (context->isRobustResourceInitEnabled())
{
markBufferInitialized(buffer, drawbuffer);
}
return NoError();
}
......@@ -1371,17 +1336,8 @@ Error Framebuffer::clearBufferiv(const Context *context,
return NoError();
}
if (partialBufferClearNeedsInit(context, buffer))
{
ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer));
}
ANGLE_TRY(mImpl->clearBufferiv(context, buffer, drawbuffer, values));
if (context->isRobustResourceInitEnabled())
{
markBufferInitialized(buffer, drawbuffer);
}
return NoError();
}
......@@ -1397,17 +1353,8 @@ Error Framebuffer::clearBufferfi(const Context *context,
return NoError();
}
if (partialBufferClearNeedsInit(context, buffer))
{
ANGLE_TRY(ensureBufferInitialized(context, buffer, drawbuffer));
}
ANGLE_TRY(mImpl->clearBufferfi(context, buffer, drawbuffer, depth, stencil));
if (context->isRobustResourceInitEnabled())
{
markBufferInitialized(buffer, drawbuffer);
}
return NoError();
}
......@@ -2008,6 +1955,63 @@ GLenum Framebuffer::getMultiviewLayout() const
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)
{
if (!context->isRobustResourceInitEnabled())
......
......@@ -317,6 +317,10 @@ class Framebuffer final : public angle::ObserverInterface, public LabeledObject
GLint copyTextureLevel,
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 ensureReadAttachmentInitialized(const Context *context, GLbitfield blitMask);
Box getDimensions() const;
......
......@@ -2531,6 +2531,8 @@ Error State::clearUnclearedActiveTextures(const Context *context)
return NoError();
}
ASSERT(!mDirtyObjects.any());
for (auto textureIndex : mActiveTexturesMask)
{
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