dawn::wire::client Make Device::Destroy cancel mappings
This is technically visible when a succesful mapping would be returned
for a MapAsync, but the Device::Destroy comes first, cancelling the
mapping.
Bug: 344963953
Change-Id: I64f98a9212626dd6b1f2cba32b7a8f2249ab9a98
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/197456
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Loko Kung <lokokung@google.com>
Auto-Submit: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn/dawn_wire.json b/src/dawn/dawn_wire.json
index 4d7f652..8610a38 100644
--- a/src/dawn/dawn_wire.json
+++ b/src/dawn/dawn_wire.json
@@ -275,6 +275,7 @@
"BufferDestroy",
"BufferUnmap",
"DeviceCreateErrorBuffer",
+ "DeviceDestroy",
"DeviceGetAdapter",
"DeviceGetQueue",
"DeviceGetSupportedSurfaceUsage",
diff --git a/src/dawn/tests/unittests/wire/WireBufferMappingTests.cpp b/src/dawn/tests/unittests/wire/WireBufferMappingTests.cpp
index a3c541a..31923c6 100644
--- a/src/dawn/tests/unittests/wire/WireBufferMappingTests.cpp
+++ b/src/dawn/tests/unittests/wire/WireBufferMappingTests.cpp
@@ -330,6 +330,21 @@
DefaultApiDeviceWasReleased();
}
+// Check the map callback is called with "DestroyedBeforeCallback" when the map request would have
+// worked, but the device was destroyed.
+TEST_P(WireBufferMappingTests, DeviceDestroyedTooEarly) {
+ TestEarlyMapCancelled([&]() { wgpuDeviceDestroy(device); },
+ [&]() { EXPECT_CALL(api, DeviceDestroy(apiDevice)); },
+ WGPUBufferMapAsyncStatus_DestroyedBeforeCallback, false);
+}
+
+// Check that if device is destroyed early client-side, we disregard server-side validation errors.
+TEST_P(WireBufferMappingTests, DeviceDestroyedTooEarlyServerSideError) {
+ TestEarlyMapErrorCancelled([&]() { wgpuDeviceDestroy(device); },
+ [&]() { EXPECT_CALL(api, DeviceDestroy(apiDevice)); },
+ WGPUBufferMapAsyncStatus_DestroyedBeforeCallback, false);
+}
+
// Test that the callback isn't fired twice when Unmap() is called inside the callback.
TEST_P(WireBufferMappingTests, UnmapInsideMapCallback) {
TestCancelInCallback(&wgpuBufferUnmap, [&]() { EXPECT_CALL(api, BufferUnmap(apiBuffer)); });
diff --git a/src/dawn/wire/client/Device.cpp b/src/dawn/wire/client/Device.cpp
index 62cc0f4..1323967 100644
--- a/src/dawn/wire/client/Device.cpp
+++ b/src/dawn/wire/client/Device.cpp
@@ -609,4 +609,12 @@
.SetFutureReady<CreateRenderPipelineEvent>(future.id, status, message);
}
+void Device::Destroy() {
+ DeviceDestroyCmd cmd;
+ cmd.self = ToAPI(this);
+ GetClient()->SerializeCommand(cmd);
+
+ mIsAlive = false;
+}
+
} // namespace dawn::wire::client
diff --git a/src/dawn/wire/client/Device.h b/src/dawn/wire/client/Device.h
index 7a9e8c1..a811437 100644
--- a/src/dawn/wire/client/Device.h
+++ b/src/dawn/wire/client/Device.h
@@ -98,6 +98,8 @@
size_t EnumerateFeatures(WGPUFeatureName* features) const;
WGPUQueue GetQueue();
+ void Destroy();
+
private:
void WillDropLastExternalRef() override;
template <typename Event,