blob: 3114538cec7eae71997606959eef418972ad2c2a [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),
39 mVertexBuffersDirty(false),
40 mIndexBufferDirty(false)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040041{
Jamie Madillda854a22017-11-30 17:24:21 -050042 mCurrentArrayBufferHandles.fill(VK_NULL_HANDLE);
Frank Henigman17448952017-01-05 15:48:26 -050043 mCurrentArrayBufferOffsets.fill(0);
Jamie Madillda854a22017-11-30 17:24:21 -050044 mCurrentArrayBufferResources.fill(nullptr);
Jamie Madill112a3a82018-01-23 13:04:06 -050045
46 mPackedInputBindings.fill({0, 0});
47 mPackedInputAttributes.fill({0, 0, 0});
Jamie Madillc3755fc2018-04-05 08:39:13 -040048
49 mDynamicVertexData.init(1);
50 mDynamicIndexData.init(1);
Jamie Madill9e54b5a2016-05-25 12:57:39 -040051}
52
Jamie Madillacf2f3a2017-11-21 19:22:44 -050053VertexArrayVk::~VertexArrayVk()
54{
55}
56
Jamie Madill4928b7c2017-06-20 12:57:39 -040057void VertexArrayVk::destroy(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -040058{
Jamie Madillc3755fc2018-04-05 08:39:13 -040059 VkDevice device = vk::GetImpl(context)->getRenderer()->getDevice();
60
61 mDynamicVertexData.destroy(device);
62 mDynamicIndexData.destroy(device);
63 mLineLoopHandler.destroy(device);
Jamie Madill9e54b5a2016-05-25 12:57:39 -040064}
65
Jamie Madillc3755fc2018-04-05 08:39:13 -040066gl::Error VertexArrayVk::streamVertexData(RendererVk *renderer,
67 const gl::AttributesMask &attribsToStream,
Jamie Madill32fd63b2018-03-31 11:20:35 -040068 const gl::DrawCallParams &drawCallParams)
Frank Henigman17448952017-01-05 15:48:26 -050069{
Jamie Madillc3755fc2018-04-05 08:39:13 -040070 ASSERT(!attribsToStream.none());
71
Frank Henigman17448952017-01-05 15:48:26 -050072 const auto &attribs = mState.getVertexAttributes();
73 const auto &bindings = mState.getVertexBindings();
Frank Henigman17448952017-01-05 15:48:26 -050074
Jamie Madill32fd63b2018-03-31 11:20:35 -040075 const size_t lastVertex = drawCallParams.firstVertex() + drawCallParams.vertexCount();
76
Frank Henigman17448952017-01-05 15:48:26 -050077 // TODO(fjhenigman): When we have a bunch of interleaved attributes, they end up
78 // un-interleaved, wasting space and copying time. Consider improving on that.
Jamie Madillc3755fc2018-04-05 08:39:13 -040079 for (auto attribIndex : attribsToStream)
Frank Henigman17448952017-01-05 15:48:26 -050080 {
Frank Henigman6dd4a922018-03-02 16:35:13 -050081 const gl::VertexAttribute &attrib = attribs[attribIndex];
82 const gl::VertexBinding &binding = bindings[attrib.bindingIndex];
83 ASSERT(attrib.enabled && binding.getBuffer().get() == nullptr);
Frank Henigman17448952017-01-05 15:48:26 -050084
Frank Henigman6dd4a922018-03-02 16:35:13 -050085 // TODO(fjhenigman): Work with more formats than just GL_FLOAT.
86 if (attrib.type != GL_FLOAT)
Frank Henigman17448952017-01-05 15:48:26 -050087 {
Frank Henigman6dd4a922018-03-02 16:35:13 -050088 UNIMPLEMENTED();
89 return gl::InternalError();
Frank Henigman17448952017-01-05 15:48:26 -050090 }
Frank Henigman6dd4a922018-03-02 16:35:13 -050091
92 // Only [firstVertex, lastVertex] is needed by the upcoming draw so that
93 // is all we copy, but we allocate space for [0, lastVertex] so indexing
94 // will work. If we don't start at zero all the indices will be off.
95 // TODO(fjhenigman): See if we can account for indices being off by adjusting
96 // the offset, thus avoiding wasted memory.
Jamie Madill32fd63b2018-03-31 11:20:35 -040097 const size_t firstByte = drawCallParams.firstVertex() * binding.getStride();
Frank Henigman6dd4a922018-03-02 16:35:13 -050098 const size_t lastByte =
99 lastVertex * binding.getStride() + gl::ComputeVertexAttributeTypeSize(attrib);
100 uint8_t *dst = nullptr;
Luc Ferron7a06ac12018-03-15 10:17:04 -0400101 uint32_t offset = 0;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400102 ANGLE_TRY(mDynamicVertexData.allocate(
103 renderer, lastByte, &dst, &mCurrentArrayBufferHandles[attribIndex], &offset, nullptr));
Luc Ferron7a06ac12018-03-15 10:17:04 -0400104 mCurrentArrayBufferOffsets[attribIndex] = static_cast<VkDeviceSize>(offset);
Frank Henigman6dd4a922018-03-02 16:35:13 -0500105 memcpy(dst + firstByte, static_cast<const uint8_t *>(attrib.pointer) + firstByte,
106 lastByte - firstByte);
Frank Henigman17448952017-01-05 15:48:26 -0500107 }
108
Jamie Madillc3755fc2018-04-05 08:39:13 -0400109 ANGLE_TRY(mDynamicVertexData.flush(renderer->getDevice()));
110 return gl::NoError();
111}
112
113gl::Error VertexArrayVk::streamIndexData(RendererVk *renderer,
114 const gl::DrawCallParams &drawCallParams)
115{
116 ASSERT(!mState.getElementArrayBuffer().get());
117
118 uint32_t offset = 0;
119
120 const GLsizei amount = sizeof(GLushort) * drawCallParams.indexCount();
121 GLubyte *dst = nullptr;
122
123 ANGLE_TRY(mDynamicIndexData.allocate(renderer, amount, &dst, &mCurrentElementArrayBufferHandle,
124 &offset, nullptr));
125 if (drawCallParams.type() == GL_UNSIGNED_BYTE)
126 {
127 // Unsigned bytes don't have direct support in Vulkan so we have to expand the
128 // memory to a GLushort.
129 const GLubyte *in = static_cast<const GLubyte *>(drawCallParams.indices());
130 GLushort *expandedDst = reinterpret_cast<GLushort *>(dst);
131 for (GLsizei index = 0; index < drawCallParams.indexCount(); index++)
132 {
133 expandedDst[index] = static_cast<GLushort>(in[index]);
134 }
135 }
136 else
137 {
138 memcpy(dst, drawCallParams.indices(), amount);
139 }
140 ANGLE_TRY(mDynamicIndexData.flush(renderer->getDevice()));
141
142 mCurrentElementArrayBufferOffset = offset;
143
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 Madillc3755fc2018-04-05 08:39:13 -0400184 mIndexBufferDirty = true;
Jamie Madill09463932018-04-04 05:26:59 -0400185 break;
Jamie Madillda854a22017-11-30 17:24:21 -0500186 }
Jamie Madill09463932018-04-04 05:26:59 -0400187
188 case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA:
Jamie Madillc3755fc2018-04-05 08:39:13 -0400189 mLineLoopBufferFirstIndex.reset();
190 mLineLoopBufferLastIndex.reset();
Jamie Madill09463932018-04-04 05:26:59 -0400191 break;
192
193 default:
Jamie Madillda854a22017-11-30 17:24:21 -0500194 {
Jamie Madill09463932018-04-04 05:26:59 -0400195 size_t attribIndex = gl::VertexArray::GetVertexIndexFromDirtyBit(dirtyBit);
196
197 // Invalidate the input description for pipelines.
198 mDirtyPackedInputs.set(attribIndex);
199
200 const auto &attrib = attribs[attribIndex];
201 const auto &binding = bindings[attrib.bindingIndex];
202
203 if (attrib.enabled)
204 {
205 gl::Buffer *bufferGL = binding.getBuffer().get();
206
207 if (bufferGL)
208 {
209 BufferVk *bufferVk = vk::GetImpl(bufferGL);
210 mCurrentArrayBufferResources[attribIndex] = bufferVk;
211 mCurrentArrayBufferHandles[attribIndex] =
212 bufferVk->getVkBuffer().getHandle();
213 mClientMemoryAttribs.reset(attribIndex);
214 }
215 else
216 {
217 mCurrentArrayBufferResources[attribIndex] = nullptr;
218 mCurrentArrayBufferHandles[attribIndex] = VK_NULL_HANDLE;
219 mClientMemoryAttribs.set(attribIndex);
220 }
221 // TODO(jmadill): Offset handling. Assume zero for now.
222 mCurrentArrayBufferOffsets[attribIndex] = 0;
223 }
224 else
225 {
226 mClientMemoryAttribs.reset(attribIndex);
227 UNIMPLEMENTED();
228 }
Jamie Madillc3755fc2018-04-05 08:39:13 -0400229
230 invalidatePipeline = true;
Jamie Madill09463932018-04-04 05:26:59 -0400231 break;
Jamie Madillda854a22017-11-30 17:24:21 -0500232 }
Jamie Madillbd159f02017-10-09 19:39:06 -0400233 }
234 }
Frank Henigman0af5b862018-03-27 20:19:33 -0400235
Jamie Madillc3755fc2018-04-05 08:39:13 -0400236 if (invalidatePipeline)
237 {
238 mVertexBuffersDirty = true;
239 contextVk->invalidateCurrentPipeline();
240 }
241
Frank Henigman0af5b862018-03-27 20:19:33 -0400242 return gl::NoError();
Jamie Madillbd159f02017-10-09 19:39:06 -0400243}
244
Jamie Madillda854a22017-11-30 17:24:21 -0500245const gl::AttribArray<VkBuffer> &VertexArrayVk::getCurrentArrayBufferHandles() const
Jamie Madillbd159f02017-10-09 19:39:06 -0400246{
Jamie Madillda854a22017-11-30 17:24:21 -0500247 return mCurrentArrayBufferHandles;
Jamie Madillbd159f02017-10-09 19:39:06 -0400248}
249
Frank Henigman17448952017-01-05 15:48:26 -0500250const gl::AttribArray<VkDeviceSize> &VertexArrayVk::getCurrentArrayBufferOffsets() const
251{
252 return mCurrentArrayBufferOffsets;
253}
254
Jamie Madillc3755fc2018-04-05 08:39:13 -0400255void VertexArrayVk::updateArrayBufferReadDependencies(vk::CommandGraphNode *drawNode,
256 const gl::AttributesMask &activeAttribsMask,
257 Serial serial)
Jamie Madillbd159f02017-10-09 19:39:06 -0400258{
Jamie Madillda854a22017-11-30 17:24:21 -0500259 // Handle the bound array buffers.
Jamie Madillc3755fc2018-04-05 08:39:13 -0400260 for (size_t attribIndex : activeAttribsMask)
Jamie Madillbd159f02017-10-09 19:39:06 -0400261 {
Frank Henigman17448952017-01-05 15:48:26 -0500262 if (mCurrentArrayBufferResources[attribIndex])
Jamie Madillc3755fc2018-04-05 08:39:13 -0400263 mCurrentArrayBufferResources[attribIndex]->onReadResource(drawNode, serial);
Jamie Madillda854a22017-11-30 17:24:21 -0500264 }
Jamie Madillc3755fc2018-04-05 08:39:13 -0400265}
Jamie Madillda854a22017-11-30 17:24:21 -0500266
Jamie Madillc3755fc2018-04-05 08:39:13 -0400267void VertexArrayVk::updateElementArrayBufferReadDependency(vk::CommandGraphNode *drawNode,
268 Serial serial)
269{
Jamie Madillda854a22017-11-30 17:24:21 -0500270 // Handle the bound element array buffer.
Jamie Madillc3755fc2018-04-05 08:39:13 -0400271 if (mCurrentElementArrayBufferResource)
Jamie Madillda854a22017-11-30 17:24:21 -0500272 {
Jamie Madillc3755fc2018-04-05 08:39:13 -0400273 mCurrentElementArrayBufferResource->onReadResource(drawNode, serial);
Jamie Madillbd159f02017-10-09 19:39:06 -0400274 }
Jamie Madilldd43e6c2017-03-24 14:18:49 -0400275}
276
Jamie Madill112a3a82018-01-23 13:04:06 -0500277void VertexArrayVk::getPackedInputDescriptions(vk::PipelineDesc *pipelineDesc)
Jamie Madillebf72992017-10-13 14:09:45 -0400278{
Jamie Madill112a3a82018-01-23 13:04:06 -0500279 updatePackedInputDescriptions();
280 pipelineDesc->updateVertexInputInfo(mPackedInputBindings, mPackedInputAttributes);
Jamie Madillebf72992017-10-13 14:09:45 -0400281}
282
Jamie Madill112a3a82018-01-23 13:04:06 -0500283void VertexArrayVk::updatePackedInputDescriptions()
Jamie Madillebf72992017-10-13 14:09:45 -0400284{
Jamie Madill112a3a82018-01-23 13:04:06 -0500285 if (!mDirtyPackedInputs.any())
Jamie Madillebf72992017-10-13 14:09:45 -0400286 {
287 return;
288 }
289
290 const auto &attribs = mState.getVertexAttributes();
291 const auto &bindings = mState.getVertexBindings();
292
Jamie Madill112a3a82018-01-23 13:04:06 -0500293 for (auto attribIndex : mDirtyPackedInputs)
Jamie Madillebf72992017-10-13 14:09:45 -0400294 {
295 const auto &attrib = attribs[attribIndex];
296 const auto &binding = bindings[attrib.bindingIndex];
297 if (attrib.enabled)
298 {
Jamie Madill112a3a82018-01-23 13:04:06 -0500299 updatePackedInputInfo(static_cast<uint32_t>(attribIndex), binding, attrib);
Jamie Madillebf72992017-10-13 14:09:45 -0400300 }
301 else
302 {
303 UNIMPLEMENTED();
304 }
305 }
306
Jamie Madill112a3a82018-01-23 13:04:06 -0500307 mDirtyPackedInputs.reset();
308}
309
310void VertexArrayVk::updatePackedInputInfo(uint32_t attribIndex,
311 const gl::VertexBinding &binding,
312 const gl::VertexAttribute &attrib)
313{
314 vk::PackedVertexInputBindingDesc &bindingDesc = mPackedInputBindings[attribIndex];
315
316 size_t attribSize = gl::ComputeVertexAttributeTypeSize(attrib);
317 ASSERT(attribSize <= std::numeric_limits<uint16_t>::max());
318
Frank Henigmana8e868f2018-01-28 23:32:25 -0500319 bindingDesc.stride = static_cast<uint16_t>(binding.getStride());
Jamie Madill112a3a82018-01-23 13:04:06 -0500320 bindingDesc.inputRate = static_cast<uint16_t>(
321 binding.getDivisor() > 0 ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX);
322
323 gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib);
324 VkFormat vkFormat = vk::GetNativeVertexFormat(vertexFormatType);
325 ASSERT(vkFormat <= std::numeric_limits<uint16_t>::max());
326
327 vk::PackedVertexInputAttributeDesc &attribDesc = mPackedInputAttributes[attribIndex];
328 attribDesc.format = static_cast<uint16_t>(vkFormat);
329 attribDesc.location = static_cast<uint16_t>(attribIndex);
330 attribDesc.offset = static_cast<uint32_t>(ComputeVertexAttributeOffset(attrib, binding));
Jamie Madillebf72992017-10-13 14:09:45 -0400331}
332
Jamie Madillc3755fc2018-04-05 08:39:13 -0400333gl::Error VertexArrayVk::drawArrays(const gl::Context *context,
334 RendererVk *renderer,
335 const gl::DrawCallParams &drawCallParams,
336 vk::CommandGraphNode *drawNode,
337 bool newCommandBuffer)
338{
339 vk::CommandBuffer *commandBuffer = drawNode->getInsideRenderPassCommands();
340 ASSERT(commandBuffer->valid());
341
342 ANGLE_TRY(onDraw(context, renderer, drawCallParams, drawNode, newCommandBuffer));
343
344 if (drawCallParams.mode() != GL_LINE_LOOP)
345 {
346 commandBuffer->draw(drawCallParams.vertexCount(), 1, drawCallParams.firstVertex(), 0);
347 return gl::NoError();
348 }
349
350 // Handle GL_LINE_LOOP drawArrays.
351 int lastVertex = drawCallParams.firstVertex() + drawCallParams.vertexCount();
352 if (!mLineLoopBufferFirstIndex.valid() || !mLineLoopBufferLastIndex.valid() ||
353 mLineLoopBufferFirstIndex != drawCallParams.firstVertex() ||
354 mLineLoopBufferLastIndex != lastVertex)
355 {
356 ANGLE_TRY(mLineLoopHandler.createIndexBuffer(renderer, drawCallParams,
357 &mCurrentElementArrayBufferHandle,
358 &mCurrentElementArrayBufferOffset));
359
360 mLineLoopBufferFirstIndex = drawCallParams.firstVertex();
361 mLineLoopBufferLastIndex = lastVertex;
362 }
363
364 commandBuffer->bindIndexBuffer(mCurrentElementArrayBufferHandle,
365 mCurrentElementArrayBufferOffset, VK_INDEX_TYPE_UINT32);
366
367 vk::LineLoopHandler::Draw(drawCallParams.vertexCount(), commandBuffer);
368
369 return gl::NoError();
370}
371
372gl::Error VertexArrayVk::drawElements(const gl::Context *context,
373 RendererVk *renderer,
374 const gl::DrawCallParams &drawCallParams,
375 vk::CommandGraphNode *drawNode,
376 bool newCommandBuffer)
377{
378 vk::CommandBuffer *commandBuffer = drawNode->getInsideRenderPassCommands();
379 ASSERT(commandBuffer->valid());
380
381 if (drawCallParams.mode() != GL_LINE_LOOP)
382 {
383 ANGLE_TRY(onIndexedDraw(context, renderer, drawCallParams, drawNode, newCommandBuffer));
384 commandBuffer->drawIndexed(drawCallParams.indexCount(), 1, 0, 0, 0);
385 return gl::NoError();
386 }
387
388 // Handle GL_LINE_LOOP drawElements.
389 gl::Buffer *elementArrayBuffer = mState.getElementArrayBuffer().get();
390 if (!elementArrayBuffer)
391 {
392 UNIMPLEMENTED();
393 return gl::InternalError() << "Line loop indices in client memory not supported";
394 }
395
396 BufferVk *elementArrayBufferVk = vk::GetImpl(elementArrayBuffer);
397
398 VkIndexType indexType = gl_vk::GetIndexType(drawCallParams.type());
399
400 ANGLE_TRY(mLineLoopHandler.createIndexBufferFromElementArrayBuffer(
401 renderer, elementArrayBufferVk, indexType, drawCallParams.indexCount(),
402 &mCurrentElementArrayBufferHandle, &mCurrentElementArrayBufferOffset));
403
404 ANGLE_TRY(onIndexedDraw(context, renderer, drawCallParams, drawNode, newCommandBuffer));
405 vk::LineLoopHandler::Draw(drawCallParams.indexCount(), commandBuffer);
406
407 return gl::NoError();
408}
409
410gl::Error VertexArrayVk::onDraw(const gl::Context *context,
411 RendererVk *renderer,
412 const gl::DrawCallParams &drawCallParams,
413 vk::CommandGraphNode *drawNode,
414 bool newCommandBuffer)
415{
416 const gl::State &state = context->getGLState();
417 const gl::Program *programGL = state.getProgram();
418 const gl::AttributesMask &activeAttribs = programGL->getActiveAttribLocationsMask();
419 uint32_t maxAttrib = programGL->getState().getMaxActiveAttribLocation();
420
421 if (mClientMemoryAttribs.any())
422 {
423 const gl::AttributesMask &attribsToStream = (mClientMemoryAttribs & activeAttribs);
424 if (attribsToStream.any())
425 {
426 ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
427 ANGLE_TRY(streamVertexData(renderer, attribsToStream, drawCallParams));
428 vk::CommandBuffer *commandBuffer = drawNode->getInsideRenderPassCommands();
429 commandBuffer->bindVertexBuffers(0, maxAttrib, mCurrentArrayBufferHandles.data(),
430 mCurrentArrayBufferOffsets.data());
431 }
432 }
433 else if (mVertexBuffersDirty || newCommandBuffer)
434 {
435 vk::CommandBuffer *commandBuffer = drawNode->getInsideRenderPassCommands();
436 commandBuffer->bindVertexBuffers(0, maxAttrib, mCurrentArrayBufferHandles.data(),
437 mCurrentArrayBufferOffsets.data());
438 updateArrayBufferReadDependencies(drawNode, activeAttribs,
439 renderer->getCurrentQueueSerial());
440 mVertexBuffersDirty = false;
441 }
442
443 return gl::NoError();
444}
445
446gl::Error VertexArrayVk::onIndexedDraw(const gl::Context *context,
447 RendererVk *renderer,
448 const gl::DrawCallParams &drawCallParams,
449 vk::CommandGraphNode *drawNode,
450 bool newCommandBuffer)
451{
452 ANGLE_TRY(onDraw(context, renderer, drawCallParams, drawNode, newCommandBuffer));
453
454 if (!mState.getElementArrayBuffer().get())
455 {
456 ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
457 ANGLE_TRY(streamIndexData(renderer, drawCallParams));
458 vk::CommandBuffer *commandBuffer = drawNode->getInsideRenderPassCommands();
459 commandBuffer->bindIndexBuffer(mCurrentElementArrayBufferHandle,
460 mCurrentElementArrayBufferOffset,
461 gl_vk::GetIndexType(drawCallParams.type()));
462 }
463 else if (mIndexBufferDirty || newCommandBuffer)
464 {
465 if (drawCallParams.type() == GL_UNSIGNED_BYTE)
466 {
467 // TODO(fjhenigman): Index format translation.
468 UNIMPLEMENTED();
469 return gl::InternalError()
470 << "Unsigned byte translation is not implemented for indices in a buffer object";
471 }
472
473 vk::CommandBuffer *commandBuffer = drawNode->getInsideRenderPassCommands();
474 commandBuffer->bindIndexBuffer(mCurrentElementArrayBufferHandle,
475 mCurrentElementArrayBufferOffset,
476 gl_vk::GetIndexType(drawCallParams.type()));
477 updateElementArrayBufferReadDependency(drawNode, renderer->getCurrentQueueSerial());
478 mIndexBufferDirty = false;
479 }
480
481 return gl::NoError();
482}
483
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400484} // namespace rx