blob: af63f4036d9b80267b2f4390dd3c3b014cf9f542 [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 Madill17a50e12019-01-10 22:05:43 -0500453 if (bufferVk->getSize() == 0)
454 {
455 mCurrentArrayBuffers[attribIndex] = nullptr;
456 mCurrentArrayBufferHandles[attribIndex] =
457 mTheNullBuffer.getBuffer().getHandle();
458 mCurrentArrayBufferOffsets[attribIndex] = 0;
459 mCurrentArrayBufferStrides[attribIndex] = 0;
460 }
461 else
462 {
463 mCurrentArrayBuffers[attribIndex] = &bufferVk->getBuffer();
464 mCurrentArrayBufferHandles[attribIndex] =
465 bufferVk->getBuffer().getBuffer().getHandle();
466 mCurrentArrayBufferOffsets[attribIndex] = binding.getOffset();
467 mCurrentArrayBufferStrides[attribIndex] = binding.getStride();
468 }
469
Jamie Madillc759b8b2019-01-03 15:16:50 -0500470 ensureConversionReleased(renderer, attribIndex);
Frank Henigmane4523822018-07-19 16:10:53 -0400471 }
Jamie Madilla56467e2018-04-11 16:19:41 -0400472 }
473 else
474 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500475 mCurrentArrayBuffers[attribIndex] = nullptr;
Jamie Madillc759b8b2019-01-03 15:16:50 -0500476 mCurrentArrayBufferHandles[attribIndex] = mTheNullBuffer.getBuffer().getHandle();
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500477 mCurrentArrayBufferOffsets[attribIndex] = 0;
Frank Henigman419acc82018-06-24 19:57:31 -0400478 mCurrentArrayBufferStrides[attribIndex] =
Frank Henigmane4523822018-07-19 16:10:53 -0400479 mCurrentArrayBufferFormats[attribIndex]->bufferFormat().pixelBytes;
Jamie Madillc759b8b2019-01-03 15:16:50 -0500480 ensureConversionReleased(renderer, attribIndex);
Jamie Madilla56467e2018-04-11 16:19:41 -0400481 }
Jamie Madill80766cf2019-01-10 10:20:34 -0500482
483 setPackedInputInfo(contextVk, attribIndex, attrib, binding);
Jamie Madilla56467e2018-04-11 16:19:41 -0400484 }
485 else
486 {
Jamie Madill5a4c9322018-07-16 11:01:58 -0400487 contextVk->invalidateDefaultAttribute(attribIndex);
488
489 // These will be filled out by the ContextVk.
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500490 mCurrentArrayBuffers[attribIndex] = nullptr;
Jamie Madillc759b8b2019-01-03 15:16:50 -0500491 mCurrentArrayBufferHandles[attribIndex] = mTheNullBuffer.getBuffer().getHandle();
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500492 mCurrentArrayBufferOffsets[attribIndex] = 0;
493 mCurrentArrayBufferStrides[attribIndex] = 0;
Jamie Madill5a4c9322018-07-16 11:01:58 -0400494 mCurrentArrayBufferFormats[attribIndex] =
Jamie Madillba365932018-07-18 17:23:46 -0400495 &renderer->getFormat(angle::FormatID::R32G32B32A32_FLOAT);
Jamie Madill80766cf2019-01-10 10:20:34 -0500496
497 setDefaultPackedInput(contextVk, attribIndex);
Jamie Madillc759b8b2019-01-03 15:16:50 -0500498 ensureConversionReleased(renderer, attribIndex);
Jamie Madilla56467e2018-04-11 16:19:41 -0400499 }
Frank Henigmane4523822018-07-19 16:10:53 -0400500
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100501 if (anyVertexBufferConvertedOnGpu && renderer->getFeatures().flushAfterVertexConversion)
502 {
503 ANGLE_TRY(renderer->flush(contextVk));
504 }
505
Jamie Madill7c985f52018-11-29 18:16:17 -0500506 return angle::Result::Continue;
Jamie Madilla56467e2018-04-11 16:19:41 -0400507}
508
Jamie Madill88fc6da2018-08-30 16:18:36 -0400509angle::Result VertexArrayVk::updateClientAttribs(const gl::Context *context,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400510 GLint firstVertex,
511 GLsizei vertexOrIndexCount,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500512 gl::DrawElementsType indexTypeOrInvalid,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400513 const void *indices)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400514{
Jamie Madill77abad82018-10-25 17:03:48 -0400515 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400516 const gl::AttributesMask &clientAttribs = context->getStateCache().getActiveClientAttribsMask();
Jamie Madill21061022018-07-12 23:56:30 -0400517
Jamie Madill88fc6da2018-08-30 16:18:36 -0400518 ASSERT(clientAttribs.any());
Jamie Madillc1fd7372018-10-26 22:48:39 -0400519
520 GLint startVertex;
521 size_t vertexCount;
Jamie Madill8dc27f92018-11-29 11:45:44 -0500522 ANGLE_TRY(GetVertexRangeInfo(context, firstVertex, vertexOrIndexCount, indexTypeOrInvalid,
523 indices, 0, &startVertex, &vertexCount));
Jamie Madill88fc6da2018-08-30 16:18:36 -0400524
525 mDynamicVertexData.releaseRetainedBuffers(contextVk->getRenderer());
526
527 const auto &attribs = mState.getVertexAttributes();
528 const auto &bindings = mState.getVertexBindings();
529
530 // TODO(fjhenigman): When we have a bunch of interleaved attributes, they end up
531 // un-interleaved, wasting space and copying time. Consider improving on that.
532 for (size_t attribIndex : clientAttribs)
533 {
534 const gl::VertexAttribute &attrib = attribs[attribIndex];
535 const gl::VertexBinding &binding = bindings[attrib.bindingIndex];
536 ASSERT(attrib.enabled && binding.getBuffer().get() == nullptr);
537
538 const size_t bytesToAllocate =
Jamie Madillc1fd7372018-10-26 22:48:39 -0400539 (startVertex + vertexCount) * mCurrentArrayBufferStrides[attribIndex];
540 const uint8_t *src =
541 static_cast<const uint8_t *>(attrib.pointer) + startVertex * binding.getStride();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400542
Jamie Madillc1fd7372018-10-26 22:48:39 -0400543 size_t destOffset = startVertex * mCurrentArrayBufferStrides[attribIndex];
jchen105dc0a6f2018-09-20 14:30:45 +0800544 ASSERT(GetVertexInputAlignment(*mCurrentArrayBufferFormats[attribIndex]) <=
545 kMaxVertexFormatAlignment);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400546
547 // Only vertexCount() vertices will be used by the upcoming draw. so that is all we copy.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400548 // We allocate space for startVertex + vertexCount so indexing will work. If we
Jamie Madill88fc6da2018-08-30 16:18:36 -0400549 // don't start at zero all the indices will be off.
550 // TODO(fjhenigman): See if we can account for indices being off by adjusting the
551 // offset, thus avoiding wasted memory.
Jamie Madillc1fd7372018-10-26 22:48:39 -0400552 ANGLE_TRY(StreamVertexData(
553 contextVk, &mDynamicVertexData, src, bytesToAllocate, destOffset, vertexCount,
554 binding.getStride(), mCurrentArrayBufferFormats[attribIndex]->vertexLoadFunction,
Shahbaz Youssefiec063052018-12-06 01:58:06 +0100555 &mCurrentArrayBuffers[attribIndex], &mCurrentArrayBufferOffsets[attribIndex]));
556 mCurrentArrayBufferHandles[attribIndex] =
557 mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400558 }
559
Jamie Madill7c985f52018-11-29 18:16:17 -0500560 return angle::Result::Continue;
Jamie Madill88fc6da2018-08-30 16:18:36 -0400561}
562
563angle::Result VertexArrayVk::handleLineLoop(ContextVk *contextVk,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400564 GLint firstVertex,
565 GLsizei vertexOrIndexCount,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500566 gl::DrawElementsType indexTypeOrInvalid,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400567 const void *indices)
Jamie Madill88fc6da2018-08-30 16:18:36 -0400568{
Jamie Madill8dc27f92018-11-29 11:45:44 -0500569 if (indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
Jamie Madill88fc6da2018-08-30 16:18:36 -0400570 {
571 // Handle GL_LINE_LOOP drawElements.
572 if (mDirtyLineLoopTranslation)
573 {
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400574 gl::Buffer *elementArrayBuffer = mState.getElementArrayBuffer();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400575
576 if (!elementArrayBuffer)
577 {
Frank Henigman85c4b432018-09-19 23:35:00 -0400578 ANGLE_TRY(mLineLoopHelper.streamIndices(
Jamie Madill8dc27f92018-11-29 11:45:44 -0500579 contextVk, indexTypeOrInvalid, vertexOrIndexCount,
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500580 reinterpret_cast<const uint8_t *>(indices), &mCurrentElementArrayBuffer,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400581 &mCurrentElementArrayBufferOffset));
Jamie Madill88fc6da2018-08-30 16:18:36 -0400582 }
583 else
584 {
585 // When using an element array buffer, 'indices' is an offset to the first element.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400586 intptr_t offset = reinterpret_cast<intptr_t>(indices);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400587 BufferVk *elementArrayBufferVk = vk::GetImpl(elementArrayBuffer);
588 ANGLE_TRY(mLineLoopHelper.getIndexBufferForElementArrayBuffer(
Jamie Madill8dc27f92018-11-29 11:45:44 -0500589 contextVk, elementArrayBufferVk, indexTypeOrInvalid, vertexOrIndexCount, offset,
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500590 &mCurrentElementArrayBuffer, &mCurrentElementArrayBufferOffset));
Jamie Madill88fc6da2018-08-30 16:18:36 -0400591 }
592 }
593
594 // If we've had a drawArrays call with a line loop before, we want to make sure this is
595 // invalidated the next time drawArrays is called since we use the same index buffer for
596 // both calls.
597 mLineLoopBufferFirstIndex.reset();
598 mLineLoopBufferLastIndex.reset();
Jamie Madill7c985f52018-11-29 18:16:17 -0500599 return angle::Result::Continue;
Jamie Madill88fc6da2018-08-30 16:18:36 -0400600 }
Jamie Madillc3755fc2018-04-05 08:39:13 -0400601
Jamie Madill18e323a2018-05-11 16:54:17 -0400602 // Note: Vertex indexes can be arbitrarily large.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400603 uint32_t clampedVertexCount = gl::clampCast<uint32_t>(vertexOrIndexCount);
Jamie Madill18e323a2018-05-11 16:54:17 -0400604
Jamie Madillc3755fc2018-04-05 08:39:13 -0400605 // Handle GL_LINE_LOOP drawArrays.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400606 size_t lastVertex = static_cast<size_t>(firstVertex + clampedVertexCount);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400607 if (!mLineLoopBufferFirstIndex.valid() || !mLineLoopBufferLastIndex.valid() ||
Jamie Madillbfe31c42018-10-25 17:03:47 -0400608 mLineLoopBufferFirstIndex != firstVertex || mLineLoopBufferLastIndex != lastVertex)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400609 {
Jamie Madillbfe31c42018-10-25 17:03:47 -0400610 ANGLE_TRY(mLineLoopHelper.getIndexBufferForDrawArrays(
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500611 contextVk, clampedVertexCount, firstVertex, &mCurrentElementArrayBuffer,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400612 &mCurrentElementArrayBufferOffset));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400613
Jamie Madillbfe31c42018-10-25 17:03:47 -0400614 mLineLoopBufferFirstIndex = firstVertex;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400615 mLineLoopBufferLastIndex = lastVertex;
616 }
617
Jamie Madill7c985f52018-11-29 18:16:17 -0500618 return angle::Result::Continue;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400619}
620
Jamie Madill88fc6da2018-08-30 16:18:36 -0400621angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400622 GLsizei indexCount,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500623 gl::DrawElementsType type,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400624 const void *indices)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400625{
Jamie Madill8dc27f92018-11-29 11:45:44 -0500626 ASSERT(type != gl::DrawElementsType::InvalidEnum);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400627
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500628 RendererVk *renderer = contextVk->getRenderer();
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400629 gl::Buffer *glBuffer = mState.getElementArrayBuffer();
Jamie Madillc3755fc2018-04-05 08:39:13 -0400630
Jamie Madill88fc6da2018-08-30 16:18:36 -0400631 if (!glBuffer)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400632 {
Jamie Madillbfe31c42018-10-25 17:03:47 -0400633 ANGLE_TRY(streamIndexData(contextVk, type, indexCount, indices, &mDynamicIndexData));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400634 }
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500635 else if (renderer->getFormat(angle::FormatID::R16_UINT).vkSupportsStorageBuffer)
636 {
637 BufferVk *bufferVk = vk::GetImpl(glBuffer);
638
639 ASSERT(type == gl::DrawElementsType::UnsignedByte);
640
641 intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices);
642 size_t srcDataSize = static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData;
643
644 mTranslatedByteIndexData.releaseRetainedBuffers(renderer);
645
646 ANGLE_TRY(mTranslatedByteIndexData.allocate(contextVk, sizeof(GLushort) * srcDataSize,
647 nullptr, nullptr,
648 &mCurrentElementArrayBufferOffset, nullptr));
649 mCurrentElementArrayBuffer = mTranslatedByteIndexData.getCurrentBuffer();
650
651 vk::BufferHelper *dest = mTranslatedByteIndexData.getCurrentBuffer();
652 vk::BufferHelper *src = &bufferVk->getBuffer();
653
654 ANGLE_TRY(src->initBufferView(contextVk, renderer->getFormat(angle::FormatID::R8_UINT)));
655 ANGLE_TRY(dest->initBufferView(contextVk, renderer->getFormat(angle::FormatID::R16_UINT)));
656
657 // Copy relevant section of the source into destination at allocated offset. Note that the
658 // offset returned by allocate() above is in bytes, while our allocated array is of
659 // GLushorts.
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100660 UtilsVk::CopyParameters params = {};
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500661 params.destOffset =
662 static_cast<size_t>(mCurrentElementArrayBufferOffset) / sizeof(GLushort);
663 params.srcOffset = offsetIntoSrcData;
664 params.size = srcDataSize;
665
666 // Note: this is a copy, which implicitly converts between formats. Once support for
667 // primitive restart is added, a specialized shader is likely needed to special case 0xFF ->
668 // 0xFFFF.
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100669 ANGLE_TRY(renderer->getUtils().copyBuffer(contextVk, dest, src, params));
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500670 }
Jamie Madill88fc6da2018-08-30 16:18:36 -0400671 else
Jamie Madillc3755fc2018-04-05 08:39:13 -0400672 {
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500673 // If it's not possible to convert the buffer with compute, opt for a CPU read back for now.
674 // TODO(syoussefi): R8G8B8A8_UINT is required to have storage texel buffer support, so a
675 // specialized shader code can be made to read two ubyte indices and output them in R and B
676 // (or A and G based on endianness?) with 0 on the other channels. If specialized, we might
677 // as well support the ubyte to ushort case with correct handling of primitive restart.
678 // http://anglebug.com/3003
679
Frank Henigman9d84ccb2018-09-12 18:09:02 -0400680 // Needed before reading buffer or we could get stale data.
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500681 ANGLE_TRY(renderer->finish(contextVk));
Frank Henigman9d84ccb2018-09-12 18:09:02 -0400682
Jamie Madill8dc27f92018-11-29 11:45:44 -0500683 ASSERT(type == gl::DrawElementsType::UnsignedByte);
Jamie Madill88fc6da2018-08-30 16:18:36 -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());
689 ANGLE_TRY(bufferVk->mapImpl(contextVk, &srcDataMapping));
690 uint8_t *srcData = static_cast<uint8_t *>(srcDataMapping);
Jamie Madillbfe31c42018-10-25 17:03:47 -0400691 intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400692 srcData += offsetIntoSrcData;
Jamie Madill253038d2018-08-30 16:18:35 -0400693
Jamie Madillbfe31c42018-10-25 17:03:47 -0400694 ANGLE_TRY(streamIndexData(contextVk, type,
Jamie Madill88fc6da2018-08-30 16:18:36 -0400695 static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData,
696 srcData, &mTranslatedByteIndexData));
Luc Ferron6ed167a2018-06-13 13:45:55 -0400697
Jamie Madill88fc6da2018-08-30 16:18:36 -0400698 ANGLE_TRY(bufferVk->unmapImpl(contextVk));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400699 }
700
Jamie Madill7c985f52018-11-29 18:16:17 -0500701 return angle::Result::Continue;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400702}
Jamie Madill5a4c9322018-07-16 11:01:58 -0400703
Jamie Madill80766cf2019-01-10 10:20:34 -0500704void VertexArrayVk::updateDefaultAttrib(ContextVk *contextVk,
Jamie Madill5a4c9322018-07-16 11:01:58 -0400705 size_t attribIndex,
706 VkBuffer bufferHandle,
707 uint32_t offset)
708{
709 if (!mState.getEnabledAttributesMask().test(attribIndex))
710 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500711 mCurrentArrayBufferHandles[attribIndex] = bufferHandle;
712 mCurrentArrayBufferOffsets[attribIndex] = offset;
713 mCurrentArrayBuffers[attribIndex] = nullptr;
714 mCurrentArrayBufferStrides[attribIndex] = 0;
Jamie Madill5a4c9322018-07-16 11:01:58 -0400715 mCurrentArrayBufferFormats[attribIndex] =
Jamie Madill80766cf2019-01-10 10:20:34 -0500716 &contextVk->getRenderer()->getFormat(angle::FormatID::R32G32B32A32_FIXED);
717
718 setDefaultPackedInput(contextVk, attribIndex);
Jamie Madill5a4c9322018-07-16 11:01:58 -0400719 }
720}
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400721} // namespace rx