Buffer.MapAsync pending map error non validation error consumed

Bug: dawn:1613
Change-Id: Ib1e5014d36c2c35d7ed9b946de4d21e046cf1282
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/114280
Commit-Queue: Takahiro <hogehoge@gachapin.jp>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Takahiro 2022-12-15 16:44:18 +00:00 committed by Dawn LUCI CQ
parent 987902e795
commit 5208edf37d
4 changed files with 47 additions and 18 deletions

View File

@ -340,6 +340,15 @@ void BufferBase::APIMapAsync(wgpu::MapMode mode,
size_t size, size_t size,
WGPUBufferMapCallback callback, WGPUBufferMapCallback callback,
void* userdata) { void* userdata) {
// Check for an existing pending map first because it just
// rejects the callback and doesn't produce a validation error.
if (mState == BufferState::PendingMap) {
if (callback) {
callback(WGPUBufferMapAsyncStatus_Error, userdata);
}
return;
}
// Handle the defaulting of size required by WebGPU, even if in webgpu_cpp.h it is not // 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 // possible to default the function argument (because there is the callback later in the
// argument list) // argument list)
@ -481,7 +490,7 @@ MaybeError BufferBase::ValidateMapAsync(wgpu::MapMode mode,
case BufferState::MappedAtCreation: case BufferState::MappedAtCreation:
return DAWN_VALIDATION_ERROR("%s is already mapped.", this); return DAWN_VALIDATION_ERROR("%s is already mapped.", this);
case BufferState::PendingMap: case BufferState::PendingMap:
return DAWN_VALIDATION_ERROR("%s is pending map.", this); UNREACHABLE();
case BufferState::Destroyed: case BufferState::Destroyed:
return DAWN_VALIDATION_ERROR("%s is destroyed.", this); return DAWN_VALIDATION_ERROR("%s is destroyed.", this);
case BufferState::Unmapped: case BufferState::Unmapped:

View File

@ -421,14 +421,17 @@ TEST_P(BufferMappingTests, OffsetNotUpdatedOnError) {
}, },
&done1); &done1);
// Call MapAsync another time, it is an error because the buffer is already being mapped so // Call MapAsync another time, the callback will be rejected with error status
// mMapOffset is not updated. // (but doesn't produce a validation error) and mMapOffset is not updated
ASSERT_DEVICE_ERROR(buffer.MapAsync( // because the buffer is already being mapped and it doesn't allow multiple
// MapAsync requests.
buffer.MapAsync(
wgpu::MapMode::Read, 0, 4, wgpu::MapMode::Read, 0, 4,
[](WGPUBufferMapAsyncStatus status, void* userdata) { [](WGPUBufferMapAsyncStatus status, void* userdata) {
ASSERT_EQ(WGPUBufferMapAsyncStatus_Error, status);
*static_cast<bool*>(userdata) = true; *static_cast<bool*>(userdata) = true;
}, },
&done2)); &done2);
while (!done1 || !done2) { while (!done1 || !done2) {
WaitABit(); WaitABit();

View File

@ -313,15 +313,17 @@ TEST_F(BufferValidationTest, MapAsync_AlreadyMapped) {
} }
} }
// Test map async with a buffer that's pending map // Test MapAsync() immediately causes a pending map error
TEST_F(BufferValidationTest, MapAsync_PendingMap) { TEST_F(BufferValidationTest, MapAsync_PendingMap) {
// Read + overlapping range // Read + overlapping range
{ {
wgpu::Buffer buffer = CreateMapReadBuffer(4); wgpu::Buffer buffer = CreateMapReadBuffer(4);
// The first map async call should succeed while the second one should fail // The first map async call should succeed while the second one should fail
buffer.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr); buffer.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, this);
AssertMapAsyncError(buffer, wgpu::MapMode::Read, 0, 4); EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Error, this + 1))
EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, nullptr)) .Times(1);
buffer.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, this + 1);
EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, this))
.Times(1); .Times(1);
WaitForAllOperations(device); WaitForAllOperations(device);
} }
@ -330,9 +332,11 @@ TEST_F(BufferValidationTest, MapAsync_PendingMap) {
{ {
wgpu::Buffer buffer = CreateMapReadBuffer(16); wgpu::Buffer buffer = CreateMapReadBuffer(16);
// The first map async call should succeed while the second one should fail // The first map async call should succeed while the second one should fail
buffer.MapAsync(wgpu::MapMode::Read, 0, 8, ToMockBufferMapAsyncCallback, nullptr); buffer.MapAsync(wgpu::MapMode::Read, 0, 8, ToMockBufferMapAsyncCallback, this);
AssertMapAsyncError(buffer, wgpu::MapMode::Read, 8, 8); EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Error, this + 1))
EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, nullptr)) .Times(1);
buffer.MapAsync(wgpu::MapMode::Read, 8, 8, ToMockBufferMapAsyncCallback, this + 1);
EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, this))
.Times(1); .Times(1);
WaitForAllOperations(device); WaitForAllOperations(device);
} }
@ -341,9 +345,11 @@ TEST_F(BufferValidationTest, MapAsync_PendingMap) {
{ {
wgpu::Buffer buffer = CreateMapWriteBuffer(4); wgpu::Buffer buffer = CreateMapWriteBuffer(4);
// The first map async call should succeed while the second one should fail // The first map async call should succeed while the second one should fail
buffer.MapAsync(wgpu::MapMode::Write, 0, 4, ToMockBufferMapAsyncCallback, nullptr); buffer.MapAsync(wgpu::MapMode::Write, 0, 4, ToMockBufferMapAsyncCallback, this);
AssertMapAsyncError(buffer, wgpu::MapMode::Write, 0, 4); EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Error, this + 1))
EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, nullptr)) .Times(1);
buffer.MapAsync(wgpu::MapMode::Write, 0, 4, ToMockBufferMapAsyncCallback, this + 1);
EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, this))
.Times(1); .Times(1);
WaitForAllOperations(device); WaitForAllOperations(device);
} }
@ -352,9 +358,11 @@ TEST_F(BufferValidationTest, MapAsync_PendingMap) {
{ {
wgpu::Buffer buffer = CreateMapWriteBuffer(16); wgpu::Buffer buffer = CreateMapWriteBuffer(16);
// The first map async call should succeed while the second one should fail // The first map async call should succeed while the second one should fail
buffer.MapAsync(wgpu::MapMode::Write, 0, 8, ToMockBufferMapAsyncCallback, nullptr); buffer.MapAsync(wgpu::MapMode::Write, 0, 8, ToMockBufferMapAsyncCallback, this);
AssertMapAsyncError(buffer, wgpu::MapMode::Write, 8, 8); EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Error, this + 1))
EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, nullptr)) .Times(1);
buffer.MapAsync(wgpu::MapMode::Write, 8, 8, ToMockBufferMapAsyncCallback, this + 1);
EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, this))
.Times(1); .Times(1);
WaitForAllOperations(device); WaitForAllOperations(device);
} }

