Commit ad63728b by Jamie Madill Committed by Commit Bot

VertexArray: Store bound attributes mask in binding.

Making the bound attributes mask part of the struct keeps the style a bit more consistent. It will also make updating the cache variable a bit easier. Bug: angleproject:1391 Change-Id: I2b0ba1161d2579d95ddfbae7a05e490c9644a126 Reviewed-on: https://chromium-review.googlesource.com/1150513 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent ac43aaa2
...@@ -105,7 +105,10 @@ class BindingPointer ...@@ -105,7 +105,10 @@ class BindingPointer
BindingPointer(const BindingPointer<ObjectType> &other) : mObject(other.mObject) BindingPointer(const BindingPointer<ObjectType> &other) : mObject(other.mObject)
{ {
mObject->addRef(); if (mObject)
{
mObject->addRef();
}
} }
BindingPointer &operator=(BindingPointer<ObjectType> &&other) BindingPointer &operator=(BindingPointer<ObjectType> &&other)
......
...@@ -17,14 +17,14 @@ namespace gl ...@@ -17,14 +17,14 @@ namespace gl
{ {
// VertexArrayState implementation. // VertexArrayState implementation.
VertexArrayState::VertexArrayState(size_t maxAttribs, size_t maxAttribBindings) VertexArrayState::VertexArrayState(size_t maxAttribs, size_t maxAttribBindings)
: mLabel(), mVertexBindings(maxAttribBindings) : mLabel(), mVertexBindings()
{ {
ASSERT(maxAttribs <= maxAttribBindings); ASSERT(maxAttribs <= maxAttribBindings);
for (size_t i = 0; i < maxAttribs; i++) for (size_t i = 0; i < maxAttribs; i++)
{ {
mVertexAttributes.emplace_back(static_cast<GLuint>(i)); mVertexAttributes.emplace_back(static_cast<GLuint>(i));
mBindingToAttributeMasks[i].set(i); mVertexBindings.emplace_back(static_cast<GLuint>(i));
} }
// Initially all attributes start as "client" with no buffer bound. // Initially all attributes start as "client" with no buffer bound.
...@@ -40,10 +40,10 @@ bool VertexArrayState::hasEnabledNullPointerClientArray() const ...@@ -40,10 +40,10 @@ bool VertexArrayState::hasEnabledNullPointerClientArray() const
return (mNullPointerClientMemoryAttribsMask & mEnabledAttributesMask).any(); return (mNullPointerClientMemoryAttribsMask & mEnabledAttributesMask).any();
} }
AttributesMask VertexArrayState::getBindingToAttributeMasks(GLuint bindingIndex) const AttributesMask VertexArrayState::getBindingToAttributesMask(GLuint bindingIndex) const
{ {
ASSERT(bindingIndex < MAX_VERTEX_ATTRIB_BINDINGS); ASSERT(bindingIndex < MAX_VERTEX_ATTRIB_BINDINGS);
return mBindingToAttributeMasks[bindingIndex]; return mVertexBindings[bindingIndex].getBoundAttributesMask();
} }
// Set an attribute using a new binding. // Set an attribute using a new binding.
...@@ -55,11 +55,11 @@ void VertexArrayState::setAttribBinding(size_t attribIndex, GLuint newBindingInd ...@@ -55,11 +55,11 @@ void VertexArrayState::setAttribBinding(size_t attribIndex, GLuint newBindingInd
const GLuint oldBindingIndex = mVertexAttributes[attribIndex].bindingIndex; const GLuint oldBindingIndex = mVertexAttributes[attribIndex].bindingIndex;
ASSERT(oldBindingIndex != newBindingIndex); ASSERT(oldBindingIndex != newBindingIndex);
ASSERT(mBindingToAttributeMasks[oldBindingIndex].test(attribIndex) && ASSERT(mVertexBindings[oldBindingIndex].getBoundAttributesMask().test(attribIndex) &&
!mBindingToAttributeMasks[newBindingIndex].test(attribIndex)); !mVertexBindings[newBindingIndex].getBoundAttributesMask().test(attribIndex));
mBindingToAttributeMasks[oldBindingIndex].reset(attribIndex); mVertexBindings[oldBindingIndex].resetBoundAttribute(attribIndex);
mBindingToAttributeMasks[newBindingIndex].set(attribIndex); mVertexBindings[newBindingIndex].setBoundAttribute(attribIndex);
// Set the attribute using the new binding. // Set the attribute using the new binding.
mVertexAttributes[attribIndex].bindingIndex = newBindingIndex; mVertexAttributes[attribIndex].bindingIndex = newBindingIndex;
...@@ -191,11 +191,11 @@ void VertexArray::bindVertexBufferImpl(const Context *context, ...@@ -191,11 +191,11 @@ void VertexArray::bindVertexBufferImpl(const Context *context,
// Update client memory attribute pointers. Affects all bound attributes. // Update client memory attribute pointers. Affects all bound attributes.
if (boundBuffer) if (boundBuffer)
{ {
mState.mClientMemoryAttribsMask &= ~mState.mBindingToAttributeMasks[bindingIndex]; mState.mClientMemoryAttribsMask &= ~binding->getBoundAttributesMask();
} }
else else
{ {
mState.mClientMemoryAttribsMask |= mState.mBindingToAttributeMasks[bindingIndex]; mState.mClientMemoryAttribsMask |= binding->getBoundAttributesMask();
} }
} }
......
...@@ -69,7 +69,7 @@ class VertexArrayState final : angle::NonCopyable ...@@ -69,7 +69,7 @@ class VertexArrayState final : angle::NonCopyable
bool hasEnabledNullPointerClientArray() const; bool hasEnabledNullPointerClientArray() const;
// Get all the attributes in an AttributesMask that are using the given binding. // Get all the attributes in an AttributesMask that are using the given binding.
AttributesMask getBindingToAttributeMasks(GLuint bindingIndex) const; AttributesMask getBindingToAttributesMask(GLuint bindingIndex) const;
private: private:
friend class VertexArray; friend class VertexArray;
...@@ -86,11 +86,6 @@ class VertexArrayState final : angle::NonCopyable ...@@ -86,11 +86,6 @@ class VertexArrayState final : angle::NonCopyable
// attribs. // attribs.
gl::AttributesMask mClientMemoryAttribsMask; gl::AttributesMask mClientMemoryAttribsMask;
gl::AttributesMask mNullPointerClientMemoryAttribsMask; gl::AttributesMask mNullPointerClientMemoryAttribsMask;
// Records the mappings from each binding to all of the attributes that are using that binding.
// It is used to label all the relevant attributes dirty when we are updating a dirty binding in
// VertexArray11::syncStates().
std::array<AttributesMask, MAX_VERTEX_ATTRIB_BINDINGS> mBindingToAttributeMasks;
}; };
class VertexArray final : public angle::ObserverInterface, public LabeledObject class VertexArray final : public angle::ObserverInterface, public LabeledObject
......
...@@ -13,9 +13,14 @@ namespace gl ...@@ -13,9 +13,14 @@ namespace gl
// [OpenGL ES 3.1] (November 3, 2016) Section 20 Page 361 // [OpenGL ES 3.1] (November 3, 2016) Section 20 Page 361
// Table 20.2: Vertex Array Object State // Table 20.2: Vertex Array Object State
VertexBinding::VertexBinding() VertexBinding::VertexBinding() : VertexBinding(0)
{
}
VertexBinding::VertexBinding(GLuint boundAttribute)
: mStride(16u), mDivisor(0), mOffset(0), mCachedBufferSizeMinusOffset(0) : mStride(16u), mDivisor(0), mOffset(0), mCachedBufferSizeMinusOffset(0)
{ {
mBoundAttributesMask.set(boundAttribute);
} }
VertexBinding::VertexBinding(VertexBinding &&binding) VertexBinding::VertexBinding(VertexBinding &&binding)
...@@ -34,6 +39,7 @@ VertexBinding &VertexBinding::operator=(VertexBinding &&binding) ...@@ -34,6 +39,7 @@ VertexBinding &VertexBinding::operator=(VertexBinding &&binding)
mStride = binding.mStride; mStride = binding.mStride;
mDivisor = binding.mDivisor; mDivisor = binding.mDivisor;
mOffset = binding.mOffset; mOffset = binding.mOffset;
mBoundAttributesMask = binding.mBoundAttributesMask;
std::swap(binding.mBuffer, mBuffer); std::swap(binding.mBuffer, mBuffer);
mCachedBufferSizeMinusOffset = binding.mCachedBufferSizeMinusOffset; mCachedBufferSizeMinusOffset = binding.mCachedBufferSizeMinusOffset;
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define LIBANGLE_VERTEXATTRIBUTE_H_ #define LIBANGLE_VERTEXATTRIBUTE_H_
#include "libANGLE/Buffer.h" #include "libANGLE/Buffer.h"
#include "libANGLE/angletypes.h"
namespace gl namespace gl
{ {
...@@ -23,6 +24,7 @@ class VertexBinding final : angle::NonCopyable ...@@ -23,6 +24,7 @@ class VertexBinding final : angle::NonCopyable
{ {
public: public:
VertexBinding(); VertexBinding();
explicit VertexBinding(GLuint boundAttribute);
VertexBinding(VertexBinding &&binding); VertexBinding(VertexBinding &&binding);
~VertexBinding(); ~VertexBinding();
VertexBinding &operator=(VertexBinding &&binding); VertexBinding &operator=(VertexBinding &&binding);
...@@ -46,9 +48,15 @@ class VertexBinding final : angle::NonCopyable ...@@ -46,9 +48,15 @@ class VertexBinding final : angle::NonCopyable
return mCachedBufferSizeMinusOffset; return mCachedBufferSizeMinusOffset;
} }
const AttributesMask &getBoundAttributesMask() const { return mBoundAttributesMask; }
// Called from VertexArray. // Called from VertexArray.
void updateCachedBufferSizeMinusOffset(); void updateCachedBufferSizeMinusOffset();
void setBoundAttribute(size_t index) { mBoundAttributesMask.set(index); }
void resetBoundAttribute(size_t index) { mBoundAttributesMask.reset(index); }
private: private:
GLuint mStride; GLuint mStride;
GLuint mDivisor; GLuint mDivisor;
...@@ -56,6 +64,9 @@ class VertexBinding final : angle::NonCopyable ...@@ -56,6 +64,9 @@ class VertexBinding final : angle::NonCopyable
BindingPointer<Buffer> mBuffer; BindingPointer<Buffer> mBuffer;
// Mapping from this binding to all of the attributes that are using this binding.
AttributesMask mBoundAttributesMask;
// This is kept in sync by the VertexArray. It is used to optimize draw call validation. // This is kept in sync by the VertexArray. It is used to optimize draw call validation.
GLuint64 mCachedBufferSizeMinusOffset; GLuint64 mCachedBufferSizeMinusOffset;
}; };
......
...@@ -43,7 +43,7 @@ void VertexArray11::destroy(const gl::Context *context) ...@@ -43,7 +43,7 @@ void VertexArray11::destroy(const gl::Context *context)
case gl::VertexArray::DIRTY_BIT_ATTRIB_0 + INDEX: \ case gl::VertexArray::DIRTY_BIT_ATTRIB_0 + INDEX: \
if (attribBits[INDEX][gl::VertexArray::DirtyAttribBitType::DIRTY_ATTRIB_POINTER]) \ if (attribBits[INDEX][gl::VertexArray::DirtyAttribBitType::DIRTY_ATTRIB_POINTER]) \
{ \ { \
attributesToUpdate |= mState.getBindingToAttributeMasks(INDEX); \ attributesToUpdate |= mState.getBindingToAttributesMask(INDEX); \
} \ } \
else \ else \
{ \ { \
...@@ -54,7 +54,7 @@ void VertexArray11::destroy(const gl::Context *context) ...@@ -54,7 +54,7 @@ void VertexArray11::destroy(const gl::Context *context)
#define ANGLE_VERTEX_DIRTY_BINDING_FUNC(INDEX) \ #define ANGLE_VERTEX_DIRTY_BINDING_FUNC(INDEX) \
case gl::VertexArray::DIRTY_BIT_BINDING_0 + INDEX: \ case gl::VertexArray::DIRTY_BIT_BINDING_0 + INDEX: \
attributesToUpdate |= mState.getBindingToAttributeMasks(INDEX); \ attributesToUpdate |= mState.getBindingToAttributesMask(INDEX); \
invalidateVertexBuffer = true; \ invalidateVertexBuffer = true; \
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