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: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/Framebuffer.cpp b/src/libANGLE/Framebuffer.cpp
index 64c0f07..d229110 100644
--- a/src/libANGLE/Framebuffer.cpp
+++ b/src/libANGLE/Framebuffer.cpp
@@ -1288,25 +1288,8 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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())