View File

@ -455,6 +455,15 @@ crbug.com/dawn/1602 webgpu:api,validation,render_pass,storeOp:* [ Skip ]
crbug.com/dawn/1602 webgpu:api,validation,resource_usages,texture,in_render_misc:subresources,set_bind_group_on_same_index_depth_stencil_texture:* [ Skip ] crbug.com/dawn/1602 webgpu:api,validation,resource_usages,texture,in_render_misc:subresources,set_bind_group_on_same_index_depth_stencil_texture:* [ Skip ]
################################################################################ ################################################################################
################################################################################
# Buffer.MapAsync pending map error tests need updates in CTS
################################################################################
crbug.com/dawn/1613 webgpu:api,validation,buffer,mapping:getMappedRange,state,mappingPending:* [ Failure ]
crbug.com/dawn/1613 webgpu:api,validation,buffer,mapping:mapAsync,state,mappingPending:* [ Failure ]
crbug.com/dawn/1613 worker_webgpu:api,validation,buffer,mapping:getMappedRange,state,mappingPending:* [ Failure ]
crbug.com/dawn/1613 worker_webgpu:api,validation,buffer,mapping:mapAsync,state,mappingPending:* [ Failure ]
################################################################################
################################################################################ ################################################################################
# untriaged failures # untriaged failures
# KEEP # KEEP