blob: 0ce3d185542ad8d0a3cdaa62da45c3dfad70369e [file] [log] [blame]
Jamie Madill9e54b5a2016-05-25 12:57:39 -04001//
2// Copyright 2016 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// VertexArrayVk.cpp:
7// Implements the class methods for VertexArrayVk.
8//
9
10#include "libANGLE/renderer/vulkan/VertexArrayVk.h"
11
12#include "common/debug.h"
13
Jamie Madillc564c072017-06-01 12:45:42 -040014#include "libANGLE/Context.h"
Jamie Madillbd159f02017-10-09 19:39:06 -040015#include "libANGLE/renderer/vulkan/BufferVk.h"
Jamie Madilldd43e6c2017-03-24 14:18:49 -040016#include "libANGLE/renderer/vulkan/ContextVk.h"
Jamie Madillebf72992017-10-13 14:09:45 -040017#include "libANGLE/renderer/vulkan/formatutilsvk.h"
Jamie Madilldd43e6c2017-03-24 14:18:49 -040018
Jamie Madill9e54b5a2016-05-25 12:57:39 -040019namespace rx
20{
21
Jamie Madillbd159f02017-10-09 19:39:06 -040022VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state)
23 : VertexArrayImpl(state),
Jamie Madillda854a22017-11-30 17:24:21 -050024 mCurrentArrayBufferHandles{},
25 mCurrentArrayBufferResources{},
26 mCurrentElementArrayBufferResource(nullptr),
Jamie Madillebf72992017-10-13 14:09:45 -040027 mCurrentVertexDescsValid(false)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040028{
Jamie Madillda854a22017-11-30 17:24:21 -050029 mCurrentArrayBufferHandles.fill(VK_NULL_HANDLE);
30 mCurrentArrayBufferResources.fill(nullptr);
Jamie Madillebf72992017-10-13 14:09:45 -040031 mCurrentVertexBindingDescs.reserve(state.getMaxAttribs());
32 mCurrentVertexAttribDescs.reserve(state.getMaxAttribs());
Jamie Madill9e54b5a2016-05-25 12:57:39 -040033}
34
Jamie Madillacf2f3a2017-11-21 19:22:44 -050035VertexArrayVk::~VertexArrayVk()
36{
37}
38
Jamie Madill4928b7c2017-06-20 12:57:39 -040039void VertexArrayVk::destroy(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040040{
41}
42
Jamie Madillc564c072017-06-01 12:45:42 -040043void VertexArrayVk::syncState(const gl::Context *context,
44 const gl::VertexArray::DirtyBits &dirtyBits)
Jamie Madilldd43e6c2017-03-24 14:18:49 -040045{
46 ASSERT(dirtyBits.any());
Jamie Madill72106562017-03-24 14:18:50 -040047
Jamie Madillbd159f02017-10-09 19:39:06 -040048 // Invalidate current pipeline.
Jamie Madill72106562017-03-24 14:18:50 -040049 // TODO(jmadill): Use pipeline cache.
Jamie Madillacf2f3a2017-11-21 19:22:44 -050050 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madill72106562017-03-24 14:18:50 -040051 contextVk->invalidateCurrentPipeline();
Jamie Madillbd159f02017-10-09 19:39:06 -040052
Jamie Madillebf72992017-10-13 14:09:45 -040053 // Invalidate the vertex descriptions.
54 invalidateVertexDescriptions();
55
Jamie Madillbd159f02017-10-09 19:39:06 -040056 // Rebuild current attribute buffers cache. This will fail horribly if the buffer changes.
57 // TODO(jmadill): Handle buffer storage changes.
58 const auto &attribs = mState.getVertexAttributes();
59 const auto &bindings = mState.getVertexBindings();
60
61 for (auto dirtyBit : dirtyBits)
62 {
63 if (dirtyBit == gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER)
Jamie Madillda854a22017-11-30 17:24:21 -050064 {
65 gl::Buffer *bufferGL = mState.getElementArrayBuffer().get();
66 if (bufferGL)
67 {
68 mCurrentElementArrayBufferResource = vk::GetImpl(bufferGL);
69 }
70 else
71 {
72 mCurrentElementArrayBufferResource = nullptr;
73 }
Jamie Madillbd159f02017-10-09 19:39:06 -040074 continue;
Jamie Madillda854a22017-11-30 17:24:21 -050075 }
Jamie Madillbd159f02017-10-09 19:39:06 -040076
77 size_t attribIndex = gl::VertexArray::GetVertexIndexFromDirtyBit(dirtyBit);
78
79 const auto &attrib = attribs[attribIndex];
80 const auto &binding = bindings[attrib.bindingIndex];
Jamie Madillebf72992017-10-13 14:09:45 -040081
Jamie Madillbd159f02017-10-09 19:39:06 -040082 if (attrib.enabled)
83 {
84 gl::Buffer *bufferGL = binding.getBuffer().get();
85
86 if (bufferGL)
87 {
Jamie Madillda854a22017-11-30 17:24:21 -050088 BufferVk *bufferVk = vk::GetImpl(bufferGL);
89 mCurrentArrayBufferResources[attribIndex] = bufferVk;
90 mCurrentArrayBufferHandles[attribIndex] = bufferVk->getVkBuffer().getHandle();
Jamie Madillbd159f02017-10-09 19:39:06 -040091 }
92 else
93 {
Jamie Madillda854a22017-11-30 17:24:21 -050094 mCurrentArrayBufferResources[attribIndex] = nullptr;
95 mCurrentArrayBufferHandles[attribIndex] = VK_NULL_HANDLE;
Jamie Madillbd159f02017-10-09 19:39:06 -040096 }
97 }
98 else
99 {
100 UNIMPLEMENTED();
101 }
102 }
103}
104
Jamie Madillda854a22017-11-30 17:24:21 -0500105const gl::AttribArray<VkBuffer> &VertexArrayVk::getCurrentArrayBufferHandles() const
Jamie Madillbd159f02017-10-09 19:39:06 -0400106{
Jamie Madillda854a22017-11-30 17:24:21 -0500107 return mCurrentArrayBufferHandles;
Jamie Madillbd159f02017-10-09 19:39:06 -0400108}
109
110void VertexArrayVk::updateCurrentBufferSerials(const gl::AttributesMask &activeAttribsMask,
Jamie Madillda854a22017-11-30 17:24:21 -0500111 Serial serial,
112 DrawType drawType)
Jamie Madillbd159f02017-10-09 19:39:06 -0400113{
Jamie Madillda854a22017-11-30 17:24:21 -0500114 // Handle the bound array buffers.
Jamie Madillbd159f02017-10-09 19:39:06 -0400115 for (auto attribIndex : activeAttribsMask)
116 {
Jamie Madillda854a22017-11-30 17:24:21 -0500117 ASSERT(mCurrentArrayBufferResources[attribIndex]);
118 mCurrentArrayBufferResources[attribIndex]->setQueueSerial(serial);
119 }
120
121 // Handle the bound element array buffer.
122 if (drawType == DrawType::Elements)
123 {
124 ASSERT(mCurrentElementArrayBufferResource);
125 mCurrentElementArrayBufferResource->setQueueSerial(serial);
Jamie Madillbd159f02017-10-09 19:39:06 -0400126 }
Jamie Madilldd43e6c2017-03-24 14:18:49 -0400127}
128
Jamie Madillebf72992017-10-13 14:09:45 -0400129void VertexArrayVk::invalidateVertexDescriptions()
130{
131 mCurrentVertexDescsValid = false;
132 mCurrentVertexBindingDescs.clear();
133 mCurrentVertexAttribDescs.clear();
134}
135
136void VertexArrayVk::updateVertexDescriptions(const gl::Context *context)
137{
138 if (mCurrentVertexDescsValid)
139 {
140 return;
141 }
142
143 const auto &attribs = mState.getVertexAttributes();
144 const auto &bindings = mState.getVertexBindings();
145
146 const gl::Program *programGL = context->getGLState().getProgram();
147
148 for (auto attribIndex : programGL->getActiveAttribLocationsMask())
149 {
150 const auto &attrib = attribs[attribIndex];
151 const auto &binding = bindings[attrib.bindingIndex];
152 if (attrib.enabled)
153 {
154 VkVertexInputBindingDescription bindingDesc;
155 bindingDesc.binding = static_cast<uint32_t>(mCurrentVertexBindingDescs.size());
156 bindingDesc.stride = static_cast<uint32_t>(gl::ComputeVertexAttributeTypeSize(attrib));
157 bindingDesc.inputRate = (binding.getDivisor() > 0 ? VK_VERTEX_INPUT_RATE_INSTANCE
158 : VK_VERTEX_INPUT_RATE_VERTEX);
159
160 gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib);
161
162 VkVertexInputAttributeDescription attribDesc;
163 attribDesc.binding = bindingDesc.binding;
164 attribDesc.format = vk::GetNativeVertexFormat(vertexFormatType);
165 attribDesc.location = static_cast<uint32_t>(attribIndex);
166 attribDesc.offset =
167 static_cast<uint32_t>(ComputeVertexAttributeOffset(attrib, binding));
168
169 mCurrentVertexBindingDescs.push_back(bindingDesc);
170 mCurrentVertexAttribDescs.push_back(attribDesc);
171 }
172 else
173 {
174 UNIMPLEMENTED();
175 }
176 }
177
178 mCurrentVertexDescsValid = true;
179}
180
181const std::vector<VkVertexInputBindingDescription> &VertexArrayVk::getVertexBindingDescs() const
182{
183 return mCurrentVertexBindingDescs;
184}
185
186const std::vector<VkVertexInputAttributeDescription> &VertexArrayVk::getVertexAttribDescs() const
187{
188 return mCurrentVertexAttribDescs;
189}
190
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400191} // namespace rx