blob: a8c2fce1553b4cad0cb7ca64cf851128c187b2eb [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
Shaodde78e82017-05-22 14:13:27 +0800103size_t VertexArray::GetVertexIndexFromDirtyBit(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
Shaodde78e82017-05-22 14:13:27 +0800111void VertexArray::bindVertexBufferImpl(const Context *context,
112 size_t bindingIndex,
113 Buffer *boundBuffer,
114 GLintptr offset,
115 GLsizei stride)
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800116{
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);
Shaodde78e82017-05-22 14:13:27 +0800124}
125
126void VertexArray::bindVertexBuffer(const Context *context,
127 size_t bindingIndex,
128 Buffer *boundBuffer,
129 GLintptr offset,
130 GLsizei stride)
131{
132 bindVertexBufferImpl(context, bindingIndex, boundBuffer, offset, stride);
133
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800134 mDirtyBits.set(DIRTY_BIT_BINDING_0_BUFFER + bindingIndex);
135}
136
Shaodde78e82017-05-22 14:13:27 +0800137void VertexArray::setVertexAttribBinding(const Context *context,
138 size_t attribIndex,
139 GLuint bindingIndex)
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800140{
141 ASSERT(attribIndex < getMaxAttribs() && bindingIndex < getMaxBindings());
142
Shaodde78e82017-05-22 14:13:27 +0800143 if (mState.mVertexAttributes[attribIndex].bindingIndex != bindingIndex)
144 {
145 // In ES 3.0 contexts, the binding cannot change, hence the code below is unreachable.
146 ASSERT(context->getClientVersion() >= ES_3_1);
147 mState.mVertexAttributes[attribIndex].bindingIndex = bindingIndex;
148
149 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_BINDING + attribIndex);
150 }
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800151}
152
153void VertexArray::setVertexBindingDivisor(size_t bindingIndex, GLuint divisor)
154{
155 ASSERT(bindingIndex < getMaxBindings());
156
Martin Radevdd5f27e2017-06-07 10:17:09 +0300157 mState.mVertexBindings[bindingIndex].setDivisor(divisor);
Shaodde78e82017-05-22 14:13:27 +0800158
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800159 mDirtyBits.set(DIRTY_BIT_BINDING_0_DIVISOR + bindingIndex);
160}
161
Shaodde78e82017-05-22 14:13:27 +0800162void VertexArray::setVertexAttribFormatImpl(size_t attribIndex,
163 GLint size,
164 GLenum type,
165 bool normalized,
166 bool pureInteger,
167 GLuint relativeOffset)
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800168{
169 ASSERT(attribIndex < getMaxAttribs());
170
171 VertexAttribute *attrib = &mState.mVertexAttributes[attribIndex];
172
173 attrib->size = size;
174 attrib->type = type;
175 attrib->normalized = normalized;
176 attrib->pureInteger = pureInteger;
177 attrib->relativeOffset = relativeOffset;
Shaodde78e82017-05-22 14:13:27 +0800178}
179
180void VertexArray::setVertexAttribFormat(size_t attribIndex,
181 GLint size,
182 GLenum type,
183 bool normalized,
184 bool pureInteger,
185 GLuint relativeOffset)
186{
187 setVertexAttribFormatImpl(attribIndex, size, type, normalized, pureInteger, relativeOffset);
188
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800189 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_FORMAT + attribIndex);
Jamie Madill57a89722013-07-02 11:57:03 -0400190}
191
Shaodde78e82017-05-22 14:13:27 +0800192void VertexArray::setVertexAttribDivisor(const Context *context, size_t attribIndex, GLuint divisor)
Jamie Madill57a89722013-07-02 11:57:03 -0400193{
Shaodde78e82017-05-22 14:13:27 +0800194 ASSERT(attribIndex < getMaxAttribs());
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800195
Shaodde78e82017-05-22 14:13:27 +0800196 setVertexAttribBinding(context, attribIndex, static_cast<GLuint>(attribIndex));
197 setVertexBindingDivisor(attribIndex, divisor);
Jamie Madill57a89722013-07-02 11:57:03 -0400198}
199
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800200void VertexArray::enableAttribute(size_t attribIndex, bool enabledState)
Jamie Madill57a89722013-07-02 11:57:03 -0400201{
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800202 ASSERT(attribIndex < getMaxAttribs());
Shao80957d92017-02-20 21:25:59 +0800203
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800204 mState.mVertexAttributes[attribIndex].enabled = enabledState;
Shaodde78e82017-05-22 14:13:27 +0800205
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800206 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_ENABLED + attribIndex);
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400207
208 // Update state cache
209 if (enabledState)
210 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800211 mState.mMaxEnabledAttribute = std::max(attribIndex + 1, mState.mMaxEnabledAttribute);
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400212 }
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800213 else if (mState.mMaxEnabledAttribute == attribIndex + 1)
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400214 {
Jamie Madill3f572682016-04-26 13:41:36 -0400215 while (mState.mMaxEnabledAttribute > 0 &&
216 !mState.mVertexAttributes[mState.mMaxEnabledAttribute - 1].enabled)
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400217 {
Jamie Madill3f572682016-04-26 13:41:36 -0400218 --mState.mMaxEnabledAttribute;
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400219 }
220 }
Jamie Madill57a89722013-07-02 11:57:03 -0400221}
222
Shaodde78e82017-05-22 14:13:27 +0800223void VertexArray::setVertexAttribPointer(const Context *context,
224 size_t attribIndex,
225 gl::Buffer *boundBuffer,
226 GLint size,
227 GLenum type,
228 bool normalized,
229 bool pureInteger,
230 GLsizei stride,
231 const void *pointer)
Jamie Madill57a89722013-07-02 11:57:03 -0400232{
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800233 ASSERT(attribIndex < getMaxAttribs());
Jamie Madill8e344942015-07-09 14:22:07 -0400234
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800235 GLintptr offset = boundBuffer ? reinterpret_cast<GLintptr>(pointer) : 0;
Jamie Madill8e344942015-07-09 14:22:07 -0400236
Shaodde78e82017-05-22 14:13:27 +0800237 setVertexAttribFormatImpl(attribIndex, size, type, normalized, pureInteger, 0);
238 setVertexAttribBinding(context, attribIndex, static_cast<GLuint>(attribIndex));
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800239
240 VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
Shaodde78e82017-05-22 14:13:27 +0800241
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800242 GLsizei effectiveStride =
243 stride != 0 ? stride : static_cast<GLsizei>(ComputeVertexAttributeTypeSize(attrib));
244 attrib.pointer = pointer;
245 attrib.vertexAttribArrayStride = stride;
246
Shaodde78e82017-05-22 14:13:27 +0800247 bindVertexBufferImpl(context, attribIndex, boundBuffer, offset, effectiveStride);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800248
249 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_POINTER + attribIndex);
Brandon Jones5bf98292014-06-06 17:19:38 -0700250}
251
Jamie Madill4928b7c2017-06-20 12:57:39 -0400252void VertexArray::setElementArrayBuffer(const Context *context, Buffer *buffer)
Brandon Jones5bf98292014-06-06 17:19:38 -0700253{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400254 mState.mElementArrayBuffer.set(context, buffer);
Jamie Madill0b9e9032015-08-17 11:51:52 +0000255 mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
256}
257
Jamie Madill06ef36b2017-09-09 23:32:46 -0400258void VertexArray::syncState(const Context *context)
Jamie Madill0b9e9032015-08-17 11:51:52 +0000259{
260 if (mDirtyBits.any())
261 {
Jamie Madillc564c072017-06-01 12:45:42 -0400262 mVertexArray->syncState(context, mDirtyBits);
Jamie Madill0b9e9032015-08-17 11:51:52 +0000263 mDirtyBits.reset();
264 }
Jamie Madill57a89722013-07-02 11:57:03 -0400265}
266
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800267} // namespace gl