blob: aa573fea3e304154aa2181a6150043ee679d4902 [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 Madill1f46bc12018-02-20 16:09:43 -050016#include "libANGLE/renderer/vulkan/CommandGraph.h"
Jamie Madilldd43e6c2017-03-24 14:18:49 -040017#include "libANGLE/renderer/vulkan/ContextVk.h"
Jamie Madillc3755fc2018-04-05 08:39:13 -040018#include "libANGLE/renderer/vulkan/RendererVk.h"
Jamie Madill3c424b42018-01-19 12:35:09 -050019#include "libANGLE/renderer/vulkan/vk_format_utils.h"
Jamie Madilldd43e6c2017-03-24 14:18:49 -040020
Jamie Madill9e54b5a2016-05-25 12:57:39 -040021namespace rx
22{
Jamie Madillc3755fc2018-04-05 08:39:13 -040023namespace
24{
25constexpr size_t kDynamicVertexDataSize = 1024 * 1024;
26constexpr size_t kDynamicIndexDataSize = 1024 * 8;
27} // anonymous namespace
Jamie Madill9e54b5a2016-05-25 12:57:39 -040028
Jamie Madillbd159f02017-10-09 19:39:06 -040029VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state)
30 : VertexArrayImpl(state),
Jamie Madillda854a22017-11-30 17:24:21 -050031 mCurrentArrayBufferHandles{},
Frank Henigman17448952017-01-05 15:48:26 -050032 mCurrentArrayBufferOffsets{},
Jamie Madillda854a22017-11-30 17:24:21 -050033 mCurrentArrayBufferResources{},
Jamie Madillc3755fc2018-04-05 08:39:13 -040034 mCurrentElementArrayBufferHandle(VK_NULL_HANDLE),
35 mCurrentElementArrayBufferOffset(0),
36 mCurrentElementArrayBufferResource(nullptr),
37 mDynamicVertexData(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, kDynamicVertexDataSize),
38 mDynamicIndexData(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, kDynamicIndexDataSize),
Jamie Madillb8e39662018-04-04 11:41:42 -040039 mDirtyLineLoopTranslation(true),
Jamie Madillc3755fc2018-04-05 08:39:13 -040040 mVertexBuffersDirty(false),
41 mIndexBufferDirty(false)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040042{
Jamie Madillda854a22017-11-30 17:24:21 -050043 mCurrentArrayBufferHandles.fill(VK_NULL_HANDLE);
Frank Henigman17448952017-01-05 15:48:26 -050044 mCurrentArrayBufferOffsets.fill(0);
Jamie Madillda854a22017-11-30 17:24:21 -050045 mCurrentArrayBufferResources.fill(nullptr);
Jamie Madill112a3a82018-01-23 13:04:06 -050046
47 mPackedInputBindings.fill({0, 0});
48 mPackedInputAttributes.fill({0, 0, 0});
Jamie Madillc3755fc2018-04-05 08:39:13 -040049
50 mDynamicVertexData.init(1);
51 mDynamicIndexData.init(1);
Jamie Madill9e54b5a2016-05-25 12:57:39 -040052}
53
Jamie Madillacf2f3a2017-11-21 19:22:44 -050054VertexArrayVk::~VertexArrayVk()
55{
56}
57
Jamie Madill4928b7c2017-06-20 12:57:39 -040058void VertexArrayVk::destroy(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040059{
Jamie Madillc3755fc2018-04-05 08:39:13 -040060 VkDevice device = vk::GetImpl(context)->getRenderer()->getDevice();
61
62 mDynamicVertexData.destroy(device);
63 mDynamicIndexData.destroy(device);
Jamie Madill22f12fe2018-04-08 14:23:40 -040064 mLineLoopHelper.destroy(device);
Jamie Madill9e54b5a2016-05-25 12:57:39 -040065}
66
Jamie Madillc3755fc2018-04-05 08:39:13 -040067gl::Error VertexArrayVk::streamVertexData(RendererVk *renderer,
68 const gl::AttributesMask &attribsToStream,
Jamie Madill32fd63b2018-03-31 11:20:35 -040069 const gl::DrawCallParams &drawCallParams)
Frank Henigman17448952017-01-05 15:48:26 -050070{
Jamie Madillc3755fc2018-04-05 08:39:13 -040071 ASSERT(!attribsToStream.none());
72
Frank Henigman17448952017-01-05 15:48:26 -050073 const auto &attribs = mState.getVertexAttributes();
74 const auto &bindings = mState.getVertexBindings();
Frank Henigman17448952017-01-05 15:48:26 -050075
Jamie Madill32fd63b2018-03-31 11:20:35 -040076 const size_t lastVertex = drawCallParams.firstVertex() + drawCallParams.vertexCount();
77
Frank Henigman17448952017-01-05 15:48:26 -050078 // TODO(fjhenigman): When we have a bunch of interleaved attributes, they end up
79 // un-interleaved, wasting space and copying time. Consider improving on that.
Jamie Madillb8e39662018-04-04 11:41:42 -040080 for (size_t attribIndex : attribsToStream)
Frank Henigman17448952017-01-05 15:48:26 -050081 {
Frank Henigman6dd4a922018-03-02 16:35:13 -050082 const gl::VertexAttribute &attrib = attribs[attribIndex];
83 const gl::VertexBinding &binding = bindings[attrib.bindingIndex];
84 ASSERT(attrib.enabled && binding.getBuffer().get() == nullptr);
Frank Henigman17448952017-01-05 15:48:26 -050085
Frank Henigman6dd4a922018-03-02 16:35:13 -050086 // TODO(fjhenigman): Work with more formats than just GL_FLOAT.
87 if (attrib.type != GL_FLOAT)
Frank Henigman17448952017-01-05 15:48:26 -050088 {
Frank Henigman6dd4a922018-03-02 16:35:13 -050089 UNIMPLEMENTED();
90 return gl::InternalError();
Frank Henigman17448952017-01-05 15:48:26 -050091 }
Frank Henigman6dd4a922018-03-02 16:35:13 -050092
93 // Only [firstVertex, lastVertex] is needed by the upcoming draw so that
94 // is all we copy, but we allocate space for [0, lastVertex] so indexing
95 // will work. If we don't start at zero all the indices will be off.
96 // TODO(fjhenigman): See if we can account for indices being off by adjusting
97 // the offset, thus avoiding wasted memory.
Jamie Madill32fd63b2018-03-31 11:20:35 -040098 const size_t firstByte = drawCallParams.firstVertex() * binding.getStride();
Frank Henigman6dd4a922018-03-02 16:35:13 -050099 const size_t lastByte =
100 lastVertex * binding.getStride() + gl::ComputeVertexAttributeTypeSize(attrib);
101 uint8_t *dst = nullptr;
Luc Ferron7a06ac12018-03-15 10:17:04 -0400102 uint32_t offset = 0;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400103 ANGLE_TRY(mDynamicVertexData.allocate(
104 renderer, lastByte, &dst, &mCurrentArrayBufferHandles[attribIndex], &offset, nullptr));
Luc Ferron7a06ac12018-03-15 10:17:04 -0400105 mCurrentArrayBufferOffsets[attribIndex] = static_cast<VkDeviceSize>(offset);
Frank Henigman6dd4a922018-03-02 16:35:13 -0500106 memcpy(dst + firstByte, static_cast<const uint8_t *>(attrib.pointer) + firstByte,
107 lastByte - firstByte);
Frank Henigman17448952017-01-05 15:48:26 -0500108 }
109
Jamie Madillc3755fc2018-04-05 08:39:13 -0400110 ANGLE_TRY(mDynamicVertexData.flush(renderer->getDevice()));
111 return gl::NoError();
112}
113
114gl::Error VertexArrayVk::streamIndexData(RendererVk *renderer,
115 const gl::DrawCallParams &drawCallParams)
116{
117 ASSERT(!mState.getElementArrayBuffer().get());
118
119 uint32_t offset = 0;
120
121 const GLsizei amount = sizeof(GLushort) * drawCallParams.indexCount();
122 GLubyte *dst = nullptr;
123
124 ANGLE_TRY(mDynamicIndexData.allocate(renderer, amount, &dst, &mCurrentElementArrayBufferHandle,
125 &offset, nullptr));
126 if (drawCallParams.type() == GL_UNSIGNED_BYTE)
127 {
128 // Unsigned bytes don't have direct support in Vulkan so we have to expand the
129 // memory to a GLushort.
130 const GLubyte *in = static_cast<const GLubyte *>(drawCallParams.indices());
131 GLushort *expandedDst = reinterpret_cast<GLushort *>(dst);
132 for (GLsizei index = 0; index < drawCallParams.indexCount(); index++)
133 {
134 expandedDst[index] = static_cast<GLushort>(in[index]);
135 }
136 }
137 else
138 {
139 memcpy(dst, drawCallParams.indices(), amount);
140 }
141 ANGLE_TRY(mDynamicIndexData.flush(renderer->getDevice()));
142
143 mCurrentElementArrayBufferOffset = offset;
Frank Henigman17448952017-01-05 15:48:26 -0500144 return gl::NoError();
145}
146
Frank Henigman0af5b862018-03-27 20:19:33 -0400147gl::Error VertexArrayVk::syncState(const gl::Context *context,
148 const gl::VertexArray::DirtyBits &dirtyBits,
149 const gl::VertexArray::DirtyAttribBitsArray &attribBits,
150 const gl::VertexArray::DirtyBindingBitsArray &bindingBits)
Jamie Madilldd43e6c2017-03-24 14:18:49 -0400151{
152 ASSERT(dirtyBits.any());
Jamie Madill72106562017-03-24 14:18:50 -0400153
Jamie Madillc3755fc2018-04-05 08:39:13 -0400154 bool invalidatePipeline = false;
155
Jamie Madillbd159f02017-10-09 19:39:06 -0400156 // Invalidate current pipeline.
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500157 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madillbd159f02017-10-09 19:39:06 -0400158
159 // Rebuild current attribute buffers cache. This will fail horribly if the buffer changes.
160 // TODO(jmadill): Handle buffer storage changes.
161 const auto &attribs = mState.getVertexAttributes();
162 const auto &bindings = mState.getVertexBindings();
163
Jamie Madill09463932018-04-04 05:26:59 -0400164 for (size_t dirtyBit : dirtyBits)
Jamie Madillbd159f02017-10-09 19:39:06 -0400165 {
Jamie Madill09463932018-04-04 05:26:59 -0400166 switch (dirtyBit)
Jamie Madillda854a22017-11-30 17:24:21 -0500167 {
Jamie Madill09463932018-04-04 05:26:59 -0400168 case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER:
Jamie Madillda854a22017-11-30 17:24:21 -0500169 {
Jamie Madill09463932018-04-04 05:26:59 -0400170 gl::Buffer *bufferGL = mState.getElementArrayBuffer().get();
171 if (bufferGL)
172 {
Jamie Madillc3755fc2018-04-05 08:39:13 -0400173 BufferVk *bufferVk = vk::GetImpl(bufferGL);
174 mCurrentElementArrayBufferResource = bufferVk;
175 mCurrentElementArrayBufferHandle = bufferVk->getVkBuffer().getHandle();
176 mCurrentElementArrayBufferOffset = 0;
Jamie Madill09463932018-04-04 05:26:59 -0400177 }
178 else
179 {
180 mCurrentElementArrayBufferResource = nullptr;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400181 mCurrentElementArrayBufferHandle = VK_NULL_HANDLE;
182 mCurrentElementArrayBufferOffset = 0;
Jamie Madill09463932018-04-04 05:26:59 -0400183 }
Jamie Madillb8e39662018-04-04 11:41:42 -0400184 mIndexBufferDirty = true;
185 mDirtyLineLoopTranslation = true;
Jamie Madill09463932018-04-04 05:26:59 -0400186 break;
Jamie Madillda854a22017-11-30 17:24:21 -0500187 }
Jamie Madill09463932018-04-04 05:26:59 -0400188
189 case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA:
Jamie Madillc3755fc2018-04-05 08:39:13 -0400190 mLineLoopBufferFirstIndex.reset();
191 mLineLoopBufferLastIndex.reset();
Jamie Madillb8e39662018-04-04 11:41:42 -0400192 mDirtyLineLoopTranslation = true;
Jamie Madill09463932018-04-04 05:26:59 -0400193 break;
194
195 default:
Jamie Madillda854a22017-11-30 17:24:21 -0500196 {
Jamie Madill09463932018-04-04 05:26:59 -0400197 size_t attribIndex = gl::VertexArray::GetVertexIndexFromDirtyBit(dirtyBit);
198
199 // Invalidate the input description for pipelines.
200 mDirtyPackedInputs.set(attribIndex);
201
202 const auto &attrib = attribs[attribIndex];
203 const auto &binding = bindings[attrib.bindingIndex];
204
205 if (attrib.enabled)
206 {
207 gl::Buffer *bufferGL = binding.getBuffer().get();
208
209 if (bufferGL)
210 {
211 BufferVk *bufferVk = vk::GetImpl(bufferGL);
212 mCurrentArrayBufferResources[attribIndex] = bufferVk;
213 mCurrentArrayBufferHandles[attribIndex] =
214 bufferVk->getVkBuffer().getHandle();
215 mClientMemoryAttribs.reset(attribIndex);
216 }
217 else
218 {
219 mCurrentArrayBufferResources[attribIndex] = nullptr;
220 mCurrentArrayBufferHandles[attribIndex] = VK_NULL_HANDLE;
221 mClientMemoryAttribs.set(attribIndex);
222 }
223 // TODO(jmadill): Offset handling. Assume zero for now.
224 mCurrentArrayBufferOffsets[attribIndex] = 0;
225 }
226 else
227 {
228 mClientMemoryAttribs.reset(attribIndex);
229 UNIMPLEMENTED();
230 }
Jamie Madillc3755fc2018-04-05 08:39:13 -0400231
232 invalidatePipeline = true;
Jamie Madill09463932018-04-04 05:26:59 -0400233 break;
Jamie Madillda854a22017-11-30 17:24:21 -0500234 }
Jamie Madillbd159f02017-10-09 19:39:06 -0400235 }
236 }
Frank Henigman0af5b862018-03-27 20:19:33 -0400237
Jamie Madillc3755fc2018-04-05 08:39:13 -0400238 if (invalidatePipeline)
239 {
240 mVertexBuffersDirty = true;
241 contextVk->invalidateCurrentPipeline();
242 }
243
Frank Henigman0af5b862018-03-27 20:19:33 -0400244 return gl::NoError();
Jamie Madillbd159f02017-10-09 19:39:06 -0400245}
246
Jamie Madillda854a22017-11-30 17:24:21 -0500247const gl::AttribArray<VkBuffer> &VertexArrayVk::getCurrentArrayBufferHandles() const
Jamie Madillbd159f02017-10-09 19:39:06 -0400248{
Jamie Madillda854a22017-11-30 17:24:21 -0500249 return mCurrentArrayBufferHandles;
Jamie Madillbd159f02017-10-09 19:39:06 -0400250}
251
Frank Henigman17448952017-01-05 15:48:26 -0500252const gl::AttribArray<VkDeviceSize> &VertexArrayVk::getCurrentArrayBufferOffsets() const
253{
254 return mCurrentArrayBufferOffsets;
255}
256
Jamie Madill9cceac42018-03-31 14:19:16 -0400257void VertexArrayVk::updateArrayBufferReadDependencies(vk::CommandGraphNode *readingNode,
Jamie Madillc3755fc2018-04-05 08:39:13 -0400258 const gl::AttributesMask &activeAttribsMask,
259 Serial serial)
Jamie Madillbd159f02017-10-09 19:39:06 -0400260{
Jamie Madillda854a22017-11-30 17:24:21 -0500261 // Handle the bound array buffers.
Jamie Madillc3755fc2018-04-05 08:39:13 -0400262 for (size_t attribIndex : activeAttribsMask)
Jamie Madillbd159f02017-10-09 19:39:06 -0400263 {
Frank Henigman17448952017-01-05 15:48:26 -0500264 if (mCurrentArrayBufferResources[attribIndex])
Jamie Madill9cceac42018-03-31 14:19:16 -0400265 mCurrentArrayBufferResources[attribIndex]->onReadResource(readingNode, serial);
Jamie Madillda854a22017-11-30 17:24:21 -0500266 }
Jamie Madillc3755fc2018-04-05 08:39:13 -0400267}
Jamie Madillda854a22017-11-30 17:24:21 -0500268
Jamie Madill9cceac42018-03-31 14:19:16 -0400269void VertexArrayVk::updateElementArrayBufferReadDependency(vk::CommandGraphNode *readingNode,
Jamie Madillc3755fc2018-04-05 08:39:13 -0400270 Serial serial)
271{
Jamie Madillda854a22017-11-30 17:24:21 -0500272 // Handle the bound element array buffer.
Jamie Madillc3755fc2018-04-05 08:39:13 -0400273 if (mCurrentElementArrayBufferResource)
Jamie Madillda854a22017-11-30 17:24:21 -0500274 {
Jamie Madill9cceac42018-03-31 14:19:16 -0400275 mCurrentElementArrayBufferResource->onReadResource(readingNode, serial);
Jamie Madillbd159f02017-10-09 19:39:06 -0400276 }
Jamie Madilldd43e6c2017-03-24 14:18:49 -0400277}
278
Jamie Madill112a3a82018-01-23 13:04:06 -0500279void VertexArrayVk::getPackedInputDescriptions(vk::PipelineDesc *pipelineDesc)
Jamie Madillebf72992017-10-13 14:09:45 -0400280{
Jamie Madill112a3a82018-01-23 13:04:06 -0500281 updatePackedInputDescriptions();
282 pipelineDesc->updateVertexInputInfo(mPackedInputBindings, mPackedInputAttributes);
Jamie Madillebf72992017-10-13 14:09:45 -0400283}
284
Jamie Madill112a3a82018-01-23 13:04:06 -0500285void VertexArrayVk::updatePackedInputDescriptions()
Jamie Madillebf72992017-10-13 14:09:45 -0400286{
Jamie Madill112a3a82018-01-23 13:04:06 -0500287 if (!mDirtyPackedInputs.any())
Jamie Madillebf72992017-10-13 14:09:45 -0400288 {
289 return;
290 }
291
292 const auto &attribs = mState.getVertexAttributes();
293 const auto &bindings = mState.getVertexBindings();
294
Jamie Madill112a3a82018-01-23 13:04:06 -0500295 for (auto attribIndex : mDirtyPackedInputs)
Jamie Madillebf72992017-10-13 14:09:45 -0400296 {
297 const auto &attrib = attribs[attribIndex];
298 const auto &binding = bindings[attrib.bindingIndex];
299 if (attrib.enabled)
300 {
Jamie Madill112a3a82018-01-23 13:04:06 -0500301 updatePackedInputInfo(static_cast<uint32_t>(attribIndex), binding, attrib);
Jamie Madillebf72992017-10-13 14:09:45 -0400302 }
303 else
304 {
305 UNIMPLEMENTED();
306 }
307 }
308
Jamie Madill112a3a82018-01-23 13:04:06 -0500309 mDirtyPackedInputs.reset();
310}
311
312void VertexArrayVk::updatePackedInputInfo(uint32_t attribIndex,
313 const gl::VertexBinding &binding,
314 const gl::VertexAttribute &attrib)
315{
316 vk::PackedVertexInputBindingDesc &bindingDesc = mPackedInputBindings[attribIndex];
317
318 size_t attribSize = gl::ComputeVertexAttributeTypeSize(attrib);
319 ASSERT(attribSize <= std::numeric_limits<uint16_t>::max());
320
Frank Henigmana8e868f2018-01-28 23:32:25 -0500321 bindingDesc.stride = static_cast<uint16_t>(binding.getStride());
Jamie Madill112a3a82018-01-23 13:04:06 -0500322 bindingDesc.inputRate = static_cast<uint16_t>(
323 binding.getDivisor() > 0 ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX);
324
325 gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib);
326 VkFormat vkFormat = vk::GetNativeVertexFormat(vertexFormatType);
327 ASSERT(vkFormat <= std::numeric_limits<uint16_t>::max());
328
329 vk::PackedVertexInputAttributeDesc &attribDesc = mPackedInputAttributes[attribIndex];
330 attribDesc.format = static_cast<uint16_t>(vkFormat);
331 attribDesc.location = static_cast<uint16_t>(attribIndex);
332 attribDesc.offset = static_cast<uint32_t>(ComputeVertexAttributeOffset(attrib, binding));
Jamie Madillebf72992017-10-13 14:09:45 -0400333}
334
Jamie Madillc3755fc2018-04-05 08:39:13 -0400335gl::Error VertexArrayVk::drawArrays(const gl::Context *context,
336 RendererVk *renderer,
337 const gl::DrawCallParams &drawCallParams,
338 vk::CommandGraphNode *drawNode,
339 bool newCommandBuffer)
340{
341 vk::CommandBuffer *commandBuffer = drawNode->getInsideRenderPassCommands();
342 ASSERT(commandBuffer->valid());
343
344 ANGLE_TRY(onDraw(context, renderer, drawCallParams, drawNode, newCommandBuffer));
345
346 if (drawCallParams.mode() != GL_LINE_LOOP)
347 {
348 commandBuffer->draw(drawCallParams.vertexCount(), 1, drawCallParams.firstVertex(), 0);
349 return gl::NoError();
350 }
351
352 // Handle GL_LINE_LOOP drawArrays.
Jamie Madillb8e39662018-04-04 11:41:42 -0400353 // This test may be incorrect if the draw call switches from DrawArrays/DrawElements.
Jamie Madillc3755fc2018-04-05 08:39:13 -0400354 int lastVertex = drawCallParams.firstVertex() + drawCallParams.vertexCount();
355 if (!mLineLoopBufferFirstIndex.valid() || !mLineLoopBufferLastIndex.valid() ||
356 mLineLoopBufferFirstIndex != drawCallParams.firstVertex() ||
357 mLineLoopBufferLastIndex != lastVertex)
358 {
Jamie Madill22f12fe2018-04-08 14:23:40 -0400359 ANGLE_TRY(mLineLoopHelper.getIndexBufferForDrawArrays(renderer, drawCallParams,
360 &mCurrentElementArrayBufferHandle,
361 &mCurrentElementArrayBufferOffset));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400362
363 mLineLoopBufferFirstIndex = drawCallParams.firstVertex();
364 mLineLoopBufferLastIndex = lastVertex;
365 }
366
367 commandBuffer->bindIndexBuffer(mCurrentElementArrayBufferHandle,
368 mCurrentElementArrayBufferOffset, VK_INDEX_TYPE_UINT32);
369
Jamie Madill22f12fe2018-04-08 14:23:40 -0400370 vk::LineLoopHelper::Draw(drawCallParams.vertexCount(), commandBuffer);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400371
372 return gl::NoError();
373}
374
375gl::Error VertexArrayVk::drawElements(const gl::Context *context,
376 RendererVk *renderer,
377 const gl::DrawCallParams &drawCallParams,
378 vk::CommandGraphNode *drawNode,
379 bool newCommandBuffer)
380{
381 vk::CommandBuffer *commandBuffer = drawNode->getInsideRenderPassCommands();
382 ASSERT(commandBuffer->valid());
383
384 if (drawCallParams.mode() != GL_LINE_LOOP)
385 {
386 ANGLE_TRY(onIndexedDraw(context, renderer, drawCallParams, drawNode, newCommandBuffer));
387 commandBuffer->drawIndexed(drawCallParams.indexCount(), 1, 0, 0, 0);
388 return gl::NoError();
389 }
390
391 // Handle GL_LINE_LOOP drawElements.
392 gl::Buffer *elementArrayBuffer = mState.getElementArrayBuffer().get();
393 if (!elementArrayBuffer)
394 {
395 UNIMPLEMENTED();
396 return gl::InternalError() << "Line loop indices in client memory not supported";
397 }
398
399 BufferVk *elementArrayBufferVk = vk::GetImpl(elementArrayBuffer);
400
401 VkIndexType indexType = gl_vk::GetIndexType(drawCallParams.type());
402
Jamie Madillb8e39662018-04-04 11:41:42 -0400403 // This also doesn't check if the element type changed, which should trigger translation.
404 if (mDirtyLineLoopTranslation)
405 {
Jamie Madill22f12fe2018-04-08 14:23:40 -0400406 ANGLE_TRY(mLineLoopHelper.getIndexBufferForElementArrayBuffer(
Jamie Madillb8e39662018-04-04 11:41:42 -0400407 renderer, elementArrayBufferVk, indexType, drawCallParams.indexCount(),
408 &mCurrentElementArrayBufferHandle, &mCurrentElementArrayBufferOffset));
409 }
Jamie Madillc3755fc2018-04-05 08:39:13 -0400410
411 ANGLE_TRY(onIndexedDraw(context, renderer, drawCallParams, drawNode, newCommandBuffer));
Jamie Madill22f12fe2018-04-08 14:23:40 -0400412 vk::LineLoopHelper::Draw(drawCallParams.indexCount(), commandBuffer);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400413
414 return gl::NoError();
415}
416
417gl::Error VertexArrayVk::onDraw(const gl::Context *context,
418 RendererVk *renderer,
419 const gl::DrawCallParams &drawCallParams,
420 vk::CommandGraphNode *drawNode,
421 bool newCommandBuffer)
422{
423 const gl::State &state = context->getGLState();
424 const gl::Program *programGL = state.getProgram();
425 const gl::AttributesMask &activeAttribs = programGL->getActiveAttribLocationsMask();
426 uint32_t maxAttrib = programGL->getState().getMaxActiveAttribLocation();
427
428 if (mClientMemoryAttribs.any())
429 {
430 const gl::AttributesMask &attribsToStream = (mClientMemoryAttribs & activeAttribs);
431 if (attribsToStream.any())
432 {
433 ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
434 ANGLE_TRY(streamVertexData(renderer, attribsToStream, drawCallParams));
435 vk::CommandBuffer *commandBuffer = drawNode->getInsideRenderPassCommands();
436 commandBuffer->bindVertexBuffers(0, maxAttrib, mCurrentArrayBufferHandles.data(),
437 mCurrentArrayBufferOffsets.data());
438 }
439 }
440 else if (mVertexBuffersDirty || newCommandBuffer)
441 {
Luc Ferron44162472018-04-06 13:20:45 -0400442 if (maxAttrib > 0)
443 {
444 vk::CommandBuffer *commandBuffer = drawNode->getInsideRenderPassCommands();
445 commandBuffer->bindVertexBuffers(0, maxAttrib, mCurrentArrayBufferHandles.data(),
446 mCurrentArrayBufferOffsets.data());
447 updateArrayBufferReadDependencies(drawNode, activeAttribs,
448 renderer->getCurrentQueueSerial());
449 }
Jamie Madillc3755fc2018-04-05 08:39:13 -0400450 mVertexBuffersDirty = false;
451 }
452
453 return gl::NoError();
454}
455
456gl::Error VertexArrayVk::onIndexedDraw(const gl::Context *context,
457 RendererVk *renderer,
458 const gl::DrawCallParams &drawCallParams,
459 vk::CommandGraphNode *drawNode,
460 bool newCommandBuffer)
461{
462 ANGLE_TRY(onDraw(context, renderer, drawCallParams, drawNode, newCommandBuffer));
463
464 if (!mState.getElementArrayBuffer().get())
465 {
466 ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
467 ANGLE_TRY(streamIndexData(renderer, drawCallParams));
468 vk::CommandBuffer *commandBuffer = drawNode->getInsideRenderPassCommands();
469 commandBuffer->bindIndexBuffer(mCurrentElementArrayBufferHandle,
470 mCurrentElementArrayBufferOffset,
471 gl_vk::GetIndexType(drawCallParams.type()));
472 }
473 else if (mIndexBufferDirty || newCommandBuffer)
474 {
475 if (drawCallParams.type() == GL_UNSIGNED_BYTE)
476 {
477 // TODO(fjhenigman): Index format translation.
478 UNIMPLEMENTED();
479 return gl::InternalError()
480 << "Unsigned byte translation is not implemented for indices in a buffer object";
481 }
482
483 vk::CommandBuffer *commandBuffer = drawNode->getInsideRenderPassCommands();
484 commandBuffer->bindIndexBuffer(mCurrentElementArrayBufferHandle,
485 mCurrentElementArrayBufferOffset,
486 gl_vk::GetIndexType(drawCallParams.type()));
487 updateElementArrayBufferReadDependency(drawNode, renderer->getCurrentQueueSerial());
488 mIndexBufferDirty = false;
489 }
490
491 return gl::NoError();
492}
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400493} // namespace rx