blob: 18c30242b797f9d8f51b361eda2a320b0383d984 [file] [log] [blame]
Jamie Madill9e54b5a2016-05-25 12:57:39 -04001//
2// Copyright 2016 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6// VertexArrayVk.cpp:
7// Implements the class methods for VertexArrayVk.
8//
9
10#include "libANGLE/renderer/vulkan/VertexArrayVk.h"
11
12#include "common/debug.h"
Jamie Madillbfe31c42018-10-25 17:03:47 -040013#include "common/utilities.h"
Jamie Madillc564c072017-06-01 12:45:42 -040014#include "libANGLE/Context.h"
Jamie Madillbd159f02017-10-09 19:39:06 -040015#include "libANGLE/renderer/vulkan/BufferVk.h"
Jamie Madill1f46bc12018-02-20 16:09:43 -050016#include "libANGLE/renderer/vulkan/CommandGraph.h"
Jamie Madilldd43e6c2017-03-24 14:18:49 -040017#include "libANGLE/renderer/vulkan/ContextVk.h"
Jamie Madill316c6062018-05-29 10:49:45 -040018#include "libANGLE/renderer/vulkan/FramebufferVk.h"
Jamie Madillc3755fc2018-04-05 08:39:13 -040019#include "libANGLE/renderer/vulkan/RendererVk.h"
Jamie Madill3c424b42018-01-19 12:35:09 -050020#include "libANGLE/renderer/vulkan/vk_format_utils.h"
Jamie Madilldd43e6c2017-03-24 14:18:49 -040021
Jamie Madill9e54b5a2016-05-25 12:57:39 -040022namespace rx
23{
Jamie Madillc3755fc2018-04-05 08:39:13 -040024namespace
25{
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +010026constexpr size_t kDynamicVertexDataSize = 1024 * 1024;
27constexpr size_t kDynamicIndexDataSize = 1024 * 8;
28constexpr size_t kMaxVertexFormatAlignment = 4;
29constexpr VkBufferUsageFlags kVertexBufferUsageFlags =
30 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -050031constexpr VkBufferUsageFlags kIndexBufferUsageFlags = VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
32 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
33 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
Frank Henigmane4523822018-07-19 16:10:53 -040034
Jamie Madilldbc605c2019-01-04 16:39:14 -050035ANGLE_INLINE bool BindingIsAligned(const gl::VertexBinding &binding,
36 const angle::Format &angleFormat,
37 unsigned int attribSize)
Frank Henigmane4523822018-07-19 16:10:53 -040038{
Jamie Madilldbc605c2019-01-04 16:39:14 -050039 GLuint mask = angleFormat.componentAlignmentMask;
40 if (mask != std::numeric_limits<GLuint>::max())
41 {
42 return ((binding.getOffset() & mask) == 0 && (binding.getStride() & mask) == 0);
43 }
44 else
45 {
46 unsigned int formatSize = angleFormat.pixelBytes;
47 return ((binding.getOffset() * attribSize) % formatSize == 0) &&
48 ((binding.getStride() * attribSize) % formatSize == 0);
49 }
Frank Henigmane4523822018-07-19 16:10:53 -040050}
Jamie Madilla064c272018-08-30 16:18:34 -040051
52angle::Result StreamVertexData(ContextVk *contextVk,
53 vk::DynamicBuffer *dynamicBuffer,
54 const uint8_t *sourceData,
55 size_t bytesToAllocate,
56 size_t destOffset,
57 size_t vertexCount,
58 size_t stride,
59 VertexCopyFunction vertexLoadFunction,
Shahbaz Youssefiec063052018-12-06 01:58:06 +010060 vk::BufferHelper **bufferOut,
Jamie Madilla064c272018-08-30 16:18:34 -040061 VkDeviceSize *bufferOffsetOut)
62{
63 uint8_t *dst = nullptr;
Shahbaz Youssefiec063052018-12-06 01:58:06 +010064 ANGLE_TRY(dynamicBuffer->allocate(contextVk, bytesToAllocate, &dst, nullptr, bufferOffsetOut,
65 nullptr));
66 *bufferOut = dynamicBuffer->getCurrentBuffer();
Jamie Madilla064c272018-08-30 16:18:34 -040067 dst += destOffset;
68 vertexLoadFunction(sourceData, stride, vertexCount, dst);
69
70 ANGLE_TRY(dynamicBuffer->flush(contextVk));
Jamie Madill7c985f52018-11-29 18:16:17 -050071 return angle::Result::Continue;
Jamie Madilla064c272018-08-30 16:18:34 -040072}
jchen105dc0a6f2018-09-20 14:30:45 +080073
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +010074size_t GetVertexCount(BufferVk *srcBuffer, const gl::VertexBinding &binding, uint32_t srcFormatSize)
75{
76 // Bytes usable for vertex data.
77 GLint64 bytes = srcBuffer->getSize() - binding.getOffset();
78 if (bytes < srcFormatSize)
79 return 0;
80
81 // Count the last vertex. It may occupy less than a full stride.
82 size_t numVertices = 1;
83 bytes -= srcFormatSize;
84
85 // Count how many strides fit remaining space.
86 if (bytes > 0)
87 numVertices += static_cast<size_t>(bytes) / binding.getStride();
88
89 return numVertices;
90}
Jamie Madillc3755fc2018-04-05 08:39:13 -040091} // anonymous namespace
Jamie Madill9e54b5a2016-05-25 12:57:39 -040092
Shahbaz Youssefi254b32c2018-11-26 11:58:03 -050093#define INIT \
94 { \
95 kVertexBufferUsageFlags, 1024 * 8, true \
Frank Henigmane4523822018-07-19 16:10:53 -040096 }
97
Luc Ferrona9ab0f32018-05-17 17:03:55 -040098VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state, RendererVk *renderer)
Jamie Madillbd159f02017-10-09 19:39:06 -040099 : VertexArrayImpl(state),
Jamie Madillda854a22017-11-30 17:24:21 -0500100 mCurrentArrayBufferHandles{},
Frank Henigman17448952017-01-05 15:48:26 -0500101 mCurrentArrayBufferOffsets{},
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500102 mCurrentArrayBuffers{},
Frank Henigman419acc82018-06-24 19:57:31 -0400103 mCurrentArrayBufferFormats{},
104 mCurrentArrayBufferStrides{},
Frank Henigmane4523822018-07-19 16:10:53 -0400105 mCurrentArrayBufferConversion{{
Jamie Madillb980c562018-11-27 11:34:27 -0500106 INIT,
107 INIT,
108 INIT,
109 INIT,
110 INIT,
111 INIT,
112 INIT,
113 INIT,
114 INIT,
115 INIT,
116 INIT,
117 INIT,
118 INIT,
119 INIT,
120 INIT,
Frank Henigmane4523822018-07-19 16:10:53 -0400121 INIT,
122 }},
123 mCurrentArrayBufferConversionCanRelease{},
Jamie Madillc3755fc2018-04-05 08:39:13 -0400124 mCurrentElementArrayBufferOffset(0),
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500125 mCurrentElementArrayBuffer(nullptr),
Jamie Madill77b24362018-11-05 22:39:29 -0500126 mPackedInputBindings{},
127 mPackedInputAttributes{},
Shahbaz Youssefi254b32c2018-11-26 11:58:03 -0500128 mDynamicVertexData(kVertexBufferUsageFlags, kDynamicVertexDataSize, true),
129 mDynamicIndexData(kIndexBufferUsageFlags, kDynamicIndexDataSize, true),
130 mTranslatedByteIndexData(kIndexBufferUsageFlags, kDynamicIndexDataSize, true),
Luc Ferrona9ab0f32018-05-17 17:03:55 -0400131 mLineLoopHelper(renderer),
Jamie Madill88fc6da2018-08-30 16:18:36 -0400132 mDirtyLineLoopTranslation(true)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400133{
Jamie Madillda854a22017-11-30 17:24:21 -0500134 mCurrentArrayBufferHandles.fill(VK_NULL_HANDLE);
Frank Henigman17448952017-01-05 15:48:26 -0500135 mCurrentArrayBufferOffsets.fill(0);
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500136 mCurrentArrayBuffers.fill(nullptr);
Jamie Madill112a3a82018-01-23 13:04:06 -0500137
Frank Henigmane4523822018-07-19 16:10:53 -0400138 for (vk::DynamicBuffer &buffer : mCurrentArrayBufferConversion)
139 {
jchen105dc0a6f2018-09-20 14:30:45 +0800140 buffer.init(kMaxVertexFormatAlignment, renderer);
Frank Henigmane4523822018-07-19 16:10:53 -0400141 }
jchen105dc0a6f2018-09-20 14:30:45 +0800142 mDynamicVertexData.init(kMaxVertexFormatAlignment, renderer);
Luc Ferrona9ab0f32018-05-17 17:03:55 -0400143 mDynamicIndexData.init(1, renderer);
Luc Ferron6ed167a2018-06-13 13:45:55 -0400144 mTranslatedByteIndexData.init(1, renderer);
Jamie Madill0a17e482018-08-31 17:19:11 -0400145
146 // Initially consider all inputs dirty.
147 mDirtyPackedInputs.set();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400148}
149
Jamie Madillb980c562018-11-27 11:34:27 -0500150VertexArrayVk::~VertexArrayVk() {}
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500151
Jamie Madill4928b7c2017-06-20 12:57:39 -0400152void VertexArrayVk::destroy(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400153{
Shahbaz Youssefifca8fd62018-11-13 13:55:48 -0500154 RendererVk *renderer = vk::GetImpl(context)->getRenderer();
155
Frank Henigmane4523822018-07-19 16:10:53 -0400156 for (vk::DynamicBuffer &buffer : mCurrentArrayBufferConversion)
157 {
Shahbaz Youssefifca8fd62018-11-13 13:55:48 -0500158 buffer.release(renderer);
Frank Henigmane4523822018-07-19 16:10:53 -0400159 }
Shahbaz Youssefifca8fd62018-11-13 13:55:48 -0500160 mDynamicVertexData.release(renderer);
161 mDynamicIndexData.release(renderer);
162 mTranslatedByteIndexData.release(renderer);
163 mLineLoopHelper.release(renderer);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400164}
165
Jamie Madill21061022018-07-12 23:56:30 -0400166angle::Result VertexArrayVk::streamIndexData(ContextVk *contextVk,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500167 gl::DrawElementsType indexType,
Jamie Madill253038d2018-08-30 16:18:35 -0400168 size_t indexCount,
169 const void *sourcePointer,
170 vk::DynamicBuffer *dynamicBuffer)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400171{
Jamie Madill8dc27f92018-11-29 11:45:44 -0500172 ASSERT(!mState.getElementArrayBuffer() || indexType == gl::DrawElementsType::UnsignedByte);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400173
Jamie Madill253038d2018-08-30 16:18:35 -0400174 dynamicBuffer->releaseRetainedBuffers(contextVk->getRenderer());
Jamie Madilla064c272018-08-30 16:18:34 -0400175
Jamie Madill253038d2018-08-30 16:18:35 -0400176 const size_t amount = sizeof(GLushort) * indexCount;
177 GLubyte *dst = nullptr;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400178
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500179 ANGLE_TRY(dynamicBuffer->allocate(contextVk, amount, &dst, nullptr,
Jamie Madill253038d2018-08-30 16:18:35 -0400180 &mCurrentElementArrayBufferOffset, nullptr));
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500181 mCurrentElementArrayBuffer = dynamicBuffer->getCurrentBuffer();
Jamie Madill8dc27f92018-11-29 11:45:44 -0500182 if (indexType == gl::DrawElementsType::UnsignedByte)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400183 {
184 // Unsigned bytes don't have direct support in Vulkan so we have to expand the
185 // memory to a GLushort.
Jamie Madill253038d2018-08-30 16:18:35 -0400186 const GLubyte *in = static_cast<const GLubyte *>(sourcePointer);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400187 GLushort *expandedDst = reinterpret_cast<GLushort *>(dst);
Jamie Madill253038d2018-08-30 16:18:35 -0400188 for (size_t index = 0; index < indexCount; index++)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400189 {
190 expandedDst[index] = static_cast<GLushort>(in[index]);
191 }
192 }
193 else
194 {
Jamie Madill253038d2018-08-30 16:18:35 -0400195 memcpy(dst, sourcePointer, amount);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400196 }
Jamie Madill253038d2018-08-30 16:18:35 -0400197 ANGLE_TRY(dynamicBuffer->flush(contextVk));
Jamie Madill7c985f52018-11-29 18:16:17 -0500198 return angle::Result::Continue;
Frank Henigman17448952017-01-05 15:48:26 -0500199}
200
Frank Henigmane4523822018-07-19 16:10:53 -0400201// We assume the buffer is completely full of the same kind of data and convert
202// and/or align it as we copy it to a DynamicBuffer. The assumption could be wrong
203// but the alternative of copying it piecemeal on each draw would have a lot more
204// overhead.
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100205angle::Result VertexArrayVk::convertVertexBufferGpu(ContextVk *contextVk,
206 BufferVk *srcBuffer,
207 const gl::VertexBinding &binding,
208 size_t attribIndex)
209{
210 RendererVk *renderer = contextVk->getRenderer();
211
212 const angle::Format &srcFormat = mCurrentArrayBufferFormats[attribIndex]->angleFormat();
213 const angle::Format &destFormat = mCurrentArrayBufferFormats[attribIndex]->bufferFormat();
214
215 ASSERT(binding.getStride() % (srcFormat.pixelBytes / srcFormat.channelCount()) == 0);
216
217 unsigned srcFormatSize = srcFormat.pixelBytes;
218 unsigned destFormatSize = destFormat.pixelBytes;
219
220 size_t numVertices = GetVertexCount(srcBuffer, binding, srcFormatSize);
221 if (numVertices == 0)
222 {
223 return angle::Result::Continue;
224 }
225
226 ASSERT(GetVertexInputAlignment(*mCurrentArrayBufferFormats[attribIndex]) <=
227 kMaxVertexFormatAlignment);
228
229 // Allocate buffer for results
230 mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(renderer);
231 ANGLE_TRY(mCurrentArrayBufferConversion[attribIndex].allocate(
232 contextVk, numVertices * destFormatSize, nullptr, nullptr,
233 &mCurrentArrayBufferOffsets[attribIndex], nullptr));
234 mCurrentArrayBuffers[attribIndex] =
235 mCurrentArrayBufferConversion[attribIndex].getCurrentBuffer();
236
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100237 UtilsVk::ConvertVertexParameters params;
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100238 params.vertexCount = numVertices;
239 params.srcFormat = &srcFormat;
240 params.destFormat = &destFormat;
241 params.srcStride = binding.getStride();
242 params.srcOffset = binding.getOffset();
243 params.destOffset = static_cast<size_t>(mCurrentArrayBufferOffsets[attribIndex]);
244
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100245 ANGLE_TRY(renderer->getUtils().convertVertexBuffer(contextVk, mCurrentArrayBuffers[attribIndex],
246 &srcBuffer->getBuffer(), params));
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100247
248 mCurrentArrayBufferHandles[attribIndex] =
249 mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle();
250 mCurrentArrayBufferConversionCanRelease[attribIndex] = true;
251
252 return angle::Result::Continue;
253}
254
255angle::Result VertexArrayVk::convertVertexBufferCpu(ContextVk *contextVk,
256 BufferVk *srcBuffer,
257 const gl::VertexBinding &binding,
258 size_t attribIndex)
Frank Henigmane4523822018-07-19 16:10:53 -0400259{
Frank Henigman9d84ccb2018-09-12 18:09:02 -0400260 // Needed before reading buffer or we could get stale data.
Jamie Madilla064c272018-08-30 16:18:34 -0400261 ANGLE_TRY(contextVk->getRenderer()->finish(contextVk));
Frank Henigmane4523822018-07-19 16:10:53 -0400262
263 unsigned srcFormatSize = mCurrentArrayBufferFormats[attribIndex]->angleFormat().pixelBytes;
Jamie Madilla064c272018-08-30 16:18:34 -0400264 unsigned dstFormatSize = mCurrentArrayBufferStrides[attribIndex];
265
266 mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(contextVk->getRenderer());
Frank Henigmane4523822018-07-19 16:10:53 -0400267
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100268 size_t numVertices = GetVertexCount(srcBuffer, binding, srcFormatSize);
269 if (numVertices == 0)
270 {
Jamie Madill7c985f52018-11-29 18:16:17 -0500271 return angle::Result::Continue;
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100272 }
Frank Henigmane4523822018-07-19 16:10:53 -0400273
Jamie Madill77abad82018-10-25 17:03:48 -0400274 void *src = nullptr;
Jamie Madilla064c272018-08-30 16:18:34 -0400275 ANGLE_TRY(srcBuffer->mapImpl(contextVk, &src));
276 const uint8_t *srcBytes = reinterpret_cast<const uint8_t *>(src);
277 srcBytes += binding.getOffset();
jchen105dc0a6f2018-09-20 14:30:45 +0800278 ASSERT(GetVertexInputAlignment(*mCurrentArrayBufferFormats[attribIndex]) <=
279 kMaxVertexFormatAlignment);
Jamie Madilla064c272018-08-30 16:18:34 -0400280 ANGLE_TRY(StreamVertexData(contextVk, &mCurrentArrayBufferConversion[attribIndex], srcBytes,
281 numVertices * dstFormatSize, 0, numVertices, binding.getStride(),
282 mCurrentArrayBufferFormats[attribIndex]->vertexLoadFunction,
Shahbaz Youssefiec063052018-12-06 01:58:06 +0100283 &mCurrentArrayBuffers[attribIndex],
Jamie Madilla064c272018-08-30 16:18:34 -0400284 &mCurrentArrayBufferOffsets[attribIndex]));
285 ANGLE_TRY(srcBuffer->unmapImpl(contextVk));
Frank Henigmane4523822018-07-19 16:10:53 -0400286
Shahbaz Youssefiec063052018-12-06 01:58:06 +0100287 mCurrentArrayBufferHandles[attribIndex] =
288 mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle();
Frank Henigmane4523822018-07-19 16:10:53 -0400289 mCurrentArrayBufferConversionCanRelease[attribIndex] = true;
Frank Henigmane4523822018-07-19 16:10:53 -0400290
Jamie Madill7c985f52018-11-29 18:16:17 -0500291 return angle::Result::Continue;
Frank Henigmane4523822018-07-19 16:10:53 -0400292}
293
294void VertexArrayVk::ensureConversionReleased(RendererVk *renderer, size_t attribIndex)
295{
296 if (mCurrentArrayBufferConversionCanRelease[attribIndex])
297 {
298 mCurrentArrayBufferConversion[attribIndex].release(renderer);
299 mCurrentArrayBufferConversionCanRelease[attribIndex] = false;
300 }
301}
302
303#define ANGLE_VERTEX_DIRTY_ATTRIB_FUNC(INDEX) \
304 case gl::VertexArray::DIRTY_BIT_ATTRIB_0 + INDEX: \
305 ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
306 bindings[attribs[INDEX].bindingIndex], INDEX)); \
Jamie Madillbc5834c2018-11-06 11:13:50 -0500307 invalidateContext = true; \
Jamie Madilla56467e2018-04-11 16:19:41 -0400308 break;
309
Frank Henigmane4523822018-07-19 16:10:53 -0400310#define ANGLE_VERTEX_DIRTY_BINDING_FUNC(INDEX) \
311 case gl::VertexArray::DIRTY_BIT_BINDING_0 + INDEX: \
312 ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
313 bindings[attribs[INDEX].bindingIndex], INDEX)); \
Jamie Madillbc5834c2018-11-06 11:13:50 -0500314 invalidateContext = true; \
Jamie Madilla56467e2018-04-11 16:19:41 -0400315 break;
316
Frank Henigmane4523822018-07-19 16:10:53 -0400317#define ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC(INDEX) \
318 case gl::VertexArray::DIRTY_BIT_BUFFER_DATA_0 + INDEX: \
319 ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
320 bindings[attribs[INDEX].bindingIndex], INDEX)); \
Jamie Madilla56467e2018-04-11 16:19:41 -0400321 break;
322
Jamie Madill6f755b22018-10-09 12:48:54 -0400323angle::Result VertexArrayVk::syncState(const gl::Context *context,
324 const gl::VertexArray::DirtyBits &dirtyBits,
325 const gl::VertexArray::DirtyAttribBitsArray &attribBits,
326 const gl::VertexArray::DirtyBindingBitsArray &bindingBits)
Jamie Madilldd43e6c2017-03-24 14:18:49 -0400327{
328 ASSERT(dirtyBits.any());
Jamie Madill72106562017-03-24 14:18:50 -0400329
Jamie Madillbc5834c2018-11-06 11:13:50 -0500330 bool invalidateContext = false;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400331
Jamie Madill5a4c9322018-07-16 11:01:58 -0400332 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madillbd159f02017-10-09 19:39:06 -0400333
334 // Rebuild current attribute buffers cache. This will fail horribly if the buffer changes.
335 // TODO(jmadill): Handle buffer storage changes.
336 const auto &attribs = mState.getVertexAttributes();
337 const auto &bindings = mState.getVertexBindings();
338
Jamie Madill09463932018-04-04 05:26:59 -0400339 for (size_t dirtyBit : dirtyBits)
Jamie Madillbd159f02017-10-09 19:39:06 -0400340 {
Jamie Madill09463932018-04-04 05:26:59 -0400341 switch (dirtyBit)
Jamie Madillda854a22017-11-30 17:24:21 -0500342 {
Jamie Madill09463932018-04-04 05:26:59 -0400343 case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER:
Jamie Madillda854a22017-11-30 17:24:21 -0500344 {
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400345 gl::Buffer *bufferGL = mState.getElementArrayBuffer();
Jamie Madill09463932018-04-04 05:26:59 -0400346 if (bufferGL)
347 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500348 BufferVk *bufferVk = vk::GetImpl(bufferGL);
349 mCurrentElementArrayBuffer = &bufferVk->getBuffer();
Jamie Madill09463932018-04-04 05:26:59 -0400350 }
351 else
352 {
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500353 mCurrentElementArrayBuffer = nullptr;
Jamie Madill09463932018-04-04 05:26:59 -0400354 }
Luc Ferron387b3b32018-05-28 10:11:57 -0400355
356 mCurrentElementArrayBufferOffset = 0;
357 mLineLoopBufferFirstIndex.reset();
358 mLineLoopBufferLastIndex.reset();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400359 contextVk->setIndexBufferDirty();
Jamie Madillb8e39662018-04-04 11:41:42 -0400360 mDirtyLineLoopTranslation = true;
Jamie Madill09463932018-04-04 05:26:59 -0400361 break;
Jamie Madillda854a22017-11-30 17:24:21 -0500362 }
Jamie Madill09463932018-04-04 05:26:59 -0400363
364 case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA:
Jamie Madillc3755fc2018-04-05 08:39:13 -0400365 mLineLoopBufferFirstIndex.reset();
366 mLineLoopBufferLastIndex.reset();
Jamie Madillb8e39662018-04-04 11:41:42 -0400367 mDirtyLineLoopTranslation = true;
Jamie Madill09463932018-04-04 05:26:59 -0400368 break;
369
Jamie Madilla56467e2018-04-11 16:19:41 -0400370 ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_ATTRIB_FUNC);
371 ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BINDING_FUNC);
372 ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC);
373
Jamie Madill09463932018-04-04 05:26:59 -0400374 default:
Jamie Madilla56467e2018-04-11 16:19:41 -0400375 UNREACHABLE();
Jamie Madill09463932018-04-04 05:26:59 -0400376 break;
Jamie Madillbd159f02017-10-09 19:39:06 -0400377 }
378 }
Frank Henigman0af5b862018-03-27 20:19:33 -0400379
Jamie Madillbc5834c2018-11-06 11:13:50 -0500380 if (invalidateContext)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400381 {
Jamie Madillbc5834c2018-11-06 11:13:50 -0500382 contextVk->invalidateVertexAndIndexBuffers();
Jamie Madillc3755fc2018-04-05 08:39:13 -0400383 }
384
Jamie Madill7c985f52018-11-29 18:16:17 -0500385 return angle::Result::Continue;
Jamie Madillbd159f02017-10-09 19:39:06 -0400386}
387
Frank Henigmane4523822018-07-19 16:10:53 -0400388angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
389 const gl::VertexAttribute &attrib,
390 const gl::VertexBinding &binding,
391 size_t attribIndex)
Jamie Madilla56467e2018-04-11 16:19:41 -0400392{
393 // Invalidate the input description for pipelines.
394 mDirtyPackedInputs.set(attribIndex);
395
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100396 RendererVk *renderer = contextVk->getRenderer();
397 bool releaseConversion = true;
398 bool anyVertexBufferConvertedOnGpu = false;
Jamie Madill5a4c9322018-07-16 11:01:58 -0400399
Jamie Madilla56467e2018-04-11 16:19:41 -0400400 if (attrib.enabled)
401 {
Frank Henigman67c388e2018-07-19 19:16:11 -0400402 gl::Buffer *bufferGL = binding.getBuffer().get();
Frank Henigman419acc82018-06-24 19:57:31 -0400403 mCurrentArrayBufferFormats[attribIndex] = &renderer->getFormat(GetVertexFormatID(attrib));
Frank Henigmane4523822018-07-19 16:10:53 -0400404
Jamie Madilla56467e2018-04-11 16:19:41 -0400405 if (bufferGL)
406 {
Frank Henigmane4523822018-07-19 16:10:53 -0400407 BufferVk *bufferVk = vk::GetImpl(bufferGL);
Jamie Madilldbc605c2019-01-04 16:39:14 -0500408 const angle::Format &angleFormat =
409 mCurrentArrayBufferFormats[attribIndex]->angleFormat();
410 bool bindingIsAligned = BindingIsAligned(binding, angleFormat, attrib.size);
Frank Henigman419acc82018-06-24 19:57:31 -0400411
Frank Henigmane4523822018-07-19 16:10:53 -0400412 if (mCurrentArrayBufferFormats[attribIndex]->vertexLoadRequiresConversion ||
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100413 !bindingIsAligned)
Frank Henigmane4523822018-07-19 16:10:53 -0400414 {
Jamie Madilla064c272018-08-30 16:18:34 -0400415 mCurrentArrayBufferStrides[attribIndex] =
416 mCurrentArrayBufferFormats[attribIndex]->bufferFormat().pixelBytes;
417
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100418 if (bindingIsAligned)
419 {
420 ANGLE_TRY(convertVertexBufferGpu(contextVk, bufferVk, binding, attribIndex));
421 anyVertexBufferConvertedOnGpu = true;
422 }
423 else
424 {
425 // TODO(syoussefi): Implement unaligned vertex buffer conversions in compute.
426 // http://anglebug.com/3009
427 ANGLE_TRY(convertVertexBufferCpu(contextVk, bufferVk, binding, attribIndex));
428 }
Frank Henigmane4523822018-07-19 16:10:53 -0400429
Jamie Madill7c985f52018-11-29 18:16:17 -0500430 releaseConversion = false;
Frank Henigmane4523822018-07-19 16:10:53 -0400431 }
432 else
433 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500434 mCurrentArrayBuffers[attribIndex] = &bufferVk->getBuffer();
Jamie Madill2d03ff42018-09-27 15:04:26 -0400435 mCurrentArrayBufferHandles[attribIndex] =
436 bufferVk->getBuffer().getBuffer().getHandle();
Jamie Madill77abad82018-10-25 17:03:48 -0400437 mCurrentArrayBufferOffsets[attribIndex] = binding.getOffset();
438 mCurrentArrayBufferStrides[attribIndex] = binding.getStride();
Frank Henigmane4523822018-07-19 16:10:53 -0400439 }
Jamie Madilla56467e2018-04-11 16:19:41 -0400440 }
441 else
442 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500443 mCurrentArrayBuffers[attribIndex] = nullptr;
444 mCurrentArrayBufferHandles[attribIndex] = VK_NULL_HANDLE;
445 mCurrentArrayBufferOffsets[attribIndex] = 0;
Frank Henigman419acc82018-06-24 19:57:31 -0400446 mCurrentArrayBufferStrides[attribIndex] =
Frank Henigmane4523822018-07-19 16:10:53 -0400447 mCurrentArrayBufferFormats[attribIndex]->bufferFormat().pixelBytes;
Jamie Madilla56467e2018-04-11 16:19:41 -0400448 }
Jamie Madilla56467e2018-04-11 16:19:41 -0400449 }
450 else
451 {
Jamie Madill5a4c9322018-07-16 11:01:58 -0400452 contextVk->invalidateDefaultAttribute(attribIndex);
453
454 // These will be filled out by the ContextVk.
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500455 mCurrentArrayBuffers[attribIndex] = nullptr;
456 mCurrentArrayBufferHandles[attribIndex] = VK_NULL_HANDLE;
457 mCurrentArrayBufferOffsets[attribIndex] = 0;
458 mCurrentArrayBufferStrides[attribIndex] = 0;
Jamie Madill5a4c9322018-07-16 11:01:58 -0400459 mCurrentArrayBufferFormats[attribIndex] =
Jamie Madillba365932018-07-18 17:23:46 -0400460 &renderer->getFormat(angle::FormatID::R32G32B32A32_FLOAT);
Jamie Madilla56467e2018-04-11 16:19:41 -0400461 }
Frank Henigmane4523822018-07-19 16:10:53 -0400462
Shahbaz Youssefi611bbaa2018-12-06 01:59:53 +0100463 if (anyVertexBufferConvertedOnGpu && renderer->getFeatures().flushAfterVertexConversion)
464 {
465 ANGLE_TRY(renderer->flush(contextVk));
466 }
467
Frank Henigmane4523822018-07-19 16:10:53 -0400468 if (releaseConversion)
469 ensureConversionReleased(renderer, attribIndex);
470
Jamie Madill7c985f52018-11-29 18:16:17 -0500471 return angle::Result::Continue;
Jamie Madilla56467e2018-04-11 16:19:41 -0400472}
473
Frank Henigman419acc82018-06-24 19:57:31 -0400474void VertexArrayVk::updatePackedInputDescriptions()
Jamie Madillebf72992017-10-13 14:09:45 -0400475{
Jamie Madilldbc605c2019-01-04 16:39:14 -0500476 ASSERT(mDirtyPackedInputs.any());
Jamie Madillebf72992017-10-13 14:09:45 -0400477
478 const auto &attribs = mState.getVertexAttributes();
479 const auto &bindings = mState.getVertexBindings();
480
Jamie Madill112a3a82018-01-23 13:04:06 -0500481 for (auto attribIndex : mDirtyPackedInputs)
Jamie Madillebf72992017-10-13 14:09:45 -0400482 {
483 const auto &attrib = attribs[attribIndex];
484 const auto &binding = bindings[attrib.bindingIndex];
485 if (attrib.enabled)
486 {
Frank Henigman419acc82018-06-24 19:57:31 -0400487 updatePackedInputInfo(static_cast<uint32_t>(attribIndex), binding, attrib);
Jamie Madillebf72992017-10-13 14:09:45 -0400488 }
489 else
490 {
Jamie Madill5a4c9322018-07-16 11:01:58 -0400491 vk::PackedVertexInputBindingDesc &bindingDesc = mPackedInputBindings[attribIndex];
492 bindingDesc.stride = 0;
493 bindingDesc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
494
Jamie Madill77b24362018-11-05 22:39:29 -0500495 mPackedInputAttributes.formats[attribIndex] =
496 static_cast<uint16_t>(VK_FORMAT_R32G32B32A32_SFLOAT);
497 mPackedInputAttributes.offsets[attribIndex] = 0;
Jamie Madillebf72992017-10-13 14:09:45 -0400498 }
499 }
500
Jamie Madill112a3a82018-01-23 13:04:06 -0500501 mDirtyPackedInputs.reset();
502}
503
Frank Henigman419acc82018-06-24 19:57:31 -0400504void VertexArrayVk::updatePackedInputInfo(uint32_t attribIndex,
Jamie Madill112a3a82018-01-23 13:04:06 -0500505 const gl::VertexBinding &binding,
506 const gl::VertexAttribute &attrib)
507{
508 vk::PackedVertexInputBindingDesc &bindingDesc = mPackedInputBindings[attribIndex];
509
Frank Henigman419acc82018-06-24 19:57:31 -0400510 bindingDesc.stride = static_cast<uint16_t>(mCurrentArrayBufferStrides[attribIndex]);
Jamie Madill112a3a82018-01-23 13:04:06 -0500511 bindingDesc.inputRate = static_cast<uint16_t>(
512 binding.getDivisor() > 0 ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX);
513
Frank Henigman419acc82018-06-24 19:57:31 -0400514 VkFormat vkFormat = mCurrentArrayBufferFormats[attribIndex]->vkBufferFormat;
Jamie Madill112a3a82018-01-23 13:04:06 -0500515 ASSERT(vkFormat <= std::numeric_limits<uint16_t>::max());
Frank Henigman8c379f32018-06-21 19:55:05 -0400516 if (vkFormat == VK_FORMAT_UNDEFINED)
517 {
Frank Henigman8c379f32018-06-21 19:55:05 -0400518 UNIMPLEMENTED();
519 }
Jamie Madill112a3a82018-01-23 13:04:06 -0500520
Jamie Madill77b24362018-11-05 22:39:29 -0500521 mPackedInputAttributes.formats[attribIndex] = static_cast<uint8_t>(vkFormat);
522 mPackedInputAttributes.offsets[attribIndex] = static_cast<uint16_t>(attrib.relativeOffset);
Jamie Madillebf72992017-10-13 14:09:45 -0400523}
524
Jamie Madill88fc6da2018-08-30 16:18:36 -0400525angle::Result VertexArrayVk::updateClientAttribs(const gl::Context *context,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400526 GLint firstVertex,
527 GLsizei vertexOrIndexCount,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500528 gl::DrawElementsType indexTypeOrInvalid,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400529 const void *indices)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400530{
Jamie Madill77abad82018-10-25 17:03:48 -0400531 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400532 const gl::AttributesMask &clientAttribs = context->getStateCache().getActiveClientAttribsMask();
Jamie Madill21061022018-07-12 23:56:30 -0400533
Jamie Madill88fc6da2018-08-30 16:18:36 -0400534 ASSERT(clientAttribs.any());
Jamie Madillc1fd7372018-10-26 22:48:39 -0400535
536 GLint startVertex;
537 size_t vertexCount;
Jamie Madill8dc27f92018-11-29 11:45:44 -0500538 ANGLE_TRY(GetVertexRangeInfo(context, firstVertex, vertexOrIndexCount, indexTypeOrInvalid,
539 indices, 0, &startVertex, &vertexCount));
Jamie Madill88fc6da2018-08-30 16:18:36 -0400540
541 mDynamicVertexData.releaseRetainedBuffers(contextVk->getRenderer());
542
543 const auto &attribs = mState.getVertexAttributes();
544 const auto &bindings = mState.getVertexBindings();
545
546 // TODO(fjhenigman): When we have a bunch of interleaved attributes, they end up
547 // un-interleaved, wasting space and copying time. Consider improving on that.
548 for (size_t attribIndex : clientAttribs)
549 {
550 const gl::VertexAttribute &attrib = attribs[attribIndex];
551 const gl::VertexBinding &binding = bindings[attrib.bindingIndex];
552 ASSERT(attrib.enabled && binding.getBuffer().get() == nullptr);
553
554 const size_t bytesToAllocate =
Jamie Madillc1fd7372018-10-26 22:48:39 -0400555 (startVertex + vertexCount) * mCurrentArrayBufferStrides[attribIndex];
556 const uint8_t *src =
557 static_cast<const uint8_t *>(attrib.pointer) + startVertex * binding.getStride();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400558
Jamie Madillc1fd7372018-10-26 22:48:39 -0400559 size_t destOffset = startVertex * mCurrentArrayBufferStrides[attribIndex];
jchen105dc0a6f2018-09-20 14:30:45 +0800560 ASSERT(GetVertexInputAlignment(*mCurrentArrayBufferFormats[attribIndex]) <=
561 kMaxVertexFormatAlignment);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400562
563 // Only vertexCount() vertices will be used by the upcoming draw. so that is all we copy.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400564 // We allocate space for startVertex + vertexCount so indexing will work. If we
Jamie Madill88fc6da2018-08-30 16:18:36 -0400565 // don't start at zero all the indices will be off.
566 // TODO(fjhenigman): See if we can account for indices being off by adjusting the
567 // offset, thus avoiding wasted memory.
Jamie Madillc1fd7372018-10-26 22:48:39 -0400568 ANGLE_TRY(StreamVertexData(
569 contextVk, &mDynamicVertexData, src, bytesToAllocate, destOffset, vertexCount,
570 binding.getStride(), mCurrentArrayBufferFormats[attribIndex]->vertexLoadFunction,
Shahbaz Youssefiec063052018-12-06 01:58:06 +0100571 &mCurrentArrayBuffers[attribIndex], &mCurrentArrayBufferOffsets[attribIndex]));
572 mCurrentArrayBufferHandles[attribIndex] =
573 mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400574 }
575
Jamie Madill7c985f52018-11-29 18:16:17 -0500576 return angle::Result::Continue;
Jamie Madill88fc6da2018-08-30 16:18:36 -0400577}
578
579angle::Result VertexArrayVk::handleLineLoop(ContextVk *contextVk,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400580 GLint firstVertex,
581 GLsizei vertexOrIndexCount,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500582 gl::DrawElementsType indexTypeOrInvalid,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400583 const void *indices)
Jamie Madill88fc6da2018-08-30 16:18:36 -0400584{
Jamie Madill8dc27f92018-11-29 11:45:44 -0500585 if (indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
Jamie Madill88fc6da2018-08-30 16:18:36 -0400586 {
587 // Handle GL_LINE_LOOP drawElements.
588 if (mDirtyLineLoopTranslation)
589 {
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400590 gl::Buffer *elementArrayBuffer = mState.getElementArrayBuffer();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400591
592 if (!elementArrayBuffer)
593 {
Frank Henigman85c4b432018-09-19 23:35:00 -0400594 ANGLE_TRY(mLineLoopHelper.streamIndices(
Jamie Madill8dc27f92018-11-29 11:45:44 -0500595 contextVk, indexTypeOrInvalid, vertexOrIndexCount,
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500596 reinterpret_cast<const uint8_t *>(indices), &mCurrentElementArrayBuffer,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400597 &mCurrentElementArrayBufferOffset));
Jamie Madill88fc6da2018-08-30 16:18:36 -0400598 }
599 else
600 {
601 // When using an element array buffer, 'indices' is an offset to the first element.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400602 intptr_t offset = reinterpret_cast<intptr_t>(indices);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400603 BufferVk *elementArrayBufferVk = vk::GetImpl(elementArrayBuffer);
604 ANGLE_TRY(mLineLoopHelper.getIndexBufferForElementArrayBuffer(
Jamie Madill8dc27f92018-11-29 11:45:44 -0500605 contextVk, elementArrayBufferVk, indexTypeOrInvalid, vertexOrIndexCount, offset,
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500606 &mCurrentElementArrayBuffer, &mCurrentElementArrayBufferOffset));
Jamie Madill88fc6da2018-08-30 16:18:36 -0400607 }
608 }
609
610 // If we've had a drawArrays call with a line loop before, we want to make sure this is
611 // invalidated the next time drawArrays is called since we use the same index buffer for
612 // both calls.
613 mLineLoopBufferFirstIndex.reset();
614 mLineLoopBufferLastIndex.reset();
Jamie Madill7c985f52018-11-29 18:16:17 -0500615 return angle::Result::Continue;
Jamie Madill88fc6da2018-08-30 16:18:36 -0400616 }
Jamie Madillc3755fc2018-04-05 08:39:13 -0400617
Jamie Madill18e323a2018-05-11 16:54:17 -0400618 // Note: Vertex indexes can be arbitrarily large.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400619 uint32_t clampedVertexCount = gl::clampCast<uint32_t>(vertexOrIndexCount);
Jamie Madill18e323a2018-05-11 16:54:17 -0400620
Jamie Madillc3755fc2018-04-05 08:39:13 -0400621 // Handle GL_LINE_LOOP drawArrays.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400622 size_t lastVertex = static_cast<size_t>(firstVertex + clampedVertexCount);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400623 if (!mLineLoopBufferFirstIndex.valid() || !mLineLoopBufferLastIndex.valid() ||
Jamie Madillbfe31c42018-10-25 17:03:47 -0400624 mLineLoopBufferFirstIndex != firstVertex || mLineLoopBufferLastIndex != lastVertex)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400625 {
Jamie Madillbfe31c42018-10-25 17:03:47 -0400626 ANGLE_TRY(mLineLoopHelper.getIndexBufferForDrawArrays(
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500627 contextVk, clampedVertexCount, firstVertex, &mCurrentElementArrayBuffer,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400628 &mCurrentElementArrayBufferOffset));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400629
Jamie Madillbfe31c42018-10-25 17:03:47 -0400630 mLineLoopBufferFirstIndex = firstVertex;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400631 mLineLoopBufferLastIndex = lastVertex;
632 }
633
Jamie Madill7c985f52018-11-29 18:16:17 -0500634 return angle::Result::Continue;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400635}
636
Jamie Madill88fc6da2018-08-30 16:18:36 -0400637angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400638 GLsizei indexCount,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500639 gl::DrawElementsType type,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400640 const void *indices)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400641{
Jamie Madill8dc27f92018-11-29 11:45:44 -0500642 ASSERT(type != gl::DrawElementsType::InvalidEnum);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400643
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500644 RendererVk *renderer = contextVk->getRenderer();
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400645 gl::Buffer *glBuffer = mState.getElementArrayBuffer();
Jamie Madillc3755fc2018-04-05 08:39:13 -0400646
Jamie Madill88fc6da2018-08-30 16:18:36 -0400647 if (!glBuffer)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400648 {
Jamie Madillbfe31c42018-10-25 17:03:47 -0400649 ANGLE_TRY(streamIndexData(contextVk, type, indexCount, indices, &mDynamicIndexData));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400650 }
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500651 else if (renderer->getFormat(angle::FormatID::R16_UINT).vkSupportsStorageBuffer)
652 {
653 BufferVk *bufferVk = vk::GetImpl(glBuffer);
654
655 ASSERT(type == gl::DrawElementsType::UnsignedByte);
656
657 intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices);
658 size_t srcDataSize = static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData;
659
660 mTranslatedByteIndexData.releaseRetainedBuffers(renderer);
661
662 ANGLE_TRY(mTranslatedByteIndexData.allocate(contextVk, sizeof(GLushort) * srcDataSize,
663 nullptr, nullptr,
664 &mCurrentElementArrayBufferOffset, nullptr));
665 mCurrentElementArrayBuffer = mTranslatedByteIndexData.getCurrentBuffer();
666
667 vk::BufferHelper *dest = mTranslatedByteIndexData.getCurrentBuffer();
668 vk::BufferHelper *src = &bufferVk->getBuffer();
669
670 ANGLE_TRY(src->initBufferView(contextVk, renderer->getFormat(angle::FormatID::R8_UINT)));
671 ANGLE_TRY(dest->initBufferView(contextVk, renderer->getFormat(angle::FormatID::R16_UINT)));
672
673 // Copy relevant section of the source into destination at allocated offset. Note that the
674 // offset returned by allocate() above is in bytes, while our allocated array is of
675 // GLushorts.
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100676 UtilsVk::CopyParameters params = {};
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500677 params.destOffset =
678 static_cast<size_t>(mCurrentElementArrayBufferOffset) / sizeof(GLushort);
679 params.srcOffset = offsetIntoSrcData;
680 params.size = srcDataSize;
681
682 // Note: this is a copy, which implicitly converts between formats. Once support for
683 // primitive restart is added, a specialized shader is likely needed to special case 0xFF ->
684 // 0xFFFF.
Shahbaz Youssefie3219402018-12-08 16:54:14 +0100685 ANGLE_TRY(renderer->getUtils().copyBuffer(contextVk, dest, src, params));
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500686 }
Jamie Madill88fc6da2018-08-30 16:18:36 -0400687 else
Jamie Madillc3755fc2018-04-05 08:39:13 -0400688 {
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500689 // If it's not possible to convert the buffer with compute, opt for a CPU read back for now.
690 // TODO(syoussefi): R8G8B8A8_UINT is required to have storage texel buffer support, so a
691 // specialized shader code can be made to read two ubyte indices and output them in R and B
692 // (or A and G based on endianness?) with 0 on the other channels. If specialized, we might
693 // as well support the ubyte to ushort case with correct handling of primitive restart.
694 // http://anglebug.com/3003
695
Frank Henigman9d84ccb2018-09-12 18:09:02 -0400696 // Needed before reading buffer or we could get stale data.
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500697 ANGLE_TRY(renderer->finish(contextVk));
Frank Henigman9d84ccb2018-09-12 18:09:02 -0400698
Jamie Madill8dc27f92018-11-29 11:45:44 -0500699 ASSERT(type == gl::DrawElementsType::UnsignedByte);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400700 // Unsigned bytes don't have direct support in Vulkan so we have to expand the
701 // memory to a GLushort.
702 BufferVk *bufferVk = vk::GetImpl(glBuffer);
703 void *srcDataMapping = nullptr;
704 ASSERT(!glBuffer->isMapped());
705 ANGLE_TRY(bufferVk->mapImpl(contextVk, &srcDataMapping));
706 uint8_t *srcData = static_cast<uint8_t *>(srcDataMapping);
Jamie Madillbfe31c42018-10-25 17:03:47 -0400707 intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400708 srcData += offsetIntoSrcData;
Jamie Madill253038d2018-08-30 16:18:35 -0400709
Jamie Madillbfe31c42018-10-25 17:03:47 -0400710 ANGLE_TRY(streamIndexData(contextVk, type,
Jamie Madill88fc6da2018-08-30 16:18:36 -0400711 static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData,
712 srcData, &mTranslatedByteIndexData));
Luc Ferron6ed167a2018-06-13 13:45:55 -0400713
Jamie Madill88fc6da2018-08-30 16:18:36 -0400714 ANGLE_TRY(bufferVk->unmapImpl(contextVk));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400715 }
716
Jamie Madill7c985f52018-11-29 18:16:17 -0500717 return angle::Result::Continue;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400718}
Jamie Madill5a4c9322018-07-16 11:01:58 -0400719
720void VertexArrayVk::updateDefaultAttrib(RendererVk *renderer,
721 size_t attribIndex,
722 VkBuffer bufferHandle,
723 uint32_t offset)
724{
725 if (!mState.getEnabledAttributesMask().test(attribIndex))
726 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500727 mCurrentArrayBufferHandles[attribIndex] = bufferHandle;
728 mCurrentArrayBufferOffsets[attribIndex] = offset;
729 mCurrentArrayBuffers[attribIndex] = nullptr;
730 mCurrentArrayBufferStrides[attribIndex] = 0;
Jamie Madill5a4c9322018-07-16 11:01:58 -0400731 mCurrentArrayBufferFormats[attribIndex] =
Jamie Madillba365932018-07-18 17:23:46 -0400732 &renderer->getFormat(angle::FormatID::R32G32B32A32_FIXED);
Jamie Madill5a4c9322018-07-16 11:01:58 -0400733 mDirtyPackedInputs.set(attribIndex);
734 }
735}
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400736} // namespace rx