diff --git a/generator/templates/webgpu.h b/generator/templates/webgpu.h index 9630d1af03..d305dd260e 100644 --- a/generator/templates/webgpu.h +++ b/generator/templates/webgpu.h @@ -74,6 +74,7 @@ #include #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 951f6ad1a2..dfbe6c423c 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 86ffcb97de..abb7f1bcf1 100644 --- a/src/dawn_native/Buffer.cpp +++ b/src/dawn_native/Buffer.cpp @@ -298,7 +298,18 @@ namespace dawn_native { // 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 @@ namespace dawn_native { *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 f27b99ea4e..5077b5aa49 100644 --- a/src/dawn_wire/client/Buffer.cpp +++ b/src/dawn_wire/client/Buffer.cpp @@ -166,7 +166,7 @@ namespace dawn_wire { namespace client { } // 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 9548857d77..0dff12615e 100644 --- a/src/tests/DawnTest.cpp +++ b/src/tests/DawnTest.cpp @@ -1430,7 +1430,8 @@ void DawnTestBase::MapSlotsSynchronously() { 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 74289c7e33..b893c02912 100644 --- a/src/tests/end2end/BufferTests.cpp +++ b/src/tests/end2end/BufferTests.cpp @@ -77,7 +77,7 @@ TEST_P(BufferMappingTests, MapRead_Basic) { 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_BasicRange) { 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_InCallbackRange) { 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 0bda014d01..097185ed54 100644 --- a/src/tests/end2end/DeprecatedAPITests.cpp +++ b/src/tests/end2end/DeprecatedAPITests.cpp @@ -63,7 +63,7 @@ TEST_P(DeprecationTests, SetBufferWithZeroSizeAsDefault) { } { - // 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_P(DeprecationTests, SetBufferWithZeroSizeAsDefault) { } } +// 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 f93c714626..b7ada26b44 100644 --- a/src/tests/end2end/QueueTimelineTests.cpp +++ b/src/tests/end2end/QueueTimelineTests.cpp @@ -69,7 +69,7 @@ TEST_P(QueueTimelineTests, MapRead_OnWorkDone) { 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 @@ TEST_P(QueueTimelineTests, OnWorkDone_MapRead) { 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 18978dfd41..bf9050bc5f 100644 --- a/src/tests/unittests/validation/BufferValidationTests.cpp +++ b/src/tests/unittests/validation/BufferValidationTests.cpp @@ -219,13 +219,21 @@ TEST_F(BufferValidationTest, MapAsync_OffsetSizeOOB) { // 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 @@ TEST_F(BufferValidationTest, GetMappedRange_OffsetSizeOOB) { // 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); }