blob: 04b5aa385388ec74341eef1315338548f4027568 [file] [log] [blame]
Jamie Madill57a89722013-07-02 11:57:03 -04001//
2// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6// Implementation of the state class for mananging GLES 3 Vertex Array Objects.
7//
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/VertexArray.h"
10#include "libANGLE/Buffer.h"
Jamie Madilldd43e6c2017-03-24 14:18:49 -040011#include "libANGLE/Context.h"
Jamie Madill7aea7e02016-05-10 10:39:45 -040012#include "libANGLE/renderer/GLImplFactory.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050013#include "libANGLE/renderer/VertexArrayImpl.h"
Jamie Madill57a89722013-07-02 11:57:03 -040014
15namespace gl
16{
17
Jiawei-Shao2597fb62016-12-09 16:38:02 +080018VertexArrayState::VertexArrayState(size_t maxAttribs, size_t maxAttribBindings)
19 : mLabel(), mVertexBindings(maxAttribBindings), mMaxEnabledAttribute(0)
Jamie Madill57a89722013-07-02 11:57:03 -040020{
Jiawei-Shao2597fb62016-12-09 16:38:02 +080021 ASSERT(maxAttribs <= maxAttribBindings);
22
23 for (size_t i = 0; i < maxAttribs; i++)
24 {
25 mVertexAttributes.emplace_back(static_cast<GLuint>(i));
26 }
Jamie Madill8e344942015-07-09 14:22:07 -040027}
28
Jamie Madill3f572682016-04-26 13:41:36 -040029VertexArrayState::~VertexArrayState()
Jamie Madill8e344942015-07-09 14:22:07 -040030{
Jamie Madill8e344942015-07-09 14:22:07 -040031}
32
Jiawei-Shao2597fb62016-12-09 16:38:02 +080033VertexArray::VertexArray(rx::GLImplFactory *factory,
34 GLuint id,
35 size_t maxAttribs,
36 size_t maxAttribBindings)
37 : mId(id),
38 mState(maxAttribs, maxAttribBindings),
39 mVertexArray(factory->createVertexArray(mState))
Jamie Madill8e344942015-07-09 14:22:07 -040040{
Jamie Madill004a6f92013-07-10 15:13:38 -040041}
42
Jamie Madill4928b7c2017-06-20 12:57:39 -040043void VertexArray::onDestroy(const Context *context)
44{
45 for (auto &binding : mState.mVertexBindings)
46 {
47 binding.setBuffer(context, nullptr);
48 }
49 mState.mElementArrayBuffer.set(context, nullptr);
50 mVertexArray->destroy(context);
51 SafeDelete(mVertexArray);
52 delete this;
53}
54
Jamie Madill004a6f92013-07-10 15:13:38 -040055VertexArray::~VertexArray()
56{
Jamie Madill4928b7c2017-06-20 12:57:39 -040057 ASSERT(!mVertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -040058}
59
Shannon Woodsaa2ab7d2014-06-24 17:51:51 -040060GLuint VertexArray::id() const
61{
62 return mId;
63}
64
Geoff Lang70d0f492015-12-10 17:45:46 -050065void VertexArray::setLabel(const std::string &label)
66{
Jamie Madill3f572682016-04-26 13:41:36 -040067 mState.mLabel = label;
Geoff Lang70d0f492015-12-10 17:45:46 -050068}
69
70const std::string &VertexArray::getLabel() const
71{
Jamie Madill3f572682016-04-26 13:41:36 -040072 return mState.mLabel;
Geoff Lang70d0f492015-12-10 17:45:46 -050073}
74
Jamie Madill4928b7c2017-06-20 12:57:39 -040075void VertexArray::detachBuffer(const Context *context, GLuint bufferName)
Jamie Madill57a89722013-07-02 11:57:03 -040076{
Jiawei-Shao2597fb62016-12-09 16:38:02 +080077 for (auto &binding : mState.mVertexBindings)
Jamie Madill57a89722013-07-02 11:57:03 -040078 {
Martin Radevdd5f27e2017-06-07 10:17:09 +030079 if (binding.getBuffer().id() == bufferName)
Jamie Madill57a89722013-07-02 11:57:03 -040080 {
Jamie Madill4928b7c2017-06-20 12:57:39 -040081 binding.setBuffer(context, nullptr);
Jamie Madill57a89722013-07-02 11:57:03 -040082 }
83 }
84
Jamie Madill3f572682016-04-26 13:41:36 -040085 if (mState.mElementArrayBuffer.id() == bufferName)
Jamie Madill57a89722013-07-02 11:57:03 -040086 {
Jamie Madill4928b7c2017-06-20 12:57:39 -040087 mState.mElementArrayBuffer.set(context, nullptr);
Jamie Madill57a89722013-07-02 11:57:03 -040088 }
89}
90
Jiawei-Shao2597fb62016-12-09 16:38:02 +080091const VertexAttribute &VertexArray::getVertexAttribute(size_t attribIndex) const
Jamie Madill57a89722013-07-02 11:57:03 -040092{
Jiawei-Shao2597fb62016-12-09 16:38:02 +080093 ASSERT(attribIndex < getMaxAttribs());
94 return mState.mVertexAttributes[attribIndex];
95}
96
97const VertexBinding &VertexArray::getVertexBinding(size_t bindingIndex) const
98{
99 ASSERT(bindingIndex < getMaxBindings());
100 return mState.mVertexBindings[bindingIndex];
101}
102
Jamie Madill6de51852017-04-12 09:53:01 -0400103size_t VertexArray::GetAttribIndex(size_t dirtyBit)
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800104{
105 static_assert(gl::MAX_VERTEX_ATTRIBS == gl::MAX_VERTEX_ATTRIB_BINDINGS,
106 "The stride of vertex attributes should equal to that of vertex bindings.");
Shao80957d92017-02-20 21:25:59 +0800107 ASSERT(dirtyBit > DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
108 return (dirtyBit - DIRTY_BIT_ATTRIB_0_ENABLED) % gl::MAX_VERTEX_ATTRIBS;
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800109}
110
Jamie Madill4928b7c2017-06-20 12:57:39 -0400111void VertexArray::bindVertexBuffer(const Context *context,
112 size_t bindingIndex,
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800113 Buffer *boundBuffer,
114 GLintptr offset,
115 GLsizei stride)
116{
117 ASSERT(bindingIndex < getMaxBindings());
118
119 VertexBinding *binding = &mState.mVertexBindings[bindingIndex];
120
Jamie Madill4928b7c2017-06-20 12:57:39 -0400121 binding->setBuffer(context, boundBuffer);
Martin Radevdd5f27e2017-06-07 10:17:09 +0300122 binding->setOffset(offset);
123 binding->setStride(stride);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800124 mDirtyBits.set(DIRTY_BIT_BINDING_0_BUFFER + bindingIndex);
125}
126
127void VertexArray::setVertexAttribBinding(size_t attribIndex, size_t bindingIndex)
128{
129 ASSERT(attribIndex < getMaxAttribs() && bindingIndex < getMaxBindings());
130
Shao80957d92017-02-20 21:25:59 +0800131 mState.mVertexAttributes[attribIndex].bindingIndex = static_cast<GLuint>(bindingIndex);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800132 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_BINDING + attribIndex);
133}
134
135void VertexArray::setVertexBindingDivisor(size_t bindingIndex, GLuint divisor)
136{
137 ASSERT(bindingIndex < getMaxBindings());
138
Martin Radevdd5f27e2017-06-07 10:17:09 +0300139 mState.mVertexBindings[bindingIndex].setDivisor(divisor);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800140 mDirtyBits.set(DIRTY_BIT_BINDING_0_DIVISOR + bindingIndex);
141}
142
143void VertexArray::setVertexAttribFormat(size_t attribIndex,
144 GLint size,
145 GLenum type,
146 bool normalized,
147 bool pureInteger,
148 GLintptr relativeOffset)
149{
150 ASSERT(attribIndex < getMaxAttribs());
151
152 VertexAttribute *attrib = &mState.mVertexAttributes[attribIndex];
153
154 attrib->size = size;
155 attrib->type = type;
156 attrib->normalized = normalized;
157 attrib->pureInteger = pureInteger;
158 attrib->relativeOffset = relativeOffset;
159 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_FORMAT + attribIndex);
Jamie Madill57a89722013-07-02 11:57:03 -0400160}
161
Jamie Madill8e344942015-07-09 14:22:07 -0400162void VertexArray::setVertexAttribDivisor(size_t index, GLuint divisor)
Jamie Madill57a89722013-07-02 11:57:03 -0400163{
Brandon Jones5bf98292014-06-06 17:19:38 -0700164 ASSERT(index < getMaxAttribs());
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800165
166 setVertexAttribBinding(index, index);
167 setVertexBindingDivisor(index, divisor);
Jamie Madill57a89722013-07-02 11:57:03 -0400168}
169
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800170void VertexArray::enableAttribute(size_t attribIndex, bool enabledState)
Jamie Madill57a89722013-07-02 11:57:03 -0400171{
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800172 ASSERT(attribIndex < getMaxAttribs());
Shao80957d92017-02-20 21:25:59 +0800173
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800174 mState.mVertexAttributes[attribIndex].enabled = enabledState;
175 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_ENABLED + attribIndex);
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400176
177 // Update state cache
178 if (enabledState)
179 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800180 mState.mMaxEnabledAttribute = std::max(attribIndex + 1, mState.mMaxEnabledAttribute);
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400181 }
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800182 else if (mState.mMaxEnabledAttribute == attribIndex + 1)
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400183 {
Jamie Madill3f572682016-04-26 13:41:36 -0400184 while (mState.mMaxEnabledAttribute > 0 &&
185 !mState.mVertexAttributes[mState.mMaxEnabledAttribute - 1].enabled)
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400186 {
Jamie Madill3f572682016-04-26 13:41:36 -0400187 --mState.mMaxEnabledAttribute;
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400188 }
189 }
Jamie Madill57a89722013-07-02 11:57:03 -0400190}
191
Jamie Madill4928b7c2017-06-20 12:57:39 -0400192void VertexArray::setAttributeState(const Context *context,
193 size_t attribIndex,
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800194 gl::Buffer *boundBuffer,
195 GLint size,
196 GLenum type,
197 bool normalized,
198 bool pureInteger,
199 GLsizei stride,
200 const void *pointer)
Jamie Madill57a89722013-07-02 11:57:03 -0400201{
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800202 ASSERT(attribIndex < getMaxAttribs());
Jamie Madill8e344942015-07-09 14:22:07 -0400203
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800204 GLintptr offset = boundBuffer ? reinterpret_cast<GLintptr>(pointer) : 0;
Jamie Madill8e344942015-07-09 14:22:07 -0400205
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800206 setVertexAttribFormat(attribIndex, size, type, normalized, pureInteger, 0);
207 setVertexAttribBinding(attribIndex, attribIndex);
208
209 VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
210 GLsizei effectiveStride =
211 stride != 0 ? stride : static_cast<GLsizei>(ComputeVertexAttributeTypeSize(attrib));
212 attrib.pointer = pointer;
213 attrib.vertexAttribArrayStride = stride;
214
Jamie Madill4928b7c2017-06-20 12:57:39 -0400215 bindVertexBuffer(context, attribIndex, boundBuffer, offset, effectiveStride);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800216
217 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_POINTER + attribIndex);
Brandon Jones5bf98292014-06-06 17:19:38 -0700218}
219
Jamie Madill4928b7c2017-06-20 12:57:39 -0400220void VertexArray::setElementArrayBuffer(const Context *context, Buffer *buffer)
Brandon Jones5bf98292014-06-06 17:19:38 -0700221{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400222 mState.mElementArrayBuffer.set(context, buffer);
Jamie Madill0b9e9032015-08-17 11:51:52 +0000223 mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
224}
225
Jamie Madilldd43e6c2017-03-24 14:18:49 -0400226void VertexArray::syncImplState(const Context *context)
Jamie Madill0b9e9032015-08-17 11:51:52 +0000227{
228 if (mDirtyBits.any())
229 {
Jamie Madillc564c072017-06-01 12:45:42 -0400230 mVertexArray->syncState(context, mDirtyBits);
Jamie Madill0b9e9032015-08-17 11:51:52 +0000231 mDirtyBits.reset();
232 }
Jamie Madill57a89722013-07-02 11:57:03 -0400233}
234
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800235} // namespace gl