GL: Apply dirty bit mask on sync state.
This prevents us from updating some dirty bits in some operations.
It can prevent us from doing things like updating the Program when
we don't use it in a GPU operation.
Also adds Framebuffer dirty bits to TexImage to work around a bug
on the Windows Intel OpenGL driver.
Bug: angleproject:2763
Bug: angleproject:2906
Change-Id: I9f69775fb930a9bbcbd40d0f9012d62a9381c9f8
Reviewed-on: https://chromium-review.googlesource.com/c/1292610
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 5c8462b..c5b180b 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -3452,6 +3452,13 @@
// Lose the context upon out of memory error if the application is
// expecting to watch for those events.
mWorkarounds.loseContextOnOutOfMemory = (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
+
+ if (mWorkarounds.syncFramebufferBindingsOnTexImage)
+ {
+ // Update the Framebuffer bindings on TexImage to work around an Intel bug.
+ mTexImageDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
+ mTexImageDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
+ }
}
// Return true if the draw is a no-op, else return false.
diff --git a/src/libANGLE/Workarounds.h b/src/libANGLE/Workarounds.h
index 898031d..2421dd6 100644
--- a/src/libANGLE/Workarounds.h
+++ b/src/libANGLE/Workarounds.h
@@ -23,6 +23,11 @@
// Program binaries don't contain transform feedback varyings on Qualcomm GPUs.
// Work around this by disabling the program cache for programs with transform feedback.
bool disableProgramCachingForTransformFeedback = false;
+
+ // On Windows Intel OpenGL drivers TexImage sometimes seems to interact with the Framebuffer.
+ // Flaky crashes can occur unless we sync the Framebuffer bindings. The workaround is to add
+ // Framebuffer binding dirty bits to TexImage updates. See http://anglebug.com/2906
+ bool syncFramebufferBindingsOnTexImage = false;
};
} // namespace gl
diff --git a/src/libANGLE/renderer/gl/StateManagerGL.cpp b/src/libANGLE/renderer/gl/StateManagerGL.cpp
index 7cb71db..32e4d6c 100644
--- a/src/libANGLE/renderer/gl/StateManagerGL.cpp
+++ b/src/libANGLE/renderer/gl/StateManagerGL.cpp
@@ -1747,7 +1747,7 @@
mMultiviewDirtyBits.reset();
}
- const gl::State::DirtyBits &glAndLocalDirtyBits = (glDirtyBits | mLocalDirtyBits);
+ const gl::State::DirtyBits &glAndLocalDirtyBits = (glDirtyBits | mLocalDirtyBits) & bitMask;
if (!glAndLocalDirtyBits.any())
{
@@ -1939,6 +1939,11 @@
case gl::State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING:
{
gl::Framebuffer *framebuffer = state.getReadFramebuffer();
+
+ // Necessary for an Intel TexImage workaround.
+ if (!framebuffer)
+ continue;
+
FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
bindFramebuffer(GL_READ_FRAMEBUFFER, framebufferGL->getFramebufferID());
break;
@@ -1946,11 +1951,19 @@
case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING:
{
gl::Framebuffer *framebuffer = state.getDrawFramebuffer();
+
+ // Necessary for an Intel TexImage workaround.
+ if (!framebuffer)
+ continue;
+
FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferGL->getFramebufferID());
const gl::Program *program = state.getProgram();
- updateMultiviewBaseViewLayerIndexUniform(program, framebufferGL->getState());
+ if (program)
+ {
+ updateMultiviewBaseViewLayerIndexUniform(program, framebufferGL->getState());
+ }
break;
}
case gl::State::DIRTY_BIT_RENDERBUFFER_BINDING:
@@ -2070,9 +2083,9 @@
UNREACHABLE();
break;
}
-
- mLocalDirtyBits.reset();
}
+
+ mLocalDirtyBits &= ~(bitMask);
}
void StateManagerGL::setFramebufferSRGBEnabled(const gl::Context *context, bool enabled)
diff --git a/src/libANGLE/renderer/gl/renderergl_utils.cpp b/src/libANGLE/renderer/gl/renderergl_utils.cpp
index 2b44ce0..42539be 100644
--- a/src/libANGLE/renderer/gl/renderergl_utils.cpp
+++ b/src/libANGLE/renderer/gl/renderergl_utils.cpp
@@ -1243,14 +1243,22 @@
void ApplyWorkarounds(const FunctionsGL *functions, gl::Workarounds *workarounds)
{
-#if defined(ANGLE_PLATFORM_ANDROID)
VendorID vendor = GetVendorID(functions);
+ ANGLE_UNUSED_VARIABLE(vendor);
+#if defined(ANGLE_PLATFORM_ANDROID)
if (IsQualcomm(vendor))
{
workarounds->disableProgramCachingForTransformFeedback = true;
}
#endif // defined(ANGLE_PLATFORM_ANDROID)
+
+#if defined(ANGLE_PLATFORM_WINDOWS)
+ if (IsIntel(vendor))
+ {
+ workarounds->syncFramebufferBindingsOnTexImage = true;
+ }
+#endif // defined(ANGLE_PLATFORM_WINDOWS)
}
} // namespace nativegl_gl