Vulkan: Clean up VAO cached resources.

We can actually store a pointer to the base ResourceVk instead of
BufferVk for updating serials. This will work a little nicer with
streaming vertex data, which won't have a BufferVk but will have an
accessible ResourceVk pointer.

Also add an element array resource pointer for serial update. This was
missing and could lead to incorrect behaviour. Also change the types
of the caches from std::vector to gl::AttribArray, which is a
std::array.

Bug: angleproject:2264
Change-Id: Ibd79b7676b5dbc3875ae9d110be477d228e01c5c
Reviewed-on: https://chromium-review.googlesource.com/798170
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
index eab9749..0ce3d18 100644
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
@@ -21,10 +21,13 @@
 
 VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state)
     : VertexArrayImpl(state),
-      mCurrentVertexBufferHandlesCache(state.getMaxAttribs(), VK_NULL_HANDLE),
-      mCurrentVkBuffersCache(state.getMaxAttribs(), nullptr),
+      mCurrentArrayBufferHandles{},
+      mCurrentArrayBufferResources{},
+      mCurrentElementArrayBufferResource(nullptr),
       mCurrentVertexDescsValid(false)
 {
+    mCurrentArrayBufferHandles.fill(VK_NULL_HANDLE);
+    mCurrentArrayBufferResources.fill(nullptr);
     mCurrentVertexBindingDescs.reserve(state.getMaxAttribs());
     mCurrentVertexAttribDescs.reserve(state.getMaxAttribs());
 }
@@ -58,7 +61,18 @@
     for (auto dirtyBit : dirtyBits)
     {
         if (dirtyBit == gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER)
+        {
+            gl::Buffer *bufferGL = mState.getElementArrayBuffer().get();
+            if (bufferGL)
+            {
+                mCurrentElementArrayBufferResource = vk::GetImpl(bufferGL);
+            }
+            else
+            {
+                mCurrentElementArrayBufferResource = nullptr;
+            }
             continue;
+        }
 
         size_t attribIndex = gl::VertexArray::GetVertexIndexFromDirtyBit(dirtyBit);
 
@@ -71,14 +85,14 @@
 
             if (bufferGL)
             {
-                BufferVk *bufferVk                            = vk::GetImpl(bufferGL);
-                mCurrentVkBuffersCache[attribIndex]           = bufferVk;
-                mCurrentVertexBufferHandlesCache[attribIndex] = bufferVk->getVkBuffer().getHandle();
+                BufferVk *bufferVk                        = vk::GetImpl(bufferGL);
+                mCurrentArrayBufferResources[attribIndex] = bufferVk;
+                mCurrentArrayBufferHandles[attribIndex]   = bufferVk->getVkBuffer().getHandle();
             }
             else
             {
-                mCurrentVkBuffersCache[attribIndex]           = nullptr;
-                mCurrentVertexBufferHandlesCache[attribIndex] = VK_NULL_HANDLE;
+                mCurrentArrayBufferResources[attribIndex] = nullptr;
+                mCurrentArrayBufferHandles[attribIndex]   = VK_NULL_HANDLE;
             }
         }
         else
@@ -88,17 +102,27 @@
     }
 }
 
-const std::vector<VkBuffer> &VertexArrayVk::getCurrentVertexBufferHandlesCache() const
+const gl::AttribArray<VkBuffer> &VertexArrayVk::getCurrentArrayBufferHandles() const
 {
-    return mCurrentVertexBufferHandlesCache;
+    return mCurrentArrayBufferHandles;
 }
 
 void VertexArrayVk::updateCurrentBufferSerials(const gl::AttributesMask &activeAttribsMask,
-                                               Serial serial)
+                                               Serial serial,
+                                               DrawType drawType)
 {
+    // Handle the bound array buffers.
     for (auto attribIndex : activeAttribsMask)
     {
-        mCurrentVkBuffersCache[attribIndex]->setQueueSerial(serial);
+        ASSERT(mCurrentArrayBufferResources[attribIndex]);
+        mCurrentArrayBufferResources[attribIndex]->setQueueSerial(serial);
+    }
+
+    // Handle the bound element array buffer.
+    if (drawType == DrawType::Elements)
+    {
+        ASSERT(mCurrentElementArrayBufferResource);
+        mCurrentElementArrayBufferResource->setQueueSerial(serial);
     }
 }