baseVertex in drawIndexed() should be int32, not uint32

baseVertex in drawIndexed() is int32 in web idl. But it is uint32 in Dawn
project. I also checked the native Graphics API sets. baseVertex is int32
on all native APIs (D3D12, Vulkan, Metal). So this feature in web idl is
definitely correct.

This small change makes dawn match web idl for this feature. And it also
adds a couple of tests to cover negative baseVertex.

BUG=dawn:135
TEST=dawn_end2end_tests

Change-Id: I642c96faed9103c8392979f3714527ed0aac4089
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/6442
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/dawn.json b/dawn.json
index 7528d46..d1c321f 100644
--- a/dawn.json
+++ b/dawn.json
@@ -776,7 +776,7 @@
                     {"name": "index count", "type": "uint32_t"},
                     {"name": "instance count", "type": "uint32_t"},
                     {"name": "first index", "type": "uint32_t"},
-                    {"name": "base vertex", "type": "uint32_t"},
+                    {"name": "base vertex", "type": "int32_t"},
                     {"name": "first instance", "type": "uint32_t"}
                 ]
             },
diff --git a/src/dawn_native/Commands.h b/src/dawn_native/Commands.h
index 091547c..26e0b68 100644
--- a/src/dawn_native/Commands.h
+++ b/src/dawn_native/Commands.h
@@ -143,7 +143,7 @@
         uint32_t indexCount;
         uint32_t instanceCount;
         uint32_t firstIndex;
-        uint32_t baseVertex;
+        int32_t baseVertex;
         uint32_t firstInstance;
     };
 
diff --git a/src/dawn_native/RenderPassEncoder.cpp b/src/dawn_native/RenderPassEncoder.cpp
index 9288c6a..7470063 100644
--- a/src/dawn_native/RenderPassEncoder.cpp
+++ b/src/dawn_native/RenderPassEncoder.cpp
@@ -60,7 +60,7 @@
     void RenderPassEncoderBase::DrawIndexed(uint32_t indexCount,
                                             uint32_t instanceCount,
                                             uint32_t firstIndex,
-                                            uint32_t baseVertex,
+                                            int32_t baseVertex,
                                             uint32_t firstInstance) {
         if (mTopLevelEncoder->ConsumedError(ValidateCanRecordCommands())) {
             return;
diff --git a/src/dawn_native/RenderPassEncoder.h b/src/dawn_native/RenderPassEncoder.h
index ccc776f..7e8243e 100644
--- a/src/dawn_native/RenderPassEncoder.h
+++ b/src/dawn_native/RenderPassEncoder.h
@@ -40,7 +40,7 @@
         void DrawIndexed(uint32_t vertexCount,
                          uint32_t instanceCount,
                          uint32_t firstIndex,
-                         uint32_t baseVertex,
+                         int32_t baseVertex,
                          uint32_t firstInstance);
 
         void SetPipeline(RenderPipelineBase* pipeline);
diff --git a/src/tests/end2end/DrawIndexedTests.cpp b/src/tests/end2end/DrawIndexedTests.cpp
index c1b889e..02421c7 100644
--- a/src/tests/end2end/DrawIndexedTests.cpp
+++ b/src/tests/end2end/DrawIndexedTests.cpp
@@ -67,9 +67,11 @@
                  1.0f, -1.0f, 0.0f, 1.0f,
                 -1.0f,  1.0f, 0.0f, 1.0f
             });
-            indexBuffer = utils::CreateBufferFromData<uint32_t>(device, dawn::BufferUsageBit::Index, {
-                0, 1, 2, 0, 3, 1
-            });
+            indexBuffer = utils::CreateBufferFromData<uint32_t>(
+                device, dawn::BufferUsageBit::Index,
+                {0, 1, 2, 0, 3, 1,
+                 // The indices below are added to test negatve baseVertex
+                 0 + 4, 1 + 4, 2 + 4, 0 + 4, 3 + 4, 1 + 4});
         }
 
         utils::BasicRenderPass renderPass;
@@ -77,8 +79,13 @@
         dawn::Buffer vertexBuffer;
         dawn::Buffer indexBuffer;
 
-        void Test(uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex,
-                  uint32_t baseVertex, uint32_t firstInstance, RGBA8 bottomLeftExpected,
+        void Test(uint32_t indexCount,
+                  uint32_t instanceCount,
+                  uint32_t firstIndex,
+                  int32_t baseVertex,
+                  uint32_t firstInstance,
+                  uint64_t bufferOffset,
+                  RGBA8 bottomLeftExpected,
                   RGBA8 topRightExpected) {
             uint64_t zeroOffset = 0;
             dawn::CommandEncoder encoder = device.CreateCommandEncoder();
@@ -87,7 +94,7 @@
                     &renderPass.renderPassInfo);
                 pass.SetPipeline(pipeline);
                 pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset);
-                pass.SetIndexBuffer(indexBuffer, 0);
+                pass.SetIndexBuffer(indexBuffer, bufferOffset);
                 pass.DrawIndexed(indexCount, instanceCount, firstIndex, baseVertex, firstInstance);
                 pass.EndPass();
             }
@@ -107,13 +114,13 @@
     RGBA8 notFilled(0, 0, 0, 0);
 
     // Test a draw with no indices.
-    Test(0, 0, 0, 0, 0, notFilled, notFilled);
+    Test(0, 0, 0, 0, 0, 0, notFilled, notFilled);
     // Test a draw with only the first 3 indices of the first quad (bottom left triangle)
-    Test(3, 1, 0, 0, 0, filled, notFilled);
+    Test(3, 1, 0, 0, 0, 0, filled, notFilled);
     // Test a draw with only the last 3 indices of the first quad (top right triangle)
-    Test(3, 1, 3, 0, 0, notFilled, filled);
+    Test(3, 1, 3, 0, 0, 0, notFilled, filled);
     // Test a draw with all 6 indices (both triangles).
-    Test(6, 1, 0, 0, 0, filled, filled);
+    Test(6, 1, 0, 0, 0, 0, filled, filled);
 }
 
 // Test the parameter 'baseVertex' of DrawIndexed() works.
@@ -122,9 +129,15 @@
     RGBA8 notFilled(0, 0, 0, 0);
 
     // Test a draw with only the first 3 indices of the second quad (top right triangle)
-    Test(3, 1, 0, 4, 0, notFilled, filled);
+    Test(3, 1, 0, 4, 0, 0, notFilled, filled);
     // Test a draw with only the last 3 indices of the second quad (bottom left triangle)
-    Test(3, 1, 3, 4, 0, filled, notFilled);
+    Test(3, 1, 3, 4, 0, 0, filled, notFilled);
+
+    // Test negative baseVertex
+    // Test a draw with only the first 3 indices of the first quad (bottom left triangle)
+    Test(3, 1, 0, -4, 0, 6 * sizeof(uint32_t), filled, notFilled);
+    // Test a draw with only the last 3 indices of the first quad (top right triangle)
+    Test(3, 1, 3, -4, 0, 6 * sizeof(uint32_t), notFilled, filled);
 }
 
 DAWN_INSTANTIATE_TEST(DrawIndexedTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend);