Deprecation of using 0 as default size in buffer mapAsync

For size parameter in mapAsync, use wgpu::kWholeMapSize rather than 0 to
indicate using the default size, i.e. remaining buffer size after
offset. Using size=0 is still available but will cause a deprecation
warning.

Bug: dawn:1159
Change-Id: I474d87ecae4a54ceb28d636f883a6233c91f16fa
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/66284
Auto-Submit: Zhaoming Jiang <zhaoming.jiang@intel.com>
Commit-Queue: Zhaoming Jiang <zhaoming.jiang@intel.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/generator/templates/webgpu.h b/generator/templates/webgpu.h
index 9630d1a..d305dd2 100644
--- a/generator/templates/webgpu.h
+++ b/generator/templates/webgpu.h
@@ -74,6 +74,7 @@
 #include <stdbool.h>
 
 #define WGPU_WHOLE_SIZE (0xffffffffffffffffULL)
+#define WGPU_WHOLE_MAP_SIZE SIZE_MAX
 {% if 'deprecated' in enabled_tags %}
     // TODO(crbug.com/dawn/520): Remove WGPU_STRIDE_UNDEFINED in favor of WGPU_COPY_STRIDE_UNDEFINED.
     #define WGPU_STRIDE_UNDEFINED (0xffffffffUL)
