blob: 2ee0581cec0b60e8f64794625378e527b7f2b578 [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{
Jiawei-Shao2597fb62016-12-09 16:38:02 +080031 for (auto &binding : mVertexBindings)
Jamie Madill8e344942015-07-09 14:22:07 -040032 {
Martin Radevdd5f27e2017-06-07 10:17:09 +030033 binding.setBuffer(nullptr);
Jamie Madill8e344942015-07-09 14:22:07 -040034 }
35 mElementArrayBuffer.set(nullptr);
36}
37
Jiawei-Shao2597fb62016-12-09 16:38:02 +080038VertexArray::VertexArray(rx::GLImplFactory *factory,
39 GLuint id,
40 size_t maxAttribs,
41 size_t maxAttribBindings)
42 : mId(id),
43 mState(maxAttribs, maxAttribBindings),
44 mVertexArray(factory->createVertexArray(mState))
Jamie Madill8e344942015-07-09 14:22:07 -040045{
Jamie Madill004a6f92013-07-10 15:13:38 -040046}
47
48VertexArray::~VertexArray()
49{
Brandon Jonesd38f9262014-06-18 16:26:45 -070050 SafeDelete(mVertexArray);
Jamie Madill57a89722013-07-02 11:57:03 -040051}
52
Shannon Woodsaa2ab7d2014-06-24 17:51:51 -040053GLuint VertexArray::id() const
54{
55 return mId;
56}
57
Geoff Lang70d0f492015-12-10 17:45:46 -050058void VertexArray::setLabel(const std::string &label)
59{
Jamie Madill3f572682016-04-26 13:41:36 -040060 mState.mLabel = label;
Geoff Lang70d0f492015-12-10 17:45:46 -050061}
62
63const std::string &VertexArray::getLabel() const
64{
Jamie Madill3f572682016-04-26 13:41:36 -040065 return mState.mLabel;
Geoff Lang70d0f492015-12-10 17:45:46 -050066}
67
Jamie Madill57a89722013-07-02 11:57:03 -040068void VertexArray::detachBuffer(GLuint bufferName)
69{
Jiawei-Shao2597fb62016-12-09 16:38:02 +080070 for (auto &binding : mState.mVertexBindings)
Jamie Madill57a89722013-07-02 11:57:03 -040071 {
Martin Radevdd5f27e2017-06-07 10:17:09 +030072 if (binding.getBuffer().id() == bufferName)
Jamie Madill57a89722013-07-02 11:57:03 -040073 {
Martin Radevdd5f27e2017-06-07 10:17:09 +030074 binding.setBuffer(nullptr);
Jamie Madill57a89722013-07-02 11:57:03 -040075 }
76 }
77
Jamie Madill3f572682016-04-26 13:41:36 -040078 if (mState.mElementArrayBuffer.id() == bufferName)
Jamie Madill57a89722013-07-02 11:57:03 -040079 {
Jamie Madill3f572682016-04-26 13:41:36 -040080 mState.mElementArrayBuffer.set(nullptr);
Jamie Madill57a89722013-07-02 11:57:03 -040081 }
82}
83
Jiawei-Shao2597fb62016-12-09 16:38:02 +080084const VertexAttribute &VertexArray::getVertexAttribute(size_t attribIndex) const
Jamie Madill57a89722013-07-02 11:57:03 -040085{
Jiawei-Shao2597fb62016-12-09 16:38:02 +080086 ASSERT(attribIndex < getMaxAttribs());
87 return mState.mVertexAttributes[attribIndex];
88}
89
90const VertexBinding &VertexArray::getVertexBinding(size_t bindingIndex) const
91{
92 ASSERT(bindingIndex < getMaxBindings());
93 return mState.mVertexBindings[bindingIndex];
94}
95
Jamie Madill6de51852017-04-12 09:53:01 -040096size_t VertexArray::GetAttribIndex(size_t dirtyBit)
Jiawei-Shao2597fb62016-12-09 16:38:02 +080097{
98 static_assert(gl::MAX_VERTEX_ATTRIBS == gl::MAX_VERTEX_ATTRIB_BINDINGS,
99 "The stride of vertex attributes should equal to that of vertex bindings.");
Shao80957d92017-02-20 21:25:59 +0800100 ASSERT(dirtyBit > DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
101 return (dirtyBit - DIRTY_BIT_ATTRIB_0_ENABLED) % gl::MAX_VERTEX_ATTRIBS;
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800102}
103
104void VertexArray::bindVertexBuffer(size_t bindingIndex,
105 Buffer *boundBuffer,
106 GLintptr offset,
107 GLsizei stride)
108{
109 ASSERT(bindingIndex < getMaxBindings());
110
111 VertexBinding *binding = &mState.mVertexBindings[bindingIndex];
112
Martin Radevdd5f27e2017-06-07 10:17:09 +0300113 binding->setBuffer(boundBuffer);
114 binding->setOffset(offset);
115 binding->setStride(stride);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800116 mDirtyBits.set(DIRTY_BIT_BINDING_0_BUFFER + bindingIndex);
117}
118
119void VertexArray::setVertexAttribBinding(size_t attribIndex, size_t bindingIndex)
120{
121 ASSERT(attribIndex < getMaxAttribs() && bindingIndex < getMaxBindings());
122
Shao80957d92017-02-20 21:25:59 +0800123 mState.mVertexAttributes[attribIndex].bindingIndex = static_cast<GLuint>(bindingIndex);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800124 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_BINDING + attribIndex);
125}
126
127void VertexArray::setVertexBindingDivisor(size_t bindingIndex, GLuint divisor)
128{
129 ASSERT(bindingIndex < getMaxBindings());
130
Martin Radevdd5f27e2017-06-07 10:17:09 +0300131 mState.mVertexBindings[bindingIndex].setDivisor(divisor);
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800132 mDirtyBits.set(DIRTY_BIT_BINDING_0_DIVISOR + bindingIndex);
133}
134
135void VertexArray::setVertexAttribFormat(size_t attribIndex,
136 GLint size,
137 GLenum type,
138 bool normalized,
139 bool pureInteger,
140 GLintptr relativeOffset)
141{
142 ASSERT(attribIndex < getMaxAttribs());
143
144 VertexAttribute *attrib = &mState.mVertexAttributes[attribIndex];
145
146 attrib->size = size;
147 attrib->type = type;
148 attrib->normalized = normalized;
149 attrib->pureInteger = pureInteger;
150 attrib->relativeOffset = relativeOffset;
151 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_FORMAT + attribIndex);
Jamie Madill57a89722013-07-02 11:57:03 -0400152}
153
Jamie Madill8e344942015-07-09 14:22:07 -0400154void VertexArray::setVertexAttribDivisor(size_t index, GLuint divisor)
Jamie Madill57a89722013-07-02 11:57:03 -0400155{
Brandon Jones5bf98292014-06-06 17:19:38 -0700156 ASSERT(index < getMaxAttribs());
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800157
158 setVertexAttribBinding(index, index);
159 setVertexBindingDivisor(index, divisor);
Jamie Madill57a89722013-07-02 11:57:03 -0400160}
161
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800162void VertexArray::enableAttribute(size_t attribIndex, bool enabledState)
Jamie Madill57a89722013-07-02 11:57:03 -0400163{
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800164 ASSERT(attribIndex < getMaxAttribs());
Shao80957d92017-02-20 21:25:59 +0800165
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800166 mState.mVertexAttributes[attribIndex].enabled = enabledState;
167 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_ENABLED + attribIndex);
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400168
169 // Update state cache
170 if (enabledState)
171 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800172 mState.mMaxEnabledAttribute = std::max(attribIndex + 1, mState.mMaxEnabledAttribute);
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400173 }
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800174 else if (mState.mMaxEnabledAttribute == attribIndex + 1)
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400175 {
Jamie Madill3f572682016-04-26 13:41:36 -0400176 while (mState.mMaxEnabledAttribute > 0 &&
177 !mState.mVertexAttributes[mState.mMaxEnabledAttribute - 1].enabled)
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400178 {
Jamie Madill3f572682016-04-26 13:41:36 -0400179 --mState.mMaxEnabledAttribute;
Jamie Madillaebf9dd2015-04-28 12:39:07 -0400180 }
181 }
Jamie Madill57a89722013-07-02 11:57:03 -0400182}
183
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800184void VertexArray::setAttributeState(size_t attribIndex,
185 gl::Buffer *boundBuffer,
186 GLint size,
187 GLenum type,
188 bool normalized,
189 bool pureInteger,
190 GLsizei stride,
191 const void *pointer)
Jamie Madill57a89722013-07-02 11:57:03 -0400192{
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800193 ASSERT(attribIndex < getMaxAttribs());
Jamie Madill8e344942015-07-09 14:22:07 -0400194
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800195 GLintptr offset = boundBuffer ? reinterpret_cast<GLintptr>(pointer) : 0;
Jamie Madill8e344942015-07-09 14:22:07 -0400196
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800197 setVertexAttribFormat(attribIndex, size, type, normalized, pureInteger, 0);
198 setVertexAttribBinding(attribIndex, attribIndex);
199
200 VertexAttribute &attrib = mState.mVertexAttributes[attribIndex];
201 GLsizei effectiveStride =
202 stride != 0 ? stride : static_cast<GLsizei>(ComputeVertexAttributeTypeSize(attrib));
203 attrib.pointer = pointer;
204 attrib.vertexAttribArrayStride = stride;
205
206 bindVertexBuffer(attribIndex, boundBuffer, offset, effectiveStride);
207
208 mDirtyBits.set(DIRTY_BIT_ATTRIB_0_POINTER + attribIndex);
Brandon Jones5bf98292014-06-06 17:19:38 -0700209}
210
211void VertexArray::setElementArrayBuffer(Buffer *buffer)
212{
Jamie Madill3f572682016-04-26 13:41:36 -0400213 mState.mElementArrayBuffer.set(buffer);
Jamie Madill0b9e9032015-08-17 11:51:52 +0000214 mDirtyBits.set(DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
215}
216
Jamie Madilldd43e6c2017-03-24 14:18:49 -0400217void VertexArray::syncImplState(const Context *context)
Jamie Madill0b9e9032015-08-17 11:51:52 +0000218{
219 if (mDirtyBits.any())
220 {
Jamie Madillc564c072017-06-01 12:45:42 -0400221 mVertexArray->syncState(context, mDirtyBits);
Jamie Madill0b9e9032015-08-17 11:51:52 +0000222 mDirtyBits.reset();
223 }
Jamie Madill57a89722013-07-02 11:57:03 -0400224}
225
Jiawei-Shao2597fb62016-12-09 16:38:02 +0800226} // namespace gl