summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE/VertexArray.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/VertexArray.cpp')
-rw-r--r--src/3rdparty/angle/src/libANGLE/VertexArray.cpp235
1 files changed, 181 insertions, 54 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/VertexArray.cpp b/src/3rdparty/angle/src/libANGLE/VertexArray.cpp
index 8d51e9b469..a8c2fce155 100644
--- a/src/3rdparty/angle/src/libANGLE/VertexArray.cpp
+++ b/src/3rdparty/angle/src/libANGLE/VertexArray.cpp
@@ -8,36 +8,53 @@
#include "libANGLE/VertexArray.h"
#include "libANGLE/Buffer.h"
-#include "libANGLE/renderer/ImplFactory.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/renderer/GLImplFactory.h"
#include "libANGLE/renderer/VertexArrayImpl.h"
namespace gl
{
-VertexArray::Data::Data(size_t maxAttribs)
- : mLabel(), mVertexAttributes(maxAttribs), mMaxEnabledAttribute(0)
+VertexArrayState::VertexArrayState(size_t maxAttribs, size_t maxAttribBindings)
+ : mLabel(), mVertexBindings(maxAttribBindings), mMaxEnabledAttribute(0)
{
-}
+ ASSERT(maxAttribs <= maxAttribBindings);
-VertexArray::Data::~Data()
-{
- for (size_t i = 0; i < getMaxAttribs(); i++)
+ for (size_t i = 0; i < maxAttribs; i++)
{
- mVertexAttributes[i].buffer.set(nullptr);
+ mVertexAttributes.emplace_back(static_cast<GLuint>(i));
}
- mElementArrayBuffer.set(nullptr);
}
-VertexArray::VertexArray(rx::ImplFactory *factory, GLuint id, size_t maxAttribs)
+VertexArrayState::~VertexArrayState()
+{
+}
+
+VertexArray::VertexArray(rx::GLImplFactory *factory,
+ GLuint id,
+ size_t maxAttribs,
+ size_t maxAttribBindings)
: mId(id),
- mVertexArray(factory->createVertexArray(mData)),
- mData(maxAttribs)
+ mState(maxAttribs, maxAttribBindings),
+ mVertexArray(factory->createVertexArray(mState))
{
}
-VertexArray::~VertexArray()
+void VertexArray::onDestroy(const Context *context)
{
+ for (auto &binding : mState.mVertexBindings)
+ {
+ binding.setBuffer(context, nullptr);
+ }
+ mState.mElementArrayBuffer.set(context, nullptr);
+ mVertexArray->destroy(context);
SafeDelete(mVertexArray);
+ delete this;
+}
+
+VertexArray::~VertexArray()
+{
+ ASSERT(!mVertexArray);
}
GLuint VertexArray::id() const
@@ -47,94 +64,204 @@ GLuint VertexArray::id() const
void VertexArray::setLabel(const std::string &label)
{
- mData.mLabel = label;
+ mState.mLabel = label;
}
const std::string &VertexArray::getLabel() const
{
- return mData.mLabel;
+ return mState.mLabel;
}
-void VertexArray::detachBuffer(GLuint bufferName)
+void VertexArray::detachBuffer(const Context *context, GLuint bufferName)
{
- for (size_t attribute = 0; attribute < getMaxAttribs(); attribute++)
+ for (auto &binding : mState.mVertexBindings)
{
- if (mData.mVertexAttributes[attribute].buffer.id() == bufferName)
+ if (binding.getBuffer().id() == bufferName)
{
- mData.mVertexAttributes[attribute].buffer.set(nullptr);
+ binding.setBuffer(context, nullptr);
}
}
- if (mData.mElementArrayBuffer.id() == bufferName)
+ if (mState.mElementArrayBuffer.id() == bufferName)
+ {
+ mState.mElementArrayBuffer.set(context, nullptr);
+ }
+}
+
+const VertexAttribute &VertexArray::getVertexAttribute(size_t attribIndex) const
+{
+ ASSERT(attribIndex < getMaxAttribs());
+ return mState.mVertexAttributes[attribIndex];
+}
+
+const VertexBinding &VertexArray::getVertexBinding(size_t bindingIndex) const
+{
+ ASSERT(bindingIndex < getMaxBindings());
+ return mState.mVertexBindings[bindingIndex];
+}
+
+size_t VertexArray::GetVertexIndexFromDirtyBit(size_t dirtyBit)
+{
+ static_assert(gl::MAX_VERTEX_ATTRIBS == gl::MAX_VERTEX_ATTRIB_BINDINGS,
+ "The stride of vertex attributes should equal to that of vertex bindings.");
+ ASSERT(dirtyBit > DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
+ return (dirtyBit - DIRTY_BIT_ATTRIB_0_ENABLED) % gl::MAX_VERTEX_ATTRIBS;
+}
+
+void VertexArray::bindVertexBufferImpl(const Context *context,
+ size_t bindingIndex,
+ Buffer *boundBuffer,
+ GLintptr offset,
+ GLsizei stride)
+{
+ ASSERT(bindingIndex < getMaxBindings());
+
+ VertexBinding *binding = &mState.mVertexBindings[bindingIndex];
+
+ binding->setBuffer(context, boundBuffer);
+ binding->setOffset(offset);
+ binding->setStride(stride);
+}
+
+void VertexArray::bindVertexBuffer(const Context *context,
+ size_t bindingIndex,
+ Buffer *boundBuffer,
+ GLintptr offset,
+ GLsizei stride)
+{
+ bindVertexBufferImpl(context, bindingIndex, boundBuffer, offset, stride);
+
+ mDirtyBits.set(DIRTY_BIT_BINDING_0_BUFFER + bindingIndex);
+}
+
+void VertexArray::setVertexAttribBinding(const Context *context,
+ size_t attribIndex,
+ GLuint bindingIndex)
+{
+ ASSERT(attribIndex < getMaxAttribs() && bindingIndex < getMaxBindings());
+
+ if (mState.mVertexAttributes[attribIndex].bindingIndex != bindingIndex)
{
- mData.mElementArrayBuffer.set(nullptr);
+ // In ES 3.0 contexts, the binding cannot change, hence the code below is unreachable.
+ ASSERT(context->getClientVersion() >= ES_3_1);
+ mState.mVertexAttributes[attribIndex].bindingIndex = bindingIndex;
+
+ mDirtyBits.set(DIRTY_BIT_ATTRIB_0_BINDING + attribIndex);
}
}
-const VertexAttribute &VertexArray::getVertexAttribute(size_t attributeIndex) const
+void VertexArray::setVertexBindingDivisor(size_t bindingIndex, GLuint divisor)
+{
+ ASSERT(bindingIndex < getMaxBindings());
+
+ mState.mVertexBindings[bindingIndex].setDivisor(divisor);
+
+ mDirtyBits.set(DIRTY_BIT_BINDING_0_DIVISOR + bindingIndex);
+}
+
+void VertexArray::setVertexAttribFormatImpl(size_t attribIndex,
+ GLint size,
+ GLenum type,
+ bool normalized,
+ bool pureInteger,
+ GLuint relativeOffset)
{
- ASSERT(attributeIndex < getMaxAttribs());
- return mData.mVertexAttributes[attributeIndex];
+ ASSERT(attribIndex < getMaxAttribs());
+
+ VertexAttribute *attrib = &mState.mVertexAttributes[attribIndex];
+
+ attrib->size = size;
+ attrib->type = type;
+ attrib->normalized = normalized;
+ attrib->pureInteger = pureInteger;
+ attrib->relativeOffset = relativeOffset;
}
-void VertexArray::setVertexAttribDivisor(size_t index, GLuint divisor)
+void VertexArray::setVertexAttribFormat(size_t attribIndex,
+ GLint size,
+ GLenum type,
+ bool normalized,
+ bool pureInteger,
+ GLuint relativeOffset)
{
- ASSERT(index < getMaxAttribs());
- mData.mVertexAttributes[index].divisor = divisor;
- mDirtyBits.set(DIRTY_BIT_ATTRIB_0_DIVISOR + index);
+ setVertexAttribFormatImpl(attribIndex, size, type, normalized, pureInteger, relativeOffset);
+
+ mDirtyBits.set(DIRTY_BIT_ATTRIB_0_FORMAT + attribIndex);
+}
+
+void VertexArray::setVertexAttribDivisor(const Context *context, size_t attribIndex, GLuint divisor)
+{
+ ASSERT(attribIndex < getMaxAttribs());
+
+ setVertexAttribBinding(context, attribIndex, static_cast<GLuint>(attribIndex));
+ setVertexBindingDivisor(attribIndex, divisor);
}
-void VertexArray::enableAttribute(size_t attributeIndex, bool enabledState)
+void VertexArray::enableAttribute(size_t attribIndex, bool enabledState)
{
- ASSERT(attributeIndex < getMaxAttribs());
- mData.mVertexAttributes[attributeIndex].enabled = enabledState;
- mDirtyBits.set(DIRTY_BIT_ATTRIB_0_ENABLED + attributeIndex);
+ ASSERT(attribIndex < getMaxAttribs());
+
+ mState.mVertexAttributes[attribIndex].enabled = enabledState;
+
+ mDirtyBits.set(DIRTY_BIT_ATTRIB_0_ENABLED + attribIndex);
// Update state cache
if (enabledState)
{
- mData.mMaxEnabledAttribute = std::max(attributeIndex + 1, mData.mMaxEnabledAttribute);
+ mState.mMaxEnabledAttribute = std::max(attribIndex + 1, mState.mMaxEnabledAttribute);
}
- else if (mData.mMaxEnabledAttribute == attributeIndex + 1)
+ else if (mState.mMaxEnabledAttribute == attribIndex + 1)
{
- while (mData.mMaxEnabledAttribute > 0 &&
- !mData.mVertexAttributes[mData.mMaxEnabledAttribute - 1].enabled)
+ while (mState.mMaxEnabledAttribute > 0 &&
+ !mState.mVertexAttributes[mState.mMaxEnabledAttribute - 1].enabled)
{
- --mData.mMaxEnabledAttribute;
+ --mState.mMaxEnabledAttribute;
}
}
}
-void VertexArray::setAttributeState(size_t attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type,
- bool normalized, bool pureInteger, GLsizei stride, const void *pointer)
+void VertexArray::setVertexAttribPointer(const Context *context,
+ size_t attribIndex,
+ gl::Buffer *boundBuffer,
+ GLint size,
+ GLenum type,
+ bool normalized,
+ bool pureInteger,
+ GLsizei stride,
+ const void *pointer)
{
- ASSERT(attributeIndex < getMaxAttribs());
+ ASSERT(attribIndex < getMaxAttribs());
+
+ GLintptr offset = boundBuffer ? reinterpret_cast<GLintptr>(pointer) : 0;
+
+ setVertexAttribFormatImpl(attribIndex, size, type, normalized, pureInteger, 0);
+ setVertexAttribBinding(context, attribIndex, static_cast<GLuint>(attribIndex));
- VertexAttribute *attrib = &mData.mVertexAttributes[attributeIndex];
+ VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
- attrib->buffer.set(boundBuffer);
- attrib->size = size;
- attrib->type = type;
- attrib->normalized = normalized;
- attrib->pureInteger = pureInteger;
- attrib->stride = stride;
- attrib->pointer = pointer;
- mDirtyBits.set(DIRTY_BIT_ATTRIB_0_POINTER + attributeIndex);
+ GLsizei effectiveStride =
+ stride != 0 ? stride : static_cast<GLsizei>(ComputeVertexAttributeTypeSize(attrib));
+ attrib.pointer = pointer;
+ attrib.vertexAttribArrayStride = stride;
+
+ bindVertexBufferImpl(context, attribIndex, boundBuffer, offset, effectiveStride);
+
+ mDirtyBits.set(DIRTY_BIT_ATTRIB_0_POINTER + attribIndex);
}
-void VertexArray::setElementArrayBuffer(Buffer *buffer)
+void VertexArray::setElementArrayBuffer(const Context *context, Buffer *buffer)
{
- mData.mElementArrayBuffer.set(buffer);
+ mState.mElementArrayBuffer.set(context, buffer);
mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
}
-void VertexArray::syncImplState()
+void VertexArray::syncState(const Context *context)
{
if (mDirtyBits.any())
{
- mVertexArray->syncState(mDirtyBits);
+ mVertexArray->syncState(context, mDirtyBits);
mDirtyBits.reset();
}
}
-}
+} // namespace gl