Vulkan: support instanced draws.

Enable instanced draws with the Vulkan backend.
So far it only works when Vulkan has VK_EXT_vertex_attribute_divisor.

BUG=angleproject:2672

Change-Id: I9445ba64282fa00a6eaee207b15efa2c7a9abbd3
Reviewed-on: https://chromium-review.googlesource.com/c/1334973
Commit-Queue: Frank Henigman <fjhenigman@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
index 79e1f37..a10c7b3 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -199,6 +199,7 @@
                                    gl::PrimitiveMode mode,
                                    GLint firstVertex,
                                    GLsizei vertexOrIndexCount,
+                                   GLsizei instanceCount,
                                    gl::DrawElementsType indexTypeOrNone,
                                    const void *indices,
                                    DirtyBits dirtyBitMask,
@@ -216,7 +217,7 @@
     if (context->getStateCache().hasAnyActiveClientAttrib())
     {
         ANGLE_TRY(mVertexArray->updateClientAttribs(context, firstVertex, vertexOrIndexCount,
-                                                    indexTypeOrNone, indices));
+                                                    instanceCount, indexTypeOrNone, indices));
         mDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
     }
 
@@ -266,6 +267,7 @@
 angle::Result ContextVk::setupIndexedDraw(const gl::Context *context,
                                           gl::PrimitiveMode mode,
                                           GLsizei indexCount,
+                                          GLsizei instanceCount,
                                           gl::DrawElementsType indexType,
                                           const void *indices,
                                           vk::CommandBuffer **commandBufferOut)
@@ -297,8 +299,8 @@
         }
     }
 
-    return setupDraw(context, mode, 0, indexCount, indexType, indices, mIndexedDirtyBitsMask,
-                     commandBufferOut);
+    return setupDraw(context, mode, 0, indexCount, instanceCount, indexType, indices,
+                     mIndexedDirtyBitsMask, commandBufferOut);
 }
 
 angle::Result ContextVk::setupLineLoopDraw(const gl::Context *context,
@@ -315,7 +317,7 @@
     mCurrentDrawElementsType = indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum
                                    ? indexTypeOrInvalid
                                    : gl::DrawElementsType::UnsignedInt;
-    return setupDraw(context, mode, firstVertex, vertexOrIndexCount, indexTypeOrInvalid, indices,
+    return setupDraw(context, mode, firstVertex, vertexOrIndexCount, 1, indexTypeOrInvalid, indices,
                      mIndexedDirtyBitsMask, commandBufferOut);
 }
 
@@ -455,8 +457,8 @@
     }
     else
     {
-        ANGLE_TRY(setupDraw(context, mode, first, count, gl::DrawElementsType::InvalidEnum, nullptr,
-                            mNonIndexedDirtyBitsMask, &commandBuffer));
+        ANGLE_TRY(setupDraw(context, mode, first, count, 1, gl::DrawElementsType::InvalidEnum,
+                            nullptr, mNonIndexedDirtyBitsMask, &commandBuffer));
         commandBuffer->draw(clampedVertexCount, 1, first, 0);
     }
 
@@ -467,10 +469,20 @@
                                              gl::PrimitiveMode mode,
                                              GLint first,
                                              GLsizei count,
-                                             GLsizei instanceCount)
+                                             GLsizei instances)
 {
-    ANGLE_VK_UNREACHABLE(this);
-    return angle::Result::Stop;
+    if (mode == gl::PrimitiveMode::LineLoop)
+    {
+        // TODO - http://anglebug.com/2672
+        ANGLE_VK_UNREACHABLE(this);
+        return angle::Result::Stop;
+    }
+
+    vk::CommandBuffer *commandBuffer = nullptr;
+    ANGLE_TRY(setupDraw(context, mode, first, count, instances, gl::DrawElementsType::InvalidEnum,
+                        nullptr, mNonIndexedDirtyBitsMask, &commandBuffer));
+    commandBuffer->draw(gl::GetClampedVertexCount<uint32_t>(count), instances, first, 0);
+    return angle::Result::Continue;
 }
 
 angle::Result ContextVk::drawElements(const gl::Context *context,
@@ -487,7 +499,7 @@
     }
     else
     {
-        ANGLE_TRY(setupIndexedDraw(context, mode, count, type, indices, &commandBuffer));
+        ANGLE_TRY(setupIndexedDraw(context, mode, count, 1, type, indices, &commandBuffer));
         commandBuffer->drawIndexed(count, 1, 0, 0, 0);
     }
 
@@ -501,8 +513,17 @@
                                                const void *indices,
                                                GLsizei instances)
 {
-    ANGLE_VK_UNREACHABLE(this);
-    return angle::Result::Stop;
+    if (mode == gl::PrimitiveMode::LineLoop)
+    {
+        // TODO - http://anglebug.com/2672
+        ANGLE_VK_UNREACHABLE(this);
+        return angle::Result::Stop;
+    }
+
+    vk::CommandBuffer *commandBuffer = nullptr;
+    ANGLE_TRY(setupIndexedDraw(context, mode, count, instances, type, indices, &commandBuffer));
+    commandBuffer->drawIndexed(count, instances, 0, 0, 0);
+    return angle::Result::Continue;
 }
 
 angle::Result ContextVk::drawRangeElements(const gl::Context *context,