blob: f831e7ff4ac9bf81960000dfc5a02d66e9feca49 [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 Madill7aea7e02016-05-10 10:39:45 -040011#include "libANGLE/renderer/GLImplFactory.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050012#include "libANGLE/renderer/VertexArrayImpl.h"
Jamie Madill57a89722013-07-02 11:57:03 -040013
14namespace gl
15{
16
Jiawei-Shao2597fb62016-12-09 16:38:02 +080017VertexArrayState::VertexArrayState(size_t maxAttribs, size_t maxAttribBindings)
18 : mLabel(), mVertexBindings(maxAttribBindings), mMaxEnabledAttribute(0)
Jamie Madill57a89722013-07-02 11:57:03 -040019{
Jiawei-Shao2597fb62016-12-09 16:38:02 +080020 ASSERT(maxAttribs <= maxAttribBindings);
21
22 for (size_t i = 0; i < maxAttribs; i++)
23 {
24 mVertexAttributes.emplace_back(static_cast<GLuint>(i));
25 }
Jamie Madill8e344942015-07-09 14:22:07 -040026}
27
Jamie Madill3f572682016-04-26 13:41:36 -040028VertexArrayState::~VertexArrayState()
Jamie Madill8e344942015-07-09 14:22:07 -040029{
Jiawei-Shao2597fb62016-12-09 16:38:02 +080030 for (auto &binding : mVertexBindings)
Jamie Madill8e344942015-07-09 14:22:07 -040031 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +080032 binding.buffer.set(nullptr);
Jamie Madill8e344942015-07-09 14:22:07 -040033 }
34 mElementArrayBuffer.set(nullptr);
35}
36
Jiawei-Shao2597fb62016-12-09 16:38:02 +080037VertexArray::VertexArray(rx::GLImplFactory *factory,
38 GLuint id,
39 size_t maxAttribs,
40 size_t maxAttribBindings)
41 : mId(id),
42 mState(maxAttribs, maxAttribBindings),
43 mVertexArray(factory->createVertexArray(mState))
Jamie Madill8e344942015-07-09 14:22:07 -040044{
Jamie Madill004a6f92013-07-10 15:13:38 -040045}
46
47VertexArray::~VertexArray()
48{
Brandon Jonesd38f9262014-06-18 16:26:45 -070049 SafeDelete(mVertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -040050}
51
Shannon Woodsaa2ab7d2014-06-24 17:51:51 -040052GLuint VertexArray::id() const
53{
54 return mId;
55}
56
Geoff Lang70d0f492015-12-10 17:45:46 -050057void VertexArray::setLabel(const std::string &label)
58{
Jamie Madill3f572682016-04-26 13:41:36 -040059 mState.mLabel = label;
Geoff Lang70d0f492015-12-10 17:45:46 -050060}
61
62const std::string &VertexArray::getLabel() const
63{
Jamie Madill3f572682016-04-26 13:41:36 -040064 return mState.mLabel;
Geoff Lang70d0f492015-12-10 17:45:46 -050065}
66
Jamie Madill57a89722013-07-02 11:57:03 -040067void VertexArray::detachBuffer(GLuint bufferName)
68{
Jiawei-Shao2597fb62016-12-09 16:38:02 +080069 for (auto &binding : mState.mVertexBindings)
Jamie Madill57a89722013-07-02 11:57:03 -040070 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +080071 if (binding.buffer.id() == bufferName)
Jamie Madill57a89722013-07-02 11:57:03 -040072 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +080073 binding.buffer.set(nullptr);
Jamie Madill57a89722013-07-02 11:57:03 -040074 }
75 }
76
Jamie Madill3f572682016-04-26 13:41:36 -040077 if (mState.mElementArrayBuffer.id() == bufferName)
Jamie Madill57a89722013-07-02 11:57:03 -040078 {
Jamie Madill3f572682016-04-26 13:41:36 -040079 mState.mElementArrayBuffer.set(nullptr);
Jamie Madill57a89722013-07-02 11:57:03 -040080 }
81}
82
Jiawei-Shao2597fb62016-12-09 16:38:02 +080083const VertexAttribute &VertexArray::getVertexAttribute(size_t attribIndex) const
Jamie Madill57a89722013-07-02 11:57:03 -040084{
Jiawei-Shao2597fb62016-12-09 16:38:02 +080085 ASSERT(attribIndex < getMaxAttribs());
86 return mState.mVertexAttributes[attribIndex];
87}
88
89const VertexBinding &VertexArray::getVertexBinding(size_t bindingIndex) const
90{
91 ASSERT(bindingIndex < getMaxBindings());
92 return mState.mVertexBindings[bindingIndex];
93}
94
95size_t VertexArray::GetAttribIndex(unsigned long dirtyBit)
96{
97 static_assert(gl::MAX_VERTEX_ATTRIBS == gl::MAX_VERTEX_ATTRIB_BINDINGS,
98 "The stride of vertex attributes should equal to that of vertex bindings.");
Shao80957d92017-02-20 21:25:59 +080099 ASSERT(dirtyBit > DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
100 return (dirtyBit - DIRTY_BIT_ATTRIB_0_ENABLED) % gl::MAX_VERTEX_ATTRIBS;
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800101}
102
103void VertexArray::bindVertexBuffer(size_t bindingIndex,
104 Buffer *boundBuffer,
105 GLintptr offset,
106 GLsizei stride)
107{
108 ASSERT(bindingIndex < getMaxBindings());
109
110 VertexBinding *binding = &mState.mVertexBindings[bindingIndex];
111
112 binding->buffer.set(boundBuffer);
113 binding->offset = offset;
114 binding->stride = stride;
115 mDirtyBits.set(DIRTY_BIT_BINDING_0_BUFFER + bindingIndex);
116}
117
118void VertexArray::setVertexAttribBinding(size_t attribIndex, size_t bindingIndex)
119{
120 ASSERT(attribIndex < getMaxAttribs() && bindingIndex < getMaxBindings());
121
Shao80957d92017-02-20 21:25:59 +0800122 mState.mVertexAttributes[attribIndex].bindingIndex = static_cast<GLuint>(bindingIndex);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800123 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_BINDING + attribIndex);
124}
125
126void VertexArray::setVertexBindingDivisor(size_t bindingIndex, GLuint divisor)
127{
128 ASSERT(bindingIndex < getMaxBindings());
129
130 mState.mVertexBindings[bindingIndex].divisor = divisor;
131 mDirtyBits.set(DIRTY_BIT_BINDING_0_DIVISOR + bindingIndex);
132}
133
134void VertexArray::setVertexAttribFormat(size_t attribIndex,
135 GLint size,
136 GLenum type,
137 bool normalized,
138 bool pureInteger,
139 GLintptr relativeOffset)
140{
141 ASSERT(attribIndex < getMaxAttribs());
142
143 VertexAttribute *attrib = &mState.mVertexAttributes[attribIndex];
144
145 attrib->size = size;
146 attrib->type = type;
147 attrib->normalized = normalized;
148 attrib->pureInteger = pureInteger;
149 attrib->relativeOffset = relativeOffset;
150 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_FORMAT + attribIndex);
Jamie Madill57a89722013-07-02 11:57:03 -0400151}
152
Jamie Madill8e344942015-07-09 14:22:07 -0400153void VertexArray::setVertexAttribDivisor(size_t index, GLuint divisor)
Jamie Madill57a89722013-07-02 11:57:03 -0400154{
Brandon Jones5bf98292014-06-06 17:19:38 -0700155 ASSERT(index < getMaxAttribs());
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800156
157 setVertexAttribBinding(index, index);
158 setVertexBindingDivisor(index, divisor);
Jamie Madill57a89722013-07-02 11:57:03 -0400159}
160
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800161void VertexArray::enableAttribute(size_t attribIndex, bool enabledState)
Jamie Madill57a89722013-07-02 11:57:03 -0400162{
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800163 ASSERT(attribIndex < getMaxAttribs());
Shao80957d92017-02-20 21:25:59 +0800164
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800165 mState.mVertexAttributes[attribIndex].enabled = enabledState;
166 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_ENABLED + attribIndex);
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400167
168 // Update state cache
169 if (enabledState)
170 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800171 mState.mMaxEnabledAttribute = std::max(attribIndex + 1, mState.mMaxEnabledAttribute);
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400172 }
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800173 else if (mState.mMaxEnabledAttribute == attribIndex + 1)
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400174 {
Jamie Madill3f572682016-04-26 13:41:36 -0400175 while (mState.mMaxEnabledAttribute > 0 &&
176 !mState.mVertexAttributes[mState.mMaxEnabledAttribute - 1].enabled)
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400177 {
Jamie Madill3f572682016-04-26 13:41:36 -0400178 --mState.mMaxEnabledAttribute;
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400179 }
180 }
Jamie Madill57a89722013-07-02 11:57:03 -0400181}
182
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800183void VertexArray::setAttributeState(size_t attribIndex,
184 gl::Buffer *boundBuffer,
185 GLint size,
186 GLenum type,
187 bool normalized,
188 bool pureInteger,
189 GLsizei stride,
190 const void *pointer)
Jamie Madill57a89722013-07-02 11:57:03 -0400191{
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800192 ASSERT(attribIndex < getMaxAttribs());
Jamie Madill8e344942015-07-09 14:22:07 -0400193
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800194 GLintptr offset = boundBuffer ? reinterpret_cast<GLintptr>(pointer) : 0;
Jamie Madill8e344942015-07-09 14:22:07 -0400195
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800196 setVertexAttribFormat(attribIndex, size, type, normalized, pureInteger, 0);
197 setVertexAttribBinding(attribIndex, attribIndex);
198
199 VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
200 GLsizei effectiveStride =
201 stride != 0 ? stride : static_cast<GLsizei>(ComputeVertexAttributeTypeSize(attrib));
202 attrib.pointer = pointer;
203 attrib.vertexAttribArrayStride = stride;
204
205 bindVertexBuffer(attribIndex, boundBuffer, offset, effectiveStride);
206
207 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_POINTER + attribIndex);
Brandon Jones5bf98292014-06-06 17:19:38 -0700208}
209
210void VertexArray::setElementArrayBuffer(Buffer *buffer)
211{
Jamie Madill3f572682016-04-26 13:41:36 -0400212 mState.mElementArrayBuffer.set(buffer);
Jamie Madill0b9e9032015-08-17 11:51:52 +0000213 mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
214}
215
216void VertexArray::syncImplState()
217{
218 if (mDirtyBits.any())
219 {
220 mVertexArray->syncState(mDirtyBits);
221 mDirtyBits.reset();
222 }
Jamie Madill57a89722013-07-02 11:57:03 -0400223}
224
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800225} // namespace gl