diff --git a/generator/templates/webgpu_cpp.h b/generator/templates/webgpu_cpp.h
index 951f6ad..dfbe6c4 100644
--- a/generator/templates/webgpu_cpp.h
+++ b/generator/templates/webgpu_cpp.h
@@ -20,6 +20,7 @@
 namespace wgpu {
 
     static constexpr uint64_t kWholeSize = WGPU_WHOLE_SIZE;
+    static constexpr size_t kWholeMapSize = WGPU_WHOLE_MAP_SIZE;
     {% if 'deprecated' in enabled_tags %}
         // TODO(crbug.com/520): Remove kStrideUndefined in favor of kCopyStrideUndefined.
         static constexpr uint32_t kStrideUndefined = WGPU_STRIDE_UNDEFINED;
diff --git a/src/dawn_native/Buffer.cpp b/src/dawn_native/Buffer.cpp
index 86ffcb9..abb7f1b 100644
--- a/src/dawn_native/Buffer.cpp
+++ b/src/dawn_native/Buffer.cpp
@@ -298,7 +298,18 @@
         // Handle the defaulting of size required by WebGPU, even if in webgpu_cpp.h it is not
         // possible to default the function argument (because there is the callback later in the
         // argument list)
-        if (size == 0 && offset < mSize) {
+        if (size == 0) {
+            // Using 0 to indicating default size is deprecated.
+            // Temporarily treat 0 as undefined for size, and give a warning
+            // TODO(dawn:1058): Remove this if block
+            size = wgpu::kWholeMapSize;
+            GetDevice()->EmitDeprecationWarning(
+                "Using size=0 to indicate default mapping size for mapAsync "
+                "is deprecated. In the future it will result in a zero-size mapping. "
+                "Use `undefined` (wgpu::kWholeMapSize) or just omit the parameter instead.");
+        }
+
+        if ((size == wgpu::kWholeMapSize) && (offset <= mSize)) {
             size = mSize - offset;
         }
 
@@ -450,10 +461,14 @@
         *status = WGPUBufferMapAsyncStatus_Error;
         DAWN_TRY(GetDevice()->ValidateObject(this));
 
+        DAWN_INVALID_IF(uint64_t(offset) > mSize,
+                        "Mapping offset (%u) is larger than the size (%u) of %s.", offset, mSize,
+                        this);
+
         DAWN_INVALID_IF(offset % 8 != 0, "Offset (%u) must be a multiple of 8.", offset);
         DAWN_INVALID_IF(size % 4 != 0, "Size (%u) must be a multiple of 4.", size);
 
-        DAWN_INVALID_IF(uint64_t(offset) > mSize || uint64_t(size) > mSize - uint64_t(offset),
+        DAWN_INVALID_IF(uint64_t(size) > mSize - uint64_t(offset),
                         "Mapping range (offset:%u, size: %u) doesn't fit in the size (%u) of %s.",
                         offset, size, mSize, this);
 
diff --git a/src/dawn_wire/client/Buffer.cpp b/src/dawn_wire/client/Buffer.cpp
index f27b99e..5077b5a 100644
--- a/src/dawn_wire/client/Buffer.cpp
+++ b/src/dawn_wire/client/Buffer.cpp
@@ -166,7 +166,7 @@
         }
 
         // Handle the defaulting of size required by WebGPU.
-        if (size == 0 && offset < mSize) {
+        if ((size == WGPU_WHOLE_MAP_SIZE) && (offset <= mSize)) {
             size = mSize - offset;
         }
 
diff --git a/src/tests/DawnTest.cpp b/src/tests/DawnTest.cpp
index 9548857..0dff126 100644
--- a/src/tests/DawnTest.cpp
+++ b/src/tests/DawnTest.cpp
@@ -1430,7 +1430,8 @@
         MapReadUserdata* userdata = new MapReadUserdata{this, i};
 
         const ReadbackSlot& slot = mReadbackSlots[i];
-        slot.buffer.MapAsync(wgpu::MapMode::Read, 0, 0, SlotMapCallback, userdata);
+        slot.buffer.MapAsync(wgpu::MapMode::Read, 0, wgpu::kWholeMapSize, SlotMapCallback,
+                             userdata);
     }
 
     // Busy wait until all map operations are done.
diff --git a/src/tests/end2end/BufferTests.cpp b/src/tests/end2end/BufferTests.cpp
index 74289c7..b893c02 100644
--- a/src/tests/end2end/BufferTests.cpp
+++ b/src/tests/end2end/BufferTests.cpp
@@ -77,7 +77,7 @@
 TEST_P(BufferMappingTests, MapRead_ZeroSized) {
     wgpu::Buffer buffer = CreateMapReadBuffer(0);
 
-    MapAsyncAndWait(buffer, wgpu::MapMode::Read, 0, 0);
+    MapAsyncAndWait(buffer, wgpu::MapMode::Read, 0, wgpu::kWholeMapSize);
     ASSERT_NE(buffer.GetConstMappedRange(), nullptr);
     buffer.Unmap();
 }
@@ -235,7 +235,7 @@
 TEST_P(BufferMappingTests, MapWrite_ZeroSized) {
     wgpu::Buffer buffer = CreateMapWriteBuffer(0);
 
-    MapAsyncAndWait(buffer, wgpu::MapMode::Write, 0, 0);
+    MapAsyncAndWait(buffer, wgpu::MapMode::Write, 0, wgpu::kWholeMapSize);
     ASSERT_NE(buffer.GetConstMappedRange(), nullptr);
     ASSERT_NE(buffer.GetMappedRange(), nullptr);
     buffer.Unmap();
@@ -523,10 +523,10 @@
 TEST_P(BufferMappingTests, MapWrite_ZeroSizedTwice) {
     wgpu::Buffer buffer = CreateMapWriteBuffer(0);
 
-    MapAsyncAndWait(buffer, wgpu::MapMode::Write, 0, 0);
+    MapAsyncAndWait(buffer, wgpu::MapMode::Write, 0, wgpu::kWholeMapSize);
     buffer.Unmap();
 
-    MapAsyncAndWait(buffer, wgpu::MapMode::Write, 0, 0);
+    MapAsyncAndWait(buffer, wgpu::MapMode::Write, 0, wgpu::kWholeMapSize);
 }
 
 DAWN_INSTANTIATE_TEST(BufferMappingTests,
diff --git a/src/tests/end2end/DeprecatedAPITests.cpp b/src/tests/end2end/DeprecatedAPITests.cpp
index 0bda014..097185e 100644
--- a/src/tests/end2end/DeprecatedAPITests.cpp
+++ b/src/tests/end2end/DeprecatedAPITests.cpp
@@ -63,7 +63,7 @@
     }
 
     {
-        // Error case, use 0 to indicate default size will cause deprecated warning.
+        // Deprecated case, use 0 to indicate default size will cause deprecated warning.
         wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
         EXPECT_DEPRECATION_WARNING(pass.SetIndexBuffer(buffer, wgpu::IndexFormat::Uint32, 0, 0));
         EXPECT_DEPRECATION_WARNING(pass.SetVertexBuffer(0, buffer, 0, 0));
@@ -71,6 +71,32 @@
     }
 }
 
+// Test that using size=0 to indicate default size in mapAsync of buffer is
+// deprecated.
+TEST_P(DeprecationTests, BufferMapAsyncWithZeroSizeAsDefault) {
+    wgpu::BufferDescriptor bufferDesc;
+    bufferDesc.size = 128;
+    bufferDesc.usage = wgpu::BufferUsage::MapWrite;
+
+    {
+        // Control case, use wgpu::kWholeMapSize to indicate default size.
+        wgpu::Buffer buffer = device.CreateBuffer(&bufferDesc);
+
+        buffer.MapAsync(wgpu::MapMode::Write, 0, wgpu::kWholeMapSize, nullptr, nullptr);
+
+        WaitForAllOperations();
+    }
+
+    {
+        // Deprecated case, use 0 to indicate default size will cause deprecated warning.
+        wgpu::Buffer buffer = device.CreateBuffer(&bufferDesc);
+
+        EXPECT_DEPRECATION_WARNING(buffer.MapAsync(wgpu::MapMode::Write, 0, 0, nullptr, nullptr));
+
+        WaitForAllOperations();
+    }
+}
+
 DAWN_INSTANTIATE_TEST(DeprecationTests,
                       D3D12Backend(),
                       MetalBackend(),
diff --git a/src/tests/end2end/QueueTimelineTests.cpp b/src/tests/end2end/QueueTimelineTests.cpp
index f93c714..b7ada26 100644
--- a/src/tests/end2end/QueueTimelineTests.cpp
+++ b/src/tests/end2end/QueueTimelineTests.cpp
@@ -69,7 +69,7 @@
     EXPECT_CALL(*mockMapCallback, Call(WGPUBufferMapAsyncStatus_Success, this)).Times(1);
     EXPECT_CALL(*mockQueueWorkDoneCallback, Call(WGPUQueueWorkDoneStatus_Success, this)).Times(1);
 
-    mMapReadBuffer.MapAsync(wgpu::MapMode::Read, 0, 0, ToMockMapCallback, this);
+    mMapReadBuffer.MapAsync(wgpu::MapMode::Read, 0, wgpu::kWholeMapSize, ToMockMapCallback, this);
 
     queue.OnSubmittedWorkDone(0u, ToMockQueueWorkDone, this);
 
@@ -87,7 +87,7 @@
 
     queue.OnSubmittedWorkDone(0u, ToMockQueueWorkDone, this);
 
-    mMapReadBuffer.MapAsync(wgpu::MapMode::Read, 0, 0, ToMockMapCallback, this);
+    mMapReadBuffer.MapAsync(wgpu::MapMode::Read, 0, wgpu::kWholeMapSize, ToMockMapCallback, this);
 
     WaitForAllOperations();
     mMapReadBuffer.Unmap();
diff --git a/src/tests/unittests/validation/BufferValidationTests.cpp b/src/tests/unittests/validation/BufferValidationTests.cpp
index 18978df..bf9050b 100644
--- a/src/tests/unittests/validation/BufferValidationTests.cpp
+++ b/src/tests/unittests/validation/BufferValidationTests.cpp
@@ -219,13 +219,21 @@
     // Valid case: empty range at the end of the buffer is ok.
     {
         wgpu::Buffer buffer = CreateMapReadBuffer(8);
-        buffer.MapAsync(wgpu::MapMode::Read, 8, 0, nullptr, nullptr);
+        // Currently using size=0 will cause a deprecation warning, and result in default size.
+        // After the deprecation is finished, size=0 will result in a mapping with zero size
+        // exactly.
+        // TODO(dawn:1058): Remove the deprecation warning expection after the removal.
+        EXPECT_DEPRECATION_WARNING(buffer.MapAsync(wgpu::MapMode::Read, 8, 0, nullptr, nullptr));
     }
 
     // Error case, offset is larger than the buffer size (even if size is 0).
     {
         wgpu::Buffer buffer = CreateMapReadBuffer(12);
-        AssertMapAsyncError(buffer, wgpu::MapMode::Read, 16, 0);
+        // Currently using size=0 will cause a deprecation warning, and result in default size.
+        // After the deprecation is finished, size=0 will result in a mapping with zero size
+        // exactly.
+        // TODO(dawn:1058): Remove the deprecation warning expection after the removal.
+        EXPECT_DEPRECATION_WARNING(AssertMapAsyncError(buffer, wgpu::MapMode::Read, 16, 0));
     }
 
     // Error case, offset + size is larger than the buffer
@@ -819,7 +827,7 @@
     // Valid case: full range is ok with defaulted MapAsync size
     {
         wgpu::Buffer buffer = CreateMapWriteBuffer(8);
-        buffer.MapAsync(wgpu::MapMode::Write, 0, 0, nullptr, nullptr);
+        buffer.MapAsync(wgpu::MapMode::Write, 0, wgpu::kWholeMapSize, nullptr, nullptr);
         WaitForAllOperations(device);
         EXPECT_NE(buffer.GetMappedRange(0, 8), nullptr);
     }