blob: 55fb1b274bc4c4e06b2bd25ce4d7f972c8b3ec26 [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)
Jamie Madilld078c682018-01-02 11:50:24 -050019 : mLabel(), mVertexBindings(maxAttribBindings)
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;
Brandon Jonesc405ae72017-12-06 14:15:03 -0800178 mState.mVertexAttributesTypeMask.setIndex(GetVertexAttributeBaseType(*attrib), attribIndex);
179 mState.mEnabledAttributesMask.set(attribIndex);
Shaodde78e82017-05-22 14:13:27 +0800180}
181
182void VertexArray::setVertexAttribFormat(size_t attribIndex,
183 GLint size,
184 GLenum type,
185 bool normalized,
186 bool pureInteger,
187 GLuint relativeOffset)
188{
189 setVertexAttribFormatImpl(attribIndex, size, type, normalized, pureInteger, relativeOffset);
190
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800191 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_FORMAT + attribIndex);
Jamie Madill57a89722013-07-02 11:57:03 -0400192}
193
Shaodde78e82017-05-22 14:13:27 +0800194void VertexArray::setVertexAttribDivisor(const Context *context, size_t attribIndex, GLuint divisor)
Jamie Madill57a89722013-07-02 11:57:03 -0400195{
Shaodde78e82017-05-22 14:13:27 +0800196 ASSERT(attribIndex < getMaxAttribs());
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800197
Shaodde78e82017-05-22 14:13:27 +0800198 setVertexAttribBinding(context, attribIndex, static_cast<GLuint>(attribIndex));
199 setVertexBindingDivisor(attribIndex, divisor);
Jamie Madill57a89722013-07-02 11:57:03 -0400200}
201
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800202void VertexArray::enableAttribute(size_t attribIndex, bool enabledState)
Jamie Madill57a89722013-07-02 11:57:03 -0400203{
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800204 ASSERT(attribIndex < getMaxAttribs());
Shao80957d92017-02-20 21:25:59 +0800205
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800206 mState.mVertexAttributes[attribIndex].enabled = enabledState;
Brandon Jonesc405ae72017-12-06 14:15:03 -0800207 mState.mVertexAttributesTypeMask.setIndex(
208 GetVertexAttributeBaseType(mState.mVertexAttributes[attribIndex]), attribIndex);
Shaodde78e82017-05-22 14:13:27 +0800209
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800210 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_ENABLED + attribIndex);
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400211
212 // Update state cache
Jamie Madilld078c682018-01-02 11:50:24 -0500213 mState.mEnabledAttributesMask.set(attribIndex, enabledState);
Jamie Madill57a89722013-07-02 11:57:03 -0400214}
215
Shaodde78e82017-05-22 14:13:27 +0800216void VertexArray::setVertexAttribPointer(const Context *context,
217 size_t attribIndex,
218 gl::Buffer *boundBuffer,
219 GLint size,
220 GLenum type,
221 bool normalized,
222 bool pureInteger,
223 GLsizei stride,
224 const void *pointer)
Jamie Madill57a89722013-07-02 11:57:03 -0400225{
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800226 ASSERT(attribIndex < getMaxAttribs());
Jamie Madill8e344942015-07-09 14:22:07 -0400227
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800228 GLintptr offset = boundBuffer ? reinterpret_cast<GLintptr>(pointer) : 0;
Jamie Madill8e344942015-07-09 14:22:07 -0400229
Shaodde78e82017-05-22 14:13:27 +0800230 setVertexAttribFormatImpl(attribIndex, size, type, normalized, pureInteger, 0);
231 setVertexAttribBinding(context, attribIndex, static_cast<GLuint>(attribIndex));
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800232
233 VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
Shaodde78e82017-05-22 14:13:27 +0800234
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800235 GLsizei effectiveStride =
236 stride != 0 ? stride : static_cast<GLsizei>(ComputeVertexAttributeTypeSize(attrib));
237 attrib.pointer = pointer;
238 attrib.vertexAttribArrayStride = stride;
239
Shaodde78e82017-05-22 14:13:27 +0800240 bindVertexBufferImpl(context, attribIndex, boundBuffer, offset, effectiveStride);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800241
242 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_POINTER + attribIndex);
Brandon Jones5bf98292014-06-06 17:19:38 -0700243}
244
Jamie Madill4928b7c2017-06-20 12:57:39 -0400245void VertexArray::setElementArrayBuffer(const Context *context, Buffer *buffer)
Brandon Jones5bf98292014-06-06 17:19:38 -0700246{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400247 mState.mElementArrayBuffer.set(context, buffer);
Jamie Madill0b9e9032015-08-17 11:51:52 +0000248 mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
249}
250
Jamie Madill06ef36b2017-09-09 23:32:46 -0400251void VertexArray::syncState(const Context *context)
Jamie Madill0b9e9032015-08-17 11:51:52 +0000252{
253 if (mDirtyBits.any())
254 {
Jamie Madillc564c072017-06-01 12:45:42 -0400255 mVertexArray->syncState(context, mDirtyBits);
Jamie Madill0b9e9032015-08-17 11:51:52 +0000256 mDirtyBits.reset();
257 }
Jamie Madill57a89722013-07-02 11:57:03 -0400258}
259
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800260} // namespace gl