blob: 355fa73e6a7cb9be0cb3b7c92995fe9166feb974 [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 Madill316c6062018-05-29 10:49:45 -040018#include "libANGLE/renderer/vulkan/FramebufferVk.h"
Jamie Madillc3755fc2018-04-05 08:39:13 -040019#include "libANGLE/renderer/vulkan/RendererVk.h"
Jamie Madill3c424b42018-01-19 12:35:09 -050020#include "libANGLE/renderer/vulkan/vk_format_utils.h"
Jamie Madilldd43e6c2017-03-24 14:18:49 -040021
Jamie Madill9e54b5a2016-05-25 12:57:39 -040022namespace rx
23{
Jamie Madillc3755fc2018-04-05 08:39:13 -040024namespace
25{
26constexpr size_t kDynamicVertexDataSize = 1024 * 1024;
27constexpr size_t kDynamicIndexDataSize = 1024 * 8;
Frank Henigmane4523822018-07-19 16:10:53 -040028
29bool BindingIsAligned(const gl::VertexBinding &binding, unsigned componentSize)
30{
31 return (binding.getOffset() % componentSize == 0) && (binding.getStride() % componentSize == 0);
32}
Jamie Madilla064c272018-08-30 16:18:34 -040033
34angle::Result StreamVertexData(ContextVk *contextVk,
35 vk::DynamicBuffer *dynamicBuffer,
36 const uint8_t *sourceData,
37 size_t bytesToAllocate,
38 size_t destOffset,
39 size_t vertexCount,
40 size_t stride,
41 VertexCopyFunction vertexLoadFunction,
42 VkBuffer *bufferHandleOut,
43 VkDeviceSize *bufferOffsetOut)
44{
45 uint8_t *dst = nullptr;
46 ANGLE_TRY(dynamicBuffer->allocate(contextVk, bytesToAllocate, &dst, bufferHandleOut,
47 bufferOffsetOut, nullptr));
48 dst += destOffset;
49 vertexLoadFunction(sourceData, stride, vertexCount, dst);
50
51 ANGLE_TRY(dynamicBuffer->flush(contextVk));
52 return angle::Result::Continue();
53}
Geoff Lang89e82972018-08-28 11:32:53 -040054
55void BindNonNullVertexBufferRanges(vk::CommandBuffer *commandBuffer,
56 const gl::AttributesMask &nonNullAttribMask,
57 uint32_t maxAttrib,
58 const gl::AttribArray<VkBuffer> &arrayBufferHandles,
59 const gl::AttribArray<VkDeviceSize> &arrayBufferOffsets)
60{
61 // Vulkan does not allow binding a null vertex buffer but the default state of null buffers is
62 // valid.
63
64 // We can detect if there are no gaps in active attributes by using the mask of the program
65 // attribs and the max enabled attrib.
66 ASSERT(maxAttrib > 0);
67 if (nonNullAttribMask.to_ulong() == (maxAttrib - 1))
68 {
69 commandBuffer->bindVertexBuffers(0, maxAttrib, arrayBufferHandles.data(),
70 arrayBufferOffsets.data());
71 return;
72 }
73
74 // Find ranges of non-null buffers and bind them all together.
75 for (uint32_t attribIdx = 0; attribIdx < maxAttrib; attribIdx++)
76 {
77 if (arrayBufferHandles[attribIdx] != VK_NULL_HANDLE)
78 {
79 // Find the end of this range of non-null handles
80 uint32_t rangeCount = 1;
81 while (attribIdx + rangeCount < maxAttrib &&
82 arrayBufferHandles[attribIdx + rangeCount] != VK_NULL_HANDLE)
83 {
84 rangeCount++;
85 }
86
87 commandBuffer->bindVertexBuffers(attribIdx, rangeCount, &arrayBufferHandles[attribIdx],
88 &arrayBufferOffsets[attribIdx]);
89 attribIdx += rangeCount;
90 }
91 }
92}
93
Jamie Madillc3755fc2018-04-05 08:39:13 -040094} // anonymous namespace
Jamie Madill9e54b5a2016-05-25 12:57:39 -040095
Frank Henigmane4523822018-07-19 16:10:53 -040096#define INIT \
97 { \
98 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, 1024 * 8 \
99 }
100
Luc Ferrona9ab0f32018-05-17 17:03:55 -0400101VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state, RendererVk *renderer)
Jamie Madillbd159f02017-10-09 19:39:06 -0400102 : VertexArrayImpl(state),
Jamie Madillda854a22017-11-30 17:24:21 -0500103 mCurrentArrayBufferHandles{},
Frank Henigman17448952017-01-05 15:48:26 -0500104 mCurrentArrayBufferOffsets{},
Jamie Madillda854a22017-11-30 17:24:21 -0500105 mCurrentArrayBufferResources{},
Frank Henigman419acc82018-06-24 19:57:31 -0400106 mCurrentArrayBufferFormats{},
107 mCurrentArrayBufferStrides{},
Frank Henigmane4523822018-07-19 16:10:53 -0400108 mCurrentArrayBufferConversion{{
109 INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT,
110 INIT,
111 }},
112 mCurrentArrayBufferConversionCanRelease{},
Jamie Madillc3755fc2018-04-05 08:39:13 -0400113 mCurrentElementArrayBufferHandle(VK_NULL_HANDLE),
114 mCurrentElementArrayBufferOffset(0),
115 mCurrentElementArrayBufferResource(nullptr),
116 mDynamicVertexData(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, kDynamicVertexDataSize),
117 mDynamicIndexData(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, kDynamicIndexDataSize),
Luc Ferron6ed167a2018-06-13 13:45:55 -0400118 mTranslatedByteIndexData(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, kDynamicIndexDataSize),
Luc Ferrona9ab0f32018-05-17 17:03:55 -0400119 mLineLoopHelper(renderer),
Jamie Madillb8e39662018-04-04 11:41:42 -0400120 mDirtyLineLoopTranslation(true),
Jamie Madillc3755fc2018-04-05 08:39:13 -0400121 mVertexBuffersDirty(false),
Luc Ferron49aacad2018-06-12 08:33:59 -0400122 mIndexBufferDirty(false),
123 mLastIndexBufferOffset(0)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400124{
Jamie Madillda854a22017-11-30 17:24:21 -0500125 mCurrentArrayBufferHandles.fill(VK_NULL_HANDLE);
Frank Henigman17448952017-01-05 15:48:26 -0500126 mCurrentArrayBufferOffsets.fill(0);
Jamie Madillda854a22017-11-30 17:24:21 -0500127 mCurrentArrayBufferResources.fill(nullptr);
Jamie Madill112a3a82018-01-23 13:04:06 -0500128
129 mPackedInputBindings.fill({0, 0});
130 mPackedInputAttributes.fill({0, 0, 0});
Jamie Madillc3755fc2018-04-05 08:39:13 -0400131
Frank Henigmane4523822018-07-19 16:10:53 -0400132 for (vk::DynamicBuffer &buffer : mCurrentArrayBufferConversion)
133 {
134 buffer.init(1, renderer);
135 }
Luc Ferrona9ab0f32018-05-17 17:03:55 -0400136 mDynamicVertexData.init(1, renderer);
137 mDynamicIndexData.init(1, renderer);
Luc Ferron6ed167a2018-06-13 13:45:55 -0400138 mTranslatedByteIndexData.init(1, renderer);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400139}
140
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500141VertexArrayVk::~VertexArrayVk()
142{
143}
144
Jamie Madill4928b7c2017-06-20 12:57:39 -0400145void VertexArrayVk::destroy(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400146{
Jamie Madillc3755fc2018-04-05 08:39:13 -0400147 VkDevice device = vk::GetImpl(context)->getRenderer()->getDevice();
Frank Henigmane4523822018-07-19 16:10:53 -0400148 for (vk::DynamicBuffer &buffer : mCurrentArrayBufferConversion)
149 {
150 buffer.destroy(device);
151 }
Jamie Madillc3755fc2018-04-05 08:39:13 -0400152 mDynamicVertexData.destroy(device);
153 mDynamicIndexData.destroy(device);
Luc Ferron6ed167a2018-06-13 13:45:55 -0400154 mTranslatedByteIndexData.destroy(device);
Jamie Madill22f12fe2018-04-08 14:23:40 -0400155 mLineLoopHelper.destroy(device);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400156}
157
Jamie Madill21061022018-07-12 23:56:30 -0400158angle::Result VertexArrayVk::streamIndexData(ContextVk *contextVk,
159 const gl::DrawCallParams &drawCallParams)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400160{
161 ASSERT(!mState.getElementArrayBuffer().get());
162
Jamie Madilla064c272018-08-30 16:18:34 -0400163 mDynamicIndexData.releaseRetainedBuffers(contextVk->getRenderer());
164
Jamie Madillc3755fc2018-04-05 08:39:13 -0400165 const GLsizei amount = sizeof(GLushort) * drawCallParams.indexCount();
166 GLubyte *dst = nullptr;
167
Jamie Madill21061022018-07-12 23:56:30 -0400168 ANGLE_TRY(mDynamicIndexData.allocate(contextVk, amount, &dst, &mCurrentElementArrayBufferHandle,
Jamie Madill4c310832018-08-29 13:43:17 -0400169 &mCurrentElementArrayBufferOffset, nullptr));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400170 if (drawCallParams.type() == GL_UNSIGNED_BYTE)
171 {
172 // Unsigned bytes don't have direct support in Vulkan so we have to expand the
173 // memory to a GLushort.
174 const GLubyte *in = static_cast<const GLubyte *>(drawCallParams.indices());
175 GLushort *expandedDst = reinterpret_cast<GLushort *>(dst);
176 for (GLsizei index = 0; index < drawCallParams.indexCount(); index++)
177 {
178 expandedDst[index] = static_cast<GLushort>(in[index]);
179 }
180 }
181 else
182 {
183 memcpy(dst, drawCallParams.indices(), amount);
184 }
Jamie Madill21061022018-07-12 23:56:30 -0400185 ANGLE_TRY(mDynamicIndexData.flush(contextVk));
Jamie Madill21061022018-07-12 23:56:30 -0400186 return angle::Result::Continue();
Frank Henigman17448952017-01-05 15:48:26 -0500187}
188
Frank Henigmane4523822018-07-19 16:10:53 -0400189// We assume the buffer is completely full of the same kind of data and convert
190// and/or align it as we copy it to a DynamicBuffer. The assumption could be wrong
191// but the alternative of copying it piecemeal on each draw would have a lot more
192// overhead.
Jamie Madilla064c272018-08-30 16:18:34 -0400193angle::Result VertexArrayVk::convertVertexBuffer(ContextVk *contextVk,
Frank Henigmane4523822018-07-19 16:10:53 -0400194 BufferVk *srcBuffer,
195 const gl::VertexBinding &binding,
196 size_t attribIndex)
197{
198
199 // Preparation for mapping source buffer.
Jamie Madilla064c272018-08-30 16:18:34 -0400200 ANGLE_TRY(contextVk->getRenderer()->finish(contextVk));
Frank Henigmane4523822018-07-19 16:10:53 -0400201
202 unsigned srcFormatSize = mCurrentArrayBufferFormats[attribIndex]->angleFormat().pixelBytes;
Jamie Madilla064c272018-08-30 16:18:34 -0400203 unsigned dstFormatSize = mCurrentArrayBufferStrides[attribIndex];
204
205 mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(contextVk->getRenderer());
Frank Henigmane4523822018-07-19 16:10:53 -0400206
207 // Bytes usable for vertex data.
208 GLint64 bytes = srcBuffer->getSize() - binding.getOffset();
209 if (bytes < srcFormatSize)
210 return angle::Result::Continue();
211
212 // Count the last vertex. It may occupy less than a full stride.
213 size_t numVertices = 1;
214 bytes -= srcFormatSize;
215
216 // Count how many strides fit remaining space.
217 if (bytes > 0)
218 numVertices += static_cast<size_t>(bytes) / binding.getStride();
219
220 void *src = nullptr;
Jamie Madilla064c272018-08-30 16:18:34 -0400221 ANGLE_TRY(srcBuffer->mapImpl(contextVk, &src));
222 const uint8_t *srcBytes = reinterpret_cast<const uint8_t *>(src);
223 srcBytes += binding.getOffset();
224 ANGLE_TRY(StreamVertexData(contextVk, &mCurrentArrayBufferConversion[attribIndex], srcBytes,
225 numVertices * dstFormatSize, 0, numVertices, binding.getStride(),
226 mCurrentArrayBufferFormats[attribIndex]->vertexLoadFunction,
227 &mCurrentArrayBufferHandles[attribIndex],
228 &mCurrentArrayBufferOffsets[attribIndex]));
229 ANGLE_TRY(srcBuffer->unmapImpl(contextVk));
Frank Henigmane4523822018-07-19 16:10:53 -0400230
231 mCurrentArrayBufferConversionCanRelease[attribIndex] = true;
Frank Henigmane4523822018-07-19 16:10:53 -0400232
233 return angle::Result::Continue();
234}
235
236void VertexArrayVk::ensureConversionReleased(RendererVk *renderer, size_t attribIndex)
237{
238 if (mCurrentArrayBufferConversionCanRelease[attribIndex])
239 {
240 mCurrentArrayBufferConversion[attribIndex].release(renderer);
241 mCurrentArrayBufferConversionCanRelease[attribIndex] = false;
242 }
243}
244
245#define ANGLE_VERTEX_DIRTY_ATTRIB_FUNC(INDEX) \
246 case gl::VertexArray::DIRTY_BIT_ATTRIB_0 + INDEX: \
247 ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
248 bindings[attribs[INDEX].bindingIndex], INDEX)); \
249 invalidatePipeline = true; \
Jamie Madilla56467e2018-04-11 16:19:41 -0400250 break;
251
Frank Henigmane4523822018-07-19 16:10:53 -0400252#define ANGLE_VERTEX_DIRTY_BINDING_FUNC(INDEX) \
253 case gl::VertexArray::DIRTY_BIT_BINDING_0 + INDEX: \
254 ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
255 bindings[attribs[INDEX].bindingIndex], INDEX)); \
256 invalidatePipeline = true; \
Jamie Madilla56467e2018-04-11 16:19:41 -0400257 break;
258
Frank Henigmane4523822018-07-19 16:10:53 -0400259#define ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC(INDEX) \
260 case gl::VertexArray::DIRTY_BIT_BUFFER_DATA_0 + INDEX: \
261 ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
262 bindings[attribs[INDEX].bindingIndex], INDEX)); \
Jamie Madilla56467e2018-04-11 16:19:41 -0400263 break;
264
Frank Henigman0af5b862018-03-27 20:19:33 -0400265gl::Error VertexArrayVk::syncState(const gl::Context *context,
266 const gl::VertexArray::DirtyBits &dirtyBits,
267 const gl::VertexArray::DirtyAttribBitsArray &attribBits,
268 const gl::VertexArray::DirtyBindingBitsArray &bindingBits)
Jamie Madilldd43e6c2017-03-24 14:18:49 -0400269{
270 ASSERT(dirtyBits.any());
Jamie Madill72106562017-03-24 14:18:50 -0400271
Jamie Madillc3755fc2018-04-05 08:39:13 -0400272 bool invalidatePipeline = false;
273
Jamie Madill5a4c9322018-07-16 11:01:58 -0400274 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madillbd159f02017-10-09 19:39:06 -0400275
276 // Rebuild current attribute buffers cache. This will fail horribly if the buffer changes.
277 // TODO(jmadill): Handle buffer storage changes.
278 const auto &attribs = mState.getVertexAttributes();
279 const auto &bindings = mState.getVertexBindings();
280
Jamie Madill09463932018-04-04 05:26:59 -0400281 for (size_t dirtyBit : dirtyBits)
Jamie Madillbd159f02017-10-09 19:39:06 -0400282 {
Jamie Madill09463932018-04-04 05:26:59 -0400283 switch (dirtyBit)
Jamie Madillda854a22017-11-30 17:24:21 -0500284 {
Jamie Madill09463932018-04-04 05:26:59 -0400285 case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER:
Jamie Madillda854a22017-11-30 17:24:21 -0500286 {
Jamie Madill09463932018-04-04 05:26:59 -0400287 gl::Buffer *bufferGL = mState.getElementArrayBuffer().get();
288 if (bufferGL)
289 {
Jamie Madillc3755fc2018-04-05 08:39:13 -0400290 BufferVk *bufferVk = vk::GetImpl(bufferGL);
291 mCurrentElementArrayBufferResource = bufferVk;
292 mCurrentElementArrayBufferHandle = bufferVk->getVkBuffer().getHandle();
Jamie Madill09463932018-04-04 05:26:59 -0400293 }
294 else
295 {
296 mCurrentElementArrayBufferResource = nullptr;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400297 mCurrentElementArrayBufferHandle = VK_NULL_HANDLE;
Jamie Madill09463932018-04-04 05:26:59 -0400298 }
Luc Ferron387b3b32018-05-28 10:11:57 -0400299
300 mCurrentElementArrayBufferOffset = 0;
301 mLineLoopBufferFirstIndex.reset();
302 mLineLoopBufferLastIndex.reset();
Jamie Madillb8e39662018-04-04 11:41:42 -0400303 mIndexBufferDirty = true;
304 mDirtyLineLoopTranslation = true;
Jamie Madill09463932018-04-04 05:26:59 -0400305 break;
Jamie Madillda854a22017-11-30 17:24:21 -0500306 }
Jamie Madill09463932018-04-04 05:26:59 -0400307
308 case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA:
Jamie Madillc3755fc2018-04-05 08:39:13 -0400309 mLineLoopBufferFirstIndex.reset();
310 mLineLoopBufferLastIndex.reset();
Jamie Madillb8e39662018-04-04 11:41:42 -0400311 mDirtyLineLoopTranslation = true;
Jamie Madill09463932018-04-04 05:26:59 -0400312 break;
313
Jamie Madilla56467e2018-04-11 16:19:41 -0400314 ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_ATTRIB_FUNC);
315 ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BINDING_FUNC);
316 ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC);
317
Jamie Madill09463932018-04-04 05:26:59 -0400318 default:
Jamie Madilla56467e2018-04-11 16:19:41 -0400319 UNREACHABLE();
Jamie Madill09463932018-04-04 05:26:59 -0400320 break;
Jamie Madillbd159f02017-10-09 19:39:06 -0400321 }
322 }
Frank Henigman0af5b862018-03-27 20:19:33 -0400323
Jamie Madillc3755fc2018-04-05 08:39:13 -0400324 if (invalidatePipeline)
325 {
326 mVertexBuffersDirty = true;
327 contextVk->invalidateCurrentPipeline();
328 }
329
Frank Henigman0af5b862018-03-27 20:19:33 -0400330 return gl::NoError();
Jamie Madillbd159f02017-10-09 19:39:06 -0400331}
332
Frank Henigmane4523822018-07-19 16:10:53 -0400333angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
334 const gl::VertexAttribute &attrib,
335 const gl::VertexBinding &binding,
336 size_t attribIndex)
Jamie Madilla56467e2018-04-11 16:19:41 -0400337{
338 // Invalidate the input description for pipelines.
339 mDirtyPackedInputs.set(attribIndex);
340
Frank Henigman67c388e2018-07-19 19:16:11 -0400341 RendererVk *renderer = contextVk->getRenderer();
Frank Henigmane4523822018-07-19 16:10:53 -0400342 bool releaseConversion = true;
Jamie Madill5a4c9322018-07-16 11:01:58 -0400343
Jamie Madilla56467e2018-04-11 16:19:41 -0400344 if (attrib.enabled)
345 {
Frank Henigman67c388e2018-07-19 19:16:11 -0400346 gl::Buffer *bufferGL = binding.getBuffer().get();
Frank Henigman419acc82018-06-24 19:57:31 -0400347 mCurrentArrayBufferFormats[attribIndex] = &renderer->getFormat(GetVertexFormatID(attrib));
Frank Henigmane4523822018-07-19 16:10:53 -0400348
Jamie Madilla56467e2018-04-11 16:19:41 -0400349 if (bufferGL)
350 {
Frank Henigmane4523822018-07-19 16:10:53 -0400351 BufferVk *bufferVk = vk::GetImpl(bufferGL);
352 unsigned componentSize =
353 mCurrentArrayBufferFormats[attribIndex]->angleFormat().pixelBytes / attrib.size;
Frank Henigman419acc82018-06-24 19:57:31 -0400354
Frank Henigmane4523822018-07-19 16:10:53 -0400355 if (mCurrentArrayBufferFormats[attribIndex]->vertexLoadRequiresConversion ||
356 !BindingIsAligned(binding, componentSize))
357 {
Jamie Madilla064c272018-08-30 16:18:34 -0400358 mCurrentArrayBufferStrides[attribIndex] =
359 mCurrentArrayBufferFormats[attribIndex]->bufferFormat().pixelBytes;
360
Frank Henigmane4523822018-07-19 16:10:53 -0400361 ANGLE_TRY(convertVertexBuffer(contextVk, bufferVk, binding, attribIndex));
362
Frank Henigmane4523822018-07-19 16:10:53 -0400363 mCurrentArrayBufferResources[attribIndex] = nullptr;
364 releaseConversion = false;
365 }
366 else
367 {
368 mCurrentArrayBufferResources[attribIndex] = bufferVk;
369 mCurrentArrayBufferHandles[attribIndex] = bufferVk->getVkBuffer().getHandle();
370 mCurrentArrayBufferOffsets[attribIndex] = binding.getOffset();
371 mCurrentArrayBufferStrides[attribIndex] = binding.getStride();
372 }
Jamie Madilla56467e2018-04-11 16:19:41 -0400373 }
374 else
375 {
376 mCurrentArrayBufferResources[attribIndex] = nullptr;
377 mCurrentArrayBufferHandles[attribIndex] = VK_NULL_HANDLE;
Luc Ferronfa5d84b2018-06-28 10:40:04 -0400378 mCurrentArrayBufferOffsets[attribIndex] = 0;
Frank Henigman419acc82018-06-24 19:57:31 -0400379 mCurrentArrayBufferStrides[attribIndex] =
Frank Henigmane4523822018-07-19 16:10:53 -0400380 mCurrentArrayBufferFormats[attribIndex]->bufferFormat().pixelBytes;
Jamie Madilla56467e2018-04-11 16:19:41 -0400381 }
Jamie Madilla56467e2018-04-11 16:19:41 -0400382 }
383 else
384 {
Jamie Madill5a4c9322018-07-16 11:01:58 -0400385 contextVk->invalidateDefaultAttribute(attribIndex);
386
387 // These will be filled out by the ContextVk.
388 mCurrentArrayBufferResources[attribIndex] = nullptr;
389 mCurrentArrayBufferHandles[attribIndex] = VK_NULL_HANDLE;
390 mCurrentArrayBufferOffsets[attribIndex] = 0;
391 mCurrentArrayBufferStrides[attribIndex] = 0;
392 mCurrentArrayBufferFormats[attribIndex] =
Jamie Madillba365932018-07-18 17:23:46 -0400393 &renderer->getFormat(angle::FormatID::R32G32B32A32_FLOAT);
Jamie Madilla56467e2018-04-11 16:19:41 -0400394 }
Frank Henigmane4523822018-07-19 16:10:53 -0400395
396 if (releaseConversion)
397 ensureConversionReleased(renderer, attribIndex);
398
399 return angle::Result::Continue();
Jamie Madilla56467e2018-04-11 16:19:41 -0400400}
401
Jamie Madill316c6062018-05-29 10:49:45 -0400402void VertexArrayVk::updateArrayBufferReadDependencies(vk::CommandGraphResource *drawFramebuffer,
Jamie Madillc3755fc2018-04-05 08:39:13 -0400403 const gl::AttributesMask &activeAttribsMask,
404 Serial serial)
Jamie Madillbd159f02017-10-09 19:39:06 -0400405{
Jamie Madillda854a22017-11-30 17:24:21 -0500406 // Handle the bound array buffers.
Jamie Madillc3755fc2018-04-05 08:39:13 -0400407 for (size_t attribIndex : activeAttribsMask)
Jamie Madillbd159f02017-10-09 19:39:06 -0400408 {
Frank Henigman17448952017-01-05 15:48:26 -0500409 if (mCurrentArrayBufferResources[attribIndex])
Jamie Madill316c6062018-05-29 10:49:45 -0400410 mCurrentArrayBufferResources[attribIndex]->addReadDependency(drawFramebuffer);
Jamie Madillda854a22017-11-30 17:24:21 -0500411 }
Jamie Madillc3755fc2018-04-05 08:39:13 -0400412}
Jamie Madillda854a22017-11-30 17:24:21 -0500413
Jamie Madill316c6062018-05-29 10:49:45 -0400414void VertexArrayVk::updateElementArrayBufferReadDependency(
415 vk::CommandGraphResource *drawFramebuffer,
416 Serial serial)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400417{
Jamie Madillda854a22017-11-30 17:24:21 -0500418 // Handle the bound element array buffer.
Jamie Madillc3755fc2018-04-05 08:39:13 -0400419 if (mCurrentElementArrayBufferResource)
Jamie Madillda854a22017-11-30 17:24:21 -0500420 {
Jamie Madill316c6062018-05-29 10:49:45 -0400421 mCurrentElementArrayBufferResource->addReadDependency(drawFramebuffer);
Jamie Madillbd159f02017-10-09 19:39:06 -0400422 }
Jamie Madilldd43e6c2017-03-24 14:18:49 -0400423}
424
Frank Henigman419acc82018-06-24 19:57:31 -0400425void VertexArrayVk::getPackedInputDescriptions(vk::PipelineDesc *pipelineDesc)
Jamie Madillebf72992017-10-13 14:09:45 -0400426{
Frank Henigman419acc82018-06-24 19:57:31 -0400427 updatePackedInputDescriptions();
Jamie Madill112a3a82018-01-23 13:04:06 -0500428 pipelineDesc->updateVertexInputInfo(mPackedInputBindings, mPackedInputAttributes);
Jamie Madillebf72992017-10-13 14:09:45 -0400429}
430
Frank Henigman419acc82018-06-24 19:57:31 -0400431void VertexArrayVk::updatePackedInputDescriptions()
Jamie Madillebf72992017-10-13 14:09:45 -0400432{
Jamie Madill112a3a82018-01-23 13:04:06 -0500433 if (!mDirtyPackedInputs.any())
Jamie Madillebf72992017-10-13 14:09:45 -0400434 {
435 return;
436 }
437
438 const auto &attribs = mState.getVertexAttributes();
439 const auto &bindings = mState.getVertexBindings();
440
Jamie Madill112a3a82018-01-23 13:04:06 -0500441 for (auto attribIndex : mDirtyPackedInputs)
Jamie Madillebf72992017-10-13 14:09:45 -0400442 {
443 const auto &attrib = attribs[attribIndex];
444 const auto &binding = bindings[attrib.bindingIndex];
445 if (attrib.enabled)
446 {
Frank Henigman419acc82018-06-24 19:57:31 -0400447 updatePackedInputInfo(static_cast<uint32_t>(attribIndex), binding, attrib);
Jamie Madillebf72992017-10-13 14:09:45 -0400448 }
449 else
450 {
Jamie Madill5a4c9322018-07-16 11:01:58 -0400451 vk::PackedVertexInputBindingDesc &bindingDesc = mPackedInputBindings[attribIndex];
452 bindingDesc.stride = 0;
453 bindingDesc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
454
455 vk::PackedVertexInputAttributeDesc &attribDesc = mPackedInputAttributes[attribIndex];
456 attribDesc.format = static_cast<uint16_t>(VK_FORMAT_R32G32B32A32_SFLOAT);
457 attribDesc.location = static_cast<uint16_t>(attribIndex);
458 attribDesc.offset = 0;
Jamie Madillebf72992017-10-13 14:09:45 -0400459 }
460 }
461
Jamie Madill112a3a82018-01-23 13:04:06 -0500462 mDirtyPackedInputs.reset();
463}
464
Frank Henigman419acc82018-06-24 19:57:31 -0400465void VertexArrayVk::updatePackedInputInfo(uint32_t attribIndex,
Jamie Madill112a3a82018-01-23 13:04:06 -0500466 const gl::VertexBinding &binding,
467 const gl::VertexAttribute &attrib)
468{
469 vk::PackedVertexInputBindingDesc &bindingDesc = mPackedInputBindings[attribIndex];
470
Frank Henigman419acc82018-06-24 19:57:31 -0400471 bindingDesc.stride = static_cast<uint16_t>(mCurrentArrayBufferStrides[attribIndex]);
Jamie Madill112a3a82018-01-23 13:04:06 -0500472 bindingDesc.inputRate = static_cast<uint16_t>(
473 binding.getDivisor() > 0 ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX);
474
Frank Henigman419acc82018-06-24 19:57:31 -0400475 VkFormat vkFormat = mCurrentArrayBufferFormats[attribIndex]->vkBufferFormat;
Jamie Madill112a3a82018-01-23 13:04:06 -0500476 ASSERT(vkFormat <= std::numeric_limits<uint16_t>::max());
Frank Henigman8c379f32018-06-21 19:55:05 -0400477 if (vkFormat == VK_FORMAT_UNDEFINED)
478 {
479 // TODO(fjhenigman): Add support for vertex data format. anglebug.com/2405
480 UNIMPLEMENTED();
481 }
Jamie Madill112a3a82018-01-23 13:04:06 -0500482
483 vk::PackedVertexInputAttributeDesc &attribDesc = mPackedInputAttributes[attribIndex];
484 attribDesc.format = static_cast<uint16_t>(vkFormat);
485 attribDesc.location = static_cast<uint16_t>(attribIndex);
Luc Ferronfa5d84b2018-06-28 10:40:04 -0400486 attribDesc.offset = static_cast<uint32_t>(attrib.relativeOffset);
Jamie Madillebf72992017-10-13 14:09:45 -0400487}
488
Jamie Madillc3755fc2018-04-05 08:39:13 -0400489gl::Error VertexArrayVk::drawArrays(const gl::Context *context,
Jamie Madillc3755fc2018-04-05 08:39:13 -0400490 const gl::DrawCallParams &drawCallParams,
Jamie Madill316c6062018-05-29 10:49:45 -0400491 vk::CommandBuffer *commandBuffer,
Jamie Madillc3755fc2018-04-05 08:39:13 -0400492 bool newCommandBuffer)
493{
Jamie Madillc3755fc2018-04-05 08:39:13 -0400494 ASSERT(commandBuffer->valid());
495
Jamie Madill21061022018-07-12 23:56:30 -0400496 ContextVk *contextVk = vk::GetImpl(context);
497
498 ANGLE_TRY(onDraw(context, drawCallParams, commandBuffer, newCommandBuffer));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400499
Jamie Madill18e323a2018-05-11 16:54:17 -0400500 // Note: Vertex indexes can be arbitrarily large.
501 uint32_t clampedVertexCount = drawCallParams.getClampedVertexCount<uint32_t>();
502
Jamie Madill493f9572018-05-24 19:52:15 -0400503 if (drawCallParams.mode() != gl::PrimitiveMode::LineLoop)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400504 {
Jamie Madill18e323a2018-05-11 16:54:17 -0400505 commandBuffer->draw(clampedVertexCount, 1, drawCallParams.firstVertex(), 0);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400506 return gl::NoError();
507 }
508
509 // Handle GL_LINE_LOOP drawArrays.
Jamie Madill18e323a2018-05-11 16:54:17 -0400510 size_t lastVertex = static_cast<size_t>(drawCallParams.firstVertex() + clampedVertexCount);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400511 if (!mLineLoopBufferFirstIndex.valid() || !mLineLoopBufferLastIndex.valid() ||
512 mLineLoopBufferFirstIndex != drawCallParams.firstVertex() ||
513 mLineLoopBufferLastIndex != lastVertex)
514 {
Jamie Madill21061022018-07-12 23:56:30 -0400515 ANGLE_TRY(mLineLoopHelper.getIndexBufferForDrawArrays(contextVk, drawCallParams,
Jamie Madill22f12fe2018-04-08 14:23:40 -0400516 &mCurrentElementArrayBufferHandle,
517 &mCurrentElementArrayBufferOffset));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400518
519 mLineLoopBufferFirstIndex = drawCallParams.firstVertex();
520 mLineLoopBufferLastIndex = lastVertex;
521 }
522
523 commandBuffer->bindIndexBuffer(mCurrentElementArrayBufferHandle,
524 mCurrentElementArrayBufferOffset, VK_INDEX_TYPE_UINT32);
525
Jamie Madill18e323a2018-05-11 16:54:17 -0400526 vk::LineLoopHelper::Draw(clampedVertexCount, commandBuffer);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400527
528 return gl::NoError();
529}
530
531gl::Error VertexArrayVk::drawElements(const gl::Context *context,
Jamie Madillc3755fc2018-04-05 08:39:13 -0400532 const gl::DrawCallParams &drawCallParams,
Jamie Madill316c6062018-05-29 10:49:45 -0400533 vk::CommandBuffer *commandBuffer,
Jamie Madillc3755fc2018-04-05 08:39:13 -0400534 bool newCommandBuffer)
535{
Jamie Madillc3755fc2018-04-05 08:39:13 -0400536 ASSERT(commandBuffer->valid());
537
Jamie Madill21061022018-07-12 23:56:30 -0400538 ContextVk *contextVk = vk::GetImpl(context);
539
Jamie Madill493f9572018-05-24 19:52:15 -0400540 if (drawCallParams.mode() != gl::PrimitiveMode::LineLoop)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400541 {
Jamie Madill21061022018-07-12 23:56:30 -0400542 ANGLE_TRY(onIndexedDraw(context, drawCallParams, commandBuffer, newCommandBuffer));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400543 commandBuffer->drawIndexed(drawCallParams.indexCount(), 1, 0, 0, 0);
544 return gl::NoError();
545 }
546
547 // Handle GL_LINE_LOOP drawElements.
Jamie Madillb8e39662018-04-04 11:41:42 -0400548 if (mDirtyLineLoopTranslation)
549 {
Luc Ferrona9120462018-04-12 13:11:03 -0400550 gl::Buffer *elementArrayBuffer = mState.getElementArrayBuffer().get();
551 VkIndexType indexType = gl_vk::GetIndexType(drawCallParams.type());
552
553 if (!elementArrayBuffer)
554 {
555 ANGLE_TRY(mLineLoopHelper.getIndexBufferForClientElementArray(
Jamie Madill21061022018-07-12 23:56:30 -0400556 contextVk, drawCallParams, &mCurrentElementArrayBufferHandle,
Luc Ferron3e313802018-06-11 14:44:33 -0400557 &mCurrentElementArrayBufferOffset));
Luc Ferrona9120462018-04-12 13:11:03 -0400558 }
559 else
560 {
Luc Ferrona4fa9c22018-04-13 07:00:56 -0400561 // When using an element array buffer, 'indices' is an offset to the first element.
562 intptr_t offset = reinterpret_cast<intptr_t>(drawCallParams.indices());
Luc Ferrona9120462018-04-12 13:11:03 -0400563 BufferVk *elementArrayBufferVk = vk::GetImpl(elementArrayBuffer);
564 ANGLE_TRY(mLineLoopHelper.getIndexBufferForElementArrayBuffer(
Jamie Madill21061022018-07-12 23:56:30 -0400565 contextVk, elementArrayBufferVk, indexType, drawCallParams.indexCount(), offset,
Luc Ferrona9120462018-04-12 13:11:03 -0400566 &mCurrentElementArrayBufferHandle, &mCurrentElementArrayBufferOffset));
567 }
Jamie Madillb8e39662018-04-04 11:41:42 -0400568 }
Jamie Madillc3755fc2018-04-05 08:39:13 -0400569
Jamie Madill21061022018-07-12 23:56:30 -0400570 ANGLE_TRY(onIndexedDraw(context, drawCallParams, commandBuffer, newCommandBuffer));
Jamie Madill22f12fe2018-04-08 14:23:40 -0400571 vk::LineLoopHelper::Draw(drawCallParams.indexCount(), commandBuffer);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400572
573 return gl::NoError();
574}
575
576gl::Error VertexArrayVk::onDraw(const gl::Context *context,
Jamie Madillc3755fc2018-04-05 08:39:13 -0400577 const gl::DrawCallParams &drawCallParams,
Jamie Madill316c6062018-05-29 10:49:45 -0400578 vk::CommandBuffer *commandBuffer,
Jamie Madillc3755fc2018-04-05 08:39:13 -0400579 bool newCommandBuffer)
580{
Jamie Madill21061022018-07-12 23:56:30 -0400581 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400582 const gl::State &state = context->getGLState();
583 const gl::Program *programGL = state.getProgram();
Geoff Lang89e82972018-08-28 11:32:53 -0400584 const gl::AttributesMask &programAttribsMask = programGL->getActiveAttribLocationsMask();
Jamie Madilldc358af2018-07-31 11:22:13 -0400585 const gl::AttributesMask &clientAttribs = context->getStateCache().getActiveClientAttribsMask();
Jamie Madillc3755fc2018-04-05 08:39:13 -0400586 uint32_t maxAttrib = programGL->getState().getMaxActiveAttribLocation();
587
Jamie Madillbcef3222018-04-13 15:19:11 -0400588 if (clientAttribs.any())
Jamie Madillc3755fc2018-04-05 08:39:13 -0400589 {
Jamie Madilldc358af2018-07-31 11:22:13 -0400590 ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
Jamie Madilla064c272018-08-30 16:18:34 -0400591
592 mDynamicVertexData.releaseRetainedBuffers(contextVk->getRenderer());
593
594 const auto &attribs = mState.getVertexAttributes();
595 const auto &bindings = mState.getVertexBindings();
596
597 // TODO(fjhenigman): When we have a bunch of interleaved attributes, they end up
598 // un-interleaved, wasting space and copying time. Consider improving on that.
599 for (size_t attribIndex : clientAttribs)
600 {
601 const gl::VertexAttribute &attrib = attribs[attribIndex];
602 const gl::VertexBinding &binding = bindings[attrib.bindingIndex];
603 ASSERT(attrib.enabled && binding.getBuffer().get() == nullptr);
604
605 const size_t bytesToAllocate =
606 (drawCallParams.firstVertex() + drawCallParams.vertexCount()) *
607 mCurrentArrayBufferStrides[attribIndex];
608 const uint8_t *src = static_cast<const uint8_t *>(attrib.pointer) +
609 drawCallParams.firstVertex() * binding.getStride();
610
611 size_t destOffset =
612 drawCallParams.firstVertex() * mCurrentArrayBufferStrides[attribIndex];
613
614 // Only vertexCount() vertices will be used by the upcoming draw so that is all we copy,
615 // but we allocate space firstVertex() + vertexCount() so indexing will work. If we
616 // don't start at zero all the indices will be off.
617 // TODO(fjhenigman): See if we can account for indices being off by adjusting the
618 // offset, thus avoiding wasted memory.
619 ANGLE_TRY(StreamVertexData(contextVk, &mDynamicVertexData, src, bytesToAllocate,
620 destOffset, drawCallParams.vertexCount(),
621 binding.getStride(),
622 mCurrentArrayBufferFormats[attribIndex]->vertexLoadFunction,
623 &mCurrentArrayBufferHandles[attribIndex],
624 &mCurrentArrayBufferOffsets[attribIndex]));
625 }
626
Geoff Lang89e82972018-08-28 11:32:53 -0400627 BindNonNullVertexBufferRanges(commandBuffer, programAttribsMask, maxAttrib,
628 mCurrentArrayBufferHandles, mCurrentArrayBufferOffsets);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400629 }
630 else if (mVertexBuffersDirty || newCommandBuffer)
631 {
Luc Ferron44162472018-04-06 13:20:45 -0400632 if (maxAttrib > 0)
633 {
Geoff Lang89e82972018-08-28 11:32:53 -0400634 BindNonNullVertexBufferRanges(commandBuffer, programAttribsMask, maxAttrib,
635 mCurrentArrayBufferHandles, mCurrentArrayBufferOffsets);
Jamie Madill316c6062018-05-29 10:49:45 -0400636
Jamie Madilldc358af2018-07-31 11:22:13 -0400637 const gl::AttributesMask &bufferedAttribs =
638 context->getStateCache().getActiveBufferedAttribsMask();
639
Jamie Madill316c6062018-05-29 10:49:45 -0400640 vk::CommandGraphResource *drawFramebuffer = vk::GetImpl(state.getDrawFramebuffer());
Jamie Madilldc358af2018-07-31 11:22:13 -0400641 updateArrayBufferReadDependencies(drawFramebuffer, bufferedAttribs,
Jamie Madill21061022018-07-12 23:56:30 -0400642 contextVk->getRenderer()->getCurrentQueueSerial());
Luc Ferron44162472018-04-06 13:20:45 -0400643 }
Luc Ferronc1e02682018-04-11 11:02:55 -0400644
Jamie Madillc3755fc2018-04-05 08:39:13 -0400645 mVertexBuffersDirty = false;
Luc Ferronc1e02682018-04-11 11:02:55 -0400646
647 // This forces the binding to happen if we follow a drawElement call from a drawArrays call.
648 mIndexBufferDirty = true;
Luc Ferron983c4292018-04-10 13:05:45 -0400649
650 // If we've had a drawElements call with a line loop before, we want to make sure this is
651 // invalidated the next time drawElements is called since we use the same index buffer for
652 // both calls.
653 mDirtyLineLoopTranslation = true;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400654 }
655
656 return gl::NoError();
657}
658
659gl::Error VertexArrayVk::onIndexedDraw(const gl::Context *context,
Jamie Madillc3755fc2018-04-05 08:39:13 -0400660 const gl::DrawCallParams &drawCallParams,
Jamie Madill316c6062018-05-29 10:49:45 -0400661 vk::CommandBuffer *commandBuffer,
Jamie Madillc3755fc2018-04-05 08:39:13 -0400662 bool newCommandBuffer)
663{
Jamie Madill21061022018-07-12 23:56:30 -0400664 ContextVk *contextVk = vk::GetImpl(context);
665 ANGLE_TRY(onDraw(context, drawCallParams, commandBuffer, newCommandBuffer));
Frank Henigman419acc82018-06-24 19:57:31 -0400666 bool isLineLoop = drawCallParams.mode() == gl::PrimitiveMode::LineLoop;
Luc Ferron6ed167a2018-06-13 13:45:55 -0400667 gl::Buffer *glBuffer = mState.getElementArrayBuffer().get();
668 uintptr_t offset =
669 glBuffer && !isLineLoop ? reinterpret_cast<uintptr_t>(drawCallParams.indices()) : 0;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400670
Luc Ferron6ed167a2018-06-13 13:45:55 -0400671 if (!glBuffer && !isLineLoop)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400672 {
673 ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
Jamie Madill21061022018-07-12 23:56:30 -0400674 ANGLE_TRY(streamIndexData(contextVk, drawCallParams));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400675 commandBuffer->bindIndexBuffer(mCurrentElementArrayBufferHandle,
676 mCurrentElementArrayBufferOffset,
677 gl_vk::GetIndexType(drawCallParams.type()));
678 }
Luc Ferron49aacad2018-06-12 08:33:59 -0400679 else if (mIndexBufferDirty || newCommandBuffer || offset != mLastIndexBufferOffset)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400680 {
Luc Ferron3e313802018-06-11 14:44:33 -0400681 if (drawCallParams.type() == GL_UNSIGNED_BYTE &&
682 drawCallParams.mode() != gl::PrimitiveMode::LineLoop)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400683 {
Luc Ferron6ed167a2018-06-13 13:45:55 -0400684 // Unsigned bytes don't have direct support in Vulkan so we have to expand the
685 // memory to a GLushort.
686 BufferVk *bufferVk = vk::GetImpl(glBuffer);
687 void *srcDataMapping = nullptr;
688 ASSERT(!glBuffer->isMapped());
Jamie Madill21061022018-07-12 23:56:30 -0400689 ANGLE_TRY(bufferVk->mapImpl(contextVk, &srcDataMapping));
Rafael Cintron05a449a2018-06-20 18:08:04 -0700690 uint8_t *srcData = static_cast<uint8_t *>(srcDataMapping);
Luc Ferron6ed167a2018-06-13 13:45:55 -0400691 intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(drawCallParams.indices());
692 srcData += offsetIntoSrcData;
693
694 // Allocate a new buffer that's double the size of the buffer provided by the user to
695 // go from unsigned byte to unsigned short.
696 uint8_t *allocatedData = nullptr;
697 bool newBufferAllocated = false;
Jamie Madilleebe2192018-07-11 09:01:18 -0400698 ANGLE_TRY(mTranslatedByteIndexData.allocate(
Jamie Madill21061022018-07-12 23:56:30 -0400699 contextVk, static_cast<size_t>(bufferVk->getSize()) * 2, &allocatedData,
Jamie Madill4c310832018-08-29 13:43:17 -0400700 &mCurrentElementArrayBufferHandle, &mCurrentElementArrayBufferOffset,
701 &newBufferAllocated));
Luc Ferron6ed167a2018-06-13 13:45:55 -0400702
703 // Expand the source into the destination
704 ASSERT(!context->getGLState().isPrimitiveRestartEnabled());
705 uint16_t *expandedDst = reinterpret_cast<uint16_t *>(allocatedData);
706 for (GLsizei index = 0; index < bufferVk->getSize() - offsetIntoSrcData; index++)
707 {
708 expandedDst[index] = static_cast<GLushort>(srcData[index]);
709 }
710
711 // Make sure our writes are available.
Jamie Madill21061022018-07-12 23:56:30 -0400712 ANGLE_TRY(mTranslatedByteIndexData.flush(contextVk));
Luc Ferron6ed167a2018-06-13 13:45:55 -0400713 GLboolean result = false;
714 ANGLE_TRY(bufferVk->unmap(context, &result));
715
716 // We do not add the offset from the drawCallParams here because we've already copied
717 // the source starting at the offset requested.
718 commandBuffer->bindIndexBuffer(mCurrentElementArrayBufferHandle,
719 mCurrentElementArrayBufferOffset,
720 gl_vk::GetIndexType(drawCallParams.type()));
721 }
722 else
723 {
724 commandBuffer->bindIndexBuffer(mCurrentElementArrayBufferHandle,
725 mCurrentElementArrayBufferOffset + offset,
726 gl_vk::GetIndexType(drawCallParams.type()));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400727 }
728
Luc Ferron49aacad2018-06-12 08:33:59 -0400729 mLastIndexBufferOffset = offset;
Jamie Madill316c6062018-05-29 10:49:45 -0400730
731 const gl::State &glState = context->getGLState();
732 vk::CommandGraphResource *drawFramebuffer = vk::GetImpl(glState.getDrawFramebuffer());
Jamie Madill21061022018-07-12 23:56:30 -0400733 updateElementArrayBufferReadDependency(drawFramebuffer,
734 contextVk->getRenderer()->getCurrentQueueSerial());
Jamie Madillc3755fc2018-04-05 08:39:13 -0400735 mIndexBufferDirty = false;
Luc Ferron983c4292018-04-10 13:05:45 -0400736
737 // If we've had a drawArrays call with a line loop before, we want to make sure this is
738 // invalidated the next time drawArrays is called since we use the same index buffer for
739 // both calls.
740 mLineLoopBufferFirstIndex.reset();
741 mLineLoopBufferLastIndex.reset();
Jamie Madillc3755fc2018-04-05 08:39:13 -0400742 }
743
744 return gl::NoError();
745}
Jamie Madill5a4c9322018-07-16 11:01:58 -0400746
747void VertexArrayVk::updateDefaultAttrib(RendererVk *renderer,
748 size_t attribIndex,
749 VkBuffer bufferHandle,
750 uint32_t offset)
751{
752 if (!mState.getEnabledAttributesMask().test(attribIndex))
753 {
754 mCurrentArrayBufferHandles[attribIndex] = bufferHandle;
755 mCurrentArrayBufferOffsets[attribIndex] = offset;
756 mCurrentArrayBufferResources[attribIndex] = nullptr;
757 mCurrentArrayBufferStrides[attribIndex] = 0;
758 mCurrentArrayBufferFormats[attribIndex] =
Jamie Madillba365932018-07-18 17:23:46 -0400759 &renderer->getFormat(angle::FormatID::R32G32B32A32_FIXED);
Jamie Madill5a4c9322018-07-16 11:01:58 -0400760 mDirtyPackedInputs.set(attribIndex);
761 }
762}
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400763} // namespace rx