blob: 5ee91ee448487234edc45e890fecf0fc69f3e414 [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"
Jamie Madillbfe31c42018-10-25 17:03:47 -040013#include "common/utilities.h"
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{
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +010026constexpr size_t kDynamicVertexDataSize = 1024 * 1024;
27constexpr size_t kDynamicIndexDataSize = 1024 * 8;
28constexpr size_t kMaxVertexFormatAlignment = 4;
29constexpr VkBufferUsageFlags kVertexBufferUsageFlags =
30 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -050031constexpr VkBufferUsageFlags kIndexBufferUsageFlags = VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
32 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
33 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
Frank Henigmane4523822018-07-19 16:10:53 -040034
Jamie Madilldbc605c2019-01-04 16:39:14 -050035ANGLE_INLINE bool BindingIsAligned(const gl::VertexBinding &binding,
36 const angle::Format &angleFormat,
37 unsigned int attribSize)
Frank Henigmane4523822018-07-19 16:10:53 -040038{
Jamie Madilldbc605c2019-01-04 16:39:14 -050039 GLuint mask = angleFormat.componentAlignmentMask;
40 if (mask != std::numeric_limits<GLuint>::max())
41 {
42 return ((binding.getOffset() & mask) == 0 && (binding.getStride() & mask) == 0);
43 }
44 else
45 {
46 unsigned int formatSize = angleFormat.pixelBytes;
47 return ((binding.getOffset() * attribSize) % formatSize == 0) &&
48 ((binding.getStride() * attribSize) % formatSize == 0);
49 }
Frank Henigmane4523822018-07-19 16:10:53 -040050}
Jamie Madilla064c272018-08-30 16:18:34 -040051
52angle::Result StreamVertexData(ContextVk *contextVk,
53 vk::DynamicBuffer *dynamicBuffer,
54 const uint8_t *sourceData,
55 size_t bytesToAllocate,
56 size_t destOffset,
57 size_t vertexCount,
58 size_t stride,
59 VertexCopyFunction vertexLoadFunction,
Shahbaz Youssefiec063052018-12-06 01:58:06 +010060 vk::BufferHelper **bufferOut,
Jamie Madilla064c272018-08-30 16:18:34 -040061 VkDeviceSize *bufferOffsetOut)
62{
63 uint8_t *dst = nullptr;
Shahbaz Youssefiec063052018-12-06 01:58:06 +010064 ANGLE_TRY(dynamicBuffer->allocate(contextVk, bytesToAllocate, &dst, nullptr, bufferOffsetOut,
65 nullptr));
66 *bufferOut = dynamicBuffer->getCurrentBuffer();
Jamie Madilla064c272018-08-30 16:18:34 -040067 dst += destOffset;
68 vertexLoadFunction(sourceData, stride, vertexCount, dst);
69
70 ANGLE_TRY(dynamicBuffer->flush(contextVk));
Jamie Madill7c985f52018-11-29 18:16:17 -050071 return angle::Result::Continue;
Jamie Madilla064c272018-08-30 16:18:34 -040072}
jchen105dc0a6f2018-09-20 14:30:45 +080073
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +010074size_t GetVertexCount(BufferVk *srcBuffer, const gl::VertexBinding &binding, uint32_t srcFormatSize)
75{
76 // Bytes usable for vertex data.
77 GLint64 bytes = srcBuffer->getSize() - binding.getOffset();
78 if (bytes < srcFormatSize)
79 return 0;
80
81 // Count the last vertex. It may occupy less than a full stride.
82 size_t numVertices = 1;
83 bytes -= srcFormatSize;
84
85 // Count how many strides fit remaining space.
86 if (bytes > 0)
87 numVertices += static_cast<size_t>(bytes) / binding.getStride();
88
89 return numVertices;
90}
Jamie Madillc3755fc2018-04-05 08:39:13 -040091} // anonymous namespace
Jamie Madill9e54b5a2016-05-25 12:57:39 -040092
Shahbaz Youssefi254b32c2018-11-26 11:58:03 -050093#define INIT \
94 { \
95 kVertexBufferUsageFlags, 1024 * 8, true \
Frank Henigmane4523822018-07-19 16:10:53 -040096 }
97
Luc Ferrona9ab0f32018-05-17 17:03:55 -040098VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state, RendererVk *renderer)
Jamie Madillbd159f02017-10-09 19:39:06 -040099 : VertexArrayImpl(state),
Jamie Madillda854a22017-11-30 17:24:21 -0500100 mCurrentArrayBufferHandles{},
Frank Henigman17448952017-01-05 15:48:26 -0500101 mCurrentArrayBufferOffsets{},
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500102 mCurrentArrayBuffers{},
Frank Henigman419acc82018-06-24 19:57:31 -0400103 mCurrentArrayBufferFormats{},
104 mCurrentArrayBufferStrides{},
Frank Henigmane4523822018-07-19 16:10:53 -0400105 mCurrentArrayBufferConversion{{
Jamie Madillb980c562018-11-27 11:34:27 -0500106 INIT,
107 INIT,
108 INIT,
109 INIT,
110 INIT,
111 INIT,
112 INIT,
113 INIT,
114 INIT,
115 INIT,
116 INIT,
117 INIT,
118 INIT,
119 INIT,
120 INIT,
Frank Henigmane4523822018-07-19 16:10:53 -0400121 INIT,
122 }},
123 mCurrentArrayBufferConversionCanRelease{},
Jamie Madillc3755fc2018-04-05 08:39:13 -0400124 mCurrentElementArrayBufferOffset(0),
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500125 mCurrentElementArrayBuffer(nullptr),
Shahbaz Youssefi254b32c2018-11-26 11:58:03 -0500126 mDynamicVertexData(kVertexBufferUsageFlags, kDynamicVertexDataSize, true),
127 mDynamicIndexData(kIndexBufferUsageFlags, kDynamicIndexDataSize, true),
128 mTranslatedByteIndexData(kIndexBufferUsageFlags, kDynamicIndexDataSize, true),
Luc Ferrona9ab0f32018-05-17 17:03:55 -0400129 mLineLoopHelper(renderer),
Jamie Madill88fc6da2018-08-30 16:18:36 -0400130 mDirtyLineLoopTranslation(true)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400131{
Jamie Madillda854a22017-11-30 17:24:21 -0500132 mCurrentArrayBufferHandles.fill(VK_NULL_HANDLE);
Frank Henigman17448952017-01-05 15:48:26 -0500133 mCurrentArrayBufferOffsets.fill(0);
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500134 mCurrentArrayBuffers.fill(nullptr);
Jamie Madill112a3a82018-01-23 13:04:06 -0500135
Frank Henigmane4523822018-07-19 16:10:53 -0400136 for (vk::DynamicBuffer &buffer : mCurrentArrayBufferConversion)
137 {
jchen105dc0a6f2018-09-20 14:30:45 +0800138 buffer.init(kMaxVertexFormatAlignment, renderer);
Frank Henigmane4523822018-07-19 16:10:53 -0400139 }
jchen105dc0a6f2018-09-20 14:30:45 +0800140 mDynamicVertexData.init(kMaxVertexFormatAlignment, renderer);
Luc Ferrona9ab0f32018-05-17 17:03:55 -0400141 mDynamicIndexData.init(1, renderer);
Luc Ferron6ed167a2018-06-13 13:45:55 -0400142 mTranslatedByteIndexData.init(1, renderer);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400143}
144
Jamie Madillb980c562018-11-27 11:34:27 -0500145VertexArrayVk::~VertexArrayVk() {}
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500146
Jamie Madill4928b7c2017-06-20 12:57:39 -0400147void VertexArrayVk::destroy(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400148{
Shahbaz Youssefifca8fd62018-11-13 13:55:48 -0500149 RendererVk *renderer = vk::GetImpl(context)->getRenderer();
150
Frank Henigmane4523822018-07-19 16:10:53 -0400151 for (vk::DynamicBuffer &buffer : mCurrentArrayBufferConversion)
152 {
Shahbaz Youssefifca8fd62018-11-13 13:55:48 -0500153 buffer.release(renderer);
Frank Henigmane4523822018-07-19 16:10:53 -0400154 }
Shahbaz Youssefifca8fd62018-11-13 13:55:48 -0500155 mDynamicVertexData.release(renderer);
156 mDynamicIndexData.release(renderer);
157 mTranslatedByteIndexData.release(renderer);
158 mLineLoopHelper.release(renderer);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400159}
160
Jamie Madill21061022018-07-12 23:56:30 -0400161angle::Result VertexArrayVk::streamIndexData(ContextVk *contextVk,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500162 gl::DrawElementsType indexType,
Jamie Madill253038d2018-08-30 16:18:35 -0400163 size_t indexCount,
164 const void *sourcePointer,
165 vk::DynamicBuffer *dynamicBuffer)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400166{
Jamie Madill8dc27f92018-11-29 11:45:44 -0500167 ASSERT(!mState.getElementArrayBuffer() || indexType == gl::DrawElementsType::UnsignedByte);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400168
Jamie Madill253038d2018-08-30 16:18:35 -0400169 dynamicBuffer->releaseRetainedBuffers(contextVk->getRenderer());
Jamie Madilla064c272018-08-30 16:18:34 -0400170
Jamie Madill253038d2018-08-30 16:18:35 -0400171 const size_t amount = sizeof(GLushort) * indexCount;
172 GLubyte *dst = nullptr;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400173
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500174 ANGLE_TRY(dynamicBuffer->allocate(contextVk, amount, &dst, nullptr,
Jamie Madill253038d2018-08-30 16:18:35 -0400175 &mCurrentElementArrayBufferOffset, nullptr));
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500176 mCurrentElementArrayBuffer = dynamicBuffer->getCurrentBuffer();
Jamie Madill8dc27f92018-11-29 11:45:44 -0500177 if (indexType == gl::DrawElementsType::UnsignedByte)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400178 {
179 // Unsigned bytes don't have direct support in Vulkan so we have to expand the
180 // memory to a GLushort.
Jamie Madill253038d2018-08-30 16:18:35 -0400181 const GLubyte *in = static_cast<const GLubyte *>(sourcePointer);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400182 GLushort *expandedDst = reinterpret_cast<GLushort *>(dst);
Jamie Madill253038d2018-08-30 16:18:35 -0400183 for (size_t index = 0; index < indexCount; index++)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400184 {
185 expandedDst[index] = static_cast<GLushort>(in[index]);
186 }
187 }
188 else
189 {
Jamie Madill253038d2018-08-30 16:18:35 -0400190 memcpy(dst, sourcePointer, amount);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400191 }
Jamie Madill253038d2018-08-30 16:18:35 -0400192 ANGLE_TRY(dynamicBuffer->flush(contextVk));
Jamie Madill7c985f52018-11-29 18:16:17 -0500193 return angle::Result::Continue;
Frank Henigman17448952017-01-05 15:48:26 -0500194}
195
Frank Henigmane4523822018-07-19 16:10:53 -0400196// We assume the buffer is completely full of the same kind of data and convert
197// and/or align it as we copy it to a DynamicBuffer. The assumption could be wrong
198// but the alternative of copying it piecemeal on each draw would have a lot more
199// overhead.
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100200angle::Result VertexArrayVk::convertVertexBufferGpu(ContextVk *contextVk,
201 BufferVk *srcBuffer,
202 const gl::VertexBinding &binding,
203 size_t attribIndex)
204{
205 RendererVk *renderer = contextVk->getRenderer();
206
207 const angle::Format &srcFormat = mCurrentArrayBufferFormats[attribIndex]->angleFormat();
208 const angle::Format &destFormat = mCurrentArrayBufferFormats[attribIndex]->bufferFormat();
209
210 ASSERT(binding.getStride() % (srcFormat.pixelBytes / srcFormat.channelCount()) == 0);
211
212 unsigned srcFormatSize = srcFormat.pixelBytes;
213 unsigned destFormatSize = destFormat.pixelBytes;
214
215 size_t numVertices = GetVertexCount(srcBuffer, binding, srcFormatSize);
216 if (numVertices == 0)
217 {
218 return angle::Result::Continue;
219 }
220
221 ASSERT(GetVertexInputAlignment(*mCurrentArrayBufferFormats[attribIndex]) <=
222 kMaxVertexFormatAlignment);
223
224 // Allocate buffer for results
225 mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(renderer);
226 ANGLE_TRY(mCurrentArrayBufferConversion[attribIndex].allocate(
227 contextVk, numVertices * destFormatSize, nullptr, nullptr,
228 &mCurrentArrayBufferOffsets[attribIndex], nullptr));
229 mCurrentArrayBuffers[attribIndex] =
230 mCurrentArrayBufferConversion[attribIndex].getCurrentBuffer();
231
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100232 UtilsVk::ConvertVertexParameters params;
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100233 params.vertexCount = numVertices;
234 params.srcFormat = &srcFormat;
235 params.destFormat = &destFormat;
236 params.srcStride = binding.getStride();
237 params.srcOffset = binding.getOffset();
238 params.destOffset = static_cast<size_t>(mCurrentArrayBufferOffsets[attribIndex]);
239
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100240 ANGLE_TRY(renderer->getUtils().convertVertexBuffer(contextVk, mCurrentArrayBuffers[attribIndex],
241 &srcBuffer->getBuffer(), params));
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100242
243 mCurrentArrayBufferHandles[attribIndex] =
244 mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle();
245 mCurrentArrayBufferConversionCanRelease[attribIndex] = true;
246
247 return angle::Result::Continue;
248}
249
250angle::Result VertexArrayVk::convertVertexBufferCpu(ContextVk *contextVk,
251 BufferVk *srcBuffer,
252 const gl::VertexBinding &binding,
253 size_t attribIndex)
Frank Henigmane4523822018-07-19 16:10:53 -0400254{
Frank Henigman9d84ccb2018-09-12 18:09:02 -0400255 // Needed before reading buffer or we could get stale data.
Jamie Madilla064c272018-08-30 16:18:34 -0400256 ANGLE_TRY(contextVk->getRenderer()->finish(contextVk));
Frank Henigmane4523822018-07-19 16:10:53 -0400257
258 unsigned srcFormatSize = mCurrentArrayBufferFormats[attribIndex]->angleFormat().pixelBytes;
Jamie Madilla064c272018-08-30 16:18:34 -0400259 unsigned dstFormatSize = mCurrentArrayBufferStrides[attribIndex];
260
261 mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(contextVk->getRenderer());
Frank Henigmane4523822018-07-19 16:10:53 -0400262
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100263 size_t numVertices = GetVertexCount(srcBuffer, binding, srcFormatSize);
264 if (numVertices == 0)
265 {
Jamie Madill7c985f52018-11-29 18:16:17 -0500266 return angle::Result::Continue;
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100267 }
Frank Henigmane4523822018-07-19 16:10:53 -0400268
Jamie Madill77abad82018-10-25 17:03:48 -0400269 void *src = nullptr;
Jamie Madilla064c272018-08-30 16:18:34 -0400270 ANGLE_TRY(srcBuffer->mapImpl(contextVk, &src));
271 const uint8_t *srcBytes = reinterpret_cast<const uint8_t *>(src);
272 srcBytes += binding.getOffset();
jchen105dc0a6f2018-09-20 14:30:45 +0800273 ASSERT(GetVertexInputAlignment(*mCurrentArrayBufferFormats[attribIndex]) <=
274 kMaxVertexFormatAlignment);
Jamie Madilla064c272018-08-30 16:18:34 -0400275 ANGLE_TRY(StreamVertexData(contextVk, &mCurrentArrayBufferConversion[attribIndex], srcBytes,
276 numVertices * dstFormatSize, 0, numVertices, binding.getStride(),
277 mCurrentArrayBufferFormats[attribIndex]->vertexLoadFunction,
Shahbaz Youssefiec063052018-12-06 01:58:06 +0100278 &mCurrentArrayBuffers[attribIndex],
Jamie Madilla064c272018-08-30 16:18:34 -0400279 &mCurrentArrayBufferOffsets[attribIndex]));
280 ANGLE_TRY(srcBuffer->unmapImpl(contextVk));
Frank Henigmane4523822018-07-19 16:10:53 -0400281
Shahbaz Youssefiec063052018-12-06 01:58:06 +0100282 mCurrentArrayBufferHandles[attribIndex] =
283 mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle();
Frank Henigmane4523822018-07-19 16:10:53 -0400284 mCurrentArrayBufferConversionCanRelease[attribIndex] = true;
Frank Henigmane4523822018-07-19 16:10:53 -0400285
Jamie Madill7c985f52018-11-29 18:16:17 -0500286 return angle::Result::Continue;
Frank Henigmane4523822018-07-19 16:10:53 -0400287}
288
289void VertexArrayVk::ensureConversionReleased(RendererVk *renderer, size_t attribIndex)
290{
291 if (mCurrentArrayBufferConversionCanRelease[attribIndex])
292 {
293 mCurrentArrayBufferConversion[attribIndex].release(renderer);
294 mCurrentArrayBufferConversionCanRelease[attribIndex] = false;
295 }
296}
297
Jamie Madill6f755b22018-10-09 12:48:54 -0400298angle::Result VertexArrayVk::syncState(const gl::Context *context,
299 const gl::VertexArray::DirtyBits &dirtyBits,
300 const gl::VertexArray::DirtyAttribBitsArray &attribBits,
301 const gl::VertexArray::DirtyBindingBitsArray &bindingBits)
Jamie Madilldd43e6c2017-03-24 14:18:49 -0400302{
303 ASSERT(dirtyBits.any());
Jamie Madill72106562017-03-24 14:18:50 -0400304
Jamie Madillbc5834c2018-11-06 11:13:50 -0500305 bool invalidateContext = false;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400306
Jamie Madill5a4c9322018-07-16 11:01:58 -0400307 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madillbd159f02017-10-09 19:39:06 -0400308
309 // Rebuild current attribute buffers cache. This will fail horribly if the buffer changes.
310 // TODO(jmadill): Handle buffer storage changes.
311 const auto &attribs = mState.getVertexAttributes();
312 const auto &bindings = mState.getVertexBindings();
313
Jamie Madill09463932018-04-04 05:26:59 -0400314 for (size_t dirtyBit : dirtyBits)
Jamie Madillbd159f02017-10-09 19:39:06 -0400315 {
Jamie Madill09463932018-04-04 05:26:59 -0400316 switch (dirtyBit)
Jamie Madillda854a22017-11-30 17:24:21 -0500317 {
Jamie Madill09463932018-04-04 05:26:59 -0400318 case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER:
Jamie Madillda854a22017-11-30 17:24:21 -0500319 {
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400320 gl::Buffer *bufferGL = mState.getElementArrayBuffer();
Jamie Madill09463932018-04-04 05:26:59 -0400321 if (bufferGL)
322 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500323 BufferVk *bufferVk = vk::GetImpl(bufferGL);
324 mCurrentElementArrayBuffer = &bufferVk->getBuffer();
Jamie Madill09463932018-04-04 05:26:59 -0400325 }
326 else
327 {
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500328 mCurrentElementArrayBuffer = nullptr;
Jamie Madill09463932018-04-04 05:26:59 -0400329 }
Luc Ferron387b3b32018-05-28 10:11:57 -0400330
331 mCurrentElementArrayBufferOffset = 0;
332 mLineLoopBufferFirstIndex.reset();
333 mLineLoopBufferLastIndex.reset();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400334 contextVk->setIndexBufferDirty();
Jamie Madillb8e39662018-04-04 11:41:42 -0400335 mDirtyLineLoopTranslation = true;
Jamie Madill09463932018-04-04 05:26:59 -0400336 break;
Jamie Madillda854a22017-11-30 17:24:21 -0500337 }
Jamie Madill09463932018-04-04 05:26:59 -0400338
339 case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA:
Jamie Madillc3755fc2018-04-05 08:39:13 -0400340 mLineLoopBufferFirstIndex.reset();
341 mLineLoopBufferLastIndex.reset();
Jamie Madillb8e39662018-04-04 11:41:42 -0400342 mDirtyLineLoopTranslation = true;
Jamie Madill09463932018-04-04 05:26:59 -0400343 break;
344
Jamie Madill80766cf2019-01-10 10:20:34 -0500345#define ANGLE_VERTEX_DIRTY_ATTRIB_FUNC(INDEX) \
346 case gl::VertexArray::DIRTY_BIT_ATTRIB_0 + INDEX: \
347 ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
348 bindings[attribs[INDEX].bindingIndex], INDEX)); \
349 invalidateContext = true; \
350 break;
351
Jamie Madilla56467e2018-04-11 16:19:41 -0400352 ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_ATTRIB_FUNC);
Jamie Madill80766cf2019-01-10 10:20:34 -0500353
354#define ANGLE_VERTEX_DIRTY_BINDING_FUNC(INDEX) \
355 case gl::VertexArray::DIRTY_BIT_BINDING_0 + INDEX: \
356 ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
357 bindings[attribs[INDEX].bindingIndex], INDEX)); \
358 invalidateContext = true; \
359 break;
360
Jamie Madilla56467e2018-04-11 16:19:41 -0400361 ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BINDING_FUNC);
Jamie Madill80766cf2019-01-10 10:20:34 -0500362
363#define ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC(INDEX) \
364 case gl::VertexArray::DIRTY_BIT_BUFFER_DATA_0 + INDEX: \
365 ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
366 bindings[attribs[INDEX].bindingIndex], INDEX)); \
367 break;
368
Jamie Madilla56467e2018-04-11 16:19:41 -0400369 ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC);
370
Jamie Madill09463932018-04-04 05:26:59 -0400371 default:
Jamie Madilla56467e2018-04-11 16:19:41 -0400372 UNREACHABLE();
Jamie Madill09463932018-04-04 05:26:59 -0400373 break;
Jamie Madillbd159f02017-10-09 19:39:06 -0400374 }
375 }
Frank Henigman0af5b862018-03-27 20:19:33 -0400376
Jamie Madillbc5834c2018-11-06 11:13:50 -0500377 if (invalidateContext)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400378 {
Jamie Madillbc5834c2018-11-06 11:13:50 -0500379 contextVk->invalidateVertexAndIndexBuffers();
Jamie Madillc3755fc2018-04-05 08:39:13 -0400380 }
381
Jamie Madill7c985f52018-11-29 18:16:17 -0500382 return angle::Result::Continue;
Jamie Madillbd159f02017-10-09 19:39:06 -0400383}
384
Jamie Madill80766cf2019-01-10 10:20:34 -0500385ANGLE_INLINE void VertexArrayVk::setPackedInputInfo(ContextVk *contextVk,
386 size_t attribIndex,
387 const gl::VertexAttribute &attrib,
388 const gl::VertexBinding &binding)
389{
390 ASSERT(attrib.enabled);
391 contextVk->onVertexAttributeChange(
392 attribIndex, mCurrentArrayBufferStrides[attribIndex], binding.getDivisor(),
393 mCurrentArrayBufferFormats[attribIndex]->vkBufferFormat, attrib.relativeOffset);
394}
395
396ANGLE_INLINE void VertexArrayVk::setDefaultPackedInput(ContextVk *contextVk, size_t attribIndex)
397{
398 contextVk->onVertexAttributeChange(attribIndex, 0, 0, VK_FORMAT_R32G32B32A32_SFLOAT, 0);
399}
400
Frank Henigmane4523822018-07-19 16:10:53 -0400401angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
402 const gl::VertexAttribute &attrib,
403 const gl::VertexBinding &binding,
404 size_t attribIndex)
Jamie Madilla56467e2018-04-11 16:19:41 -0400405{
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100406 RendererVk *renderer = contextVk->getRenderer();
407 bool releaseConversion = true;
408 bool anyVertexBufferConvertedOnGpu = false;
Jamie Madill5a4c9322018-07-16 11:01:58 -0400409
Jamie Madilla56467e2018-04-11 16:19:41 -0400410 if (attrib.enabled)
411 {
Frank Henigman67c388e2018-07-19 19:16:11 -0400412 gl::Buffer *bufferGL = binding.getBuffer().get();
Frank Henigman419acc82018-06-24 19:57:31 -0400413 mCurrentArrayBufferFormats[attribIndex] = &renderer->getFormat(GetVertexFormatID(attrib));
Frank Henigmane4523822018-07-19 16:10:53 -0400414
Jamie Madilla56467e2018-04-11 16:19:41 -0400415 if (bufferGL)
416 {
Frank Henigmane4523822018-07-19 16:10:53 -0400417 BufferVk *bufferVk = vk::GetImpl(bufferGL);
Jamie Madilldbc605c2019-01-04 16:39:14 -0500418 const angle::Format &angleFormat =
419 mCurrentArrayBufferFormats[attribIndex]->angleFormat();
420 bool bindingIsAligned = BindingIsAligned(binding, angleFormat, attrib.size);
Frank Henigman419acc82018-06-24 19:57:31 -0400421
Frank Henigmane4523822018-07-19 16:10:53 -0400422 if (mCurrentArrayBufferFormats[attribIndex]->vertexLoadRequiresConversion ||
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100423 !bindingIsAligned)
Frank Henigmane4523822018-07-19 16:10:53 -0400424 {
Jamie Madilla064c272018-08-30 16:18:34 -0400425 mCurrentArrayBufferStrides[attribIndex] =
426 mCurrentArrayBufferFormats[attribIndex]->bufferFormat().pixelBytes;
427
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100428 if (bindingIsAligned)
429 {
430 ANGLE_TRY(convertVertexBufferGpu(contextVk, bufferVk, binding, attribIndex));
431 anyVertexBufferConvertedOnGpu = true;
432 }
433 else
434 {
435 // TODO(syoussefi): Implement unaligned vertex buffer conversions in compute.
436 // http://anglebug.com/3009
437 ANGLE_TRY(convertVertexBufferCpu(contextVk, bufferVk, binding, attribIndex));
438 }
Frank Henigmane4523822018-07-19 16:10:53 -0400439
Jamie Madill7c985f52018-11-29 18:16:17 -0500440 releaseConversion = false;
Frank Henigmane4523822018-07-19 16:10:53 -0400441 }
442 else
443 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500444 mCurrentArrayBuffers[attribIndex] = &bufferVk->getBuffer();
Jamie Madill2d03ff42018-09-27 15:04:26 -0400445 mCurrentArrayBufferHandles[attribIndex] =
446 bufferVk->getBuffer().getBuffer().getHandle();
Jamie Madill77abad82018-10-25 17:03:48 -0400447 mCurrentArrayBufferOffsets[attribIndex] = binding.getOffset();
448 mCurrentArrayBufferStrides[attribIndex] = binding.getStride();
Frank Henigmane4523822018-07-19 16:10:53 -0400449 }
Jamie Madilla56467e2018-04-11 16:19:41 -0400450 }
451 else
452 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500453 mCurrentArrayBuffers[attribIndex] = nullptr;
454 mCurrentArrayBufferHandles[attribIndex] = VK_NULL_HANDLE;
455 mCurrentArrayBufferOffsets[attribIndex] = 0;
Frank Henigman419acc82018-06-24 19:57:31 -0400456 mCurrentArrayBufferStrides[attribIndex] =
Frank Henigmane4523822018-07-19 16:10:53 -0400457 mCurrentArrayBufferFormats[attribIndex]->bufferFormat().pixelBytes;
Jamie Madilla56467e2018-04-11 16:19:41 -0400458 }
Jamie Madill80766cf2019-01-10 10:20:34 -0500459
460 setPackedInputInfo(contextVk, attribIndex, attrib, binding);
Jamie Madilla56467e2018-04-11 16:19:41 -0400461 }
462 else
463 {
Jamie Madill5a4c9322018-07-16 11:01:58 -0400464 contextVk->invalidateDefaultAttribute(attribIndex);
465
466 // These will be filled out by the ContextVk.
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500467 mCurrentArrayBuffers[attribIndex] = nullptr;
468 mCurrentArrayBufferHandles[attribIndex] = VK_NULL_HANDLE;
469 mCurrentArrayBufferOffsets[attribIndex] = 0;
470 mCurrentArrayBufferStrides[attribIndex] = 0;
Jamie Madill5a4c9322018-07-16 11:01:58 -0400471 mCurrentArrayBufferFormats[attribIndex] =
Jamie Madillba365932018-07-18 17:23:46 -0400472 &renderer->getFormat(angle::FormatID::R32G32B32A32_FLOAT);
Jamie Madill80766cf2019-01-10 10:20:34 -0500473
474 setDefaultPackedInput(contextVk, attribIndex);
Jamie Madilla56467e2018-04-11 16:19:41 -0400475 }
Frank Henigmane4523822018-07-19 16:10:53 -0400476
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100477 if (anyVertexBufferConvertedOnGpu && renderer->getFeatures().flushAfterVertexConversion)
478 {
479 ANGLE_TRY(renderer->flush(contextVk));
480 }
481
Frank Henigmane4523822018-07-19 16:10:53 -0400482 if (releaseConversion)
483 ensureConversionReleased(renderer, attribIndex);
484
Jamie Madill7c985f52018-11-29 18:16:17 -0500485 return angle::Result::Continue;
Jamie Madilla56467e2018-04-11 16:19:41 -0400486}
487
Jamie Madill88fc6da2018-08-30 16:18:36 -0400488angle::Result VertexArrayVk::updateClientAttribs(const gl::Context *context,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400489 GLint firstVertex,
490 GLsizei vertexOrIndexCount,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500491 gl::DrawElementsType indexTypeOrInvalid,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400492 const void *indices)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400493{
Jamie Madill77abad82018-10-25 17:03:48 -0400494 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400495 const gl::AttributesMask &clientAttribs = context->getStateCache().getActiveClientAttribsMask();
Jamie Madill21061022018-07-12 23:56:30 -0400496
Jamie Madill88fc6da2018-08-30 16:18:36 -0400497 ASSERT(clientAttribs.any());
Jamie Madillc1fd7372018-10-26 22:48:39 -0400498
499 GLint startVertex;
500 size_t vertexCount;
Jamie Madill8dc27f92018-11-29 11:45:44 -0500501 ANGLE_TRY(GetVertexRangeInfo(context, firstVertex, vertexOrIndexCount, indexTypeOrInvalid,
502 indices, 0, &startVertex, &vertexCount));
Jamie Madill88fc6da2018-08-30 16:18:36 -0400503
504 mDynamicVertexData.releaseRetainedBuffers(contextVk->getRenderer());
505
506 const auto &attribs = mState.getVertexAttributes();
507 const auto &bindings = mState.getVertexBindings();
508
509 // TODO(fjhenigman): When we have a bunch of interleaved attributes, they end up
510 // un-interleaved, wasting space and copying time. Consider improving on that.
511 for (size_t attribIndex : clientAttribs)
512 {
513 const gl::VertexAttribute &attrib = attribs[attribIndex];
514 const gl::VertexBinding &binding = bindings[attrib.bindingIndex];
515 ASSERT(attrib.enabled && binding.getBuffer().get() == nullptr);
516
517 const size_t bytesToAllocate =
Jamie Madillc1fd7372018-10-26 22:48:39 -0400518 (startVertex + vertexCount) * mCurrentArrayBufferStrides[attribIndex];
519 const uint8_t *src =
520 static_cast<const uint8_t *>(attrib.pointer) + startVertex * binding.getStride();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400521
Jamie Madillc1fd7372018-10-26 22:48:39 -0400522 size_t destOffset = startVertex * mCurrentArrayBufferStrides[attribIndex];
jchen105dc0a6f2018-09-20 14:30:45 +0800523 ASSERT(GetVertexInputAlignment(*mCurrentArrayBufferFormats[attribIndex]) <=
524 kMaxVertexFormatAlignment);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400525
526 // Only vertexCount() vertices will be used by the upcoming draw. so that is all we copy.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400527 // We allocate space for startVertex + vertexCount so indexing will work. If we
Jamie Madill88fc6da2018-08-30 16:18:36 -0400528 // don't start at zero all the indices will be off.
529 // TODO(fjhenigman): See if we can account for indices being off by adjusting the
530 // offset, thus avoiding wasted memory.
Jamie Madillc1fd7372018-10-26 22:48:39 -0400531 ANGLE_TRY(StreamVertexData(
532 contextVk, &mDynamicVertexData, src, bytesToAllocate, destOffset, vertexCount,
533 binding.getStride(), mCurrentArrayBufferFormats[attribIndex]->vertexLoadFunction,
Shahbaz Youssefiec063052018-12-06 01:58:06 +0100534 &mCurrentArrayBuffers[attribIndex], &mCurrentArrayBufferOffsets[attribIndex]));
535 mCurrentArrayBufferHandles[attribIndex] =
536 mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400537 }
538
Jamie Madill7c985f52018-11-29 18:16:17 -0500539 return angle::Result::Continue;
Jamie Madill88fc6da2018-08-30 16:18:36 -0400540}
541
542angle::Result VertexArrayVk::handleLineLoop(ContextVk *contextVk,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400543 GLint firstVertex,
544 GLsizei vertexOrIndexCount,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500545 gl::DrawElementsType indexTypeOrInvalid,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400546 const void *indices)
Jamie Madill88fc6da2018-08-30 16:18:36 -0400547{
Jamie Madill8dc27f92018-11-29 11:45:44 -0500548 if (indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
Jamie Madill88fc6da2018-08-30 16:18:36 -0400549 {
550 // Handle GL_LINE_LOOP drawElements.
551 if (mDirtyLineLoopTranslation)
552 {
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400553 gl::Buffer *elementArrayBuffer = mState.getElementArrayBuffer();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400554
555 if (!elementArrayBuffer)
556 {
Frank Henigman85c4b432018-09-19 23:35:00 -0400557 ANGLE_TRY(mLineLoopHelper.streamIndices(
Jamie Madill8dc27f92018-11-29 11:45:44 -0500558 contextVk, indexTypeOrInvalid, vertexOrIndexCount,
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500559 reinterpret_cast<const uint8_t *>(indices), &mCurrentElementArrayBuffer,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400560 &mCurrentElementArrayBufferOffset));
Jamie Madill88fc6da2018-08-30 16:18:36 -0400561 }
562 else
563 {
564 // When using an element array buffer, 'indices' is an offset to the first element.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400565 intptr_t offset = reinterpret_cast<intptr_t>(indices);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400566 BufferVk *elementArrayBufferVk = vk::GetImpl(elementArrayBuffer);
567 ANGLE_TRY(mLineLoopHelper.getIndexBufferForElementArrayBuffer(
Jamie Madill8dc27f92018-11-29 11:45:44 -0500568 contextVk, elementArrayBufferVk, indexTypeOrInvalid, vertexOrIndexCount, offset,
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500569 &mCurrentElementArrayBuffer, &mCurrentElementArrayBufferOffset));
Jamie Madill88fc6da2018-08-30 16:18:36 -0400570 }
571 }
572
573 // If we've had a drawArrays call with a line loop before, we want to make sure this is
574 // invalidated the next time drawArrays is called since we use the same index buffer for
575 // both calls.
576 mLineLoopBufferFirstIndex.reset();
577 mLineLoopBufferLastIndex.reset();
Jamie Madill7c985f52018-11-29 18:16:17 -0500578 return angle::Result::Continue;
Jamie Madill88fc6da2018-08-30 16:18:36 -0400579 }
Jamie Madillc3755fc2018-04-05 08:39:13 -0400580
Jamie Madill18e323a2018-05-11 16:54:17 -0400581 // Note: Vertex indexes can be arbitrarily large.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400582 uint32_t clampedVertexCount = gl::clampCast<uint32_t>(vertexOrIndexCount);
Jamie Madill18e323a2018-05-11 16:54:17 -0400583
Jamie Madillc3755fc2018-04-05 08:39:13 -0400584 // Handle GL_LINE_LOOP drawArrays.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400585 size_t lastVertex = static_cast<size_t>(firstVertex + clampedVertexCount);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400586 if (!mLineLoopBufferFirstIndex.valid() || !mLineLoopBufferLastIndex.valid() ||
Jamie Madillbfe31c42018-10-25 17:03:47 -0400587 mLineLoopBufferFirstIndex != firstVertex || mLineLoopBufferLastIndex != lastVertex)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400588 {
Jamie Madillbfe31c42018-10-25 17:03:47 -0400589 ANGLE_TRY(mLineLoopHelper.getIndexBufferForDrawArrays(
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500590 contextVk, clampedVertexCount, firstVertex, &mCurrentElementArrayBuffer,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400591 &mCurrentElementArrayBufferOffset));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400592
Jamie Madillbfe31c42018-10-25 17:03:47 -0400593 mLineLoopBufferFirstIndex = firstVertex;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400594 mLineLoopBufferLastIndex = lastVertex;
595 }
596
Jamie Madill7c985f52018-11-29 18:16:17 -0500597 return angle::Result::Continue;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400598}
599
Jamie Madill88fc6da2018-08-30 16:18:36 -0400600angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400601 GLsizei indexCount,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500602 gl::DrawElementsType type,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400603 const void *indices)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400604{
Jamie Madill8dc27f92018-11-29 11:45:44 -0500605 ASSERT(type != gl::DrawElementsType::InvalidEnum);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400606
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500607 RendererVk *renderer = contextVk->getRenderer();
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400608 gl::Buffer *glBuffer = mState.getElementArrayBuffer();
Jamie Madillc3755fc2018-04-05 08:39:13 -0400609
Jamie Madill88fc6da2018-08-30 16:18:36 -0400610 if (!glBuffer)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400611 {
Jamie Madillbfe31c42018-10-25 17:03:47 -0400612 ANGLE_TRY(streamIndexData(contextVk, type, indexCount, indices, &mDynamicIndexData));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400613 }
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500614 else if (renderer->getFormat(angle::FormatID::R16_UINT).vkSupportsStorageBuffer)
615 {
616 BufferVk *bufferVk = vk::GetImpl(glBuffer);
617
618 ASSERT(type == gl::DrawElementsType::UnsignedByte);
619
620 intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices);
621 size_t srcDataSize = static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData;
622
623 mTranslatedByteIndexData.releaseRetainedBuffers(renderer);
624
625 ANGLE_TRY(mTranslatedByteIndexData.allocate(contextVk, sizeof(GLushort) * srcDataSize,
626 nullptr, nullptr,
627 &mCurrentElementArrayBufferOffset, nullptr));
628 mCurrentElementArrayBuffer = mTranslatedByteIndexData.getCurrentBuffer();
629
630 vk::BufferHelper *dest = mTranslatedByteIndexData.getCurrentBuffer();
631 vk::BufferHelper *src = &bufferVk->getBuffer();
632
633 ANGLE_TRY(src->initBufferView(contextVk, renderer->getFormat(angle::FormatID::R8_UINT)));
634 ANGLE_TRY(dest->initBufferView(contextVk, renderer->getFormat(angle::FormatID::R16_UINT)));
635
636 // Copy relevant section of the source into destination at allocated offset. Note that the
637 // offset returned by allocate() above is in bytes, while our allocated array is of
638 // GLushorts.
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100639 UtilsVk::CopyParameters params = {};
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500640 params.destOffset =
641 static_cast<size_t>(mCurrentElementArrayBufferOffset) / sizeof(GLushort);
642 params.srcOffset = offsetIntoSrcData;
643 params.size = srcDataSize;
644
645 // Note: this is a copy, which implicitly converts between formats. Once support for
646 // primitive restart is added, a specialized shader is likely needed to special case 0xFF ->
647 // 0xFFFF.
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100648 ANGLE_TRY(renderer->getUtils().copyBuffer(contextVk, dest, src, params));
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500649 }
Jamie Madill88fc6da2018-08-30 16:18:36 -0400650 else
Jamie Madillc3755fc2018-04-05 08:39:13 -0400651 {
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500652 // If it's not possible to convert the buffer with compute, opt for a CPU read back for now.
653 // TODO(syoussefi): R8G8B8A8_UINT is required to have storage texel buffer support, so a
654 // specialized shader code can be made to read two ubyte indices and output them in R and B
655 // (or A and G based on endianness?) with 0 on the other channels. If specialized, we might
656 // as well support the ubyte to ushort case with correct handling of primitive restart.
657 // http://anglebug.com/3003
658
Frank Henigman9d84ccb2018-09-12 18:09:02 -0400659 // Needed before reading buffer or we could get stale data.
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500660 ANGLE_TRY(renderer->finish(contextVk));
Frank Henigman9d84ccb2018-09-12 18:09:02 -0400661
Jamie Madill8dc27f92018-11-29 11:45:44 -0500662 ASSERT(type == gl::DrawElementsType::UnsignedByte);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400663 // Unsigned bytes don't have direct support in Vulkan so we have to expand the
664 // memory to a GLushort.
665 BufferVk *bufferVk = vk::GetImpl(glBuffer);
666 void *srcDataMapping = nullptr;
667 ASSERT(!glBuffer->isMapped());
668 ANGLE_TRY(bufferVk->mapImpl(contextVk, &srcDataMapping));
669 uint8_t *srcData = static_cast<uint8_t *>(srcDataMapping);
Jamie Madillbfe31c42018-10-25 17:03:47 -0400670 intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400671 srcData += offsetIntoSrcData;
Jamie Madill253038d2018-08-30 16:18:35 -0400672
Jamie Madillbfe31c42018-10-25 17:03:47 -0400673 ANGLE_TRY(streamIndexData(contextVk, type,
Jamie Madill88fc6da2018-08-30 16:18:36 -0400674 static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData,
675 srcData, &mTranslatedByteIndexData));
Luc Ferron6ed167a2018-06-13 13:45:55 -0400676
Jamie Madill88fc6da2018-08-30 16:18:36 -0400677 ANGLE_TRY(bufferVk->unmapImpl(contextVk));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400678 }
679
Jamie Madill7c985f52018-11-29 18:16:17 -0500680 return angle::Result::Continue;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400681}
Jamie Madill5a4c9322018-07-16 11:01:58 -0400682
Jamie Madill80766cf2019-01-10 10:20:34 -0500683void VertexArrayVk::updateDefaultAttrib(ContextVk *contextVk,
Jamie Madill5a4c9322018-07-16 11:01:58 -0400684 size_t attribIndex,
685 VkBuffer bufferHandle,
686 uint32_t offset)
687{
688 if (!mState.getEnabledAttributesMask().test(attribIndex))
689 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500690 mCurrentArrayBufferHandles[attribIndex] = bufferHandle;
691 mCurrentArrayBufferOffsets[attribIndex] = offset;
692 mCurrentArrayBuffers[attribIndex] = nullptr;
693 mCurrentArrayBufferStrides[attribIndex] = 0;
Jamie Madill5a4c9322018-07-16 11:01:58 -0400694 mCurrentArrayBufferFormats[attribIndex] =
Jamie Madill80766cf2019-01-10 10:20:34 -0500695 &contextVk->getRenderer()->getFormat(angle::FormatID::R32G32B32A32_FIXED);
696
697 setDefaultPackedInput(contextVk, attribIndex);
Jamie Madill5a4c9322018-07-16 11:01:58 -0400698 }
699}
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400700} // namespace rx