Optimize check for active not paused XFB.
Local testing showed an improved score of about 2% in the most
sensitive CPU overhead benchmark. Likely because of improved
caching from fewer indirections.
Bug: angleproject:2966
Change-Id: I5d9a4b4bcf624ab0b430bb696c4227e589cdb7a6
Reviewed-on: https://chromium-review.googlesource.com/c/1359518
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index ec13562..5a62efe 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -132,12 +132,12 @@
}
ANGLE_INLINE void MarkTransformFeedbackBufferUsage(const Context *context,
- TransformFeedback *transformFeedback,
GLsizei count,
GLsizei instanceCount)
{
- if (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
+ if (context->getStateCache().isTransformFeedbackActiveUnpaused())
{
+ TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
transformFeedback->onVerticesDrawn(context, count, instanceCount);
}
}
@@ -2221,7 +2221,7 @@
ANGLE_CONTEXT_TRY(prepareForDraw(mode));
ANGLE_CONTEXT_TRY(mImplementation->drawArrays(this, mode, first, count));
- MarkTransformFeedbackBufferUsage(this, mGLState.getCurrentTransformFeedback(), count, 1);
+ MarkTransformFeedbackBufferUsage(this, count, 1);
}
void Context::drawArraysInstanced(PrimitiveMode mode,
@@ -2238,8 +2238,7 @@
ANGLE_CONTEXT_TRY(prepareForDraw(mode));
ANGLE_CONTEXT_TRY(
mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
- MarkTransformFeedbackBufferUsage(this, mGLState.getCurrentTransformFeedback(), count,
- instanceCount);
+ MarkTransformFeedbackBufferUsage(this, count, instanceCount);
}
void Context::drawElements(PrimitiveMode mode,
@@ -5406,8 +5405,7 @@
programObject->setDrawIDUniform(drawID);
ANGLE_CONTEXT_TRY(
mImplementation->drawArrays(this, mode, firsts[drawID], counts[drawID]));
- MarkTransformFeedbackBufferUsage(this, mGLState.getCurrentTransformFeedback(),
- counts[drawID], 1);
+ MarkTransformFeedbackBufferUsage(this, counts[drawID], 1);
}
}
else
@@ -5420,8 +5418,7 @@
}
ANGLE_CONTEXT_TRY(
mImplementation->drawArrays(this, mode, firsts[drawID], counts[drawID]));
- MarkTransformFeedbackBufferUsage(this, mGLState.getCurrentTransformFeedback(),
- counts[drawID], 1);
+ MarkTransformFeedbackBufferUsage(this, counts[drawID], 1);
}
}
}
@@ -5446,8 +5443,7 @@
programObject->setDrawIDUniform(drawID);
ANGLE_CONTEXT_TRY(mImplementation->drawArraysInstanced(
this, mode, firsts[drawID], counts[drawID], instanceCounts[drawID]));
- MarkTransformFeedbackBufferUsage(this, mGLState.getCurrentTransformFeedback(),
- counts[drawID], instanceCounts[drawID]);
+ MarkTransformFeedbackBufferUsage(this, counts[drawID], instanceCounts[drawID]);
}
}
else
@@ -5460,8 +5456,7 @@
}
ANGLE_CONTEXT_TRY(mImplementation->drawArraysInstanced(
this, mode, firsts[drawID], counts[drawID], instanceCounts[drawID]));
- MarkTransformFeedbackBufferUsage(this, mGLState.getCurrentTransformFeedback(),
- counts[drawID], instanceCounts[drawID]);
+ MarkTransformFeedbackBufferUsage(this, counts[drawID], instanceCounts[drawID]);
}
}
}
@@ -8192,7 +8187,8 @@
mCachedNonInstancedVertexElementLimit(0),
mCachedInstancedVertexElementLimit(0),
mCachedBasicDrawStatesError(kInvalidPointer),
- mCachedBasicDrawElementsError(kInvalidPointer)
+ mCachedBasicDrawElementsError(kInvalidPointer),
+ mCachedTransformFeedbackActiveUnpaused(false)
{}
StateCache::~StateCache() = default;
@@ -8375,6 +8371,7 @@
void StateCache::onActiveTransformFeedbackChange(Context *context)
{
+ updateTransformFeedbackActiveUnpaused(context);
updateBasicDrawStatesError();
updateBasicDrawElementsError();
updateValidDrawModes(context);
@@ -8415,10 +8412,10 @@
const State &state = context->getGLState();
Program *program = state.getProgram();
- TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
- if (curTransformFeedback && curTransformFeedback->isActive() &&
- !curTransformFeedback->isPaused())
+ if (mCachedTransformFeedbackActiveUnpaused)
{
+ TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
+
// ES Spec 3.0 validation text:
// When transform feedback is active and not paused, all geometric primitives generated must
// match the value of primitiveMode passed to BeginTransformFeedback. The error
@@ -8495,4 +8492,10 @@
{DrawElementsType::UnsignedInt, supportsUint},
}};
}
+
+void StateCache::updateTransformFeedbackActiveUnpaused(Context *context)
+{
+ TransformFeedback *xfb = context->getGLState().getCurrentTransformFeedback();
+ mCachedTransformFeedbackActiveUnpaused = xfb && xfb->isActive() && !xfb->isPaused();
+}
} // namespace gl
diff --git a/src/libANGLE/Context.h b/src/libANGLE/Context.h
index b09b6f7..be1e973 100644
--- a/src/libANGLE/Context.h
+++ b/src/libANGLE/Context.h
@@ -171,12 +171,19 @@
return mCachedValidBindTextureTypes[type];
}
- // Cannot chance except on Context/Extension init.
+ // Cannot change except on Context/Extension init.
bool isValidDrawElementsType(DrawElementsType type) const
{
return mCachedValidDrawElementsTypes[type];
}
+ // Places that can trigger updateTransformFeedbackActiveUnpaused:
+ // 1. onActiveTransformFeedbackChange.
+ bool isTransformFeedbackActiveUnpaused() const
+ {
+ return mCachedTransformFeedbackActiveUnpaused;
+ }
+
// State change notifications.
void onVertexArrayBindingChange(Context *context);
void onProgramExecutableChange(Context *context);
@@ -204,6 +211,7 @@
void updateValidDrawElementsTypes(Context *context);
void updateBasicDrawStatesError();
void updateBasicDrawElementsError();
+ void updateTransformFeedbackActiveUnpaused(Context *context);
void setValidDrawModes(bool pointsOK, bool linesOK, bool trisOK, bool lineAdjOK, bool triAdjOK);
@@ -220,6 +228,7 @@
GLint64 mCachedInstancedVertexElementLimit;
mutable intptr_t mCachedBasicDrawStatesError;
mutable intptr_t mCachedBasicDrawElementsError;
+ bool mCachedTransformFeedbackActiveUnpaused;
// Reserve an extra slot at the end of these maps for invalid enum.
angle::PackedEnumMap<PrimitiveMode, bool, angle::EnumSize<PrimitiveMode>() + 1>
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 9170c07..4046c97 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -2856,11 +2856,10 @@
return false;
}
- const State &state = context->getGLState();
- TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
- if (curTransformFeedback && curTransformFeedback->isActive() &&
- !curTransformFeedback->isPaused())
+ if (context->getStateCache().isTransformFeedbackActiveUnpaused())
{
+ const State &state = context->getGLState();
+ TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
if (!curTransformFeedback->checkBufferSpaceForDraw(count, primcount))
{
context->validationError(GL_INVALID_OPERATION, kTransformFeedbackBufferTooSmall);
@@ -2943,9 +2942,7 @@
{
const State &state = context->getGLState();
- TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
- if (curTransformFeedback && curTransformFeedback->isActive() &&
- !curTransformFeedback->isPaused())
+ if (context->getStateCache().isTransformFeedbackActiveUnpaused())
{
// EXT_geometry_shader allows transform feedback to work with all draw commands.
// [EXT_geometry_shader] Section 12.1, "Transform Feedback"