Vulkan: Support of GL_UNSIGNED_BYTE type in drawElements

Bug:angleproject:1683

Change-Id: I8c79cc92406b210c9d143761ffe4ef74e14c6bed
Reviewed-on: https://chromium-review.googlesource.com/956090
Commit-Queue: Luc Ferron <lucferron@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 4449118..6a03392 100644
--- a/src/libANGLE/renderer/vulkan/ContextVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp
@@ -45,6 +45,7 @@
 {
     switch (glIndexType)
     {
+        case GL_UNSIGNED_BYTE:
         case GL_UNSIGNED_SHORT:
             return VK_INDEX_TYPE_UINT16;
         case GL_UNSIGNED_INT:
@@ -331,13 +332,6 @@
     }
     else
     {
-        if (type == GL_UNSIGNED_BYTE)
-        {
-            // TODO(fjhenigman): Index format translation.
-            UNIMPLEMENTED();
-            return gl::InternalError() << "Unsigned byte translation is not yet implemented.";
-        }
-
         ContextVk *contextVk         = vk::GetImpl(context);
         const bool computeIndexRange = vk::GetImpl(vao)->attribsToStream(contextVk).any();
         gl::IndexRange range;
@@ -346,6 +340,14 @@
 
         if (elementArrayBuffer)
         {
+            if (type == GL_UNSIGNED_BYTE)
+            {
+                // TODO(fjhenigman): Index format translation.
+                UNIMPLEMENTED();
+                return gl::InternalError() << "Unsigned byte translation is not implemented for "
+                                           << "indices in a buffer object";
+            }
+
             BufferVk *elementArrayBufferVk = vk::GetImpl(elementArrayBuffer);
             buffer                         = elementArrayBufferVk->getVkBuffer().getHandle();
             offset                         = 0;
@@ -359,10 +361,24 @@
         else
         {
             const GLsizei amount = sizeof(GLushort) * count;
-            uint8_t *dst         = nullptr;
+            GLubyte *dst         = nullptr;
 
             ANGLE_TRY(mStreamingIndexData.allocate(contextVk, amount, &dst, &buffer, &offset));
-            memcpy(dst, indices, amount);
+            if (type == GL_UNSIGNED_BYTE)
+            {
+                // Unsigned bytes don't have direct support in Vulkan so we have to expand the
+                // memory to a GLushort.
+                const GLubyte *in     = static_cast<const GLubyte *>(indices);
+                GLushort *expandedDst = reinterpret_cast<GLushort *>(dst);
+                for (GLsizei index = 0; index < count; index++)
+                {
+                    expandedDst[index] = static_cast<GLushort>(in[index]);
+                }
+            }
+            else
+            {
+                memcpy(dst, indices, amount);
+            }
             ANGLE_TRY(mStreamingIndexData.flush(contextVk));
 
             if (computeIndexRange)