D3D11: Lazy robust resource init.
This patch moves the robust resource init logic to the GL front-end.
Instead of initializing texture resources immediately on creation in
D3D11, it defers the clear until before a draw call in some cases, or
skips the update if we can determine if a texture (or other resource)
has been fully initialized.
Currently lazy init is only implemented for Textures, Renderbuffers,
and Surfaces.
Various places where lazy resource init is triggered:
* Framebuffer operations (Draw, Blit, CopyTexImage, Clear, ReadPixels)
* Texture operations (SubImage, GenerateMipmap, CopyTexImage)
Some efficiency gains remain to be implemented, such as when a
SubImage call fills the entire object. Similarly for Blit, and a few
other operations. In these cases we can skip lazy init as an
optimization. Edge cases with EGLImage are mostly untested.
BUG=angleproject:2107
Change-Id: I2bf3a69b1eae0d4feeb5b17daca23451f1037be8
Reviewed-on: https://chromium-review.googlesource.com/576058
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 1c7520b..9c3c55d 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -1787,14 +1787,14 @@
void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
{
- syncRendererState();
+ ANGLE_CONTEXT_TRY(prepareForDraw());
ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
}
void Context::drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
{
- syncRendererState();
+ ANGLE_CONTEXT_TRY(prepareForDraw());
ANGLE_CONTEXT_TRY(
mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
MarkTransformFeedbackBufferUsage(mGLState.getCurrentTransformFeedback());
@@ -1802,7 +1802,7 @@
void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
{
- syncRendererState();
+ ANGLE_CONTEXT_TRY(prepareForDraw());
ANGLE_CONTEXT_TRY(mImplementation->drawElements(this, mode, count, type, indices));
}
@@ -1812,7 +1812,7 @@
const void *indices,
GLsizei instances)
{
- syncRendererState();
+ ANGLE_CONTEXT_TRY(prepareForDraw());
ANGLE_CONTEXT_TRY(
mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
}
@@ -1824,20 +1824,20 @@
GLenum type,
const void *indices)
{
- syncRendererState();
+ ANGLE_CONTEXT_TRY(prepareForDraw());
ANGLE_CONTEXT_TRY(
mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
}
void Context::drawArraysIndirect(GLenum mode, const void *indirect)
{
- syncRendererState();
+ ANGLE_CONTEXT_TRY(prepareForDraw());
ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
}
void Context::drawElementsIndirect(GLenum mode, GLenum type, const void *indirect)
{
- syncRendererState();
+ ANGLE_CONTEXT_TRY(prepareForDraw());
ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
}
@@ -2586,7 +2586,7 @@
mState.mTextures->signalAllTexturesDirty();
for (auto &zeroTexture : mZeroTextures)
{
- zeroTexture.second->signalDirty();
+ zeroTexture.second->signalDirty(InitState::Initialized);
}
mState.mFramebuffers->invalidateFramebufferComplenessCache();
@@ -2817,6 +2817,14 @@
mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
}
+Error Context::prepareForDraw()
+{
+ syncRendererState();
+ ANGLE_TRY(mGLState.clearUnclearedActiveTextures(this));
+ ANGLE_TRY(mGLState.getDrawFramebuffer()->ensureDrawAttachmentsInitialized(this));
+ return NoError();
+}
+
void Context::syncRendererState()
{
mGLState.syncDirtyObjects(this);
@@ -2932,7 +2940,7 @@
Rectangle sourceArea(x, y, width, height);
- const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
+ Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Texture *texture =
getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
handleError(texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
@@ -2958,7 +2966,7 @@
Offset destOffset(xoffset, yoffset, 0);
Rectangle sourceArea(x, y, width, height);
- const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
+ Framebuffer *framebuffer = mGLState.getReadFramebuffer();
Texture *texture =
getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
@@ -2985,8 +2993,8 @@
Offset destOffset(xoffset, yoffset, zoffset);
Rectangle sourceArea(x, y, width, height);
- const Framebuffer *framebuffer = mGLState.getReadFramebuffer();
- Texture *texture = getTargetTexture(target);
+ Framebuffer *framebuffer = mGLState.getReadFramebuffer();
+ Texture *texture = getTargetTexture(target);
handleError(texture->copySubImage(this, target, level, destOffset, sourceArea, framebuffer));
}
@@ -4256,6 +4264,9 @@
return;
}
+ // TODO(jmadill): Dirty bits for compute.
+ ANGLE_CONTEXT_TRY(mGLState.clearUnclearedActiveTextures(this));
+
handleError(mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ));
}