Vulkan: Implement very basic DrawElements.

This implements getIndexRange for index validation, without any
caching. Vulkan does support a version of robust access, but it would
require the robust context creation attribute. Also, it differs slight
from the OpenGL spec.

Also note that this implementation does not create the index buffer
with the correct usage bits, but seems to work and doesn't produce an
error in the validation layers. We should probably update them.

This CL also doesn't impement index support for immediate data,
offsets, or the unsigned short index type.

BUG=angleproject:2167

Change-Id: I580930f85e23034b483f3ece62eb1faf8024d624
Reviewed-on: https://chromium-review.googlesource.com/681874
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp
index c87704d..6bbfd9b 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -35,6 +35,25 @@
 namespace rx
 {
 
+namespace
+{
+
+VkIndexType GetVkIndexType(GLenum glIndexType)
+{
+    switch (glIndexType)
+    {
+        case GL_UNSIGNED_SHORT:
+            return VK_INDEX_TYPE_UINT16;
+        case GL_UNSIGNED_INT:
+            return VK_INDEX_TYPE_UINT32;
+        default:
+            UNREACHABLE();
+            return VK_INDEX_TYPE_MAX_ENUM;
+    }
+}
+
+}  // anonymous namespace
+
 ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer)
     : ContextImpl(state), mRenderer(renderer), mCurrentDrawMode(GL_NONE)
 {
@@ -265,7 +284,7 @@
     return gl::NoError();
 }
 
-gl::Error ContextVk::drawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count)
+gl::Error ContextVk::setupDraw(const gl::Context *context, GLenum mode)
 {
     if (mode != mCurrentDrawMode)
     {
@@ -323,11 +342,21 @@
     // TODO(jmadill): the queue serial should be bound to the pipeline.
     setQueueSerial(queueSerial);
     commandBuffer->bindVertexBuffers(0, vertexHandles, vertexOffsets);
-    commandBuffer->draw(count, 1, first, 0);
 
     return gl::NoError();
 }
 
+gl::Error ContextVk::drawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count)
+{
+    ANGLE_TRY(setupDraw(context, mode));
+
+    vk::CommandBuffer *commandBuffer = nullptr;
+    ANGLE_TRY(mRenderer->getStartedCommandBuffer(&commandBuffer));
+
+    commandBuffer->draw(count, 1, first, 0);
+    return gl::NoError();
+}
+
 gl::Error ContextVk::drawArraysInstanced(const gl::Context *context,
                                          GLenum mode,
                                          GLint first,
@@ -344,8 +373,35 @@
                                   GLenum type,
                                   const void *indices)
 {
-    UNIMPLEMENTED();
-    return gl::InternalError();
+    ANGLE_TRY(setupDraw(context, mode));
+
+    if (indices)
+    {
+        // TODO(jmadill): Buffer offsets and immediate data.
+        UNIMPLEMENTED();
+        return gl::InternalError() << "Only zero-offset index buffers are currently implemented.";
+    }
+
+    if (type == GL_UNSIGNED_BYTE)
+    {
+        // TODO(jmadill): Index translation.
+        UNIMPLEMENTED();
+        return gl::InternalError() << "Unsigned byte translation is not yet implemented.";
+    }
+
+    vk::CommandBuffer *commandBuffer = nullptr;
+    ANGLE_TRY(mRenderer->getStartedCommandBuffer(&commandBuffer));
+
+    const gl::Buffer *elementArrayBuffer =
+        mState.getState().getVertexArray()->getElementArrayBuffer().get();
+    ASSERT(elementArrayBuffer);
+
+    BufferVk *elementArrayBufferVk = GetImplAs<BufferVk>(elementArrayBuffer);
+
+    commandBuffer->bindIndexBuffer(elementArrayBufferVk->getVkBuffer(), 0, GetVkIndexType(type));
+    commandBuffer->drawIndexed(count, 1, 0, 0, 0);
+
+    return gl::NoError();
 }
 
 gl::Error ContextVk::drawElementsInstanced(const gl::Context *context,