Commit ded7923b by Geoff Lang Committed by Commit Bot

GL backend: Only synchronize transform feedback state when it changes.

BUG=angleproject:2188 Change-Id: I5bfcc038c887dde0770564d103eb3cb234b248c9 Reviewed-on: https://chromium-review.googlesource.com/794100Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 2eeb1b34
...@@ -1157,6 +1157,7 @@ void State::setTransformFeedbackBinding(const Context *context, ...@@ -1157,6 +1157,7 @@ void State::setTransformFeedbackBinding(const Context *context,
TransformFeedback *transformFeedback) TransformFeedback *transformFeedback)
{ {
mTransformFeedback.set(context, transformFeedback); mTransformFeedback.set(context, transformFeedback);
mDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING);
} }
TransformFeedback *State::getCurrentTransformFeedback() const TransformFeedback *State::getCurrentTransformFeedback() const
......
...@@ -399,6 +399,7 @@ class State : public OnAttachmentDirtyReceiver, angle::NonCopyable ...@@ -399,6 +399,7 @@ class State : public OnAttachmentDirtyReceiver, angle::NonCopyable
// TODO(jmadill): Fine-grained dirty bits for each texture/sampler. // TODO(jmadill): Fine-grained dirty bits for each texture/sampler.
DIRTY_BIT_TEXTURE_BINDINGS, DIRTY_BIT_TEXTURE_BINDINGS,
DIRTY_BIT_SAMPLER_BINDINGS, DIRTY_BIT_SAMPLER_BINDINGS,
DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING,
DIRTY_BIT_MULTISAMPLING, DIRTY_BIT_MULTISAMPLING,
DIRTY_BIT_SAMPLE_ALPHA_TO_ONE, DIRTY_BIT_SAMPLE_ALPHA_TO_ONE,
DIRTY_BIT_COVERAGE_MODULATION, // CHROMIUM_framebuffer_mixed_samples DIRTY_BIT_COVERAGE_MODULATION, // CHROMIUM_framebuffer_mixed_samples
......
...@@ -85,8 +85,8 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions, ...@@ -85,8 +85,8 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions,
mSamplers(rendererCaps.maxCombinedTextureImageUnits, 0), mSamplers(rendererCaps.maxCombinedTextureImageUnits, 0),
mImages(rendererCaps.maxImageUnits, ImageUnitBinding()), mImages(rendererCaps.maxImageUnits, ImageUnitBinding()),
mTransformFeedback(0), mTransformFeedback(0),
mCurrentTransformFeedback(nullptr),
mQueries(), mQueries(),
mPrevDrawTransformFeedback(nullptr),
mCurrentQueries(), mCurrentQueries(),
mPrevDrawContext(0), mPrevDrawContext(0),
mUnpackAlignment(4), mUnpackAlignment(4),
...@@ -353,10 +353,10 @@ void StateManagerGL::deleteTransformFeedback(GLuint transformFeedback) ...@@ -353,10 +353,10 @@ void StateManagerGL::deleteTransformFeedback(GLuint transformFeedback)
bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
} }
if (mPrevDrawTransformFeedback != nullptr && if (mCurrentTransformFeedback != nullptr &&
mPrevDrawTransformFeedback->getTransformFeedbackID() == transformFeedback) mCurrentTransformFeedback->getTransformFeedbackID() == transformFeedback)
{ {
mPrevDrawTransformFeedback = nullptr; mCurrentTransformFeedback = nullptr;
} }
mFunctions->deleteTransformFeedbacks(1, &transformFeedback); mFunctions->deleteTransformFeedbacks(1, &transformFeedback);
...@@ -645,18 +645,24 @@ void StateManagerGL::bindTransformFeedback(GLenum type, GLuint transformFeedback ...@@ -645,18 +645,24 @@ void StateManagerGL::bindTransformFeedback(GLenum type, GLuint transformFeedback
// Pause the current transform feedback if one is active. // Pause the current transform feedback if one is active.
// To handle virtualized contexts, StateManagerGL needs to be able to bind a new transform // To handle virtualized contexts, StateManagerGL needs to be able to bind a new transform
// feedback at any time, even if there is one active. // feedback at any time, even if there is one active.
if (mPrevDrawTransformFeedback != nullptr && if (mCurrentTransformFeedback != nullptr &&
mPrevDrawTransformFeedback->getTransformFeedbackID() != transformFeedback) mCurrentTransformFeedback->getTransformFeedbackID() != transformFeedback)
{ {
mPrevDrawTransformFeedback->syncPausedState(true); mCurrentTransformFeedback->syncPausedState(true);
mPrevDrawTransformFeedback = nullptr; mCurrentTransformFeedback = nullptr;
} }
mTransformFeedback = transformFeedback; mTransformFeedback = transformFeedback;
mFunctions->bindTransformFeedback(type, mTransformFeedback); mFunctions->bindTransformFeedback(type, mTransformFeedback);
onTransformFeedbackStateChange();
} }
} }
void StateManagerGL::onTransformFeedbackStateChange()
{
mLocalDirtyBits.set(gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING);
}
void StateManagerGL::beginQuery(GLenum type, GLuint query) 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 // Make sure this is a valid query type and there is no current active query of this type
...@@ -761,9 +767,10 @@ gl::Error StateManagerGL::setDispatchComputeState(const gl::Context *context) ...@@ -761,9 +767,10 @@ gl::Error StateManagerGL::setDispatchComputeState(const gl::Context *context)
void StateManagerGL::pauseTransformFeedback() void StateManagerGL::pauseTransformFeedback()
{ {
if (mPrevDrawTransformFeedback != nullptr) if (mCurrentTransformFeedback != nullptr)
{ {
mPrevDrawTransformFeedback->syncPausedState(true); mCurrentTransformFeedback->syncPausedState(true);
onTransformFeedbackStateChange();
} }
} }
...@@ -820,7 +827,7 @@ gl::Error StateManagerGL::onMakeCurrent(const gl::Context *context) ...@@ -820,7 +827,7 @@ gl::Error StateManagerGL::onMakeCurrent(const gl::Context *context)
ANGLE_TRY(pauseAllQueries()); ANGLE_TRY(pauseAllQueries());
} }
mCurrentQueries.clear(); mCurrentQueries.clear();
mPrevDrawTransformFeedback = nullptr; onTransformFeedbackStateChange();
mPrevDrawContext = contextID; mPrevDrawContext = contextID;
// Set the current query state // Set the current query state
...@@ -1006,24 +1013,6 @@ gl::Error StateManagerGL::setGenericDrawState(const gl::Context *context) ...@@ -1006,24 +1013,6 @@ gl::Error StateManagerGL::setGenericDrawState(const gl::Context *context)
FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer); FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferGL->getFramebufferID()); 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) if (context->getExtensions().webglCompatibility)
{ {
auto activeOutputs = glState.getProgram()->getState().getActiveOutputVariables(); auto activeOutputs = glState.getProgram()->getState().getActiveOutputVariables();
...@@ -1946,6 +1935,9 @@ void StateManagerGL::syncState(const gl::Context *context, const gl::State::Dirt ...@@ -1946,6 +1935,9 @@ void StateManagerGL::syncState(const gl::Context *context, const gl::State::Dirt
case gl::State::DIRTY_BIT_SAMPLER_BINDINGS: case gl::State::DIRTY_BIT_SAMPLER_BINDINGS:
mProgramTexturesAndSamplersDirty = true; mProgramTexturesAndSamplersDirty = true;
break; break;
case gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING:
syncTransformFeedbackState(context);
break;
case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE: case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE:
mProgramTexturesAndSamplersDirty = true; mProgramTexturesAndSamplersDirty = true;
propagateNumViewsToVAO(state.getProgram(), propagateNumViewsToVAO(state.getProgram(),
...@@ -2235,4 +2227,25 @@ void StateManagerGL::updateMultiviewBaseViewLayerIndexUniform( ...@@ -2235,4 +2227,25 @@ void StateManagerGL::updateMultiviewBaseViewLayerIndexUniform(
} }
} }
} }
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;
}
}
} }
...@@ -75,6 +75,7 @@ class StateManagerGL final : angle::NonCopyable ...@@ -75,6 +75,7 @@ class StateManagerGL final : angle::NonCopyable
void bindFramebuffer(GLenum type, GLuint framebuffer); void bindFramebuffer(GLenum type, GLuint framebuffer);
void bindRenderbuffer(GLenum type, GLuint renderbuffer); void bindRenderbuffer(GLenum type, GLuint renderbuffer);
void bindTransformFeedback(GLenum type, GLuint transformFeedback); void bindTransformFeedback(GLenum type, GLuint transformFeedback);
void onTransformFeedbackStateChange();
void beginQuery(GLenum type, GLuint query); void beginQuery(GLenum type, GLuint query);
void endQuery(GLenum type, GLuint query); void endQuery(GLenum type, GLuint query);
void onBeginQuery(QueryGL *query); void onBeginQuery(QueryGL *query);
...@@ -199,6 +200,8 @@ class StateManagerGL final : angle::NonCopyable ...@@ -199,6 +200,8 @@ class StateManagerGL final : angle::NonCopyable
void updateProgramTextureAndSamplerBindings(const gl::Context *context); void updateProgramTextureAndSamplerBindings(const gl::Context *context);
void syncTransformFeedbackState(const gl::Context *context);
enum MultiviewDirtyBitType enum MultiviewDirtyBitType
{ {
MULTIVIEW_DIRTY_BIT_SIDE_BY_SIDE_LAYOUT, MULTIVIEW_DIRTY_BIT_SIDE_BY_SIDE_LAYOUT,
...@@ -246,10 +249,9 @@ class StateManagerGL final : angle::NonCopyable ...@@ -246,10 +249,9 @@ class StateManagerGL final : angle::NonCopyable
std::vector<ImageUnitBinding> mImages; std::vector<ImageUnitBinding> mImages;
GLuint mTransformFeedback; GLuint mTransformFeedback;
TransformFeedbackGL *mCurrentTransformFeedback;
std::map<GLenum, GLuint> mQueries; std::map<GLenum, GLuint> mQueries;
TransformFeedbackGL *mPrevDrawTransformFeedback;
std::set<QueryGL *> mCurrentQueries; std::set<QueryGL *> mCurrentQueries;
gl::ContextID mPrevDrawContext; gl::ContextID mPrevDrawContext;
......
...@@ -38,22 +38,27 @@ TransformFeedbackGL::~TransformFeedbackGL() ...@@ -38,22 +38,27 @@ TransformFeedbackGL::~TransformFeedbackGL()
void TransformFeedbackGL::begin(GLenum primitiveMode) void TransformFeedbackGL::begin(GLenum primitiveMode)
{ {
// Do not begin directly, StateManagerGL will handle beginning and resuming transform feedback. mStateManager->onTransformFeedbackStateChange();
} }
void TransformFeedbackGL::end() void TransformFeedbackGL::end()
{ {
mStateManager->onTransformFeedbackStateChange();
// Immediately end the transform feedback so that the results are visible.
syncActiveState(false, GL_NONE); syncActiveState(false, GL_NONE);
} }
void TransformFeedbackGL::pause() void TransformFeedbackGL::pause()
{ {
mStateManager->onTransformFeedbackStateChange();
syncPausedState(true); syncPausedState(true);
} }
void TransformFeedbackGL::resume() 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) void TransformFeedbackGL::bindGenericBuffer(const gl::BindingPointer<gl::Buffer> &binding)
......
...@@ -709,6 +709,9 @@ void ContextVk::syncState(const gl::Context *context, const gl::State::DirtyBits ...@@ -709,6 +709,9 @@ void ContextVk::syncState(const gl::Context *context, const gl::State::DirtyBits
case gl::State::DIRTY_BIT_SAMPLER_BINDINGS: case gl::State::DIRTY_BIT_SAMPLER_BINDINGS:
dirtyTextures = true; dirtyTextures = true;
break; break;
case gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING:
WARN() << "DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING unimplemented";
break;
case gl::State::DIRTY_BIT_MULTISAMPLING: case gl::State::DIRTY_BIT_MULTISAMPLING:
WARN() << "DIRTY_BIT_MULTISAMPLING unimplemented"; WARN() << "DIRTY_BIT_MULTISAMPLING unimplemented";
break; break;
......
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