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,
TransformFeedback *transformFeedback)
{
mTransformFeedback.set(context, transformFeedback);
mDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING);
}
TransformFeedback *State::getCurrentTransformFeedback() const
......
......@@ -399,6 +399,7 @@ class State : public OnAttachmentDirtyReceiver, angle::NonCopyable
// 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
......
......@@ -85,8 +85,8 @@ StateManagerGL::StateManagerGL(const FunctionsGL *functions,
mSamplers(rendererCaps.maxCombinedTextureImageUnits, 0),
mImages(rendererCaps.maxImageUnits, ImageUnitBinding()),
mTransformFeedback(0),
mCurrentTransformFeedback(nullptr),
mQueries(),
mPrevDrawTransformFeedback(nullptr),
mCurrentQueries(),
mPrevDrawContext(0),
mUnpackAlignment(4),
......@@ -353,10 +353,10 @@ void StateManagerGL::deleteTransformFeedback(GLuint transformFeedback)
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 @@ void StateManagerGL::bindTransformFeedback(GLenum type, GLuint transformFeedback
// 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 @@ gl::Error StateManagerGL::setDispatchComputeState(const gl::Context *context)
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)
ANGLE_TRY(pauseAllQueries());
}
mCurrentQueries.clear();
mPrevDrawTransformFeedback = nullptr;
onTransformFeedbackStateChange();
mPrevDrawContext = contextID;
// Set the current query state
......@@ -1006,24 +1013,6 @@ gl::Error StateManagerGL::setGenericDrawState(const gl::Context *context)
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 @@ void StateManagerGL::syncState(const gl::Context *context, const gl::State::Dirt
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::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
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 @@ class StateManagerGL final : angle::NonCopyable
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 @@ class StateManagerGL final : angle::NonCopyable
std::vector<ImageUnitBinding> mImages;
GLuint mTransformFeedback;
TransformFeedbackGL *mCurrentTransformFeedback;
std::map<GLenum, GLuint> mQueries;
TransformFeedbackGL *mPrevDrawTransformFeedback;
std::set<QueryGL *> mCurrentQueries;
gl::ContextID mPrevDrawContext;
......
......@@ -38,22 +38,27 @@ TransformFeedbackGL::~TransformFeedbackGL()
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)
......
......@@ -709,6 +709,9 @@ void ContextVk::syncState(const gl::Context *context, const gl::State::DirtyBits
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;
......
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