Commit bf5177d3 by Jamie Madill Committed by Commit Bot

Optimize element array binding.

This inlines some methods and code that was regressing binding performance. Improves the score of a bindings benchmark by 15%. Based on contributions by matavenrath@nvidia.com. Test: bindings_gl_100_objects_allocated_at_initialization Bug: angleproject:2777 Change-Id: Ied5fdbc67ced862a36c5145fff5ac94f93b40c21 Reviewed-on: https://chromium-review.googlesource.com/1181865Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent a4e40b72
......@@ -256,15 +256,10 @@ bool Buffer::isBoundForTransformFeedbackAndOtherUse() const
mState.mBindingCount - mState.mTransformFeedbackGenericBindingCount;
}
void Buffer::onBindingChanged(const Context *context,
bool bound,
BufferBinding target,
bool indexed)
void Buffer::onTFBindingChanged(const Context *context, bool bound, bool indexed)
{
ASSERT(bound || mState.mBindingCount > 0);
mState.mBindingCount += bound ? 1 : -1;
if (target == BufferBinding::TransformFeedback)
{
if (indexed)
{
ASSERT(bound || mState.mTransformFeedbackIndexedBindingCount > 0);
......@@ -276,7 +271,6 @@ void Buffer::onBindingChanged(const Context *context,
{
mState.mTransformFeedbackGenericBindingCount += bound ? 1 : -1;
}
}
}
} // namespace gl
......@@ -117,7 +117,8 @@ class Buffer final : public RefCountObject, public LabeledObject
bool isBound() const;
bool isBoundForTransformFeedbackAndOtherUse() const;
void onBindingChanged(const Context *context, bool bound, BufferBinding target, bool indexed);
void onTFBindingChanged(const Context *context, bool bound, bool indexed);
void onNonTFBindingChanged(const Context *context, int incr) { mState.mBindingCount += incr; }
private:
BufferState mState;
......
......@@ -6562,10 +6562,6 @@ bool Context::isCurrentTransformFeedback(const TransformFeedback *tf) const
{
return mGLState.isCurrentTransformFeedback(tf);
}
bool Context::isCurrentVertexArray(const VertexArray *va) const
{
return mGLState.isCurrentVertexArray(va);
}
void Context::genProgramPipelines(GLsizei count, GLuint *pipelines)
{
......
......@@ -1492,7 +1492,11 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
bool isRobustResourceInitEnabled() const { return mGLState.isRobustResourceInitEnabled(); }
bool isCurrentTransformFeedback(const TransformFeedback *tf) const;
bool isCurrentVertexArray(const VertexArray *va) const;
bool isCurrentVertexArray(const VertexArray *va) const
{
return mGLState.isCurrentVertexArray(va);
}
const ContextState &getContextState() const { return mState; }
GLint getClientMajorVersion() const { return mState.getClientMajorVersion(); }
......
......@@ -49,32 +49,56 @@ bool GetAlternativeQueryType(QueryType type, QueryType *alternativeType)
} // anonymous namepace
void UpdateBufferBinding(const Context *context,
BindingPointer<Buffer> *binding,
Buffer *buffer,
BufferBinding target,
bool indexed)
template <typename BindingT, typename... ArgsT>
void UpdateNonTFBufferBinding(const Context *context, BindingT *binding, ArgsT... args)
{
if (binding->get())
(*binding)->onBindingChanged(context, false, target, indexed);
binding->set(context, buffer);
(*binding)->onNonTFBindingChanged(context, -1);
binding->set(context, args...);
if (binding->get())
(*binding)->onBindingChanged(context, true, target, indexed);
(*binding)->onNonTFBindingChanged(context, 1);
}
template <typename BindingT, typename... ArgsT>
void UpdateTFBufferBinding(const Context *context, BindingT *binding, bool indexed, ArgsT... args)
{
if (binding->get())
(*binding)->onTFBindingChanged(context, false, indexed);
binding->set(context, args...);
if (binding->get())
(*binding)->onTFBindingChanged(context, true, indexed);
}
void UpdateBufferBinding(const Context *context,
BindingPointer<Buffer> *binding,
Buffer *buffer,
BufferBinding target)
{
if (target == BufferBinding::TransformFeedback)
{
UpdateTFBufferBinding(context, binding, false, buffer);
}
else
{
UpdateNonTFBufferBinding(context, binding, buffer);
}
}
void UpdateIndexedBufferBinding(const Context *context,
OffsetBindingPointer<Buffer> *binding,
Buffer *buffer,
BufferBinding target,
bool indexed,
GLintptr offset,
GLsizeiptr size)
{
if (binding->get())
(*binding)->onBindingChanged(context, false, target, indexed);
binding->set(context, buffer, offset, size);
if (binding->get())
(*binding)->onBindingChanged(context, true, target, indexed);
if (target == BufferBinding::TransformFeedback)
{
UpdateTFBufferBinding(context, binding, true, buffer, offset, size);
}
else
{
UpdateNonTFBufferBinding(context, binding, buffer, offset, size);
}
}
State::State(bool debug,
......@@ -284,7 +308,7 @@ void State::reset(const Context *context)
for (auto type : angle::AllEnums<BufferBinding>())
{
UpdateBufferBinding(context, &mBoundBuffers[type], nullptr, type, false);
UpdateBufferBinding(context, &mBoundBuffers[type], nullptr, type);
}
if (mProgram)
......@@ -306,17 +330,17 @@ void State::reset(const Context *context)
for (auto &buf : mUniformBuffers)
{
UpdateBufferBinding(context, &buf, nullptr, BufferBinding::Uniform, true);
UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::Uniform, 0, 0);
}
for (auto &buf : mAtomicCounterBuffers)
{
UpdateBufferBinding(context, &buf, nullptr, BufferBinding::AtomicCounter, true);
UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::AtomicCounter, 0, 0);
}
for (auto &buf : mShaderStorageBuffers)
{
UpdateBufferBinding(context, &buf, nullptr, BufferBinding::ShaderStorage, true);
UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::ShaderStorage, 0, 0);
}
angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
......@@ -1243,10 +1267,10 @@ void State::setVertexArrayBinding(const Context *context, VertexArray *vertexArr
if (mVertexArray == vertexArray)
return;
if (mVertexArray)
mVertexArray->onBindingChanged(context, false);
mVertexArray->onBindingChanged(context, -1);
mVertexArray = vertexArray;
if (vertexArray)
vertexArray->onBindingChanged(context, true);
vertexArray->onBindingChanged(context, 1);
mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
if (mVertexArray && mVertexArray->hasAnyDirtyBit())
......@@ -1265,7 +1289,7 @@ bool State::removeVertexArrayBinding(const Context *context, GLuint vertexArray)
{
if (mVertexArray && mVertexArray->id() == vertexArray)
{
mVertexArray->onBindingChanged(context, false);
mVertexArray->onBindingChanged(context, -1);
mVertexArray = nullptr;
mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
......@@ -1425,19 +1449,19 @@ void State::setBufferBinding(const Context *context, BufferBinding target, Buffe
switch (target)
{
case BufferBinding::PixelPack:
UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target, false);
UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target);
mDirtyBits.set(DIRTY_BIT_PACK_BUFFER_BINDING);
break;
case BufferBinding::PixelUnpack:
UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target, false);
UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target);
mDirtyBits.set(DIRTY_BIT_UNPACK_BUFFER_BINDING);
break;
case BufferBinding::DrawIndirect:
UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target, false);
UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target);
mDirtyBits.set(DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING);
break;
case BufferBinding::DispatchIndirect:
UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target, false);
UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target);
mDirtyBits.set(DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING);
break;
case BufferBinding::ElementArray:
......@@ -1445,11 +1469,11 @@ void State::setBufferBinding(const Context *context, BufferBinding target, Buffe
mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
break;
case BufferBinding::ShaderStorage:
UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target, false);
UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target);
mDirtyBits.set(DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
break;
default:
UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target, false);
UpdateBufferBinding(context, &mBoundBuffers[target], buffer, target);
break;
}
}
......@@ -1470,16 +1494,16 @@ void State::setIndexedBufferBinding(const Context *context,
setBufferBinding(context, target, buffer);
break;
case BufferBinding::Uniform:
UpdateBufferBinding(context, &mUniformBuffers[index], buffer, target, true, offset,
UpdateIndexedBufferBinding(context, &mUniformBuffers[index], buffer, target, offset,
size);
mDirtyBits.set(DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
break;
case BufferBinding::AtomicCounter:
UpdateBufferBinding(context, &mAtomicCounterBuffers[index], buffer, target, true,
UpdateIndexedBufferBinding(context, &mAtomicCounterBuffers[index], buffer, target,
offset, size);
break;
case BufferBinding::ShaderStorage:
UpdateBufferBinding(context, &mShaderStorageBuffers[index], buffer, target, true,
UpdateIndexedBufferBinding(context, &mShaderStorageBuffers[index], buffer, target,
offset, size);
break;
default:
......@@ -1528,7 +1552,7 @@ void State::detachBuffer(const Context *context, const Buffer *buffer)
{
if (mBoundBuffers[target].id() == bufferName)
{
UpdateBufferBinding(context, &mBoundBuffers[target], nullptr, target, false);
UpdateBufferBinding(context, &mBoundBuffers[target], nullptr, target);
}
}
......@@ -1544,7 +1568,7 @@ void State::detachBuffer(const Context *context, const Buffer *buffer)
{
if (buf.id() == bufferName)
{
UpdateBufferBinding(context, &buf, nullptr, BufferBinding::Uniform, true);
UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::Uniform, 0, 0);
}
}
......@@ -1552,7 +1576,7 @@ void State::detachBuffer(const Context *context, const Buffer *buffer)
{
if (buf.id() == bufferName)
{
UpdateBufferBinding(context, &buf, nullptr, BufferBinding::AtomicCounter, true);
UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::AtomicCounter, 0, 0);
}
}
......@@ -1560,7 +1584,7 @@ void State::detachBuffer(const Context *context, const Buffer *buffer)
{
if (buf.id() == bufferName)
{
UpdateBufferBinding(context, &buf, nullptr, BufferBinding::ShaderStorage, true);
UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::ShaderStorage, 0, 0);
}
}
}
......@@ -2879,9 +2903,4 @@ bool State::isCurrentTransformFeedback(const TransformFeedback *tf) const
{
return tf == mTransformFeedback.get();
}
bool State::isCurrentVertexArray(const VertexArray *va) const
{
return va == mVertexArray;
}
} // namespace gl
......@@ -477,7 +477,8 @@ class State : angle::NonCopyable
Error clearUnclearedActiveTextures(const Context *context);
bool isCurrentTransformFeedback(const TransformFeedback *tf) const;
bool isCurrentVertexArray(const VertexArray *va) const;
bool isCurrentVertexArray(const VertexArray *va) const { return va == mVertexArray; }
GLES1State &gles1() { return mGLES1State; }
const GLES1State &gles1() const { return mGLES1State; }
......
......@@ -238,8 +238,7 @@ void TransformFeedback::detachBuffer(const Context *context, GLuint bufferName)
{
if (isBound)
{
mState.mIndexedBuffers[index]->onBindingChanged(
context, false, BufferBinding::TransformFeedback, true);
mState.mIndexedBuffers[index]->onTFBindingChanged(context, false, true);
}
mState.mIndexedBuffers[index].set(context, nullptr);
mImplementation->bindIndexedBuffer(index, mState.mIndexedBuffers[index]);
......@@ -257,13 +256,12 @@ void TransformFeedback::bindIndexedBuffer(const Context *context,
bool isBound = context && context->isCurrentTransformFeedback(this);
if (isBound && mState.mIndexedBuffers[index].get())
{
mState.mIndexedBuffers[index]->onBindingChanged(context, false,
BufferBinding::TransformFeedback, true);
mState.mIndexedBuffers[index]->onTFBindingChanged(context, false, true);
}
mState.mIndexedBuffers[index].set(context, buffer, offset, size);
if (isBound && buffer)
{
buffer->onBindingChanged(context, true, BufferBinding::TransformFeedback, true);
buffer->onTFBindingChanged(context, true, true);
}
mImplementation->bindIndexedBuffer(index, mState.mIndexedBuffers[index]);
......@@ -308,7 +306,7 @@ void TransformFeedback::onBindingChanged(const Context *context, bool bound)
{
if (buffer.get())
{
buffer->onBindingChanged(context, bound, BufferBinding::TransformFeedback, true);
buffer->onTFBindingChanged(context, bound, true);
}
}
}
......
......@@ -107,8 +107,7 @@ void VertexArray::onDestroy(const Context *context)
binding.setBuffer(context, nullptr, isBound);
}
if (isBound && mState.mElementArrayBuffer.get())
mState.mElementArrayBuffer->onBindingChanged(context, false, BufferBinding::ElementArray,
false);
mState.mElementArrayBuffer->onNonTFBindingChanged(context, -1);
mState.mElementArrayBuffer.set(context, nullptr);
mVertexArray->destroy(context);
SafeDelete(mVertexArray);
......@@ -149,8 +148,7 @@ void VertexArray::detachBuffer(const Context *context, GLuint bufferName)
if (mState.mElementArrayBuffer.id() == bufferName)
{
if (isBound && mState.mElementArrayBuffer.get())
mState.mElementArrayBuffer->onBindingChanged(context, false, BufferBinding::Array,
false);
mState.mElementArrayBuffer->onNonTFBindingChanged(context, -1);
mState.mElementArrayBuffer.set(context, nullptr);
}
}
......@@ -357,14 +355,18 @@ void VertexArray::setVertexAttribPointer(const Context *context,
void VertexArray::setElementArrayBuffer(const Context *context, Buffer *buffer)
{
bool isBound = context->isCurrentVertexArray(this);
if (isBound && mState.mElementArrayBuffer.get())
mState.mElementArrayBuffer->onBindingChanged(context, false, BufferBinding::ElementArray,
false);
if (context->isCurrentVertexArray(this))
{
if (mState.mElementArrayBuffer.get())
{
mState.mElementArrayBuffer->onNonTFBindingChanged(context, -1);
}
if (buffer)
{
buffer->onNonTFBindingChanged(context, 1);
}
}
mState.mElementArrayBuffer.set(context, buffer);
if (isBound && mState.mElementArrayBuffer.get())
mState.mElementArrayBuffer->onBindingChanged(context, true, BufferBinding::ElementArray,
false);
mElementArrayBufferObserverBinding.bind(buffer ? buffer->getImplementation() : nullptr);
mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
}
......@@ -389,14 +391,13 @@ gl::Error VertexArray::syncState(const Context *context)
return gl::NoError();
}
void VertexArray::onBindingChanged(const Context *context, bool bound)
void VertexArray::onBindingChanged(const Context *context, int incr)
{
if (mState.mElementArrayBuffer.get())
mState.mElementArrayBuffer->onBindingChanged(context, bound, BufferBinding::ElementArray,
false);
mState.mElementArrayBuffer->onNonTFBindingChanged(context, incr);
for (auto &binding : mState.mVertexBindings)
{
binding.onContainerBindingChanged(context, bound);
binding.onContainerBindingChanged(context, incr);
}
}
......
......@@ -254,7 +254,7 @@ class VertexArray final : public angle::ObserverInterface,
ComponentTypeMask getAttributesTypeMask() const { return mState.mVertexAttributesTypeMask; }
AttributesMask getAttributesMask() const { return mState.mEnabledAttributesMask; }
void onBindingChanged(const Context *context, bool bound);
void onBindingChanged(const Context *context, int incr);
bool hasTransformFeedbackBindingConflict(const gl::Context *context) const;
private:
......
......@@ -46,17 +46,20 @@ VertexBinding &VertexBinding::operator=(VertexBinding &&binding)
void VertexBinding::setBuffer(const gl::Context *context, Buffer *bufferIn, bool containerIsBound)
{
if (mBuffer.get() && containerIsBound)
mBuffer->onBindingChanged(context, false, BufferBinding::Array, true);
if (containerIsBound)
{
if (mBuffer.get())
mBuffer->onNonTFBindingChanged(context, -1);
if (bufferIn)
bufferIn->onNonTFBindingChanged(context, 1);
}
mBuffer.set(context, bufferIn);
if (mBuffer.get() && containerIsBound)
mBuffer->onBindingChanged(context, true, BufferBinding::Array, true);
}
void VertexBinding::onContainerBindingChanged(const Context *context, bool bound) const
void VertexBinding::onContainerBindingChanged(const Context *context, int incr) const
{
if (mBuffer.get())
mBuffer->onBindingChanged(context, bound, BufferBinding::Array, true);
mBuffer->onNonTFBindingChanged(context, incr);
}
VertexAttribute::VertexAttribute(GLuint bindingIndex)
......
......@@ -41,7 +41,7 @@ class VertexBinding final : angle::NonCopyable
const BindingPointer<Buffer> &getBuffer() const { return mBuffer; }
void setBuffer(const gl::Context *context, Buffer *bufferIn, bool containerIsBound);
void onContainerBindingChanged(const Context *context, bool bound) const;
void onContainerBindingChanged(const Context *context, int incr) const;
const AttributesMask &getBoundAttributesMask() const { return mBoundAttributesMask; }
......
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