GL backend: Only synchronize transform feedback state when it changes.
BUG=angleproject:2188
Change-Id: I5bfcc038c887dde0770564d103eb3cb234b248c9
Reviewed-on: https://chromium-review.googlesource.com/794100
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index f87e963..eaa7930 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -1157,6 +1157,7 @@
TransformFeedback *transformFeedback)
{
mTransformFeedback.set(context, transformFeedback);
+ mDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING);
}
TransformFeedback *State::getCurrentTransformFeedback() const
diff --git a/src/libANGLE/State.h b/src/libANGLE/State.h
index ad0b779..f61e2f7 100644
--- a/src/libANGLE/State.h
+++ b/src/libANGLE/State.h
@@ -399,6 +399,7 @@
// TODO(jmadill): Fine-grained dirty bits for each texture/sampler.
DIRTY_BIT_TEXTURE_BINDINGS,
DIRTY_BIT_SAMPLER_BINDINGS,
+ DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING,
DIRTY_BIT_MULTISAMPLING,
DIRTY_BIT_SAMPLE_ALPHA_TO_ONE,
DIRTY_BIT_COVERAGE_MODULATION, // CHROMIUM_framebuffer_mixed_samples
diff --git a/src/libANGLE/renderer/gl/StateManagerGL.cpp b/src/libANGLE/renderer/gl/StateManagerGL.cpp
index 258b874..416c5f5 100644
--- a/src/libANGLE/renderer/gl/StateManagerGL.cpp
+++ b/src/libANGLE/renderer/gl/StateManagerGL.cpp
@@ -85,8 +85,8 @@
mSamplers(rendererCaps.maxCombinedTextureImageUnits, 0),
mImages(rendererCaps.maxImageUnits, ImageUnitBinding()),
mTransformFeedback(0),
+ mCurrentTransformFeedback(nullptr),
mQueries(),
- mPrevDrawTransformFeedback(nullptr),
mCurrentQueries(),
mPrevDrawContext(0),
mUnpackAlignment(4),
@@ -353,10 +353,10 @@
bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
}
- if (mPrevDrawTransformFeedback != nullptr &&
- mPrevDrawTransformFeedback->getTransformFeedbackID() == transformFeedback)
+ if (mCurrentTransformFeedback != nullptr &&
+ mCurrentTransformFeedback->getTransformFeedbackID() == transformFeedback)
{
- mPrevDrawTransformFeedback = nullptr;
+ mCurrentTransformFeedback = nullptr;
}
mFunctions->deleteTransformFeedbacks(1, &transformFeedback);
@@ -645,18 +645,24 @@
// Pause the current transform feedback if one is active.
// To handle virtualized contexts, StateManagerGL needs to be able to bind a new transform
// feedback at any time, even if there is one active.
- if (mPrevDrawTransformFeedback != nullptr &&
- mPrevDrawTransformFeedback->getTransformFeedbackID() != transformFeedback)
+ if (mCurrentTransformFeedback != nullptr &&
+ mCurrentTransformFeedback->getTransformFeedbackID() != transformFeedback)
{
- mPrevDrawTransformFeedback->syncPausedState(true);
- mPrevDrawTransformFeedback = nullptr;
+ mCurrentTransformFeedback->syncPausedState(true);
+ mCurrentTransformFeedback = nullptr;
}
mTransformFeedback = transformFeedback;
mFunctions->bindTransformFeedback(type, mTransformFeedback);
+ onTransformFeedbackStateChange();
}
}
+void StateManagerGL::onTransformFeedbackStateChange()
+{
+ mLocalDirtyBits.set(gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING);
+}
+
void StateManagerGL::beginQuery(GLenum type, GLuint query)
{
// Make sure this is a valid query type and there is no current active query of this type
@@ -761,9 +767,10 @@
void StateManagerGL::pauseTransformFeedback()
{
- if (mPrevDrawTransformFeedback != nullptr)
+ if (mCurrentTransformFeedback != nullptr)
{
- mPrevDrawTransformFeedback->syncPausedState(true);
+ mCurrentTransformFeedback->syncPausedState(true);
+ onTransformFeedbackStateChange();
}
}
@@ -820,7 +827,7 @@
ANGLE_TRY(pauseAllQueries());
}
mCurrentQueries.clear();
- mPrevDrawTransformFeedback = nullptr;
+ onTransformFeedbackStateChange();
mPrevDrawContext = contextID;
// Set the current query state
@@ -1006,24 +1013,6 @@
FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferGL->getFramebufferID());
- // Set the current transform feedback state
- gl::TransformFeedback *transformFeedback = glState.getCurrentTransformFeedback();
- if (transformFeedback)
- {
- TransformFeedbackGL *transformFeedbackGL =
- GetImplAs<TransformFeedbackGL>(transformFeedback);
- bindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbackGL->getTransformFeedbackID());
- transformFeedbackGL->syncActiveState(transformFeedback->isActive(),
- transformFeedback->getPrimitiveMode());
- transformFeedbackGL->syncPausedState(transformFeedback->isPaused());
- mPrevDrawTransformFeedback = transformFeedbackGL;
- }
- else
- {
- bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
- mPrevDrawTransformFeedback = nullptr;
- }
-
if (context->getExtensions().webglCompatibility)
{
auto activeOutputs = glState.getProgram()->getState().getActiveOutputVariables();
@@ -1946,6 +1935,9 @@
case gl::State::DIRTY_BIT_SAMPLER_BINDINGS:
mProgramTexturesAndSamplersDirty = true;
break;
+ case gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING:
+ syncTransformFeedbackState(context);
+ break;
case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE:
mProgramTexturesAndSamplersDirty = true;
propagateNumViewsToVAO(state.getProgram(),
@@ -2235,4 +2227,25 @@
}
}
}
+
+void StateManagerGL::syncTransformFeedbackState(const gl::Context *context)
+{
+ // Set the current transform feedback state
+ gl::TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
+ if (transformFeedback)
+ {
+ TransformFeedbackGL *transformFeedbackGL =
+ GetImplAs<TransformFeedbackGL>(transformFeedback);
+ bindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbackGL->getTransformFeedbackID());
+ transformFeedbackGL->syncActiveState(transformFeedback->isActive(),
+ transformFeedback->getPrimitiveMode());
+ transformFeedbackGL->syncPausedState(transformFeedback->isPaused());
+ mCurrentTransformFeedback = transformFeedbackGL;
+ }
+ else
+ {
+ bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
+ mCurrentTransformFeedback = nullptr;
+ }
+}
}
diff --git a/src/libANGLE/renderer/gl/StateManagerGL.h b/src/libANGLE/renderer/gl/StateManagerGL.h
index 9153067..245af23 100644
--- a/src/libANGLE/renderer/gl/StateManagerGL.h
+++ b/src/libANGLE/renderer/gl/StateManagerGL.h
@@ -75,6 +75,7 @@
void bindFramebuffer(GLenum type, GLuint framebuffer);
void bindRenderbuffer(GLenum type, GLuint renderbuffer);
void bindTransformFeedback(GLenum type, GLuint transformFeedback);
+ void onTransformFeedbackStateChange();
void beginQuery(GLenum type, GLuint query);
void endQuery(GLenum type, GLuint query);
void onBeginQuery(QueryGL *query);
@@ -199,6 +200,8 @@
void updateProgramTextureAndSamplerBindings(const gl::Context *context);
+ void syncTransformFeedbackState(const gl::Context *context);
+
enum MultiviewDirtyBitType
{
MULTIVIEW_DIRTY_BIT_SIDE_BY_SIDE_LAYOUT,
@@ -246,10 +249,9 @@
std::vector<ImageUnitBinding> mImages;
GLuint mTransformFeedback;
+ TransformFeedbackGL *mCurrentTransformFeedback;
std::map<GLenum, GLuint> mQueries;
-
- TransformFeedbackGL *mPrevDrawTransformFeedback;
std::set<QueryGL *> mCurrentQueries;
gl::ContextID mPrevDrawContext;
diff --git a/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp b/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp
index 33354f8..7c95ccd 100644
--- a/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp
+++ b/src/libANGLE/renderer/gl/TransformFeedbackGL.cpp
@@ -38,22 +38,27 @@
void TransformFeedbackGL::begin(GLenum primitiveMode)
{
- // Do not begin directly, StateManagerGL will handle beginning and resuming transform feedback.
+ mStateManager->onTransformFeedbackStateChange();
}
void TransformFeedbackGL::end()
{
+ mStateManager->onTransformFeedbackStateChange();
+
+ // Immediately end the transform feedback so that the results are visible.
syncActiveState(false, GL_NONE);
}
void TransformFeedbackGL::pause()
{
+ mStateManager->onTransformFeedbackStateChange();
+
syncPausedState(true);
}
void TransformFeedbackGL::resume()
{
- // Do not resume directly, StateManagerGL will handle beginning and resuming transform feedback.
+ mStateManager->onTransformFeedbackStateChange();
}
void TransformFeedbackGL::bindGenericBuffer(const gl::BindingPointer<gl::Buffer> &binding)
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
index 8b9dcc1..bf422e0 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -709,6 +709,9 @@
case gl::State::DIRTY_BIT_SAMPLER_BINDINGS:
dirtyTextures = true;
break;
+ case gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING:
+ WARN() << "DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING unimplemented";
+ break;
case gl::State::DIRTY_BIT_MULTISAMPLING:
WARN() << "DIRTY_BIT_MULTISAMPLING unimplemented";
break;