blob: 16a5b4df4ec7898be7a828c858293824819f2312 [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 Henigmane4523822018-07-19 16:10:53 -0400103 mCurrentArrayBufferConversion{{
Jamie Madillb980c562018-11-27 11:34:27 -0500104 INIT,
105 INIT,
106 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,
Frank Henigmane4523822018-07-19 16:10:53 -0400119 INIT,
120 }},
121 mCurrentArrayBufferConversionCanRelease{},
Jamie Madillc3755fc2018-04-05 08:39:13 -0400122 mCurrentElementArrayBufferOffset(0),
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500123 mCurrentElementArrayBuffer(nullptr),
Shahbaz Youssefi254b32c2018-11-26 11:58:03 -0500124 mDynamicVertexData(kVertexBufferUsageFlags, kDynamicVertexDataSize, true),
125 mDynamicIndexData(kIndexBufferUsageFlags, kDynamicIndexDataSize, true),
126 mTranslatedByteIndexData(kIndexBufferUsageFlags, kDynamicIndexDataSize, true),
Jamie Madillc759b8b2019-01-03 15:16:50 -0500127 mLineLoopHelper(contextVk->getRenderer()),
Jamie Madill88fc6da2018-08-30 16:18:36 -0400128 mDirtyLineLoopTranslation(true)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400129{
Jamie Madillc759b8b2019-01-03 15:16:50 -0500130 RendererVk *renderer = contextVk->getRenderer();
131
132 VkBufferCreateInfo createInfo = {};
133 createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
134 createInfo.size = 16;
135 createInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
136 (void)mTheNullBuffer.init(contextVk, createInfo, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
137
138 mCurrentArrayBufferHandles.fill(mTheNullBuffer.getBuffer().getHandle());
Frank Henigman17448952017-01-05 15:48:26 -0500139 mCurrentArrayBufferOffsets.fill(0);
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500140 mCurrentArrayBuffers.fill(nullptr);
Jamie Madill112a3a82018-01-23 13:04:06 -0500141
Frank Henigmane4523822018-07-19 16:10:53 -0400142 for (vk::DynamicBuffer &buffer : mCurrentArrayBufferConversion)
143 {
jchen105dc0a6f2018-09-20 14:30:45 +0800144 buffer.init(kMaxVertexFormatAlignment, renderer);
Frank Henigmane4523822018-07-19 16:10:53 -0400145 }
jchen105dc0a6f2018-09-20 14:30:45 +0800146 mDynamicVertexData.init(kMaxVertexFormatAlignment, renderer);
Luc Ferrona9ab0f32018-05-17 17:03:55 -0400147 mDynamicIndexData.init(1, renderer);
Luc Ferron6ed167a2018-06-13 13:45:55 -0400148 mTranslatedByteIndexData.init(1, renderer);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400149}
150
Jamie Madillb980c562018-11-27 11:34:27 -0500151VertexArrayVk::~VertexArrayVk() {}
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500152
Jamie Madill4928b7c2017-06-20 12:57:39 -0400153void VertexArrayVk::destroy(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400154{
Shahbaz Youssefifca8fd62018-11-13 13:55:48 -0500155 RendererVk *renderer = vk::GetImpl(context)->getRenderer();
156
Jamie Madillc759b8b2019-01-03 15:16:50 -0500157 mTheNullBuffer.release(renderer);
158
Frank Henigmane4523822018-07-19 16:10:53 -0400159 for (vk::DynamicBuffer &buffer : mCurrentArrayBufferConversion)
160 {
Shahbaz Youssefifca8fd62018-11-13 13:55:48 -0500161 buffer.release(renderer);
Frank Henigmane4523822018-07-19 16:10:53 -0400162 }
Shahbaz Youssefifca8fd62018-11-13 13:55:48 -0500163 mDynamicVertexData.release(renderer);
164 mDynamicIndexData.release(renderer);
165 mTranslatedByteIndexData.release(renderer);
166 mLineLoopHelper.release(renderer);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400167}
168
Jamie Madill21061022018-07-12 23:56:30 -0400169angle::Result VertexArrayVk::streamIndexData(ContextVk *contextVk,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500170 gl::DrawElementsType indexType,
Jamie Madill253038d2018-08-30 16:18:35 -0400171 size_t indexCount,
172 const void *sourcePointer,
173 vk::DynamicBuffer *dynamicBuffer)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400174{
Jamie Madill8dc27f92018-11-29 11:45:44 -0500175 ASSERT(!mState.getElementArrayBuffer() || indexType == gl::DrawElementsType::UnsignedByte);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400176
Jamie Madill253038d2018-08-30 16:18:35 -0400177 dynamicBuffer->releaseRetainedBuffers(contextVk->getRenderer());
Jamie Madilla064c272018-08-30 16:18:34 -0400178
Jamie Madill253038d2018-08-30 16:18:35 -0400179 const size_t amount = sizeof(GLushort) * indexCount;
180 GLubyte *dst = nullptr;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400181
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500182 ANGLE_TRY(dynamicBuffer->allocate(contextVk, amount, &dst, nullptr,
Jamie Madill253038d2018-08-30 16:18:35 -0400183 &mCurrentElementArrayBufferOffset, nullptr));
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500184 mCurrentElementArrayBuffer = dynamicBuffer->getCurrentBuffer();
Jamie Madill8dc27f92018-11-29 11:45:44 -0500185 if (indexType == gl::DrawElementsType::UnsignedByte)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400186 {
187 // Unsigned bytes don't have direct support in Vulkan so we have to expand the
188 // memory to a GLushort.
Jamie Madill253038d2018-08-30 16:18:35 -0400189 const GLubyte *in = static_cast<const GLubyte *>(sourcePointer);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400190 GLushort *expandedDst = reinterpret_cast<GLushort *>(dst);
Jamie Madill253038d2018-08-30 16:18:35 -0400191 for (size_t index = 0; index < indexCount; index++)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400192 {
193 expandedDst[index] = static_cast<GLushort>(in[index]);
194 }
195 }
196 else
197 {
Jamie Madill253038d2018-08-30 16:18:35 -0400198 memcpy(dst, sourcePointer, amount);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400199 }
Jamie Madill253038d2018-08-30 16:18:35 -0400200 ANGLE_TRY(dynamicBuffer->flush(contextVk));
Jamie Madill7c985f52018-11-29 18:16:17 -0500201 return angle::Result::Continue;
Frank Henigman17448952017-01-05 15:48:26 -0500202}
203
Frank Henigmane4523822018-07-19 16:10:53 -0400204// We assume the buffer is completely full of the same kind of data and convert
205// and/or align it as we copy it to a DynamicBuffer. The assumption could be wrong
206// but the alternative of copying it piecemeal on each draw would have a lot more
207// overhead.
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100208angle::Result VertexArrayVk::convertVertexBufferGpu(ContextVk *contextVk,
209 BufferVk *srcBuffer,
210 const gl::VertexBinding &binding,
Jamie Madilla63cc592019-01-16 13:27:16 -0500211 size_t attribIndex,
212 const vk::Format &vertexFormat)
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100213{
214 RendererVk *renderer = contextVk->getRenderer();
215
Jamie Madilla63cc592019-01-16 13:27:16 -0500216 const angle::Format &srcFormat = vertexFormat.angleFormat();
217 const angle::Format &destFormat = vertexFormat.bufferFormat();
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100218
219 ASSERT(binding.getStride() % (srcFormat.pixelBytes / srcFormat.channelCount()) == 0);
220
221 unsigned srcFormatSize = srcFormat.pixelBytes;
222 unsigned destFormatSize = destFormat.pixelBytes;
223
224 size_t numVertices = GetVertexCount(srcBuffer, binding, srcFormatSize);
225 if (numVertices == 0)
226 {
227 return angle::Result::Continue;
228 }
229
Jamie Madilla63cc592019-01-16 13:27:16 -0500230 ASSERT(GetVertexInputAlignment(vertexFormat) <= kMaxVertexFormatAlignment);
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100231
232 // Allocate buffer for results
233 mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(renderer);
234 ANGLE_TRY(mCurrentArrayBufferConversion[attribIndex].allocate(
235 contextVk, numVertices * destFormatSize, nullptr, nullptr,
236 &mCurrentArrayBufferOffsets[attribIndex], nullptr));
237 mCurrentArrayBuffers[attribIndex] =
238 mCurrentArrayBufferConversion[attribIndex].getCurrentBuffer();
239
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100240 UtilsVk::ConvertVertexParameters params;
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100241 params.vertexCount = numVertices;
242 params.srcFormat = &srcFormat;
243 params.destFormat = &destFormat;
244 params.srcStride = binding.getStride();
245 params.srcOffset = binding.getOffset();
246 params.destOffset = static_cast<size_t>(mCurrentArrayBufferOffsets[attribIndex]);
247
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100248 ANGLE_TRY(renderer->getUtils().convertVertexBuffer(contextVk, mCurrentArrayBuffers[attribIndex],
249 &srcBuffer->getBuffer(), params));
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100250
251 mCurrentArrayBufferHandles[attribIndex] =
252 mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle();
253 mCurrentArrayBufferConversionCanRelease[attribIndex] = true;
254
255 return angle::Result::Continue;
256}
257
258angle::Result VertexArrayVk::convertVertexBufferCpu(ContextVk *contextVk,
259 BufferVk *srcBuffer,
260 const gl::VertexBinding &binding,
Jamie Madilla63cc592019-01-16 13:27:16 -0500261 size_t attribIndex,
262 const vk::Format &vertexFormat)
Frank Henigmane4523822018-07-19 16:10:53 -0400263{
Frank Henigman9d84ccb2018-09-12 18:09:02 -0400264 // Needed before reading buffer or we could get stale data.
Jamie Madilla064c272018-08-30 16:18:34 -0400265 ANGLE_TRY(contextVk->getRenderer()->finish(contextVk));
Frank Henigmane4523822018-07-19 16:10:53 -0400266
Jamie Madilla63cc592019-01-16 13:27:16 -0500267 unsigned srcFormatSize = vertexFormat.angleFormat().pixelBytes;
268 unsigned dstFormatSize = vertexFormat.bufferFormat().pixelBytes;
Jamie Madilla064c272018-08-30 16:18:34 -0400269
270 mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(contextVk->getRenderer());
Frank Henigmane4523822018-07-19 16:10:53 -0400271
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100272 size_t numVertices = GetVertexCount(srcBuffer, binding, srcFormatSize);
273 if (numVertices == 0)
274 {
Jamie Madill7c985f52018-11-29 18:16:17 -0500275 return angle::Result::Continue;
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100276 }
Frank Henigmane4523822018-07-19 16:10:53 -0400277
Jamie Madill77abad82018-10-25 17:03:48 -0400278 void *src = nullptr;
Jamie Madilla064c272018-08-30 16:18:34 -0400279 ANGLE_TRY(srcBuffer->mapImpl(contextVk, &src));
280 const uint8_t *srcBytes = reinterpret_cast<const uint8_t *>(src);
281 srcBytes += binding.getOffset();
Jamie Madilla63cc592019-01-16 13:27:16 -0500282 ASSERT(GetVertexInputAlignment(vertexFormat) <= kMaxVertexFormatAlignment);
Jamie Madilla064c272018-08-30 16:18:34 -0400283 ANGLE_TRY(StreamVertexData(contextVk, &mCurrentArrayBufferConversion[attribIndex], srcBytes,
284 numVertices * dstFormatSize, 0, numVertices, binding.getStride(),
Jamie Madilla63cc592019-01-16 13:27:16 -0500285 vertexFormat.vertexLoadFunction, &mCurrentArrayBuffers[attribIndex],
Jamie Madilla064c272018-08-30 16:18:34 -0400286 &mCurrentArrayBufferOffsets[attribIndex]));
287 ANGLE_TRY(srcBuffer->unmapImpl(contextVk));
Frank Henigmane4523822018-07-19 16:10:53 -0400288
Shahbaz Youssefiec063052018-12-06 01:58:06 +0100289 mCurrentArrayBufferHandles[attribIndex] =
290 mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle();
Frank Henigmane4523822018-07-19 16:10:53 -0400291 mCurrentArrayBufferConversionCanRelease[attribIndex] = true;
Frank Henigmane4523822018-07-19 16:10:53 -0400292
Jamie Madill7c985f52018-11-29 18:16:17 -0500293 return angle::Result::Continue;
Frank Henigmane4523822018-07-19 16:10:53 -0400294}
295
Jamie Madillc759b8b2019-01-03 15:16:50 -0500296ANGLE_INLINE void VertexArrayVk::ensureConversionReleased(RendererVk *renderer, size_t attribIndex)
Frank Henigmane4523822018-07-19 16:10:53 -0400297{
298 if (mCurrentArrayBufferConversionCanRelease[attribIndex])
299 {
300 mCurrentArrayBufferConversion[attribIndex].release(renderer);
301 mCurrentArrayBufferConversionCanRelease[attribIndex] = false;
302 }
303}
304
Jamie Madill6f755b22018-10-09 12:48:54 -0400305angle::Result VertexArrayVk::syncState(const gl::Context *context,
306 const gl::VertexArray::DirtyBits &dirtyBits,
Jamie Madillc759b8b2019-01-03 15:16:50 -0500307 gl::VertexArray::DirtyAttribBitsArray *attribBits,
308 gl::VertexArray::DirtyBindingBitsArray *bindingBits)
Jamie Madilldd43e6c2017-03-24 14:18:49 -0400309{
310 ASSERT(dirtyBits.any());
Jamie Madill72106562017-03-24 14:18:50 -0400311
Jamie Madillbc5834c2018-11-06 11:13:50 -0500312 bool invalidateContext = false;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400313
Jamie Madill5a4c9322018-07-16 11:01:58 -0400314 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madillbd159f02017-10-09 19:39:06 -0400315
316 // Rebuild current attribute buffers cache. This will fail horribly if the buffer changes.
317 // TODO(jmadill): Handle buffer storage changes.
318 const auto &attribs = mState.getVertexAttributes();
319 const auto &bindings = mState.getVertexBindings();
320
Jamie Madill09463932018-04-04 05:26:59 -0400321 for (size_t dirtyBit : dirtyBits)
Jamie Madillbd159f02017-10-09 19:39:06 -0400322 {
Jamie Madill09463932018-04-04 05:26:59 -0400323 switch (dirtyBit)
Jamie Madillda854a22017-11-30 17:24:21 -0500324 {
Jamie Madill09463932018-04-04 05:26:59 -0400325 case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER:
Jamie Madillda854a22017-11-30 17:24:21 -0500326 {
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400327 gl::Buffer *bufferGL = mState.getElementArrayBuffer();
Jamie Madill09463932018-04-04 05:26:59 -0400328 if (bufferGL)
329 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500330 BufferVk *bufferVk = vk::GetImpl(bufferGL);
331 mCurrentElementArrayBuffer = &bufferVk->getBuffer();
Jamie Madill09463932018-04-04 05:26:59 -0400332 }
333 else
334 {
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500335 mCurrentElementArrayBuffer = nullptr;
Jamie Madill09463932018-04-04 05:26:59 -0400336 }
Luc Ferron387b3b32018-05-28 10:11:57 -0400337
338 mCurrentElementArrayBufferOffset = 0;
339 mLineLoopBufferFirstIndex.reset();
340 mLineLoopBufferLastIndex.reset();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400341 contextVk->setIndexBufferDirty();
Jamie Madillb8e39662018-04-04 11:41:42 -0400342 mDirtyLineLoopTranslation = true;
Jamie Madill09463932018-04-04 05:26:59 -0400343 break;
Jamie Madillda854a22017-11-30 17:24:21 -0500344 }
Jamie Madill09463932018-04-04 05:26:59 -0400345
346 case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA:
Jamie Madillc3755fc2018-04-05 08:39:13 -0400347 mLineLoopBufferFirstIndex.reset();
348 mLineLoopBufferLastIndex.reset();
Jamie Madillb8e39662018-04-04 11:41:42 -0400349 mDirtyLineLoopTranslation = true;
Jamie Madill09463932018-04-04 05:26:59 -0400350 break;
351
Jamie Madill80766cf2019-01-10 10:20:34 -0500352#define ANGLE_VERTEX_DIRTY_ATTRIB_FUNC(INDEX) \
353 case gl::VertexArray::DIRTY_BIT_ATTRIB_0 + INDEX: \
354 ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
355 bindings[attribs[INDEX].bindingIndex], INDEX)); \
356 invalidateContext = true; \
Jamie Madillc759b8b2019-01-03 15:16:50 -0500357 (*attribBits)[INDEX].reset(); \
Jamie Madill80766cf2019-01-10 10:20:34 -0500358 break;
359
Jamie Madillc09ae152019-02-01 14:16:32 -0500360 ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_ATTRIB_FUNC)
Jamie Madill80766cf2019-01-10 10:20:34 -0500361
362#define ANGLE_VERTEX_DIRTY_BINDING_FUNC(INDEX) \
363 case gl::VertexArray::DIRTY_BIT_BINDING_0 + INDEX: \
364 ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
365 bindings[attribs[INDEX].bindingIndex], INDEX)); \
366 invalidateContext = true; \
Jamie Madillc759b8b2019-01-03 15:16:50 -0500367 (*bindingBits)[INDEX].reset(); \
Jamie Madill80766cf2019-01-10 10:20:34 -0500368 break;
369
Jamie Madillc09ae152019-02-01 14:16:32 -0500370 ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BINDING_FUNC)
Jamie Madill80766cf2019-01-10 10:20:34 -0500371
372#define ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC(INDEX) \
373 case gl::VertexArray::DIRTY_BIT_BUFFER_DATA_0 + INDEX: \
374 ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
375 bindings[attribs[INDEX].bindingIndex], INDEX)); \
376 break;
377
Jamie Madillc09ae152019-02-01 14:16:32 -0500378 ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC)
Jamie Madilla56467e2018-04-11 16:19:41 -0400379
Jamie Madill09463932018-04-04 05:26:59 -0400380 default:
Jamie Madilla56467e2018-04-11 16:19:41 -0400381 UNREACHABLE();
Jamie Madill09463932018-04-04 05:26:59 -0400382 break;
Jamie Madillbd159f02017-10-09 19:39:06 -0400383 }
384 }
Frank Henigman0af5b862018-03-27 20:19:33 -0400385
Jamie Madillbc5834c2018-11-06 11:13:50 -0500386 if (invalidateContext)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400387 {
Jamie Madillbc5834c2018-11-06 11:13:50 -0500388 contextVk->invalidateVertexAndIndexBuffers();
Jamie Madillc3755fc2018-04-05 08:39:13 -0400389 }
390
Jamie Madill7c985f52018-11-29 18:16:17 -0500391 return angle::Result::Continue;
Jamie Madillbd159f02017-10-09 19:39:06 -0400392}
393
Jamie Madill80766cf2019-01-10 10:20:34 -0500394ANGLE_INLINE void VertexArrayVk::setDefaultPackedInput(ContextVk *contextVk, size_t attribIndex)
395{
396 contextVk->onVertexAttributeChange(attribIndex, 0, 0, VK_FORMAT_R32G32B32A32_SFLOAT, 0);
397}
398
Frank Henigmane4523822018-07-19 16:10:53 -0400399angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
400 const gl::VertexAttribute &attrib,
401 const gl::VertexBinding &binding,
402 size_t attribIndex)
Jamie Madilla56467e2018-04-11 16:19:41 -0400403{
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100404 RendererVk *renderer = contextVk->getRenderer();
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100405 bool anyVertexBufferConvertedOnGpu = false;
Jamie Madill5a4c9322018-07-16 11:01:58 -0400406
Jamie Madilla56467e2018-04-11 16:19:41 -0400407 if (attrib.enabled)
408 {
Jamie Madilla63cc592019-01-16 13:27:16 -0500409 gl::Buffer *bufferGL = binding.getBuffer().get();
410 const vk::Format &vertexFormat = renderer->getFormat(GetVertexFormatID(attrib));
411 GLuint stride;
Frank Henigmane4523822018-07-19 16:10:53 -0400412
Jamie Madilla56467e2018-04-11 16:19:41 -0400413 if (bufferGL)
414 {
Jamie Madilla63cc592019-01-16 13:27:16 -0500415 BufferVk *bufferVk = vk::GetImpl(bufferGL);
416 const angle::Format &angleFormat = vertexFormat.angleFormat();
417 bool bindingIsAligned = BindingIsAligned(binding, angleFormat, attrib.size);
Frank Henigman419acc82018-06-24 19:57:31 -0400418
Jamie Madilla63cc592019-01-16 13:27:16 -0500419 if (vertexFormat.vertexLoadRequiresConversion || !bindingIsAligned)
Frank Henigmane4523822018-07-19 16:10:53 -0400420 {
Jamie Madilla63cc592019-01-16 13:27:16 -0500421 stride = vertexFormat.bufferFormat().pixelBytes;
Jamie Madilla064c272018-08-30 16:18:34 -0400422
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100423 if (bindingIsAligned)
424 {
Jamie Madilla63cc592019-01-16 13:27:16 -0500425 ANGLE_TRY(convertVertexBufferGpu(contextVk, bufferVk, binding, attribIndex,
426 vertexFormat));
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100427 anyVertexBufferConvertedOnGpu = true;
428 }
429 else
430 {
Jamie Madilla63cc592019-01-16 13:27:16 -0500431 ANGLE_TRY(convertVertexBufferCpu(contextVk, bufferVk, binding, attribIndex,
432 vertexFormat));
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100433 }
Frank Henigmane4523822018-07-19 16:10:53 -0400434 }
435 else
436 {
Jamie Madill17a50e12019-01-10 22:05:43 -0500437 if (bufferVk->getSize() == 0)
438 {
439 mCurrentArrayBuffers[attribIndex] = nullptr;
440 mCurrentArrayBufferHandles[attribIndex] =
441 mTheNullBuffer.getBuffer().getHandle();
442 mCurrentArrayBufferOffsets[attribIndex] = 0;
Jamie Madilla63cc592019-01-16 13:27:16 -0500443 stride = 0;
Jamie Madill17a50e12019-01-10 22:05:43 -0500444 }
445 else
446 {
447 mCurrentArrayBuffers[attribIndex] = &bufferVk->getBuffer();
448 mCurrentArrayBufferHandles[attribIndex] =
449 bufferVk->getBuffer().getBuffer().getHandle();
450 mCurrentArrayBufferOffsets[attribIndex] = binding.getOffset();
Jamie Madilla63cc592019-01-16 13:27:16 -0500451 stride = binding.getStride();
Jamie Madill17a50e12019-01-10 22:05:43 -0500452 }
453
Jamie Madillc759b8b2019-01-03 15:16:50 -0500454 ensureConversionReleased(renderer, attribIndex);
Frank Henigmane4523822018-07-19 16:10:53 -0400455 }
Jamie Madilla56467e2018-04-11 16:19:41 -0400456 }
457 else
458 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500459 mCurrentArrayBuffers[attribIndex] = nullptr;
Jamie Madillc759b8b2019-01-03 15:16:50 -0500460 mCurrentArrayBufferHandles[attribIndex] = mTheNullBuffer.getBuffer().getHandle();
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500461 mCurrentArrayBufferOffsets[attribIndex] = 0;
Jamie Madilla63cc592019-01-16 13:27:16 -0500462 stride = vertexFormat.bufferFormat().pixelBytes;
Jamie Madillc759b8b2019-01-03 15:16:50 -0500463 ensureConversionReleased(renderer, attribIndex);
Jamie Madilla56467e2018-04-11 16:19:41 -0400464 }
Jamie Madill80766cf2019-01-10 10:20:34 -0500465
Jamie Madilla63cc592019-01-16 13:27:16 -0500466 contextVk->onVertexAttributeChange(attribIndex, stride, binding.getDivisor(),
467 vertexFormat.vkBufferFormat, attrib.relativeOffset);
Jamie Madilla56467e2018-04-11 16:19:41 -0400468 }
469 else
470 {
Jamie Madill5a4c9322018-07-16 11:01:58 -0400471 contextVk->invalidateDefaultAttribute(attribIndex);
472
473 // These will be filled out by the ContextVk.
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500474 mCurrentArrayBuffers[attribIndex] = nullptr;
Jamie Madillc759b8b2019-01-03 15:16:50 -0500475 mCurrentArrayBufferHandles[attribIndex] = mTheNullBuffer.getBuffer().getHandle();
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500476 mCurrentArrayBufferOffsets[attribIndex] = 0;
Jamie Madill80766cf2019-01-10 10:20:34 -0500477
478 setDefaultPackedInput(contextVk, attribIndex);
Jamie Madillc759b8b2019-01-03 15:16:50 -0500479 ensureConversionReleased(renderer, attribIndex);
Jamie Madilla56467e2018-04-11 16:19:41 -0400480 }
Frank Henigmane4523822018-07-19 16:10:53 -0400481
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100482 if (anyVertexBufferConvertedOnGpu && renderer->getFeatures().flushAfterVertexConversion)
483 {
484 ANGLE_TRY(renderer->flush(contextVk));
485 }
486
Jamie Madill7c985f52018-11-29 18:16:17 -0500487 return angle::Result::Continue;
Jamie Madilla56467e2018-04-11 16:19:41 -0400488}
489
Jamie Madill88fc6da2018-08-30 16:18:36 -0400490angle::Result VertexArrayVk::updateClientAttribs(const gl::Context *context,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400491 GLint firstVertex,
492 GLsizei vertexOrIndexCount,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500493 gl::DrawElementsType indexTypeOrInvalid,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400494 const void *indices)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400495{
Jamie Madill77abad82018-10-25 17:03:48 -0400496 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400497 const gl::AttributesMask &clientAttribs = context->getStateCache().getActiveClientAttribsMask();
Jamie Madill21061022018-07-12 23:56:30 -0400498
Jamie Madill88fc6da2018-08-30 16:18:36 -0400499 ASSERT(clientAttribs.any());
Jamie Madillc1fd7372018-10-26 22:48:39 -0400500
501 GLint startVertex;
502 size_t vertexCount;
Jamie Madill8dc27f92018-11-29 11:45:44 -0500503 ANGLE_TRY(GetVertexRangeInfo(context, firstVertex, vertexOrIndexCount, indexTypeOrInvalid,
504 indices, 0, &startVertex, &vertexCount));
Jamie Madill88fc6da2018-08-30 16:18:36 -0400505
Jamie Madilla63cc592019-01-16 13:27:16 -0500506 RendererVk *renderer = contextVk->getRenderer();
507 mDynamicVertexData.releaseRetainedBuffers(renderer);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400508
509 const auto &attribs = mState.getVertexAttributes();
510 const auto &bindings = mState.getVertexBindings();
511
512 // TODO(fjhenigman): When we have a bunch of interleaved attributes, they end up
513 // un-interleaved, wasting space and copying time. Consider improving on that.
514 for (size_t attribIndex : clientAttribs)
515 {
516 const gl::VertexAttribute &attrib = attribs[attribIndex];
517 const gl::VertexBinding &binding = bindings[attrib.bindingIndex];
518 ASSERT(attrib.enabled && binding.getBuffer().get() == nullptr);
519
Jamie Madilla63cc592019-01-16 13:27:16 -0500520 const vk::Format &vertexFormat = renderer->getFormat(GetVertexFormatID(attrib));
521 GLuint stride = vertexFormat.bufferFormat().pixelBytes;
522
523 const size_t bytesToAllocate = (startVertex + vertexCount) * stride;
Jamie Madillc1fd7372018-10-26 22:48:39 -0400524 const uint8_t *src =
525 static_cast<const uint8_t *>(attrib.pointer) + startVertex * binding.getStride();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400526
Jamie Madilla63cc592019-01-16 13:27:16 -0500527 size_t destOffset = startVertex * stride;
528 ASSERT(GetVertexInputAlignment(vertexFormat) <= kMaxVertexFormatAlignment);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400529
530 // Only vertexCount() vertices will be used by the upcoming draw. so that is all we copy.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400531 // We allocate space for startVertex + vertexCount so indexing will work. If we
Jamie Madill88fc6da2018-08-30 16:18:36 -0400532 // don't start at zero all the indices will be off.
533 // TODO(fjhenigman): See if we can account for indices being off by adjusting the
534 // offset, thus avoiding wasted memory.
Jamie Madillc1fd7372018-10-26 22:48:39 -0400535 ANGLE_TRY(StreamVertexData(
536 contextVk, &mDynamicVertexData, src, bytesToAllocate, destOffset, vertexCount,
Jamie Madilla63cc592019-01-16 13:27:16 -0500537 binding.getStride(), vertexFormat.vertexLoadFunction,
Shahbaz Youssefiec063052018-12-06 01:58:06 +0100538 &mCurrentArrayBuffers[attribIndex], &mCurrentArrayBufferOffsets[attribIndex]));
539 mCurrentArrayBufferHandles[attribIndex] =
540 mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400541 }
542
Jamie Madill7c985f52018-11-29 18:16:17 -0500543 return angle::Result::Continue;
Jamie Madill88fc6da2018-08-30 16:18:36 -0400544}
545
546angle::Result VertexArrayVk::handleLineLoop(ContextVk *contextVk,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400547 GLint firstVertex,
548 GLsizei vertexOrIndexCount,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500549 gl::DrawElementsType indexTypeOrInvalid,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400550 const void *indices)
Jamie Madill88fc6da2018-08-30 16:18:36 -0400551{
Jamie Madill8dc27f92018-11-29 11:45:44 -0500552 if (indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
Jamie Madill88fc6da2018-08-30 16:18:36 -0400553 {
554 // Handle GL_LINE_LOOP drawElements.
555 if (mDirtyLineLoopTranslation)
556 {
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400557 gl::Buffer *elementArrayBuffer = mState.getElementArrayBuffer();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400558
559 if (!elementArrayBuffer)
560 {
Frank Henigman85c4b432018-09-19 23:35:00 -0400561 ANGLE_TRY(mLineLoopHelper.streamIndices(
Jamie Madill8dc27f92018-11-29 11:45:44 -0500562 contextVk, indexTypeOrInvalid, vertexOrIndexCount,
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500563 reinterpret_cast<const uint8_t *>(indices), &mCurrentElementArrayBuffer,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400564 &mCurrentElementArrayBufferOffset));
Jamie Madill88fc6da2018-08-30 16:18:36 -0400565 }
566 else
567 {
568 // When using an element array buffer, 'indices' is an offset to the first element.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400569 intptr_t offset = reinterpret_cast<intptr_t>(indices);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400570 BufferVk *elementArrayBufferVk = vk::GetImpl(elementArrayBuffer);
571 ANGLE_TRY(mLineLoopHelper.getIndexBufferForElementArrayBuffer(
Jamie Madill8dc27f92018-11-29 11:45:44 -0500572 contextVk, elementArrayBufferVk, indexTypeOrInvalid, vertexOrIndexCount, offset,
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500573 &mCurrentElementArrayBuffer, &mCurrentElementArrayBufferOffset));
Jamie Madill88fc6da2018-08-30 16:18:36 -0400574 }
575 }
576
577 // If we've had a drawArrays call with a line loop before, we want to make sure this is
578 // invalidated the next time drawArrays is called since we use the same index buffer for
579 // both calls.
580 mLineLoopBufferFirstIndex.reset();
581 mLineLoopBufferLastIndex.reset();
Jamie Madill7c985f52018-11-29 18:16:17 -0500582 return angle::Result::Continue;
Jamie Madill88fc6da2018-08-30 16:18:36 -0400583 }
Jamie Madillc3755fc2018-04-05 08:39:13 -0400584
Jamie Madill18e323a2018-05-11 16:54:17 -0400585 // Note: Vertex indexes can be arbitrarily large.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400586 uint32_t clampedVertexCount = gl::clampCast<uint32_t>(vertexOrIndexCount);
Jamie Madill18e323a2018-05-11 16:54:17 -0400587
Jamie Madillc3755fc2018-04-05 08:39:13 -0400588 // Handle GL_LINE_LOOP drawArrays.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400589 size_t lastVertex = static_cast<size_t>(firstVertex + clampedVertexCount);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400590 if (!mLineLoopBufferFirstIndex.valid() || !mLineLoopBufferLastIndex.valid() ||
Jamie Madillbfe31c42018-10-25 17:03:47 -0400591 mLineLoopBufferFirstIndex != firstVertex || mLineLoopBufferLastIndex != lastVertex)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400592 {
Jamie Madillbfe31c42018-10-25 17:03:47 -0400593 ANGLE_TRY(mLineLoopHelper.getIndexBufferForDrawArrays(
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500594 contextVk, clampedVertexCount, firstVertex, &mCurrentElementArrayBuffer,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400595 &mCurrentElementArrayBufferOffset));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400596
Jamie Madillbfe31c42018-10-25 17:03:47 -0400597 mLineLoopBufferFirstIndex = firstVertex;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400598 mLineLoopBufferLastIndex = lastVertex;
599 }
600
Jamie Madill7c985f52018-11-29 18:16:17 -0500601 return angle::Result::Continue;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400602}
603
Jamie Madill88fc6da2018-08-30 16:18:36 -0400604angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400605 GLsizei indexCount,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500606 gl::DrawElementsType type,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400607 const void *indices)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400608{
Jamie Madill8dc27f92018-11-29 11:45:44 -0500609 ASSERT(type != gl::DrawElementsType::InvalidEnum);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400610
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500611 RendererVk *renderer = contextVk->getRenderer();
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400612 gl::Buffer *glBuffer = mState.getElementArrayBuffer();
Jamie Madillc3755fc2018-04-05 08:39:13 -0400613
Jamie Madill88fc6da2018-08-30 16:18:36 -0400614 if (!glBuffer)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400615 {
Jamie Madillbfe31c42018-10-25 17:03:47 -0400616 ANGLE_TRY(streamIndexData(contextVk, type, indexCount, indices, &mDynamicIndexData));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400617 }
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500618 else if (renderer->getFormat(angle::FormatID::R16_UINT).vkSupportsStorageBuffer)
619 {
620 BufferVk *bufferVk = vk::GetImpl(glBuffer);
621
622 ASSERT(type == gl::DrawElementsType::UnsignedByte);
623
624 intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices);
625 size_t srcDataSize = static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData;
626
627 mTranslatedByteIndexData.releaseRetainedBuffers(renderer);
628
629 ANGLE_TRY(mTranslatedByteIndexData.allocate(contextVk, sizeof(GLushort) * srcDataSize,
630 nullptr, nullptr,
631 &mCurrentElementArrayBufferOffset, nullptr));
632 mCurrentElementArrayBuffer = mTranslatedByteIndexData.getCurrentBuffer();
633
634 vk::BufferHelper *dest = mTranslatedByteIndexData.getCurrentBuffer();
635 vk::BufferHelper *src = &bufferVk->getBuffer();
636
637 ANGLE_TRY(src->initBufferView(contextVk, renderer->getFormat(angle::FormatID::R8_UINT)));
638 ANGLE_TRY(dest->initBufferView(contextVk, renderer->getFormat(angle::FormatID::R16_UINT)));
639
640 // Copy relevant section of the source into destination at allocated offset. Note that the
641 // offset returned by allocate() above is in bytes, while our allocated array is of
642 // GLushorts.
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100643 UtilsVk::CopyParameters params = {};
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500644 params.destOffset =
645 static_cast<size_t>(mCurrentElementArrayBufferOffset) / sizeof(GLushort);
646 params.srcOffset = offsetIntoSrcData;
647 params.size = srcDataSize;
648
649 // Note: this is a copy, which implicitly converts between formats. Once support for
650 // primitive restart is added, a specialized shader is likely needed to special case 0xFF ->
651 // 0xFFFF.
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100652 ANGLE_TRY(renderer->getUtils().copyBuffer(contextVk, dest, src, params));
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500653 }
Jamie Madill88fc6da2018-08-30 16:18:36 -0400654 else
Jamie Madillc3755fc2018-04-05 08:39:13 -0400655 {
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500656 // If it's not possible to convert the buffer with compute, opt for a CPU read back for now.
657 // TODO(syoussefi): R8G8B8A8_UINT is required to have storage texel buffer support, so a
658 // specialized shader code can be made to read two ubyte indices and output them in R and B
659 // (or A and G based on endianness?) with 0 on the other channels. If specialized, we might
660 // as well support the ubyte to ushort case with correct handling of primitive restart.
661 // http://anglebug.com/3003
662
Frank Henigman9d84ccb2018-09-12 18:09:02 -0400663 // Needed before reading buffer or we could get stale data.
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500664 ANGLE_TRY(renderer->finish(contextVk));
Frank Henigman9d84ccb2018-09-12 18:09:02 -0400665
Jamie Madill8dc27f92018-11-29 11:45:44 -0500666 ASSERT(type == gl::DrawElementsType::UnsignedByte);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400667 // Unsigned bytes don't have direct support in Vulkan so we have to expand the
668 // memory to a GLushort.
669 BufferVk *bufferVk = vk::GetImpl(glBuffer);
670 void *srcDataMapping = nullptr;
671 ASSERT(!glBuffer->isMapped());
672 ANGLE_TRY(bufferVk->mapImpl(contextVk, &srcDataMapping));
673 uint8_t *srcData = static_cast<uint8_t *>(srcDataMapping);
Jamie Madillbfe31c42018-10-25 17:03:47 -0400674 intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400675 srcData += offsetIntoSrcData;
Jamie Madill253038d2018-08-30 16:18:35 -0400676
Jamie Madillbfe31c42018-10-25 17:03:47 -0400677 ANGLE_TRY(streamIndexData(contextVk, type,
Jamie Madill88fc6da2018-08-30 16:18:36 -0400678 static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData,
679 srcData, &mTranslatedByteIndexData));
Luc Ferron6ed167a2018-06-13 13:45:55 -0400680
Jamie Madill88fc6da2018-08-30 16:18:36 -0400681 ANGLE_TRY(bufferVk->unmapImpl(contextVk));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400682 }
683
Jamie Madill7c985f52018-11-29 18:16:17 -0500684 return angle::Result::Continue;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400685}
Jamie Madill5a4c9322018-07-16 11:01:58 -0400686
Jamie Madill80766cf2019-01-10 10:20:34 -0500687void VertexArrayVk::updateDefaultAttrib(ContextVk *contextVk,
Jamie Madill5a4c9322018-07-16 11:01:58 -0400688 size_t attribIndex,
689 VkBuffer bufferHandle,
690 uint32_t offset)
691{
692 if (!mState.getEnabledAttributesMask().test(attribIndex))
693 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500694 mCurrentArrayBufferHandles[attribIndex] = bufferHandle;
695 mCurrentArrayBufferOffsets[attribIndex] = offset;
696 mCurrentArrayBuffers[attribIndex] = nullptr;
Jamie Madill80766cf2019-01-10 10:20:34 -0500697
698 setDefaultPackedInput(contextVk, attribIndex);
Jamie Madill5a4c9322018-07-16 11:01:58 -0400699 }
700}
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400701} // namespace rx