D3D11: Fix out-of-range access with robust access.

When using a vertex buffer with DYNAMIC usage, with robust buffer
access enabled, we would sometimes read out-of-bounds when using very
large values for the index range. An unchecked signed addition would
overflow and lead to reading a negative offset.

Fix this problem by keeping the value size_t whenever possible. Also do
clamped casts when converting to a smaller values.

Also adds a regression test.

Bug: chromium:842028
Change-Id: Ie630ac857c6acfc0bace849a03eebfbaa2fbe89a
Reviewed-on: https://chromium-review.googlesource.com/1055928
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
index 5972339..16af443 100644
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
@@ -357,14 +357,17 @@
 
     ANGLE_TRY(onDraw(context, renderer, drawCallParams, drawNode, newCommandBuffer));
 
+    // Note: Vertex indexes can be arbitrarily large.
+    uint32_t clampedVertexCount = drawCallParams.getClampedVertexCount<uint32_t>();
+
     if (drawCallParams.mode() != GL_LINE_LOOP)
     {
-        commandBuffer->draw(drawCallParams.vertexCount(), 1, drawCallParams.firstVertex(), 0);
+        commandBuffer->draw(clampedVertexCount, 1, drawCallParams.firstVertex(), 0);
         return gl::NoError();
     }
 
     // Handle GL_LINE_LOOP drawArrays.
-    int lastVertex = drawCallParams.firstVertex() + drawCallParams.vertexCount();
+    size_t lastVertex = static_cast<size_t>(drawCallParams.firstVertex() + clampedVertexCount);
     if (!mLineLoopBufferFirstIndex.valid() || !mLineLoopBufferLastIndex.valid() ||
         mLineLoopBufferFirstIndex != drawCallParams.firstVertex() ||
         mLineLoopBufferLastIndex != lastVertex)
@@ -380,7 +383,7 @@
     commandBuffer->bindIndexBuffer(mCurrentElementArrayBufferHandle,
                                    mCurrentElementArrayBufferOffset, VK_INDEX_TYPE_UINT32);
 
-    vk::LineLoopHelper::Draw(drawCallParams.vertexCount(), commandBuffer);
+    vk::LineLoopHelper::Draw(clampedVertexCount, commandBuffer);
 
     return gl::NoError();
 }