blob: 8476bfa186eabe86e90af172b7a7b57d67b012d5 [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 Youssefi8f1b7a62018-11-14 16:02:54 -050026constexpr size_t kDynamicVertexDataSize = 1024 * 1024;
27constexpr size_t kDynamicIndexDataSize = 1024 * 8;
28constexpr size_t kMaxVertexFormatAlignment = 4;
29constexpr VkBufferUsageFlags kVertexBufferUsageFlags = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
30 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
31 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
32constexpr VkBufferUsageFlags kIndexBufferUsageFlags = VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
33 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
34 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
Frank Henigmane4523822018-07-19 16:10:53 -040035
36bool BindingIsAligned(const gl::VertexBinding &binding, unsigned componentSize)
37{
38 return (binding.getOffset() % componentSize == 0) && (binding.getStride() % componentSize == 0);
39}
Jamie Madilla064c272018-08-30 16:18:34 -040040
41angle::Result StreamVertexData(ContextVk *contextVk,
42 vk::DynamicBuffer *dynamicBuffer,
43 const uint8_t *sourceData,
44 size_t bytesToAllocate,
45 size_t destOffset,
46 size_t vertexCount,
47 size_t stride,
48 VertexCopyFunction vertexLoadFunction,
Shahbaz Youssefiec063052018-12-06 01:58:06 +010049 vk::BufferHelper **bufferOut,
Jamie Madilla064c272018-08-30 16:18:34 -040050 VkDeviceSize *bufferOffsetOut)
51{
52 uint8_t *dst = nullptr;
Shahbaz Youssefiec063052018-12-06 01:58:06 +010053 ANGLE_TRY(dynamicBuffer->allocate(contextVk, bytesToAllocate, &dst, nullptr, bufferOffsetOut,
54 nullptr));
55 *bufferOut = dynamicBuffer->getCurrentBuffer();
Jamie Madilla064c272018-08-30 16:18:34 -040056 dst += destOffset;
57 vertexLoadFunction(sourceData, stride, vertexCount, dst);
58
59 ANGLE_TRY(dynamicBuffer->flush(contextVk));
60 return angle::Result::Continue();
61}
jchen105dc0a6f2018-09-20 14:30:45 +080062
Jamie Madillc3755fc2018-04-05 08:39:13 -040063} // anonymous namespace
Jamie Madill9e54b5a2016-05-25 12:57:39 -040064
Shahbaz Youssefi254b32c2018-11-26 11:58:03 -050065#define INIT \
66 { \
67 kVertexBufferUsageFlags, 1024 * 8, true \
Frank Henigmane4523822018-07-19 16:10:53 -040068 }
69
Luc Ferrona9ab0f32018-05-17 17:03:55 -040070VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state, RendererVk *renderer)
Jamie Madillbd159f02017-10-09 19:39:06 -040071 : VertexArrayImpl(state),
Jamie Madillda854a22017-11-30 17:24:21 -050072 mCurrentArrayBufferHandles{},
Frank Henigman17448952017-01-05 15:48:26 -050073 mCurrentArrayBufferOffsets{},
Jamie Madill03d1a5e2018-11-12 11:34:24 -050074 mCurrentArrayBuffers{},
Frank Henigman419acc82018-06-24 19:57:31 -040075 mCurrentArrayBufferFormats{},
76 mCurrentArrayBufferStrides{},
Frank Henigmane4523822018-07-19 16:10:53 -040077 mCurrentArrayBufferConversion{{
Jamie Madillb980c562018-11-27 11:34:27 -050078 INIT,
79 INIT,
80 INIT,
81 INIT,
82 INIT,
83 INIT,
84 INIT,
85 INIT,
86 INIT,
87 INIT,
88 INIT,
89 INIT,
90 INIT,
91 INIT,
92 INIT,
Frank Henigmane4523822018-07-19 16:10:53 -040093 INIT,
94 }},
95 mCurrentArrayBufferConversionCanRelease{},
Jamie Madillc3755fc2018-04-05 08:39:13 -040096 mCurrentElementArrayBufferOffset(0),
Jamie Madill03d1a5e2018-11-12 11:34:24 -050097 mCurrentElementArrayBuffer(nullptr),
Jamie Madill77b24362018-11-05 22:39:29 -050098 mPackedInputBindings{},
99 mPackedInputAttributes{},
Shahbaz Youssefi254b32c2018-11-26 11:58:03 -0500100 mDynamicVertexData(kVertexBufferUsageFlags, kDynamicVertexDataSize, true),
101 mDynamicIndexData(kIndexBufferUsageFlags, kDynamicIndexDataSize, true),
102 mTranslatedByteIndexData(kIndexBufferUsageFlags, kDynamicIndexDataSize, true),
Luc Ferrona9ab0f32018-05-17 17:03:55 -0400103 mLineLoopHelper(renderer),
Jamie Madill88fc6da2018-08-30 16:18:36 -0400104 mDirtyLineLoopTranslation(true)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400105{
Jamie Madillda854a22017-11-30 17:24:21 -0500106 mCurrentArrayBufferHandles.fill(VK_NULL_HANDLE);
Frank Henigman17448952017-01-05 15:48:26 -0500107 mCurrentArrayBufferOffsets.fill(0);
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500108 mCurrentArrayBuffers.fill(nullptr);
Jamie Madill112a3a82018-01-23 13:04:06 -0500109
Frank Henigmane4523822018-07-19 16:10:53 -0400110 for (vk::DynamicBuffer &buffer : mCurrentArrayBufferConversion)
111 {
jchen105dc0a6f2018-09-20 14:30:45 +0800112 buffer.init(kMaxVertexFormatAlignment, renderer);
Frank Henigmane4523822018-07-19 16:10:53 -0400113 }
jchen105dc0a6f2018-09-20 14:30:45 +0800114 mDynamicVertexData.init(kMaxVertexFormatAlignment, renderer);
Luc Ferrona9ab0f32018-05-17 17:03:55 -0400115 mDynamicIndexData.init(1, renderer);
Luc Ferron6ed167a2018-06-13 13:45:55 -0400116 mTranslatedByteIndexData.init(1, renderer);
Jamie Madill0a17e482018-08-31 17:19:11 -0400117
118 // Initially consider all inputs dirty.
119 mDirtyPackedInputs.set();
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400120}
121
Jamie Madillb980c562018-11-27 11:34:27 -0500122VertexArrayVk::~VertexArrayVk() {}
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500123
Jamie Madill4928b7c2017-06-20 12:57:39 -0400124void VertexArrayVk::destroy(const gl::Context *context)
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400125{
Shahbaz Youssefifca8fd62018-11-13 13:55:48 -0500126 RendererVk *renderer = vk::GetImpl(context)->getRenderer();
127
Frank Henigmane4523822018-07-19 16:10:53 -0400128 for (vk::DynamicBuffer &buffer : mCurrentArrayBufferConversion)
129 {
Shahbaz Youssefifca8fd62018-11-13 13:55:48 -0500130 buffer.release(renderer);
Frank Henigmane4523822018-07-19 16:10:53 -0400131 }
Shahbaz Youssefifca8fd62018-11-13 13:55:48 -0500132 mDynamicVertexData.release(renderer);
133 mDynamicIndexData.release(renderer);
134 mTranslatedByteIndexData.release(renderer);
135 mLineLoopHelper.release(renderer);
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400136}
137
Jamie Madill21061022018-07-12 23:56:30 -0400138angle::Result VertexArrayVk::streamIndexData(ContextVk *contextVk,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500139 gl::DrawElementsType indexType,
Jamie Madill253038d2018-08-30 16:18:35 -0400140 size_t indexCount,
141 const void *sourcePointer,
142 vk::DynamicBuffer *dynamicBuffer)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400143{
Jamie Madill8dc27f92018-11-29 11:45:44 -0500144 ASSERT(!mState.getElementArrayBuffer() || indexType == gl::DrawElementsType::UnsignedByte);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400145
Jamie Madill253038d2018-08-30 16:18:35 -0400146 dynamicBuffer->releaseRetainedBuffers(contextVk->getRenderer());
Jamie Madilla064c272018-08-30 16:18:34 -0400147
Jamie Madill253038d2018-08-30 16:18:35 -0400148 const size_t amount = sizeof(GLushort) * indexCount;
149 GLubyte *dst = nullptr;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400150
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500151 ANGLE_TRY(dynamicBuffer->allocate(contextVk, amount, &dst, nullptr,
Jamie Madill253038d2018-08-30 16:18:35 -0400152 &mCurrentElementArrayBufferOffset, nullptr));
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500153 mCurrentElementArrayBuffer = dynamicBuffer->getCurrentBuffer();
Jamie Madill8dc27f92018-11-29 11:45:44 -0500154 if (indexType == gl::DrawElementsType::UnsignedByte)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400155 {
156 // Unsigned bytes don't have direct support in Vulkan so we have to expand the
157 // memory to a GLushort.
Jamie Madill253038d2018-08-30 16:18:35 -0400158 const GLubyte *in = static_cast<const GLubyte *>(sourcePointer);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400159 GLushort *expandedDst = reinterpret_cast<GLushort *>(dst);
Jamie Madill253038d2018-08-30 16:18:35 -0400160 for (size_t index = 0; index < indexCount; index++)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400161 {
162 expandedDst[index] = static_cast<GLushort>(in[index]);
163 }
164 }
165 else
166 {
Jamie Madill253038d2018-08-30 16:18:35 -0400167 memcpy(dst, sourcePointer, amount);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400168 }
Jamie Madill253038d2018-08-30 16:18:35 -0400169 ANGLE_TRY(dynamicBuffer->flush(contextVk));
Jamie Madill21061022018-07-12 23:56:30 -0400170 return angle::Result::Continue();
Frank Henigman17448952017-01-05 15:48:26 -0500171}
172
Frank Henigmane4523822018-07-19 16:10:53 -0400173// We assume the buffer is completely full of the same kind of data and convert
174// and/or align it as we copy it to a DynamicBuffer. The assumption could be wrong
175// but the alternative of copying it piecemeal on each draw would have a lot more
176// overhead.
Jamie Madilla064c272018-08-30 16:18:34 -0400177angle::Result VertexArrayVk::convertVertexBuffer(ContextVk *contextVk,
Frank Henigmane4523822018-07-19 16:10:53 -0400178 BufferVk *srcBuffer,
179 const gl::VertexBinding &binding,
180 size_t attribIndex)
181{
Frank Henigman9d84ccb2018-09-12 18:09:02 -0400182 // Needed before reading buffer or we could get stale data.
Jamie Madilla064c272018-08-30 16:18:34 -0400183 ANGLE_TRY(contextVk->getRenderer()->finish(contextVk));
Frank Henigmane4523822018-07-19 16:10:53 -0400184
185 unsigned srcFormatSize = mCurrentArrayBufferFormats[attribIndex]->angleFormat().pixelBytes;
Jamie Madilla064c272018-08-30 16:18:34 -0400186 unsigned dstFormatSize = mCurrentArrayBufferStrides[attribIndex];
187
188 mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(contextVk->getRenderer());
Frank Henigmane4523822018-07-19 16:10:53 -0400189
190 // Bytes usable for vertex data.
191 GLint64 bytes = srcBuffer->getSize() - binding.getOffset();
192 if (bytes < srcFormatSize)
193 return angle::Result::Continue();
194
195 // Count the last vertex. It may occupy less than a full stride.
196 size_t numVertices = 1;
197 bytes -= srcFormatSize;
198
199 // Count how many strides fit remaining space.
200 if (bytes > 0)
201 numVertices += static_cast<size_t>(bytes) / binding.getStride();
202
Jamie Madill77abad82018-10-25 17:03:48 -0400203 void *src = nullptr;
Jamie Madilla064c272018-08-30 16:18:34 -0400204 ANGLE_TRY(srcBuffer->mapImpl(contextVk, &src));
205 const uint8_t *srcBytes = reinterpret_cast<const uint8_t *>(src);
206 srcBytes += binding.getOffset();
jchen105dc0a6f2018-09-20 14:30:45 +0800207 ASSERT(GetVertexInputAlignment(*mCurrentArrayBufferFormats[attribIndex]) <=
208 kMaxVertexFormatAlignment);
Jamie Madilla064c272018-08-30 16:18:34 -0400209 ANGLE_TRY(StreamVertexData(contextVk, &mCurrentArrayBufferConversion[attribIndex], srcBytes,
210 numVertices * dstFormatSize, 0, numVertices, binding.getStride(),
211 mCurrentArrayBufferFormats[attribIndex]->vertexLoadFunction,
Shahbaz Youssefiec063052018-12-06 01:58:06 +0100212 &mCurrentArrayBuffers[attribIndex],
Jamie Madilla064c272018-08-30 16:18:34 -0400213 &mCurrentArrayBufferOffsets[attribIndex]));
214 ANGLE_TRY(srcBuffer->unmapImpl(contextVk));
Frank Henigmane4523822018-07-19 16:10:53 -0400215
Shahbaz Youssefiec063052018-12-06 01:58:06 +0100216 mCurrentArrayBufferHandles[attribIndex] =
217 mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle();
Frank Henigmane4523822018-07-19 16:10:53 -0400218 mCurrentArrayBufferConversionCanRelease[attribIndex] = true;
Frank Henigmane4523822018-07-19 16:10:53 -0400219
220 return angle::Result::Continue();
221}
222
223void VertexArrayVk::ensureConversionReleased(RendererVk *renderer, size_t attribIndex)
224{
225 if (mCurrentArrayBufferConversionCanRelease[attribIndex])
226 {
227 mCurrentArrayBufferConversion[attribIndex].release(renderer);
228 mCurrentArrayBufferConversionCanRelease[attribIndex] = false;
229 }
230}
231
232#define ANGLE_VERTEX_DIRTY_ATTRIB_FUNC(INDEX) \
233 case gl::VertexArray::DIRTY_BIT_ATTRIB_0 + INDEX: \
234 ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
235 bindings[attribs[INDEX].bindingIndex], INDEX)); \
Jamie Madillbc5834c2018-11-06 11:13:50 -0500236 invalidateContext = true; \
Jamie Madilla56467e2018-04-11 16:19:41 -0400237 break;
238
Frank Henigmane4523822018-07-19 16:10:53 -0400239#define ANGLE_VERTEX_DIRTY_BINDING_FUNC(INDEX) \
240 case gl::VertexArray::DIRTY_BIT_BINDING_0 + INDEX: \
241 ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
242 bindings[attribs[INDEX].bindingIndex], INDEX)); \
Jamie Madillbc5834c2018-11-06 11:13:50 -0500243 invalidateContext = true; \
Jamie Madilla56467e2018-04-11 16:19:41 -0400244 break;
245
Frank Henigmane4523822018-07-19 16:10:53 -0400246#define ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC(INDEX) \
247 case gl::VertexArray::DIRTY_BIT_BUFFER_DATA_0 + INDEX: \
248 ANGLE_TRY(syncDirtyAttrib(contextVk, attribs[INDEX], \
249 bindings[attribs[INDEX].bindingIndex], INDEX)); \
Jamie Madilla56467e2018-04-11 16:19:41 -0400250 break;
251
Jamie Madill6f755b22018-10-09 12:48:54 -0400252angle::Result VertexArrayVk::syncState(const gl::Context *context,
253 const gl::VertexArray::DirtyBits &dirtyBits,
254 const gl::VertexArray::DirtyAttribBitsArray &attribBits,
255 const gl::VertexArray::DirtyBindingBitsArray &bindingBits)
Jamie Madilldd43e6c2017-03-24 14:18:49 -0400256{
257 ASSERT(dirtyBits.any());
Jamie Madill72106562017-03-24 14:18:50 -0400258
Jamie Madillbc5834c2018-11-06 11:13:50 -0500259 bool invalidateContext = false;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400260
Jamie Madill5a4c9322018-07-16 11:01:58 -0400261 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madillbd159f02017-10-09 19:39:06 -0400262
263 // Rebuild current attribute buffers cache. This will fail horribly if the buffer changes.
264 // TODO(jmadill): Handle buffer storage changes.
265 const auto &attribs = mState.getVertexAttributes();
266 const auto &bindings = mState.getVertexBindings();
267
Jamie Madill09463932018-04-04 05:26:59 -0400268 for (size_t dirtyBit : dirtyBits)
Jamie Madillbd159f02017-10-09 19:39:06 -0400269 {
Jamie Madill09463932018-04-04 05:26:59 -0400270 switch (dirtyBit)
Jamie Madillda854a22017-11-30 17:24:21 -0500271 {
Jamie Madill09463932018-04-04 05:26:59 -0400272 case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER:
Jamie Madillda854a22017-11-30 17:24:21 -0500273 {
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400274 gl::Buffer *bufferGL = mState.getElementArrayBuffer();
Jamie Madill09463932018-04-04 05:26:59 -0400275 if (bufferGL)
276 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500277 BufferVk *bufferVk = vk::GetImpl(bufferGL);
278 mCurrentElementArrayBuffer = &bufferVk->getBuffer();
Jamie Madill09463932018-04-04 05:26:59 -0400279 }
280 else
281 {
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500282 mCurrentElementArrayBuffer = nullptr;
Jamie Madill09463932018-04-04 05:26:59 -0400283 }
Luc Ferron387b3b32018-05-28 10:11:57 -0400284
285 mCurrentElementArrayBufferOffset = 0;
286 mLineLoopBufferFirstIndex.reset();
287 mLineLoopBufferLastIndex.reset();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400288 contextVk->setIndexBufferDirty();
Jamie Madillb8e39662018-04-04 11:41:42 -0400289 mDirtyLineLoopTranslation = true;
Jamie Madill09463932018-04-04 05:26:59 -0400290 break;
Jamie Madillda854a22017-11-30 17:24:21 -0500291 }
Jamie Madill09463932018-04-04 05:26:59 -0400292
293 case gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER_DATA:
Jamie Madillc3755fc2018-04-05 08:39:13 -0400294 mLineLoopBufferFirstIndex.reset();
295 mLineLoopBufferLastIndex.reset();
Jamie Madillb8e39662018-04-04 11:41:42 -0400296 mDirtyLineLoopTranslation = true;
Jamie Madill09463932018-04-04 05:26:59 -0400297 break;
298
Jamie Madilla56467e2018-04-11 16:19:41 -0400299 ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_ATTRIB_FUNC);
300 ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BINDING_FUNC);
301 ANGLE_VERTEX_INDEX_CASES(ANGLE_VERTEX_DIRTY_BUFFER_DATA_FUNC);
302
Jamie Madill09463932018-04-04 05:26:59 -0400303 default:
Jamie Madilla56467e2018-04-11 16:19:41 -0400304 UNREACHABLE();
Jamie Madill09463932018-04-04 05:26:59 -0400305 break;
Jamie Madillbd159f02017-10-09 19:39:06 -0400306 }
307 }
Frank Henigman0af5b862018-03-27 20:19:33 -0400308
Jamie Madillbc5834c2018-11-06 11:13:50 -0500309 if (invalidateContext)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400310 {
Jamie Madillbc5834c2018-11-06 11:13:50 -0500311 contextVk->invalidateVertexAndIndexBuffers();
Jamie Madillc3755fc2018-04-05 08:39:13 -0400312 }
313
Jamie Madill6f755b22018-10-09 12:48:54 -0400314 return angle::Result::Continue();
Jamie Madillbd159f02017-10-09 19:39:06 -0400315}
316
Frank Henigmane4523822018-07-19 16:10:53 -0400317angle::Result VertexArrayVk::syncDirtyAttrib(ContextVk *contextVk,
318 const gl::VertexAttribute &attrib,
319 const gl::VertexBinding &binding,
320 size_t attribIndex)
Jamie Madilla56467e2018-04-11 16:19:41 -0400321{
322 // Invalidate the input description for pipelines.
323 mDirtyPackedInputs.set(attribIndex);
324
Frank Henigman67c388e2018-07-19 19:16:11 -0400325 RendererVk *renderer = contextVk->getRenderer();
Frank Henigmane4523822018-07-19 16:10:53 -0400326 bool releaseConversion = true;
Jamie Madill5a4c9322018-07-16 11:01:58 -0400327
Jamie Madilla56467e2018-04-11 16:19:41 -0400328 if (attrib.enabled)
329 {
Frank Henigman67c388e2018-07-19 19:16:11 -0400330 gl::Buffer *bufferGL = binding.getBuffer().get();
Frank Henigman419acc82018-06-24 19:57:31 -0400331 mCurrentArrayBufferFormats[attribIndex] = &renderer->getFormat(GetVertexFormatID(attrib));
Frank Henigmane4523822018-07-19 16:10:53 -0400332
Jamie Madilla56467e2018-04-11 16:19:41 -0400333 if (bufferGL)
334 {
Frank Henigmane4523822018-07-19 16:10:53 -0400335 BufferVk *bufferVk = vk::GetImpl(bufferGL);
336 unsigned componentSize =
337 mCurrentArrayBufferFormats[attribIndex]->angleFormat().pixelBytes / attrib.size;
Frank Henigman419acc82018-06-24 19:57:31 -0400338
Frank Henigmane4523822018-07-19 16:10:53 -0400339 if (mCurrentArrayBufferFormats[attribIndex]->vertexLoadRequiresConversion ||
340 !BindingIsAligned(binding, componentSize))
341 {
Jamie Madilla064c272018-08-30 16:18:34 -0400342 mCurrentArrayBufferStrides[attribIndex] =
343 mCurrentArrayBufferFormats[attribIndex]->bufferFormat().pixelBytes;
344
Frank Henigmane4523822018-07-19 16:10:53 -0400345 ANGLE_TRY(convertVertexBuffer(contextVk, bufferVk, binding, attribIndex));
346
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500347 releaseConversion = false;
Frank Henigmane4523822018-07-19 16:10:53 -0400348 }
349 else
350 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500351 mCurrentArrayBuffers[attribIndex] = &bufferVk->getBuffer();
Jamie Madill2d03ff42018-09-27 15:04:26 -0400352 mCurrentArrayBufferHandles[attribIndex] =
353 bufferVk->getBuffer().getBuffer().getHandle();
Jamie Madill77abad82018-10-25 17:03:48 -0400354 mCurrentArrayBufferOffsets[attribIndex] = binding.getOffset();
355 mCurrentArrayBufferStrides[attribIndex] = binding.getStride();
Frank Henigmane4523822018-07-19 16:10:53 -0400356 }
Jamie Madilla56467e2018-04-11 16:19:41 -0400357 }
358 else
359 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500360 mCurrentArrayBuffers[attribIndex] = nullptr;
361 mCurrentArrayBufferHandles[attribIndex] = VK_NULL_HANDLE;
362 mCurrentArrayBufferOffsets[attribIndex] = 0;
Frank Henigman419acc82018-06-24 19:57:31 -0400363 mCurrentArrayBufferStrides[attribIndex] =
Frank Henigmane4523822018-07-19 16:10:53 -0400364 mCurrentArrayBufferFormats[attribIndex]->bufferFormat().pixelBytes;
Jamie Madilla56467e2018-04-11 16:19:41 -0400365 }
Jamie Madilla56467e2018-04-11 16:19:41 -0400366 }
367 else
368 {
Jamie Madill5a4c9322018-07-16 11:01:58 -0400369 contextVk->invalidateDefaultAttribute(attribIndex);
370
371 // These will be filled out by the ContextVk.
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500372 mCurrentArrayBuffers[attribIndex] = nullptr;
373 mCurrentArrayBufferHandles[attribIndex] = VK_NULL_HANDLE;
374 mCurrentArrayBufferOffsets[attribIndex] = 0;
375 mCurrentArrayBufferStrides[attribIndex] = 0;
Jamie Madill5a4c9322018-07-16 11:01:58 -0400376 mCurrentArrayBufferFormats[attribIndex] =
Jamie Madillba365932018-07-18 17:23:46 -0400377 &renderer->getFormat(angle::FormatID::R32G32B32A32_FLOAT);
Jamie Madilla56467e2018-04-11 16:19:41 -0400378 }
Frank Henigmane4523822018-07-19 16:10:53 -0400379
380 if (releaseConversion)
381 ensureConversionReleased(renderer, attribIndex);
382
383 return angle::Result::Continue();
Jamie Madilla56467e2018-04-11 16:19:41 -0400384}
385
Shahbaz Youssefic30f45d2018-11-12 16:37:59 -0500386void VertexArrayVk::getPackedInputDescriptions(vk::GraphicsPipelineDesc *pipelineDesc)
Jamie Madillebf72992017-10-13 14:09:45 -0400387{
Frank Henigman419acc82018-06-24 19:57:31 -0400388 updatePackedInputDescriptions();
Jamie Madill112a3a82018-01-23 13:04:06 -0500389 pipelineDesc->updateVertexInputInfo(mPackedInputBindings, mPackedInputAttributes);
Jamie Madillebf72992017-10-13 14:09:45 -0400390}
391
Frank Henigman419acc82018-06-24 19:57:31 -0400392void VertexArrayVk::updatePackedInputDescriptions()
Jamie Madillebf72992017-10-13 14:09:45 -0400393{
Jamie Madill112a3a82018-01-23 13:04:06 -0500394 if (!mDirtyPackedInputs.any())
Jamie Madillebf72992017-10-13 14:09:45 -0400395 {
396 return;
397 }
398
399 const auto &attribs = mState.getVertexAttributes();
400 const auto &bindings = mState.getVertexBindings();
401
Jamie Madill112a3a82018-01-23 13:04:06 -0500402 for (auto attribIndex : mDirtyPackedInputs)
Jamie Madillebf72992017-10-13 14:09:45 -0400403 {
404 const auto &attrib = attribs[attribIndex];
405 const auto &binding = bindings[attrib.bindingIndex];
406 if (attrib.enabled)
407 {
Frank Henigman419acc82018-06-24 19:57:31 -0400408 updatePackedInputInfo(static_cast<uint32_t>(attribIndex), binding, attrib);
Jamie Madillebf72992017-10-13 14:09:45 -0400409 }
410 else
411 {
Jamie Madill5a4c9322018-07-16 11:01:58 -0400412 vk::PackedVertexInputBindingDesc &bindingDesc = mPackedInputBindings[attribIndex];
413 bindingDesc.stride = 0;
414 bindingDesc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
415
Jamie Madill77b24362018-11-05 22:39:29 -0500416 mPackedInputAttributes.formats[attribIndex] =
417 static_cast<uint16_t>(VK_FORMAT_R32G32B32A32_SFLOAT);
418 mPackedInputAttributes.offsets[attribIndex] = 0;
Jamie Madillebf72992017-10-13 14:09:45 -0400419 }
420 }
421
Jamie Madill112a3a82018-01-23 13:04:06 -0500422 mDirtyPackedInputs.reset();
423}
424
Frank Henigman419acc82018-06-24 19:57:31 -0400425void VertexArrayVk::updatePackedInputInfo(uint32_t attribIndex,
Jamie Madill112a3a82018-01-23 13:04:06 -0500426 const gl::VertexBinding &binding,
427 const gl::VertexAttribute &attrib)
428{
429 vk::PackedVertexInputBindingDesc &bindingDesc = mPackedInputBindings[attribIndex];
430
Frank Henigman419acc82018-06-24 19:57:31 -0400431 bindingDesc.stride = static_cast<uint16_t>(mCurrentArrayBufferStrides[attribIndex]);
Jamie Madill112a3a82018-01-23 13:04:06 -0500432 bindingDesc.inputRate = static_cast<uint16_t>(
433 binding.getDivisor() > 0 ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX);
434
Frank Henigman419acc82018-06-24 19:57:31 -0400435 VkFormat vkFormat = mCurrentArrayBufferFormats[attribIndex]->vkBufferFormat;
Jamie Madill112a3a82018-01-23 13:04:06 -0500436 ASSERT(vkFormat <= std::numeric_limits<uint16_t>::max());
Frank Henigman8c379f32018-06-21 19:55:05 -0400437 if (vkFormat == VK_FORMAT_UNDEFINED)
438 {
Frank Henigman8c379f32018-06-21 19:55:05 -0400439 UNIMPLEMENTED();
440 }
Jamie Madill112a3a82018-01-23 13:04:06 -0500441
Jamie Madill77b24362018-11-05 22:39:29 -0500442 mPackedInputAttributes.formats[attribIndex] = static_cast<uint8_t>(vkFormat);
443 mPackedInputAttributes.offsets[attribIndex] = static_cast<uint16_t>(attrib.relativeOffset);
Jamie Madillebf72992017-10-13 14:09:45 -0400444}
445
Jamie Madill88fc6da2018-08-30 16:18:36 -0400446angle::Result VertexArrayVk::updateClientAttribs(const gl::Context *context,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400447 GLint firstVertex,
448 GLsizei vertexOrIndexCount,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500449 gl::DrawElementsType indexTypeOrInvalid,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400450 const void *indices)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400451{
Jamie Madill77abad82018-10-25 17:03:48 -0400452 ContextVk *contextVk = vk::GetImpl(context);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400453 const gl::AttributesMask &clientAttribs = context->getStateCache().getActiveClientAttribsMask();
Jamie Madill21061022018-07-12 23:56:30 -0400454
Jamie Madill88fc6da2018-08-30 16:18:36 -0400455 ASSERT(clientAttribs.any());
Jamie Madillc1fd7372018-10-26 22:48:39 -0400456
457 GLint startVertex;
458 size_t vertexCount;
Jamie Madill8dc27f92018-11-29 11:45:44 -0500459 ANGLE_TRY(GetVertexRangeInfo(context, firstVertex, vertexOrIndexCount, indexTypeOrInvalid,
460 indices, 0, &startVertex, &vertexCount));
Jamie Madill88fc6da2018-08-30 16:18:36 -0400461
462 mDynamicVertexData.releaseRetainedBuffers(contextVk->getRenderer());
463
464 const auto &attribs = mState.getVertexAttributes();
465 const auto &bindings = mState.getVertexBindings();
466
467 // TODO(fjhenigman): When we have a bunch of interleaved attributes, they end up
468 // un-interleaved, wasting space and copying time. Consider improving on that.
469 for (size_t attribIndex : clientAttribs)
470 {
471 const gl::VertexAttribute &attrib = attribs[attribIndex];
472 const gl::VertexBinding &binding = bindings[attrib.bindingIndex];
473 ASSERT(attrib.enabled && binding.getBuffer().get() == nullptr);
474
475 const size_t bytesToAllocate =
Jamie Madillc1fd7372018-10-26 22:48:39 -0400476 (startVertex + vertexCount) * mCurrentArrayBufferStrides[attribIndex];
477 const uint8_t *src =
478 static_cast<const uint8_t *>(attrib.pointer) + startVertex * binding.getStride();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400479
Jamie Madillc1fd7372018-10-26 22:48:39 -0400480 size_t destOffset = startVertex * mCurrentArrayBufferStrides[attribIndex];
jchen105dc0a6f2018-09-20 14:30:45 +0800481 ASSERT(GetVertexInputAlignment(*mCurrentArrayBufferFormats[attribIndex]) <=
482 kMaxVertexFormatAlignment);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400483
484 // Only vertexCount() vertices will be used by the upcoming draw. so that is all we copy.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400485 // We allocate space for startVertex + vertexCount so indexing will work. If we
Jamie Madill88fc6da2018-08-30 16:18:36 -0400486 // don't start at zero all the indices will be off.
487 // TODO(fjhenigman): See if we can account for indices being off by adjusting the
488 // offset, thus avoiding wasted memory.
Jamie Madillc1fd7372018-10-26 22:48:39 -0400489 ANGLE_TRY(StreamVertexData(
490 contextVk, &mDynamicVertexData, src, bytesToAllocate, destOffset, vertexCount,
491 binding.getStride(), mCurrentArrayBufferFormats[attribIndex]->vertexLoadFunction,
Shahbaz Youssefiec063052018-12-06 01:58:06 +0100492 &mCurrentArrayBuffers[attribIndex], &mCurrentArrayBufferOffsets[attribIndex]));
493 mCurrentArrayBufferHandles[attribIndex] =
494 mCurrentArrayBuffers[attribIndex]->getBuffer().getHandle();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400495 }
496
497 return angle::Result::Continue();
498}
499
500angle::Result VertexArrayVk::handleLineLoop(ContextVk *contextVk,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400501 GLint firstVertex,
502 GLsizei vertexOrIndexCount,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500503 gl::DrawElementsType indexTypeOrInvalid,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400504 const void *indices)
Jamie Madill88fc6da2018-08-30 16:18:36 -0400505{
Jamie Madill8dc27f92018-11-29 11:45:44 -0500506 if (indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
Jamie Madill88fc6da2018-08-30 16:18:36 -0400507 {
508 // Handle GL_LINE_LOOP drawElements.
509 if (mDirtyLineLoopTranslation)
510 {
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400511 gl::Buffer *elementArrayBuffer = mState.getElementArrayBuffer();
Jamie Madill88fc6da2018-08-30 16:18:36 -0400512
513 if (!elementArrayBuffer)
514 {
Frank Henigman85c4b432018-09-19 23:35:00 -0400515 ANGLE_TRY(mLineLoopHelper.streamIndices(
Jamie Madill8dc27f92018-11-29 11:45:44 -0500516 contextVk, indexTypeOrInvalid, vertexOrIndexCount,
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500517 reinterpret_cast<const uint8_t *>(indices), &mCurrentElementArrayBuffer,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400518 &mCurrentElementArrayBufferOffset));
Jamie Madill88fc6da2018-08-30 16:18:36 -0400519 }
520 else
521 {
522 // When using an element array buffer, 'indices' is an offset to the first element.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400523 intptr_t offset = reinterpret_cast<intptr_t>(indices);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400524 BufferVk *elementArrayBufferVk = vk::GetImpl(elementArrayBuffer);
525 ANGLE_TRY(mLineLoopHelper.getIndexBufferForElementArrayBuffer(
Jamie Madill8dc27f92018-11-29 11:45:44 -0500526 contextVk, elementArrayBufferVk, indexTypeOrInvalid, vertexOrIndexCount, offset,
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500527 &mCurrentElementArrayBuffer, &mCurrentElementArrayBufferOffset));
Jamie Madill88fc6da2018-08-30 16:18:36 -0400528 }
529 }
530
531 // If we've had a drawArrays call with a line loop before, we want to make sure this is
532 // invalidated the next time drawArrays is called since we use the same index buffer for
533 // both calls.
534 mLineLoopBufferFirstIndex.reset();
535 mLineLoopBufferLastIndex.reset();
536 return angle::Result::Continue();
537 }
Jamie Madillc3755fc2018-04-05 08:39:13 -0400538
Jamie Madill18e323a2018-05-11 16:54:17 -0400539 // Note: Vertex indexes can be arbitrarily large.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400540 uint32_t clampedVertexCount = gl::clampCast<uint32_t>(vertexOrIndexCount);
Jamie Madill18e323a2018-05-11 16:54:17 -0400541
Jamie Madillc3755fc2018-04-05 08:39:13 -0400542 // Handle GL_LINE_LOOP drawArrays.
Jamie Madillbfe31c42018-10-25 17:03:47 -0400543 size_t lastVertex = static_cast<size_t>(firstVertex + clampedVertexCount);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400544 if (!mLineLoopBufferFirstIndex.valid() || !mLineLoopBufferLastIndex.valid() ||
Jamie Madillbfe31c42018-10-25 17:03:47 -0400545 mLineLoopBufferFirstIndex != firstVertex || mLineLoopBufferLastIndex != lastVertex)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400546 {
Jamie Madillbfe31c42018-10-25 17:03:47 -0400547 ANGLE_TRY(mLineLoopHelper.getIndexBufferForDrawArrays(
Shahbaz Youssefi4abdf742018-11-28 14:41:10 -0500548 contextVk, clampedVertexCount, firstVertex, &mCurrentElementArrayBuffer,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400549 &mCurrentElementArrayBufferOffset));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400550
Jamie Madillbfe31c42018-10-25 17:03:47 -0400551 mLineLoopBufferFirstIndex = firstVertex;
Jamie Madillc3755fc2018-04-05 08:39:13 -0400552 mLineLoopBufferLastIndex = lastVertex;
553 }
554
Jamie Madill88fc6da2018-08-30 16:18:36 -0400555 return angle::Result::Continue();
Jamie Madillc3755fc2018-04-05 08:39:13 -0400556}
557
Jamie Madill88fc6da2018-08-30 16:18:36 -0400558angle::Result VertexArrayVk::updateIndexTranslation(ContextVk *contextVk,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400559 GLsizei indexCount,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500560 gl::DrawElementsType type,
Jamie Madillbfe31c42018-10-25 17:03:47 -0400561 const void *indices)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400562{
Jamie Madill8dc27f92018-11-29 11:45:44 -0500563 ASSERT(type != gl::DrawElementsType::InvalidEnum);
Jamie Madillc3755fc2018-04-05 08:39:13 -0400564
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500565 RendererVk *renderer = contextVk->getRenderer();
Jamie Madillcd0a0a32018-10-18 18:41:57 -0400566 gl::Buffer *glBuffer = mState.getElementArrayBuffer();
Jamie Madillc3755fc2018-04-05 08:39:13 -0400567
Jamie Madill88fc6da2018-08-30 16:18:36 -0400568 if (!glBuffer)
Jamie Madillc3755fc2018-04-05 08:39:13 -0400569 {
Jamie Madillbfe31c42018-10-25 17:03:47 -0400570 ANGLE_TRY(streamIndexData(contextVk, type, indexCount, indices, &mDynamicIndexData));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400571 }
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500572 else if (renderer->getFormat(angle::FormatID::R16_UINT).vkSupportsStorageBuffer)
573 {
574 BufferVk *bufferVk = vk::GetImpl(glBuffer);
575
576 ASSERT(type == gl::DrawElementsType::UnsignedByte);
577
578 intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices);
579 size_t srcDataSize = static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData;
580
581 mTranslatedByteIndexData.releaseRetainedBuffers(renderer);
582
583 ANGLE_TRY(mTranslatedByteIndexData.allocate(contextVk, sizeof(GLushort) * srcDataSize,
584 nullptr, nullptr,
585 &mCurrentElementArrayBufferOffset, nullptr));
586 mCurrentElementArrayBuffer = mTranslatedByteIndexData.getCurrentBuffer();
587
588 vk::BufferHelper *dest = mTranslatedByteIndexData.getCurrentBuffer();
589 vk::BufferHelper *src = &bufferVk->getBuffer();
590
591 ANGLE_TRY(src->initBufferView(contextVk, renderer->getFormat(angle::FormatID::R8_UINT)));
592 ANGLE_TRY(dest->initBufferView(contextVk, renderer->getFormat(angle::FormatID::R16_UINT)));
593
594 // Copy relevant section of the source into destination at allocated offset. Note that the
595 // offset returned by allocate() above is in bytes, while our allocated array is of
596 // GLushorts.
597 DispatchUtilsVk::CopyParameters params = {};
598 params.destOffset =
599 static_cast<size_t>(mCurrentElementArrayBufferOffset) / sizeof(GLushort);
600 params.srcOffset = offsetIntoSrcData;
601 params.size = srcDataSize;
602
603 // Note: this is a copy, which implicitly converts between formats. Once support for
604 // primitive restart is added, a specialized shader is likely needed to special case 0xFF ->
605 // 0xFFFF.
606 ANGLE_TRY(renderer->getDispatchUtils()->copyBuffer(contextVk, dest, src, params));
607 }
Jamie Madill88fc6da2018-08-30 16:18:36 -0400608 else
Jamie Madillc3755fc2018-04-05 08:39:13 -0400609 {
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500610 // If it's not possible to convert the buffer with compute, opt for a CPU read back for now.
611 // TODO(syoussefi): R8G8B8A8_UINT is required to have storage texel buffer support, so a
612 // specialized shader code can be made to read two ubyte indices and output them in R and B
613 // (or A and G based on endianness?) with 0 on the other channels. If specialized, we might
614 // as well support the ubyte to ushort case with correct handling of primitive restart.
615 // http://anglebug.com/3003
616
Frank Henigman9d84ccb2018-09-12 18:09:02 -0400617 // Needed before reading buffer or we could get stale data.
Shahbaz Youssefi8f1b7a62018-11-14 16:02:54 -0500618 ANGLE_TRY(renderer->finish(contextVk));
Frank Henigman9d84ccb2018-09-12 18:09:02 -0400619
Jamie Madill8dc27f92018-11-29 11:45:44 -0500620 ASSERT(type == gl::DrawElementsType::UnsignedByte);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400621 // Unsigned bytes don't have direct support in Vulkan so we have to expand the
622 // memory to a GLushort.
623 BufferVk *bufferVk = vk::GetImpl(glBuffer);
624 void *srcDataMapping = nullptr;
625 ASSERT(!glBuffer->isMapped());
626 ANGLE_TRY(bufferVk->mapImpl(contextVk, &srcDataMapping));
627 uint8_t *srcData = static_cast<uint8_t *>(srcDataMapping);
Jamie Madillbfe31c42018-10-25 17:03:47 -0400628 intptr_t offsetIntoSrcData = reinterpret_cast<intptr_t>(indices);
Jamie Madill88fc6da2018-08-30 16:18:36 -0400629 srcData += offsetIntoSrcData;
Jamie Madill253038d2018-08-30 16:18:35 -0400630
Jamie Madillbfe31c42018-10-25 17:03:47 -0400631 ANGLE_TRY(streamIndexData(contextVk, type,
Jamie Madill88fc6da2018-08-30 16:18:36 -0400632 static_cast<size_t>(bufferVk->getSize()) - offsetIntoSrcData,
633 srcData, &mTranslatedByteIndexData));
Luc Ferron6ed167a2018-06-13 13:45:55 -0400634
Jamie Madill88fc6da2018-08-30 16:18:36 -0400635 ANGLE_TRY(bufferVk->unmapImpl(contextVk));
Jamie Madillc3755fc2018-04-05 08:39:13 -0400636 }
637
Jamie Madill88fc6da2018-08-30 16:18:36 -0400638 return angle::Result::Continue();
Jamie Madillc3755fc2018-04-05 08:39:13 -0400639}
Jamie Madill5a4c9322018-07-16 11:01:58 -0400640
641void VertexArrayVk::updateDefaultAttrib(RendererVk *renderer,
642 size_t attribIndex,
643 VkBuffer bufferHandle,
644 uint32_t offset)
645{
646 if (!mState.getEnabledAttributesMask().test(attribIndex))
647 {
Jamie Madill03d1a5e2018-11-12 11:34:24 -0500648 mCurrentArrayBufferHandles[attribIndex] = bufferHandle;
649 mCurrentArrayBufferOffsets[attribIndex] = offset;
650 mCurrentArrayBuffers[attribIndex] = nullptr;
651 mCurrentArrayBufferStrides[attribIndex] = 0;
Jamie Madill5a4c9322018-07-16 11:01:58 -0400652 mCurrentArrayBufferFormats[attribIndex] =
Jamie Madillba365932018-07-18 17:23:46 -0400653 &renderer->getFormat(angle::FormatID::R32G32B32A32_FIXED);
Jamie Madill5a4c9322018-07-16 11:01:58 -0400654 mDirtyPackedInputs.set(attribIndex);
655 }
656}
Jamie Madill9e54b5a2016-05-25 12:57:39 -0400657} // namespace rx