blob: 378321c61daa2987343fef3b09bcee3f5b191627 [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
Jamie Madillc759b8b2019-01-03 15:16:50 -050098VertexArrayVk::VertexArrayVk(ContextVk *contextVk, const gl::VertexArrayState &state)
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),
Jamie Madillc759b8b2019-01-03 15:16:50 -0500129 mLineLoopHelper(contextVk->getRenderer()),
Jamie Madill88fc6da2018-08-30 16:18:36 -0400130 mDirtyLineLoopTranslation(true)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400131{
Jamie Madillc759b8b2019-01-03 15:16:50 -0500132 RendererVk *renderer = contextVk->getRenderer();
133
134 VkBufferCreateInfo createInfo = {};
135 createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
136 createInfo.size = 16;
137 createInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
138 (void)mTheNullBuffer.init(contextVk, createInfo, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
139
140 mCurrentArrayBufferHandles.fill(mTheNullBuffer.getBuffer().getHandle());
Frank Henigman17448952017-01-05 15:48:26 -0500141 mCurrentArrayBufferOffsets.fill(0);
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500142 mCurrentArrayBuffers.fill(nullptr);
Jamie Madill112a3a82018-01-23 13:04:06 -0500143
Frank Henigmane4523822018-07-19 16:10:53 -0400144 for (vk::DynamicBuffer &buffer : mCurrentArrayBufferConversion)
145 {
jchen105dc0a6f2018-09-20 14:30:45 +0800146 buffer.init(kMaxVertexFormatAlignment, renderer);
Frank Henigmane4523822018-07-19 16:10:53 -0400147 }
jchen105dc0a6f2018-09-20 14:30:45 +0800148 mDynamicVertexData.init(kMaxVertexFormatAlignment, renderer);
Luc Ferrona9ab0f32018-05-17 17:03:55 -0400149 mDynamicIndexData.init(1, renderer);
Luc Ferron6ed167a2018-06-13 13:45:55 -0400150 mTranslatedByteIndexData.init(1, renderer);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400151}
152
Jamie Madillb980c562018-11-27 11:34:27 -0500153VertexArrayVk::~VertexArrayVk() {}
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500154
Jamie Madill4928b7c2017-06-20 12:57:39 -0400155void VertexArrayVk::destroy(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400156{
Shahbaz Youssefifca8fd62018-11-13 13:55:48 -0500157 RendererVk *renderer = vk::GetImpl(context)->getRenderer();
158
Jamie Madillc759b8b2019-01-03 15:16:50 -0500159 mTheNullBuffer.release(renderer);
160
Frank Henigmane4523822018-07-19 16:10:53 -0400161 for (vk::DynamicBuffer &buffer : mCurrentArrayBufferConversion)
162 {
Shahbaz Youssefifca8fd62018-11-13 13:55:48 -0500163 buffer.release(renderer);
Frank Henigmane4523822018-07-19 16:10:53 -0400164 }
Shahbaz Youssefifca8fd62018-11-13 13:55:48 -0500165 mDynamicVertexData.release(renderer);
166 mDynamicIndexData.release(renderer);
167 mTranslatedByteIndexData.release(renderer);
168 mLineLoopHelper.release(renderer);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400169}
170
Jamie Madill21061022018-07-12 23:56:30 -0400171angle::Result VertexArrayVk::streamIndexData(ContextVk *contextVk,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500172 gl::DrawElementsType indexType,
Jamie Madill253038d2018-08-30 16:18:35 -0400173 size_t indexCount,
174 const void *sourcePointer,
175 vk::DynamicBuffer *dynamicBuffer)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400176{
Jamie Madill8dc27f92018-11-29 11:45:44 -0500177 ASSERT(!mState.getElementArrayBuffer() || indexType == gl::DrawElementsType::UnsignedByte);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400178
Jamie Madill253038d2018-08-30 16:18:35 -0400179 dynamicBuffer->releaseRetainedBuffers(contextVk->getRenderer());
Jamie Madilla064c272018-08-30 16:18:34 -0400180
Jamie Madill253038d2018-08-30 16:18:35 -0400181 const size_t amount = sizeof(GLushort) * indexCount;
182 GLubyte *dst = nullptr;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400183
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500184 ANGLE_TRY(dynamicBuffer->allocate(contextVk, amount, &dst, nullptr,
Jamie Madill253038d2018-08-30 16:18:35 -0400185 &mCurrentElementArrayBufferOffset, nullptr));
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500186 mCurrentElementArrayBuffer = dynamicBuffer->getCurrentBuffer();
Jamie Madill8dc27f92018-11-29 11:45:44 -0500187 if (indexType == gl::DrawElementsType::UnsignedByte)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400188 {
189 // Unsigned bytes don't have direct support in Vulkan so we have to expand the
190 // memory to a GLushort.
Jamie Madill253038d2018-08-30 16:18:35 -0400191 const GLubyte *in = static_cast<const GLubyte *>(sourcePointer);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400192 GLushort *expandedDst = reinterpret_cast<GLushort *>(dst);
Jamie Madill253038d2018-08-30 16:18:35 -0400193 for (size_t index = 0; index < indexCount; index++)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400194 {
195 expandedDst[index] = static_cast<GLushort>(in[index]);
196 }
197 }
198 else
199 {
Jamie Madill253038d2018-08-30 16:18:35 -0400200 memcpy(dst, sourcePointer, amount);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400201 }
Jamie Madill253038d2018-08-30 16:18:35 -0400202 ANGLE_TRY(dynamicBuffer->flush(contextVk));
Jamie Madill7c985f52018-11-29 18:16:17 -0500203 return angle::Result::Continue;
Frank Henigman17448952017-01-05 15:48:26 -0500204}
205
Frank Henigmane4523822018-07-19 16:10:53 -0400206// We assume the buffer is completely full of the same kind of data and convert
207// and/or align it as we copy it to a DynamicBuffer. The assumption could be wrong
208// but the alternative of copying it piecemeal on each draw would have a lot more
209// overhead.
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100210angle::Result VertexArrayVk::convertVertexBufferGpu(ContextVk *contextVk,
211 BufferVk *srcBuffer,
212 const gl::VertexBinding &binding,
213 size_t attribIndex)
214{
215 RendererVk *renderer = contextVk->getRenderer();
216
217 const angle::Format &srcFormat = mCurrentArrayBufferFormats[attribIndex]->angleFormat();
218 const angle::Format &destFormat = mCurrentArrayBufferFormats[attribIndex]->bufferFormat();
219
220 ASSERT(binding.getStride() % (srcFormat.pixelBytes / srcFormat.channelCount()) == 0);
221
222 unsigned srcFormatSize = srcFormat.pixelBytes;
223 unsigned destFormatSize = destFormat.pixelBytes;
224
225 size_t numVertices = GetVertexCount(srcBuffer, binding, srcFormatSize);
226 if (numVertices == 0)
227 {
228 return angle::Result::Continue;
229 }
230
231 ASSERT(GetVertexInputAlignment(*mCurrentArrayBufferFormats[attribIndex]) <=
232 kMaxVertexFormatAlignment);
233
234 // Allocate buffer for results
235 mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(renderer);
236 ANGLE_TRY(mCurrentArrayBufferConversion[attribIndex].allocate(
237 contextVk, numVertices * destFormatSize, nullptr, nullptr,
238 &mCurrentArrayBufferOffsets[attribIndex], nullptr));
239 mCurrentArrayBuffers[attribIndex] =
240 mCurrentArrayBufferConversion[attribIndex].getCurrentBuffer();
241
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100242 UtilsVk::ConvertVertexParameters params;
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100243 params.vertexCount = numVertices;
244 params.srcFormat = &srcFormat;
245 params.destFormat = &destFormat;
246 params.srcStride = binding.getStride();
247 params.srcOffset = binding.getOffset();
248 params.destOffset = static_cast<size_t>(mCurrentArrayBufferOffsets[attribIndex]);
249
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100250 ANGLE_TRY(renderer->getUtils().convertVertexBuffer(contextVk, mCurrentArrayBuffers[attribIndex],
251 &srcBuffer->getBuffer(), params));
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100252
253 mCurrentArrayBufferHandles[attribIndex] =
254 mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle();
255 mCurrentArrayBufferConversionCanRelease[attribIndex] = true;
256
257 return angle::Result::Continue;
258}
259
260angle::Result VertexArrayVk::convertVertexBufferCpu(ContextVk *contextVk,
261 BufferVk *srcBuffer,
262 const gl::VertexBinding &binding,
263 size_t attribIndex)
Frank Henigmane4523822018-07-19 16:10:53 -0400264{
Frank Henigman9d84ccb2018-09-12 18:09:02 -0400265 // Needed before reading buffer or we could get stale data.
Jamie Madilla064c272018-08-30 16:18:34 -0400266 ANGLE_TRY(contextVk->getRenderer()->finish(contextVk));
Frank Henigmane4523822018-07-19 16:10:53 -0400267
268 unsigned srcFormatSize = mCurrentArrayBufferFormats[attribIndex]->angleFormat().pixelBytes;
Jamie Madilla064c272018-08-30 16:18:34 -0400269 unsigned dstFormatSize = mCurrentArrayBufferStrides[attribIndex];
270
271 mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(contextVk->getRenderer());
Frank Henigmane4523822018-07-19 16:10:53 -0400272
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100273 size_t numVertices = GetVertexCount(srcBuffer, binding, srcFormatSize);
274 if (numVertices == 0)
275 {
Jamie Madill7c985f52018-11-29 18:16:17 -0500276 return angle::Result::Continue;
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100277 }
Frank Henigmane4523822018-07-19 16:10:53 -0400278
Jamie Madill77abad82018-10-25 17:03:48 -0400279 void *src = nullptr;
Jamie Madilla064c272018-08-30 16:18:34 -0400280 ANGLE_TRY(srcBuffer->mapImpl(contextVk, &src));
281 const uint8_t *srcBytes = reinterpret_cast<const uint8_t *>(src);
282 srcBytes += binding.getOffset();
jchen105dc0a6f2018-09-20 14:30:45 +0800283 ASSERT(GetVertexInputAlignment(*mCurrentArrayBufferFormats[attribIndex]) <=
284 kMaxVertexFormatAlignment);
Jamie Madilla064c272018-08-30 16:18:34 -0400285 ANGLE_TRY(StreamVertexData(contextVk, &mCurrentArrayBufferConversion[attribIndex], srcBytes,
286 numVertices * dstFormatSize, 0, numVertices, binding.getStride(),
287 mCurrentArrayBufferFormats[attribIndex]->vertexLoadFunction,
Shahbaz Youssefiec063052018-12-06 01:58:06 +0100288 &mCurrentArrayBuffers[attribIndex],
Jamie Madilla064c272018-08-30 16:18:34 -0400289 &mCurrentArrayBufferOffsets[attribIndex]));
290 ANGLE_TRY(srcBuffer->unmapImpl(contextVk));
Frank Henigmane4523822018-07-19 16:10:53 -0400291
Shahbaz Youssefiec063052018-12-06 01:58:06 +0100292 mCurrentArrayBufferHandles[attribIndex] =
293 mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle();
Frank Henigmane4523822018-07-19 16:10:53 -0400294 mCurrentArrayBufferConversionCanRelease[attribIndex] = true;
Frank Henigmane4523822018-07-19 16:10:53 -0400295
Jamie Madill7c985f52018-11-29 18:16:17 -0500296 return angle::Result::Continue;
Frank Henigmane4523822018-07-19 16:10:53 -0400297}
298
Jamie Madillc759b8b2019-01-03 15:16:50 -0500299ANGLE_INLINE void VertexArrayVk::ensureConversionReleased(RendererVk *renderer, size_t attribIndex)
Frank Henigmane4523822018-07-19 16:10:53 -0400300{
301 if (mCurrentArrayBufferConversionCanRelease[attribIndex])
302 {
303 mCurrentArrayBufferConversion[attribIndex].release(renderer);
304 mCurrentArrayBufferConversionCanRelease[attribIndex] = false;
305 }
306}
307
Jamie Madill6f755b22018-10-09 12:48:54 -0400308angle::Result VertexArrayVk::syncState(const gl::Context *context,
309 const gl::VertexArray::DirtyBits &dirtyBits,
Jamie Madillc759b8b2019-01-03 15:16:50 -0500310 gl::VertexArray::DirtyAttribBitsArray *attribBits,
311 gl::VertexArray::DirtyBindingBitsArray *bindingBits)
Jamie Madilldd43e6c2017-03-24 14:18:49 -0400312{
313 ASSERT(dirtyBits.any());
Jamie Madill72106562017-03-24 14:18:50 -0400314
Jamie Madillbc5834c2018-11-06 11:13:50 -0500315 bool invalidateContext = false;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400316
Jamie Madill5a4c9322018-07-16 11:01:58 -0400317 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madillbd159f02017-10-09 19:39:06 -0400318
319 // Rebuild current attribute buffers cache. This will fail horribly if the buffer changes.
320 // TODO(jmadill): Handle buffer storage changes.
321 const auto &attribs = mState.getVertexAttributes();
322 const auto &bindings = mState.getVertexBindings();
323
Jamie Madill09463932018-04-04 05:26:59 -0400324 for (size_t dirtyBit : dirtyBits)
Jamie Madillbd159f02017-10-09 19:39:06 -0400325 {
Jamie Madill09463932018-04-04 05:26:59 -0400326 switch (dirtyBit)
Jamie Madillda854a22017-11-30 17:24:21 -0500327 {
Jamie Madill09463932018-04-04 05:26:59 -0400328 case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER:
Jamie Madillda854a22017-11-30 17:24:21 -0500329 {
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400330 gl::Buffer *bufferGL = mState.getElementArrayBuffer();
Jamie Madill09463932018-04-04 05:26:59 -0400331 if (bufferGL)
332 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500333 BufferVk *bufferVk = vk::GetImpl(bufferGL);
334 mCurrentElementArrayBuffer = &bufferVk->getBuffer();
Jamie Madill09463932018-04-04 05:26:59 -0400335 }
336 else
337 {
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500338 mCurrentElementArrayBuffer = nullptr;
Jamie Madill09463932018-04-04 05:26:59 -0400339 }
Luc Ferron387b3b32018-05-28 10:11:57 -0400340
341 mCurrentElementArrayBufferOffset = 0;
342 mLineLoopBufferFirstIndex.reset();
343 mLineLoopBufferLastIndex.reset();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400344 contextVk->setIndexBufferDirty();
Jamie Madillb8e39662018-04-04 11:41:42 -0400345 mDirtyLineLoopTranslation = true;
Jamie Madill09463932018-04-04 05:26:59 -0400346 break;
Jamie Madillda854a22017-11-30 17:24:21 -0500347 }
Jamie Madill09463932018-04-04 05:26:59 -0400348
349 case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA:
Jamie Madillc3755fc2018-04-05 08:39:13 -0400350 mLineLoopBufferFirstIndex.reset();
351 mLineLoopBufferLastIndex.reset();
Jamie Madillb8e39662018-04-04 11:41:42 -0400352 mDirtyLineLoopTranslation = true;
Jamie Madill09463932018-04-04 05:26:59 -0400353 break;
354
Jamie Madill80766cf2019-01-10 10:20:34 -0500355#define ANGLE_VERTEX_DIRTY_ATTRIB_FUNC(INDEX) \
356 case gl::VertexArray::DIRTY_BIT_ATTRIB_0 + INDEX: \
357 ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
358 bindings[attribs[INDEX].bindingIndex], INDEX)); \
359 invalidateContext = true; \
Jamie Madillc759b8b2019-01-03 15:16:50 -0500360 (*attribBits)[INDEX].reset(); \
Jamie Madill80766cf2019-01-10 10:20:34 -0500361 break;
362
Jamie Madilla56467e2018-04-11 16:19:41 -0400363 ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_ATTRIB_FUNC);
Jamie Madill80766cf2019-01-10 10:20:34 -0500364
365#define ANGLE_VERTEX_DIRTY_BINDING_FUNC(INDEX) \
366 case gl::VertexArray::DIRTY_BIT_BINDING_0 + INDEX: \
367 ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
368 bindings[attribs[INDEX].bindingIndex], INDEX)); \
369 invalidateContext = true; \
Jamie Madillc759b8b2019-01-03 15:16:50 -0500370 (*bindingBits)[INDEX].reset(); \
Jamie Madill80766cf2019-01-10 10:20:34 -0500371 break;
372
Jamie Madilla56467e2018-04-11 16:19:41 -0400373 ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BINDING_FUNC);
Jamie Madill80766cf2019-01-10 10:20:34 -0500374
375#define ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC(INDEX) \
376 case gl::VertexArray::DIRTY_BIT_BUFFER_DATA_0 + INDEX: \
377 ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
378 bindings[attribs[INDEX].bindingIndex], INDEX)); \
379 break;
380
Jamie Madilla56467e2018-04-11 16:19:41 -0400381 ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC);
382
Jamie Madill09463932018-04-04 05:26:59 -0400383 default:
Jamie Madilla56467e2018-04-11 16:19:41 -0400384 UNREACHABLE();
Jamie Madill09463932018-04-04 05:26:59 -0400385 break;
Jamie Madillbd159f02017-10-09 19:39:06 -0400386 }
387 }
Frank Henigman0af5b862018-03-27 20:19:33 -0400388
Jamie Madillbc5834c2018-11-06 11:13:50 -0500389 if (invalidateContext)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400390 {
Jamie Madillbc5834c2018-11-06 11:13:50 -0500391 contextVk->invalidateVertexAndIndexBuffers();
Jamie Madillc3755fc2018-04-05 08:39:13 -0400392 }
393
Jamie Madill7c985f52018-11-29 18:16:17 -0500394 return angle::Result::Continue;
Jamie Madillbd159f02017-10-09 19:39:06 -0400395}
396
Jamie Madill80766cf2019-01-10 10:20:34 -0500397ANGLE_INLINE void VertexArrayVk::setPackedInputInfo(ContextVk *contextVk,
398 size_t attribIndex,
399 const gl::VertexAttribute &attrib,
400 const gl::VertexBinding &binding)
401{
402 ASSERT(attrib.enabled);
403 contextVk->onVertexAttributeChange(
404 attribIndex, mCurrentArrayBufferStrides[attribIndex], binding.getDivisor(),
405 mCurrentArrayBufferFormats[attribIndex]->vkBufferFormat, attrib.relativeOffset);
406}
407
408ANGLE_INLINE void VertexArrayVk::setDefaultPackedInput(ContextVk *contextVk, size_t attribIndex)
409{
410 contextVk->onVertexAttributeChange(attribIndex, 0, 0, VK_FORMAT_R32G32B32A32_SFLOAT, 0);
411}
412
Frank Henigmane4523822018-07-19 16:10:53 -0400413angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
414 const gl::VertexAttribute &attrib,
415 const gl::VertexBinding &binding,
416 size_t attribIndex)
Jamie Madilla56467e2018-04-11 16:19:41 -0400417{
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100418 RendererVk *renderer = contextVk->getRenderer();
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100419 bool anyVertexBufferConvertedOnGpu = false;
Jamie Madill5a4c9322018-07-16 11:01:58 -0400420
Jamie Madilla56467e2018-04-11 16:19:41 -0400421 if (attrib.enabled)
422 {
Frank Henigman67c388e2018-07-19 19:16:11 -0400423 gl::Buffer *bufferGL = binding.getBuffer().get();
Frank Henigman419acc82018-06-24 19:57:31 -0400424 mCurrentArrayBufferFormats[attribIndex] = &renderer->getFormat(GetVertexFormatID(attrib));
Frank Henigmane4523822018-07-19 16:10:53 -0400425
Jamie Madilla56467e2018-04-11 16:19:41 -0400426 if (bufferGL)
427 {
Frank Henigmane4523822018-07-19 16:10:53 -0400428 BufferVk *bufferVk = vk::GetImpl(bufferGL);
Jamie Madilldbc605c2019-01-04 16:39:14 -0500429 const angle::Format &angleFormat =
430 mCurrentArrayBufferFormats[attribIndex]->angleFormat();
431 bool bindingIsAligned = BindingIsAligned(binding, angleFormat, attrib.size);
Frank Henigman419acc82018-06-24 19:57:31 -0400432
Frank Henigmane4523822018-07-19 16:10:53 -0400433 if (mCurrentArrayBufferFormats[attribIndex]->vertexLoadRequiresConversion ||
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100434 !bindingIsAligned)
Frank Henigmane4523822018-07-19 16:10:53 -0400435 {
Jamie Madilla064c272018-08-30 16:18:34 -0400436 mCurrentArrayBufferStrides[attribIndex] =
437 mCurrentArrayBufferFormats[attribIndex]->bufferFormat().pixelBytes;
438
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100439 if (bindingIsAligned)
440 {
441 ANGLE_TRY(convertVertexBufferGpu(contextVk, bufferVk, binding, attribIndex));
442 anyVertexBufferConvertedOnGpu = true;
443 }
444 else
445 {
446 // TODO(syoussefi): Implement unaligned vertex buffer conversions in compute.
447 // http://anglebug.com/3009
448 ANGLE_TRY(convertVertexBufferCpu(contextVk, bufferVk, binding, attribIndex));
449 }
Frank Henigmane4523822018-07-19 16:10:53 -0400450 }
451 else
452 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500453 mCurrentArrayBuffers[attribIndex] = &bufferVk->getBuffer();
Jamie Madill2d03ff42018-09-27 15:04:26 -0400454 mCurrentArrayBufferHandles[attribIndex] =
455 bufferVk->getBuffer().getBuffer().getHandle();
Jamie Madill77abad82018-10-25 17:03:48 -0400456 mCurrentArrayBufferOffsets[attribIndex] = binding.getOffset();
457 mCurrentArrayBufferStrides[attribIndex] = binding.getStride();
Jamie Madillc759b8b2019-01-03 15:16:50 -0500458 ensureConversionReleased(renderer, attribIndex);
Frank Henigmane4523822018-07-19 16:10:53 -0400459 }
Jamie Madilla56467e2018-04-11 16:19:41 -0400460 }
461 else
462 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500463 mCurrentArrayBuffers[attribIndex] = nullptr;
Jamie Madillc759b8b2019-01-03 15:16:50 -0500464 mCurrentArrayBufferHandles[attribIndex] = mTheNullBuffer.getBuffer().getHandle();
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500465 mCurrentArrayBufferOffsets[attribIndex] = 0;
Frank Henigman419acc82018-06-24 19:57:31 -0400466 mCurrentArrayBufferStrides[attribIndex] =
Frank Henigmane4523822018-07-19 16:10:53 -0400467 mCurrentArrayBufferFormats[attribIndex]->bufferFormat().pixelBytes;
Jamie Madillc759b8b2019-01-03 15:16:50 -0500468 ensureConversionReleased(renderer, attribIndex);
Jamie Madilla56467e2018-04-11 16:19:41 -0400469 }
Jamie Madill80766cf2019-01-10 10:20:34 -0500470
471 setPackedInputInfo(contextVk, attribIndex, attrib, binding);
Jamie Madilla56467e2018-04-11 16:19:41 -0400472 }
473 else
474 {
Jamie Madill5a4c9322018-07-16 11:01:58 -0400475 contextVk->invalidateDefaultAttribute(attribIndex);
476
477 // These will be filled out by the ContextVk.
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500478 mCurrentArrayBuffers[attribIndex] = nullptr;
Jamie Madillc759b8b2019-01-03 15:16:50 -0500479 mCurrentArrayBufferHandles[attribIndex] = mTheNullBuffer.getBuffer().getHandle();
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500480 mCurrentArrayBufferOffsets[attribIndex] = 0;
481 mCurrentArrayBufferStrides[attribIndex] = 0;
Jamie Madill5a4c9322018-07-16 11:01:58 -0400482 mCurrentArrayBufferFormats[attribIndex] =
Jamie Madillba365932018-07-18 17:23:46 -0400483 &renderer->getFormat(angle::FormatID::R32G32B32A32_FLOAT);
Jamie Madill80766cf2019-01-10 10:20:34 -0500484
485 setDefaultPackedInput(contextVk, attribIndex);
Jamie Madillc759b8b2019-01-03 15:16:50 -0500486 ensureConversionReleased(renderer, attribIndex);
Jamie Madilla56467e2018-04-11 16:19:41 -0400487 }
Frank Henigmane4523822018-07-19 16:10:53 -0400488
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100489 if (anyVertexBufferConvertedOnGpu && renderer->getFeatures().flushAfterVertexConversion)
490 {
491 ANGLE_TRY(renderer->flush(contextVk));
492 }
493
Jamie Madill7c985f52018-11-29 18:16:17 -0500494 return angle::Result::Continue;
Jamie Madilla56467e2018-04-11 16:19:41 -0400495}
496
Jamie Madill88fc6da2018-08-30 16:18:36 -0400497angle::Result VertexArrayVk::updateClientAttribs(const gl::Context *context,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400498 GLint firstVertex,
499 GLsizei vertexOrIndexCount,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500500 gl::DrawElementsType indexTypeOrInvalid,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400501 const void *indices)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400502{
Jamie Madill77abad82018-10-25 17:03:48 -0400503 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400504 const gl::AttributesMask &clientAttribs = context->getStateCache().getActiveClientAttribsMask();
Jamie Madill21061022018-07-12 23:56:30 -0400505
Jamie Madill88fc6da2018-08-30 16:18:36 -0400506 ASSERT(clientAttribs.any());
Jamie Madillc1fd7372018-10-26 22:48:39 -0400507
508 GLint startVertex;
509 size_t vertexCount;
Jamie Madill8dc27f92018-11-29 11:45:44 -0500510 ANGLE_TRY(GetVertexRangeInfo(context, firstVertex, vertexOrIndexCount, indexTypeOrInvalid,
511 indices, 0, &startVertex, &vertexCount));
Jamie Madill88fc6da2018-08-30 16:18:36 -0400512
513 mDynamicVertexData.releaseRetainedBuffers(contextVk->getRenderer());
514
515 const auto &attribs = mState.getVertexAttributes();
516 const auto &bindings = mState.getVertexBindings();
517
518 // TODO(fjhenigman): When we have a bunch of interleaved attributes, they end up
519 // un-interleaved, wasting space and copying time. Consider improving on that.
520 for (size_t attribIndex : clientAttribs)
521 {
522 const gl::VertexAttribute &attrib = attribs[attribIndex];
523 const gl::VertexBinding &binding = bindings[attrib.bindingIndex];
524 ASSERT(attrib.enabled && binding.getBuffer().get() == nullptr);
525
526 const size_t bytesToAllocate =
Jamie Madillc1fd7372018-10-26 22:48:39 -0400527 (startVertex + vertexCount) * mCurrentArrayBufferStrides[attribIndex];
528 const uint8_t *src =
529 static_cast<const uint8_t *>(attrib.pointer) + startVertex * binding.getStride();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400530
Jamie Madillc1fd7372018-10-26 22:48:39 -0400531 size_t destOffset = startVertex * mCurrentArrayBufferStrides[attribIndex];
jchen105dc0a6f2018-09-20 14:30:45 +0800532 ASSERT(GetVertexInputAlignment(*mCurrentArrayBufferFormats[attribIndex]) <=
533 kMaxVertexFormatAlignment);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400534
535 // Only vertexCount() vertices will be used by the upcoming draw. so that is all we copy.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400536 // We allocate space for startVertex + vertexCount so indexing will work. If we
Jamie Madill88fc6da2018-08-30 16:18:36 -0400537 // don't start at zero all the indices will be off.
538 // TODO(fjhenigman): See if we can account for indices being off by adjusting the
539 // offset, thus avoiding wasted memory.
Jamie Madillc1fd7372018-10-26 22:48:39 -0400540 ANGLE_TRY(StreamVertexData(
541 contextVk, &mDynamicVertexData, src, bytesToAllocate, destOffset, vertexCount,
542 binding.getStride(), mCurrentArrayBufferFormats[attribIndex]->vertexLoadFunction,
Shahbaz Youssefiec063052018-12-06 01:58:06 +0100543 &mCurrentArrayBuffers[attribIndex], &mCurrentArrayBufferOffsets[attribIndex]));
544 mCurrentArrayBufferHandles[attribIndex] =
545 mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400546 }
547
Jamie Madill7c985f52018-11-29 18:16:17 -0500548 return angle::Result::Continue;
Jamie Madill88fc6da2018-08-30 16:18:36 -0400549}
550
551angle::Result VertexArrayVk::handleLineLoop(ContextVk *contextVk,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400552 GLint firstVertex,
553 GLsizei vertexOrIndexCount,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500554 gl::DrawElementsType indexTypeOrInvalid,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400555 const void *indices)
Jamie Madill88fc6da2018-08-30 16:18:36 -0400556{
Jamie Madill8dc27f92018-11-29 11:45:44 -0500557 if (indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
Jamie Madill88fc6da2018-08-30 16:18:36 -0400558 {
559 // Handle GL_LINE_LOOP drawElements.
560 if (mDirtyLineLoopTranslation)
561 {
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400562 gl::Buffer *elementArrayBuffer = mState.getElementArrayBuffer();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400563
564 if (!elementArrayBuffer)
565 {
Frank Henigman85c4b432018-09-19 23:35:00 -0400566 ANGLE_TRY(mLineLoopHelper.streamIndices(
Jamie Madill8dc27f92018-11-29 11:45:44 -0500567 contextVk, indexTypeOrInvalid, vertexOrIndexCount,
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500568 reinterpret_cast<const uint8_t *>(indices), &mCurrentElementArrayBuffer,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400569 &mCurrentElementArrayBufferOffset));
Jamie Madill88fc6da2018-08-30 16:18:36 -0400570 }
571 else
572 {
573 // When using an element array buffer, 'indices' is an offset to the first element.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400574 intptr_t offset = reinterpret_cast<intptr_t>(indices);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400575 BufferVk *elementArrayBufferVk = vk::GetImpl(elementArrayBuffer);
576 ANGLE_TRY(mLineLoopHelper.getIndexBufferForElementArrayBuffer(
Jamie Madill8dc27f92018-11-29 11:45:44 -0500577 contextVk, elementArrayBufferVk, indexTypeOrInvalid, vertexOrIndexCount, offset,
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500578 &mCurrentElementArrayBuffer, &mCurrentElementArrayBufferOffset));
Jamie Madill88fc6da2018-08-30 16:18:36 -0400579 }
580 }
581
582 // If we've had a drawArrays call with a line loop before, we want to make sure this is
583 // invalidated the next time drawArrays is called since we use the same index buffer for
584 // both calls.
585 mLineLoopBufferFirstIndex.reset();
586 mLineLoopBufferLastIndex.reset();
Jamie Madill7c985f52018-11-29 18:16:17 -0500587 return angle::Result::Continue;
Jamie Madill88fc6da2018-08-30 16:18:36 -0400588 }
Jamie Madillc3755fc2018-04-05 08:39:13 -0400589
Jamie Madill18e323a2018-05-11 16:54:17 -0400590 // Note: Vertex indexes can be arbitrarily large.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400591 uint32_t clampedVertexCount = gl::clampCast<uint32_t>(vertexOrIndexCount);
Jamie Madill18e323a2018-05-11 16:54:17 -0400592
Jamie Madillc3755fc2018-04-05 08:39:13 -0400593 // Handle GL_LINE_LOOP drawArrays.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400594 size_t lastVertex = static_cast<size_t>(firstVertex + clampedVertexCount);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400595 if (!mLineLoopBufferFirstIndex.valid() || !mLineLoopBufferLastIndex.valid() ||
Jamie Madillbfe31c42018-10-25 17:03:47 -0400596 mLineLoopBufferFirstIndex != firstVertex || mLineLoopBufferLastIndex != lastVertex)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400597 {
Jamie Madillbfe31c42018-10-25 17:03:47 -0400598 ANGLE_TRY(mLineLoopHelper.getIndexBufferForDrawArrays(
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500599 contextVk, clampedVertexCount, firstVertex, &mCurrentElementArrayBuffer,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400600 &mCurrentElementArrayBufferOffset));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400601
Jamie Madillbfe31c42018-10-25 17:03:47 -0400602 mLineLoopBufferFirstIndex = firstVertex;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400603 mLineLoopBufferLastIndex = lastVertex;
604 }
605
Jamie Madill7c985f52018-11-29 18:16:17 -0500606 return angle::Result::Continue;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400607}
608
Jamie Madill88fc6da2018-08-30 16:18:36 -0400609angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400610 GLsizei indexCount,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500611 gl::DrawElementsType type,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400612 const void *indices)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400613{
Jamie Madill8dc27f92018-11-29 11:45:44 -0500614 ASSERT(type != gl::DrawElementsType::InvalidEnum);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400615
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500616 RendererVk *renderer = contextVk->getRenderer();
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400617 gl::Buffer *glBuffer = mState.getElementArrayBuffer();
Jamie Madillc3755fc2018-04-05 08:39:13 -0400618
Jamie Madill88fc6da2018-08-30 16:18:36 -0400619 if (!glBuffer)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400620 {
Jamie Madillbfe31c42018-10-25 17:03:47 -0400621 ANGLE_TRY(streamIndexData(contextVk, type, indexCount, indices, &mDynamicIndexData));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400622 }
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500623 else if (renderer->getFormat(angle::FormatID::R16_UINT).vkSupportsStorageBuffer)
624 {
625 BufferVk *bufferVk = vk::GetImpl(glBuffer);
626
627 ASSERT(type == gl::DrawElementsType::UnsignedByte);
628
629 intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices);
630 size_t srcDataSize = static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData;
631
632 mTranslatedByteIndexData.releaseRetainedBuffers(renderer);
633
634 ANGLE_TRY(mTranslatedByteIndexData.allocate(contextVk, sizeof(GLushort) * srcDataSize,
635 nullptr, nullptr,
636 &mCurrentElementArrayBufferOffset, nullptr));
637 mCurrentElementArrayBuffer = mTranslatedByteIndexData.getCurrentBuffer();
638
639 vk::BufferHelper *dest = mTranslatedByteIndexData.getCurrentBuffer();
640 vk::BufferHelper *src = &bufferVk->getBuffer();
641
642 ANGLE_TRY(src->initBufferView(contextVk, renderer->getFormat(angle::FormatID::R8_UINT)));
643 ANGLE_TRY(dest->initBufferView(contextVk, renderer->getFormat(angle::FormatID::R16_UINT)));
644
645 // Copy relevant section of the source into destination at allocated offset. Note that the
646 // offset returned by allocate() above is in bytes, while our allocated array is of
647 // GLushorts.
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100648 UtilsVk::CopyParameters params = {};
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500649 params.destOffset =
650 static_cast<size_t>(mCurrentElementArrayBufferOffset) / sizeof(GLushort);
651 params.srcOffset = offsetIntoSrcData;
652 params.size = srcDataSize;
653
654 // Note: this is a copy, which implicitly converts between formats. Once support for
655 // primitive restart is added, a specialized shader is likely needed to special case 0xFF ->
656 // 0xFFFF.
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100657 ANGLE_TRY(renderer->getUtils().copyBuffer(contextVk, dest, src, params));
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500658 }
Jamie Madill88fc6da2018-08-30 16:18:36 -0400659 else
Jamie Madillc3755fc2018-04-05 08:39:13 -0400660 {
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500661 // If it's not possible to convert the buffer with compute, opt for a CPU read back for now.
662 // TODO(syoussefi): R8G8B8A8_UINT is required to have storage texel buffer support, so a
663 // specialized shader code can be made to read two ubyte indices and output them in R and B
664 // (or A and G based on endianness?) with 0 on the other channels. If specialized, we might
665 // as well support the ubyte to ushort case with correct handling of primitive restart.
666 // http://anglebug.com/3003
667
Frank Henigman9d84ccb2018-09-12 18:09:02 -0400668 // Needed before reading buffer or we could get stale data.
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500669 ANGLE_TRY(renderer->finish(contextVk));
Frank Henigman9d84ccb2018-09-12 18:09:02 -0400670
Jamie Madill8dc27f92018-11-29 11:45:44 -0500671 ASSERT(type == gl::DrawElementsType::UnsignedByte);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400672 // Unsigned bytes don't have direct support in Vulkan so we have to expand the
673 // memory to a GLushort.
674 BufferVk *bufferVk = vk::GetImpl(glBuffer);
675 void *srcDataMapping = nullptr;
676 ASSERT(!glBuffer->isMapped());
677 ANGLE_TRY(bufferVk->mapImpl(contextVk, &srcDataMapping));
678 uint8_t *srcData = static_cast<uint8_t *>(srcDataMapping);
Jamie Madillbfe31c42018-10-25 17:03:47 -0400679 intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400680 srcData += offsetIntoSrcData;
Jamie Madill253038d2018-08-30 16:18:35 -0400681
Jamie Madillbfe31c42018-10-25 17:03:47 -0400682 ANGLE_TRY(streamIndexData(contextVk, type,
Jamie Madill88fc6da2018-08-30 16:18:36 -0400683 static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData,
684 srcData, &mTranslatedByteIndexData));
Luc Ferron6ed167a2018-06-13 13:45:55 -0400685
Jamie Madill88fc6da2018-08-30 16:18:36 -0400686 ANGLE_TRY(bufferVk->unmapImpl(contextVk));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400687 }
688
Jamie Madill7c985f52018-11-29 18:16:17 -0500689 return angle::Result::Continue;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400690}
Jamie Madill5a4c9322018-07-16 11:01:58 -0400691
Jamie Madill80766cf2019-01-10 10:20:34 -0500692void VertexArrayVk::updateDefaultAttrib(ContextVk *contextVk,
Jamie Madill5a4c9322018-07-16 11:01:58 -0400693 size_t attribIndex,
694 VkBuffer bufferHandle,
695 uint32_t offset)
696{
697 if (!mState.getEnabledAttributesMask().test(attribIndex))
698 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500699 mCurrentArrayBufferHandles[attribIndex] = bufferHandle;
700 mCurrentArrayBufferOffsets[attribIndex] = offset;
701 mCurrentArrayBuffers[attribIndex] = nullptr;
702 mCurrentArrayBufferStrides[attribIndex] = 0;
Jamie Madill5a4c9322018-07-16 11:01:58 -0400703 mCurrentArrayBufferFormats[attribIndex] =
Jamie Madill80766cf2019-01-10 10:20:34 -0500704 &contextVk->getRenderer()->getFormat(angle::FormatID::R32G32B32A32_FIXED);
705
706 setDefaultPackedInput(contextVk, attribIndex);
Jamie Madill5a4c9322018-07-16 11:01:58 -0400707 }
708}
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400709} // namespace rx