diff options
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/VertexArray.cpp')
-rw-r--r-- | src/3rdparty/angle/src/libANGLE/VertexArray.cpp | 235 |
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 |