[wgpu-header] Clean up for 2nd userdata for mapAsync and workDone.
- Updates relevant usages to use the new C++ helpers.
- Updates Null backend to more realistically simulate queue work.
- Note that these are done together and not in separate changes
because they have some inter-dependency.
Bug: 42241461
Change-Id: I3866972355cf3ae2b3f82a1c41d47dbbc5308535
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/188445
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Loko Kung <lokokung@google.com>
diff --git a/src/dawn/native/Buffer.cpp b/src/dawn/native/Buffer.cpp
index 9cdffb0..554c5d8 100644
--- a/src/dawn/native/Buffer.cpp
+++ b/src/dawn/native/Buffer.cpp
@@ -669,6 +669,10 @@
size_t size,
WGPUBufferMapCallback callback,
void* userdata) {
+ GetInstance()->EmitDeprecationWarning(
+ "Old MapAsync APIs are deprecated. If using C please pass a CallbackInfo "
+ "struct that has two userdatas. Otherwise, if using C++, please use templated helpers.");
+
// Check for an existing pending map first because it just
// rejects the callback and doesn't produce a validation error.
if (mState == BufferState::PendingMap) {
@@ -721,6 +725,10 @@
size_t offset,
size_t size,
const BufferMapCallbackInfo& callbackInfo) {
+ GetInstance()->EmitDeprecationWarning(
+ "Old MapAsync APIs are deprecated. If using C please pass a CallbackInfo "
+ "struct that has two userdatas. Otherwise, if using C++, please use templated helpers.");
+
// TODO(crbug.com/dawn/2052): Once we always return a future, change this to log to the instance
// (note, not raise a validation error to the device) and return the null future.
DAWN_ASSERT(callbackInfo.nextInChain == nullptr);
diff --git a/src/dawn/native/Queue.cpp b/src/dawn/native/Queue.cpp
index 9c5e924..eb6a732 100644
--- a/src/dawn/native/Queue.cpp
+++ b/src/dawn/native/Queue.cpp
@@ -257,6 +257,10 @@
}
void QueueBase::APIOnSubmittedWorkDone(WGPUQueueWorkDoneCallback callback, void* userdata) {
+ GetInstance()->EmitDeprecationWarning(
+ "Old OnSubmittedWorkDone APIs are deprecated. If using C please pass a CallbackInfo "
+ "struct that has two userdatas. Otherwise, if using C++, please use templated helpers.");
+
// The error status depends on the type of error so we let the validation function choose it
wgpu::QueueWorkDoneStatus status;
if (GetDevice()->ConsumedError(ValidateOnSubmittedWorkDone(&status))) {
@@ -279,6 +283,10 @@
}
Future QueueBase::APIOnSubmittedWorkDoneF(const QueueWorkDoneCallbackInfo& callbackInfo) {
+ GetInstance()->EmitDeprecationWarning(
+ "Old OnSubmittedWorkDone APIs are deprecated. If using C please pass a CallbackInfo "
+ "struct that has two userdatas. Otherwise, if using C++, please use templated helpers.");
+
return APIOnSubmittedWorkDone2(
{ToAPI(callbackInfo.nextInChain), ToAPI(callbackInfo.mode),
[](WGPUQueueWorkDoneStatus status, void* callback, void* userdata) {
diff --git a/src/dawn/native/null/DeviceNull.cpp b/src/dawn/native/null/DeviceNull.cpp
index b63c5c8..c0720268 100644
--- a/src/dawn/native/null/DeviceNull.cpp
+++ b/src/dawn/native/null/DeviceNull.cpp
@@ -325,7 +325,6 @@
mPendingOperations.clear();
DAWN_TRY(GetQueue()->CheckPassedSerials());
- GetQueue()->IncrementLastSubmittedCommandSerial();
return {};
}
@@ -385,6 +384,7 @@
}
MaybeError Buffer::MapAsyncImpl(wgpu::MapMode mode, size_t offset, size_t size) {
+ GetDevice()->GetQueue()->IncrementLastSubmittedCommandSerial();
return {};
}
@@ -426,6 +426,7 @@
Device* device = ToBackend(GetDevice());
DAWN_TRY(device->SubmitPendingOperations());
+ IncrementLastSubmittedCommandSerial();
return {};
}
diff --git a/src/dawn/tests/DawnTest.cpp b/src/dawn/tests/DawnTest.cpp
index e6fdcbd..78a2d90 100644
--- a/src/dawn/tests/DawnTest.cpp
+++ b/src/dawn/tests/DawnTest.cpp
@@ -48,6 +48,7 @@
#include "dawn/native/Device.h"
#include "dawn/native/Instance.h"
#include "dawn/native/dawn_platform.h"
+#include "dawn/tests/MockCallback.h"
#include "dawn/tests/PartitionAllocSupport.h"
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/utils/PlatformDebugLogger.h"
@@ -69,11 +70,7 @@
using testing::_;
using testing::AtMost;
-
-struct MapReadUserdata {
- raw_ptr<DawnTestBase> test;
- size_t slot;
-};
+using testing::MockCppCallback;
DawnTestEnvironment* gTestEnv = nullptr;
DawnTestBase* gCurrentTest = nullptr;
@@ -809,15 +806,6 @@
WaitForAllOperations();
instance = nullptr;
- // Since the native instance is a global, we can't rely on it's destruction to clean up all
- // callbacks. Instead, for each test, we make sure to clear all events. Note that we use a
- // do-while loop here because we need to flush the wire via WaitABit before we start processing
- // the native events to ensure that any remaining client side commands, i.e. destructions, are
- // flushed to the server.
- do {
- WaitABit();
- } while (dawn::native::InstanceProcessEvents(gTestEnv->GetInstance()->Get()));
-
// D3D11 and D3D12's GPU-based validation will accumulate objects over time if the backend
// device is not destroyed and recreated, so we reset it here.
if ((IsD3D11() || IsD3D12()) && IsBackendValidationEnabled()) {
@@ -1648,6 +1636,35 @@
return EXPECT_TEXTURE_EQ(colorData.data(), colorTexture, {0, 0}, {width, height});
}
+void DawnTestBase::MapAsyncAndWait(const wgpu::Buffer& buffer,
+ wgpu::MapMode mapMode,
+ uint64_t offset,
+ uint64_t size) {
+ DAWN_ASSERT(mapMode == wgpu::MapMode::Read || mapMode == wgpu::MapMode::Write);
+
+ if (!UsesWire()) {
+ // We use a new mock callback here so that the validation on the call happens as soon as the
+ // scope of this call ends.
+ MockCppCallback<void (*)(wgpu::MapAsyncStatus, const char*)> mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+
+ wgpu::FutureWaitInfo waitInfo = {buffer.MapAsync(
+ mapMode, offset, size, wgpu::CallbackMode::WaitAnyOnly, mockCb.Callback())};
+ ASSERT_EQ(instance.WaitAny(1, &waitInfo, UINT64_MAX), wgpu::WaitStatus::Success);
+ } else {
+ bool done = false;
+ buffer.MapAsync(mapMode, offset, size, wgpu::CallbackMode::AllowProcessEvents,
+ [&done](wgpu::MapAsyncStatus status, const char*) {
+ ASSERT_EQ(status, wgpu::MapAsyncStatus::Success);
+ done = true;
+ });
+
+ while (!done) {
+ WaitABit();
+ }
+ }
+}
+
void DawnTestBase::WaitABit(wgpu::Instance targetInstance) {
if (targetInstance == nullptr) {
targetInstance = instance;
@@ -1670,22 +1687,6 @@
}
void DawnTestBase::WaitForAllOperations() {
- // TODO: crbug.com/42241461 - This block should be removed once we have migrated all tests to
- // use the new entry points.
- if (device != nullptr) {
- // Callback might be invoked on another thread that calls the same WaitABit() method, not
- // necessarily the current thread. So we need to use atomic here.
- std::atomic<bool> done(false);
- device.GetQueue().OnSubmittedWorkDone(
- [](WGPUQueueWorkDoneStatus, void* userdata) {
- *static_cast<std::atomic<bool>*>(userdata) = true;
- },
- &done);
- while (!done.load()) {
- WaitABit();
- }
- }
-
do {
FlushWire();
if (UsesWire() && instance != nullptr) {
@@ -1727,12 +1728,24 @@
mNumPendingMapOperations = mReadbackSlots.size();
// Map all readback slots
- for (size_t i = 0; i < mReadbackSlots.size(); ++i) {
- MapReadUserdata* userdata = new MapReadUserdata{this, i};
+ for (size_t slotIndex = 0; slotIndex < mReadbackSlots.size(); ++slotIndex) {
+ auto& slot = mReadbackSlots[slotIndex];
- const ReadbackSlot& slot = mReadbackSlots[i];
- slot.buffer.MapAsync(wgpu::MapMode::Read, 0, wgpu::kWholeMapSize, SlotMapCallback,
- userdata);
+ slot.buffer.MapAsync(wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
+ wgpu::CallbackMode::AllowProcessEvents,
+ [this, &slot](wgpu::MapAsyncStatus status, const char*) {
+ DAWN_ASSERT(status == wgpu::MapAsyncStatus::Success);
+ Mutex::AutoLock lg(&mMutex);
+
+ if (status == wgpu::MapAsyncStatus::Success) {
+ slot.mappedData = slot.buffer.GetConstMappedRange();
+ DAWN_ASSERT(slot.mappedData != nullptr);
+ } else {
+ slot.mappedData = nullptr;
+ }
+
+ mNumPendingMapOperations.fetch_sub(1, std::memory_order_release);
+ });
}
// Busy wait until all map operations are done.
@@ -1741,26 +1754,6 @@
}
}
-// static
-void DawnTestBase::SlotMapCallback(WGPUBufferMapAsyncStatus status, void* userdata_) {
- DAWN_ASSERT(status == WGPUBufferMapAsyncStatus_Success ||
- status == WGPUBufferMapAsyncStatus_DeviceLost);
- std::unique_ptr<MapReadUserdata> userdata(static_cast<MapReadUserdata*>(userdata_));
- DawnTestBase* test = userdata->test;
-
- Mutex::AutoLock lg(&test->mMutex);
-
- ReadbackSlot* slot = &test->mReadbackSlots[userdata->slot];
- if (status == WGPUBufferMapAsyncStatus_Success) {
- slot->mappedData = slot->buffer.GetConstMappedRange();
- DAWN_ASSERT(slot->mappedData != nullptr);
- } else {
- slot->mappedData = nullptr;
- }
-
- test->mNumPendingMapOperations.fetch_sub(1, std::memory_order_release);
-}
-
void DawnTestBase::ResolveExpectations() {
for (const auto& expectation : mDeferredExpectations) {
EXPECT_TRUE(mReadbackSlots[expectation.readbackSlot].mappedData != nullptr);
diff --git a/src/dawn/tests/DawnTest.h b/src/dawn/tests/DawnTest.h
index 7688f95..208d0c4 100644
--- a/src/dawn/tests/DawnTest.h
+++ b/src/dawn/tests/DawnTest.h
@@ -586,6 +586,11 @@
mipLevel, {}, &expectedStencil);
}
+ void MapAsyncAndWait(const wgpu::Buffer& buffer,
+ wgpu::MapMode mapMode,
+ uint64_t offset,
+ uint64_t size);
+
void WaitABit(wgpu::Instance = nullptr);
void FlushWire();
void WaitForAllOperations();
@@ -659,7 +664,6 @@
// Maps all the buffers and fill ReadbackSlot::mappedData
void MapSlotsSynchronously();
- static void SlotMapCallback(WGPUBufferMapAsyncStatus status, void* userdata);
std::atomic<size_t> mNumPendingMapOperations = 0;
// Reserve space where the data for an expectation can be copied
diff --git a/src/dawn/tests/end2end/BufferHostMappedPointerTests.cpp b/src/dawn/tests/end2end/BufferHostMappedPointerTests.cpp
index 682a30d..5580b7f 100644
--- a/src/dawn/tests/end2end/BufferHostMappedPointerTests.cpp
+++ b/src/dawn/tests/end2end/BufferHostMappedPointerTests.cpp
@@ -263,9 +263,10 @@
ASSERT_DEVICE_ERROR(buffer.Unmap());
// Invalid to map a persistently host mapped buffer.
- ASSERT_DEVICE_ERROR_MSG(
- buffer.MapAsync(wgpu::MapMode::Write, 0, wgpu::kWholeMapSize, nullptr, nullptr),
- testing::HasSubstr("cannot be mapped"));
+ ASSERT_DEVICE_ERROR_MSG(buffer.MapAsync(wgpu::MapMode::Write, 0, wgpu::kWholeMapSize,
+ wgpu::CallbackMode::AllowSpontaneous,
+ [](wgpu::MapAsyncStatus, const char*) {}),
+ testing::HasSubstr("cannot be mapped"));
// Still invalid to GetMappedRange() or Unmap.
ASSERT_EQ(buffer.GetMappedRange(), nullptr);
diff --git a/src/dawn/tests/end2end/BufferTests.cpp b/src/dawn/tests/end2end/BufferTests.cpp
index e6a1d78..6eca2cd 100644
--- a/src/dawn/tests/end2end/BufferTests.cpp
+++ b/src/dawn/tests/end2end/BufferTests.cpp
@@ -34,6 +34,7 @@
#include <vector>
#include "dawn/tests/DawnTest.h"
+#include "dawn/tests/MockCallback.h"
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/utils/WGPUHelpers.h"
#include "partition_alloc/pointers/raw_ptr.h"
@@ -41,6 +42,11 @@
namespace dawn {
namespace {
+using testing::_;
+using testing::MockCppCallback;
+
+using MockMapAsyncCallback = MockCppCallback<void (*)(wgpu::MapAsyncStatus, const char*)>;
+
using FutureCallbackMode = std::optional<wgpu::CallbackMode>;
DAWN_TEST_PARAM_STRUCT(BufferMappingTestParams, FutureCallbackMode);
@@ -60,26 +66,26 @@
size_t size,
wgpu::BufferMapCallback cb = nullptr,
void* ud = nullptr) {
- struct Userdata {
- wgpu::BufferMapCallback cb;
- raw_ptr<void> ud;
- bool done = false;
- };
- Userdata userdata = Userdata{cb, ud};
- auto callback = [](WGPUBufferMapAsyncStatus status, void* rawUserdata) {
- auto* userdata = static_cast<Userdata*>(rawUserdata);
- userdata->done = true;
- ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
- auto cb = userdata->cb;
- auto ud = userdata->ud;
- if (cb) {
- cb(status, ud);
- }
- };
-
// Legacy MapAsync
if (!GetParam().mFutureCallbackMode) {
- buffer.MapAsync(mode, offset, size, callback, &userdata);
+ struct Userdata {
+ wgpu::BufferMapCallback cb;
+ raw_ptr<void> ud;
+ bool done = false;
+ };
+ Userdata userdata = Userdata{cb, ud};
+ auto callback = [](WGPUBufferMapAsyncStatus status, void* rawUserdata) {
+ auto* userdata = static_cast<Userdata*>(rawUserdata);
+ userdata->done = true;
+ ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
+ auto cb = userdata->cb;
+ auto ud = userdata->ud;
+ if (cb) {
+ cb(status, ud);
+ }
+ };
+
+ EXPECT_DEPRECATION_WARNING(buffer.MapAsync(mode, offset, size, callback, &userdata));
while (!userdata.done) {
// Flush wire and call instance process events.
WaitABit();
@@ -87,19 +93,27 @@
return;
}
- wgpu::Future future = buffer.MapAsync(
- mode, offset, size, {nullptr, *GetParam().mFutureCallbackMode, callback, &userdata});
+ bool done = false;
+ wgpu::Future future =
+ buffer.MapAsync(mode, offset, size, *GetParam().mFutureCallbackMode,
+ [cb, ud, &done](wgpu::MapAsyncStatus status, const char*) {
+ done = true;
+ ASSERT_EQ(wgpu::MapAsyncStatus::Success, status);
+ if (cb) {
+ cb(WGPUBufferMapAsyncStatus_Success, ud);
+ }
+ });
switch (*GetParam().mFutureCallbackMode) {
case wgpu::CallbackMode::WaitAnyOnly: {
wgpu::FutureWaitInfo waitInfo = {future};
GetInstance().WaitAny(1, &waitInfo, UINT64_MAX);
ASSERT_TRUE(waitInfo.completed);
- ASSERT_TRUE(userdata.done);
+ ASSERT_TRUE(done);
break;
}
case wgpu::CallbackMode::AllowProcessEvents:
case wgpu::CallbackMode::AllowSpontaneous:
- while (!userdata.done) {
+ while (!done) {
// Flush wire and call instance process events.
WaitABit();
}
@@ -448,13 +462,13 @@
if (!GetParam().mFutureCallbackMode) {
// Map all the buffers.
for (uint32_t i = 0; i < kBuffers; ++i) {
- buffers[i].MapAsync(
+ EXPECT_DEPRECATION_WARNING(buffers[i].MapAsync(
wgpu::MapMode::Write, 0, descriptor.size,
[](WGPUBufferMapAsyncStatus status, void* userdata) {
ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
(*static_cast<uint32_t*>(userdata))++;
},
- &mapCompletedCount);
+ &mapCompletedCount));
}
// Wait for all mappings to complete
@@ -464,14 +478,12 @@
} else {
std::array<wgpu::Future, kBuffers> futures;
for (uint32_t i = 0; i < kBuffers; ++i) {
- futures[i] =
- buffers[i].MapAsync(wgpu::MapMode::Write, 0, descriptor.size,
- {nullptr, *GetParam().mFutureCallbackMode,
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
- (*static_cast<uint32_t*>(userdata))++;
- },
- &mapCompletedCount});
+ futures[i] = buffers[i].MapAsync(
+ wgpu::MapMode::Write, 0, descriptor.size, *GetParam().mFutureCallbackMode,
+ [&mapCompletedCount](wgpu::MapAsyncStatus status, const char*) {
+ ASSERT_EQ(wgpu::MapAsyncStatus::Success, status);
+ mapCompletedCount++;
+ });
}
switch (*GetParam().mFutureCallbackMode) {
@@ -521,78 +533,78 @@
wgpu::Buffer buffer = CreateMapReadBuffer(sizeof(data));
queue.WriteBuffer(buffer, 0, data, sizeof(data));
- bool done1 = false;
- bool done2 = false;
- auto cb1 = [](WGPUBufferMapAsyncStatus status, void* userdata) {
- ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
- *static_cast<bool*>(userdata) = true;
- };
- // Calling MapAsync another time, will reject the callback with error status
- // and mMapOffset is not updated because the buffer is already being mapped and it doesn't allow
- // multiple MapAsync requests.
- auto cb2 = [](WGPUBufferMapAsyncStatus status, void* userdata) {
- ASSERT_EQ(WGPUBufferMapAsyncStatus_MappingAlreadyPending, status);
- *static_cast<bool*>(userdata) = true;
- };
- // Calling MapAsync when the buffer is already mapped (as opposed to pending mapping) will cause
- // a validation error.
- auto cb2Mapped = [](WGPUBufferMapAsyncStatus status, void* userdata) {
- ASSERT_EQ(WGPUBufferMapAsyncStatus_ValidationError, status);
- *static_cast<bool*>(userdata) = true;
- };
-
// Legacy MapAsync
if (!GetParam().mFutureCallbackMode) {
+ bool done1 = false;
+ bool done2 = false;
+ auto cb1 = [](WGPUBufferMapAsyncStatus status, void* userdata) {
+ ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
+ *static_cast<bool*>(userdata) = true;
+ };
+ // Calling MapAsync another time, will reject the callback with error status
+ // and mMapOffset is not updated because the buffer is already being mapped and it doesn't
+ // allow multiple MapAsync requests.
+ auto cb2 = [](WGPUBufferMapAsyncStatus status, void* userdata) {
+ ASSERT_EQ(WGPUBufferMapAsyncStatus_MappingAlreadyPending, status);
+ *static_cast<bool*>(userdata) = true;
+ };
+ // Calling MapAsync when the buffer is already mapped (as opposed to pending mapping) will
+ // cause a validation error.
+ auto cb2Mapped = [](WGPUBufferMapAsyncStatus status, void* userdata) {
+ ASSERT_EQ(WGPUBufferMapAsyncStatus_ValidationError, status);
+ *static_cast<bool*>(userdata) = true;
+ };
+
// Map the buffer but do not wait on the result yet.
- buffer.MapAsync(wgpu::MapMode::Read, 8, 4, cb1, &done1);
+ EXPECT_DEPRECATION_WARNING(buffer.MapAsync(wgpu::MapMode::Read, 8, 4, cb1, &done1));
// Call MapAsync another time, the callback will be rejected with error status
// and mMapOffset is not updated because the buffer is already being mapped and it doesn't
// allow multiple MapAsync requests.
if (buffer.GetMapState() == wgpu::BufferMapState::Mapped) {
- ASSERT_DEVICE_ERROR(buffer.MapAsync(wgpu::MapMode::Read, 0, 4, cb2Mapped, &done2));
+ ASSERT_DEVICE_ERROR(EXPECT_DEPRECATION_WARNING(
+ buffer.MapAsync(wgpu::MapMode::Read, 0, 4, cb2Mapped, &done2)));
} else {
- buffer.MapAsync(wgpu::MapMode::Read, 0, 4, cb2, &done2);
+ EXPECT_DEPRECATION_WARNING(buffer.MapAsync(wgpu::MapMode::Read, 0, 4, cb2, &done2));
}
while (!done1 || !done2) {
WaitABit();
}
} else {
+ MockMapAsyncCallback cb1;
+ MockMapAsyncCallback cb2;
+ EXPECT_CALL(cb1, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ EXPECT_CALL(cb2, Call(wgpu::MapAsyncStatus::Error, _)).Times(1);
+
// Map the buffer but do not wait on the result yet.
- wgpu::Future f1 = buffer.MapAsync(wgpu::MapMode::Read, 8, 4,
- {nullptr, *GetParam().mFutureCallbackMode, cb1, &done1});
+ wgpu::FutureWaitInfo f1 = {buffer.MapAsync(
+ wgpu::MapMode::Read, 8, 4, *GetParam().mFutureCallbackMode, cb1.Callback())};
// Call MapAsync another time, the callback will be rejected with error status
// and mMapOffset is not updated because the buffer is already being mapped and it doesn't
// allow multiple MapAsync requests.
- wgpu::Future f2;
- if (buffer.GetMapState() == wgpu::BufferMapState::Mapped) {
- ASSERT_DEVICE_ERROR(f2 = buffer.MapAsync(
- wgpu::MapMode::Read, 0, 4,
- {nullptr, *GetParam().mFutureCallbackMode, cb2Mapped, &done2}));
+ wgpu::FutureWaitInfo f2;
+ if (!UsesWire()) {
+ ASSERT_DEVICE_ERROR(
+ f2 = {buffer.MapAsync(wgpu::MapMode::Read, 0, 4, *GetParam().mFutureCallbackMode,
+ cb2.Callback())});
} else {
- f2 = buffer.MapAsync(wgpu::MapMode::Read, 0, 4,
- {nullptr, *GetParam().mFutureCallbackMode, cb2, &done2});
+ f2 = {buffer.MapAsync(wgpu::MapMode::Read, 0, 4, *GetParam().mFutureCallbackMode,
+ cb2.Callback())};
}
switch (*GetParam().mFutureCallbackMode) {
case wgpu::CallbackMode::WaitAnyOnly: {
- wgpu::FutureWaitInfo waitInfo[] = {{f1}, {f2}};
- GetInstance().WaitAny(2, waitInfo, UINT64_MAX);
-
- if (!waitInfo[0].completed) {
- GetInstance().WaitAny(1, &waitInfo[0], UINT64_MAX);
- } else if (!waitInfo[1].completed) {
- GetInstance().WaitAny(1, &waitInfo[1], UINT64_MAX);
- }
+ ASSERT_EQ(GetInstance().WaitAny(1, &f1, UINT64_MAX), wgpu::WaitStatus::Success);
+ ASSERT_EQ(GetInstance().WaitAny(1, &f2, UINT64_MAX), wgpu::WaitStatus::Success);
+ EXPECT_TRUE(f1.completed);
+ EXPECT_TRUE(f2.completed);
break;
}
case wgpu::CallbackMode::AllowProcessEvents:
case wgpu::CallbackMode::AllowSpontaneous:
- while (!done1 || !done2) {
- WaitABit();
- }
+ WaitForAllOperations();
break;
}
}
@@ -708,11 +720,19 @@
wgpu::BufferMapCallback callback,
void* userdata) {
if (!GetParam().mFutureCallbackMode) {
- buffer.MapAsync(mapMode, offset, size, callback, userdata);
+ EXPECT_DEPRECATION_WARNING(buffer.MapAsync(mapMode, offset, size, callback, userdata));
return {0};
} else {
- return buffer.MapAsync(mapMode, offset, size,
- {nullptr, *GetParam().mFutureCallbackMode, callback, userdata});
+ return buffer.MapAsync(mapMode, offset, size, *GetParam().mFutureCallbackMode,
+ [callback, userdata](wgpu::MapAsyncStatus status, const char*) {
+ // Note that technically this cast should eventually be
+ // removed once we update all tests to use the new callback
+ // status. This currently works only because this is only
+ // used for success cases which cast to the same underlying
+ // value.
+ ASSERT_EQ(status, wgpu::MapAsyncStatus::Success);
+ callback(WGPUBufferMapAsyncStatus_Success, userdata);
+ });
}
}
@@ -720,11 +740,14 @@
wgpu::QueueWorkDoneCallback callback,
void* userdata) {
if (!GetParam().mFutureCallbackMode) {
- queueObj.OnSubmittedWorkDone(callback, userdata);
+ EXPECT_DEPRECATION_WARNING(queueObj.OnSubmittedWorkDone(callback, userdata));
return {0};
} else {
return queueObj.OnSubmittedWorkDone(
- {nullptr, *GetParam().mFutureCallbackMode, callback, userdata});
+ *GetParam().mFutureCallbackMode,
+ [callback, userdata](wgpu::QueueWorkDoneStatus status) {
+ callback(static_cast<WGPUQueueWorkDoneStatus>(status), userdata);
+ });
}
}
@@ -925,7 +948,11 @@
const void* MapAsyncAndWait(const wgpu::Buffer& buffer, wgpu::MapMode mode, size_t size) {
bool done = false;
- buffer.MapAsync(mode, 0, size, MapCallback, &done);
+ buffer.MapAsync(mode, 0, size, wgpu::CallbackMode::AllowProcessEvents,
+ [&done](wgpu::MapAsyncStatus status, const char*) {
+ EXPECT_EQ(wgpu::MapAsyncStatus::Success, status);
+ done = true;
+ });
while (!done) {
WaitABit();
@@ -1053,13 +1080,11 @@
EXPECT_BUFFER_U32_EQ(myData, buffer, 0);
bool done = false;
- buffer.MapAsync(
- wgpu::MapMode::Write, 0, 4,
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
- *static_cast<bool*>(userdata) = true;
- },
- &done);
+ buffer.MapAsync(wgpu::MapMode::Write, 0, 4, wgpu::CallbackMode::AllowProcessEvents,
+ [&done](wgpu::MapAsyncStatus status, const char*) {
+ EXPECT_EQ(wgpu::MapAsyncStatus::Success, status);
+ done = true;
+ });
while (!done) {
WaitABit();
@@ -1076,13 +1101,11 @@
ASSERT_DEVICE_ERROR([&] {
bool done = false;
- buffer.MapAsync(
- wgpu::MapMode::Write, 0, 4,
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- ASSERT_EQ(WGPUBufferMapAsyncStatus_ValidationError, status);
- *static_cast<bool*>(userdata) = true;
- },
- &done);
+ buffer.MapAsync(wgpu::MapMode::Write, 0, 4, wgpu::CallbackMode::AllowProcessEvents,
+ [&done](wgpu::MapAsyncStatus status, const char*) {
+ EXPECT_EQ(wgpu::MapAsyncStatus::Error, status);
+ done = true;
+ });
while (!done) {
WaitABit();
@@ -1287,13 +1310,12 @@
ASSERT_DEVICE_ERROR(buffer = device.CreateBuffer(&descriptor));
bool done = false;
- ASSERT_DEVICE_ERROR(buffer.MapAsync(
- wgpu::MapMode::Write, 0, 4,
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- EXPECT_EQ(status, WGPUBufferMapAsyncStatus_ValidationError);
- *static_cast<bool*>(userdata) = true;
- },
- &done));
+ ASSERT_DEVICE_ERROR(buffer.MapAsync(wgpu::MapMode::Write, 0, 4,
+ wgpu::CallbackMode::AllowProcessEvents,
+ [&done](wgpu::MapAsyncStatus status, const char*) {
+ EXPECT_EQ(wgpu::MapAsyncStatus::Error, status);
+ done = true;
+ }));
while (!done) {
WaitABit();
diff --git a/src/dawn/tests/end2end/BufferZeroInitTests.cpp b/src/dawn/tests/end2end/BufferZeroInitTests.cpp
index a552b9f..9a9fd2d 100644
--- a/src/dawn/tests/end2end/BufferZeroInitTests.cpp
+++ b/src/dawn/tests/end2end/BufferZeroInitTests.cpp
@@ -78,26 +78,6 @@
return device.CreateBuffer(&descriptor);
}
- void MapAsyncAndWait(wgpu::Buffer buffer,
- wgpu::MapMode mapMode,
- uint64_t offset,
- uint64_t size) {
- DAWN_ASSERT(mapMode == wgpu::MapMode::Read || mapMode == wgpu::MapMode::Write);
-
- bool done = false;
- buffer.MapAsync(
- mapMode, offset, size,
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
- *static_cast<bool*>(userdata) = true;
- },
- &done);
-
- while (!done) {
- WaitABit();
- }
- }
-
wgpu::Texture CreateAndInitializeTexture(const wgpu::Extent3D& size,
wgpu::TextureFormat format,
wgpu::Color color = {0.f, 0.f, 0.f, 0.f}) {
diff --git a/src/dawn/tests/end2end/CopyTests.cpp b/src/dawn/tests/end2end/CopyTests.cpp
index eabf0e5..b5e4258 100644
--- a/src/dawn/tests/end2end/CopyTests.cpp
+++ b/src/dawn/tests/end2end/CopyTests.cpp
@@ -3094,12 +3094,11 @@
// Ensure the underlying ID3D12Resource of bigBuffer is deleted.
bool submittedWorkDone = false;
- queue.OnSubmittedWorkDone(
- [](WGPUQueueWorkDoneStatus status, void* userdata) {
- EXPECT_EQ(status, WGPUQueueWorkDoneStatus_Success);
- *static_cast<bool*>(userdata) = true;
- },
- &submittedWorkDone);
+ queue.OnSubmittedWorkDone(wgpu::CallbackMode::AllowProcessEvents,
+ [&submittedWorkDone](wgpu::QueueWorkDoneStatus status) {
+ EXPECT_EQ(status, wgpu::QueueWorkDoneStatus::Success);
+ submittedWorkDone = true;
+ });
while (!submittedWorkDone) {
WaitABit();
}
@@ -3133,13 +3132,12 @@
bufferDescriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::MapWrite;
wgpu::Buffer uploadBuffer = device.CreateBuffer(&bufferDescriptor);
bool done = false;
- uploadBuffer.MapAsync(
- wgpu::MapMode::Write, 0, static_cast<uint32_t>(expectedData.size()),
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
- *static_cast<bool*>(userdata) = true;
- },
- &done);
+ uploadBuffer.MapAsync(wgpu::MapMode::Write, 0, static_cast<uint32_t>(expectedData.size()),
+ wgpu::CallbackMode::AllowProcessEvents,
+ [&done](wgpu::MapAsyncStatus status, const char*) {
+ ASSERT_EQ(wgpu::MapAsyncStatus::Success, status);
+ done = true;
+ });
while (!done) {
WaitABit();
}
@@ -3339,13 +3337,12 @@
// Check the data in readback buffer
bool done = false;
- readbackBuffer.MapAsync(
- wgpu::MapMode::Read, 0, kBufferSize,
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
- *static_cast<bool*>(userdata) = true;
- },
- &done);
+ readbackBuffer.MapAsync(wgpu::MapMode::Read, 0, kBufferSize,
+ wgpu::CallbackMode::AllowProcessEvents,
+ [&done](wgpu::MapAsyncStatus status, const char*) {
+ ASSERT_EQ(wgpu::MapAsyncStatus::Success, status);
+ done = true;
+ });
while (!done) {
WaitABit();
}
@@ -3365,12 +3362,11 @@
void EnsureSubmittedWorkDone() {
bool submittedWorkDone = false;
- queue.OnSubmittedWorkDone(
- [](WGPUQueueWorkDoneStatus status, void* userdata) {
- EXPECT_EQ(status, WGPUQueueWorkDoneStatus_Success);
- *static_cast<bool*>(userdata) = true;
- },
- &submittedWorkDone);
+ queue.OnSubmittedWorkDone(wgpu::CallbackMode::AllowProcessEvents,
+ [&submittedWorkDone](wgpu::QueueWorkDoneStatus status) {
+ EXPECT_EQ(status, wgpu::QueueWorkDoneStatus::Success);
+ submittedWorkDone = true;
+ });
while (!submittedWorkDone) {
WaitABit();
}
diff --git a/src/dawn/tests/end2end/DepthStencilCopyTests.cpp b/src/dawn/tests/end2end/DepthStencilCopyTests.cpp
index 7eb9960..ca4f1ef 100644
--- a/src/dawn/tests/end2end/DepthStencilCopyTests.cpp
+++ b/src/dawn/tests/end2end/DepthStencilCopyTests.cpp
@@ -106,24 +106,6 @@
class DepthStencilCopyTests : public DawnTestWithParams<DepthStencilCopyTestParams> {
protected:
- void MapAsyncAndWait(const wgpu::Buffer& buffer,
- wgpu::MapMode mode,
- size_t offset,
- size_t size) {
- bool done = false;
- buffer.MapAsync(
- mode, offset, size,
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
- *static_cast<bool*>(userdata) = true;
- },
- &done);
-
- while (!done) {
- WaitABit();
- }
- }
-
void SetUp() override {
DawnTestWithParams<DepthStencilCopyTestParams>::SetUp();
diff --git a/src/dawn/tests/end2end/DestroyTests.cpp b/src/dawn/tests/end2end/DestroyTests.cpp
index 4c79683..d86c651 100644
--- a/src/dawn/tests/end2end/DestroyTests.cpp
+++ b/src/dawn/tests/end2end/DestroyTests.cpp
@@ -220,19 +220,10 @@
DestroyDevice();
wgpu::Queue queue = device.GetQueue();
- queue.OnSubmittedWorkDone(
- [](WGPUQueueWorkDoneStatus status, void* userdata) {
- // TODO(crbug.com/dawn/2021): Wire and native differ slightly for now. Unify once we
- // decide on the correct result. In theory maybe we want to pretend that things succeed
- // when the device is lost.
- DestroyTest* test = static_cast<DestroyTest*>(userdata);
- if (test->UsesWire()) {
- EXPECT_EQ(status, WGPUQueueWorkDoneStatus_Success);
- } else {
- EXPECT_EQ(status, WGPUQueueWorkDoneStatus_DeviceLost);
- }
- },
- this);
+ queue.OnSubmittedWorkDone(wgpu::CallbackMode::AllowProcessEvents,
+ [](wgpu::QueueWorkDoneStatus status) {
+ EXPECT_EQ(status, wgpu::QueueWorkDoneStatus::Success);
+ });
}
DAWN_INSTANTIATE_TEST(DestroyTest,
diff --git a/src/dawn/tests/end2end/DeviceInitializationTests.cpp b/src/dawn/tests/end2end/DeviceInitializationTests.cpp
index fb1f443..a0e12e2 100644
--- a/src/dawn/tests/end2end/DeviceInitializationTests.cpp
+++ b/src/dawn/tests/end2end/DeviceInitializationTests.cpp
@@ -43,42 +43,39 @@
void TearDown() override { dawnProcSetProcs(nullptr); }
- // Test that the device can still be used by testing a buffer copy.
+ // Test that the device can still be used by creating an async pipeline. Note that this test
+ // would be better if we did something like a buffer copy instead, but that can only be done
+ // once wgpu::CallbackMode::AllowSpontaneous is completely implemented.
+ // TODO(crbug.com/42241003): Update this test do a buffer copy instead.
void ExpectDeviceUsable(wgpu::Device device) {
- wgpu::Buffer src =
- utils::CreateBufferFromData<uint32_t>(device, wgpu::BufferUsage::CopySrc, {1, 2, 3, 4});
+ device.PushErrorScope(wgpu::ErrorFilter::Validation);
- wgpu::Buffer dst = utils::CreateBufferFromData<uint32_t>(
- device, wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::MapRead, {0, 0, 0, 0});
+ wgpu::ComputePipelineDescriptor desc;
+ desc.compute.module = utils::CreateShaderModule(device, R"(
+ @compute @workgroup_size(1) fn main() {}
+ )");
- wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
- encoder.CopyBufferToBuffer(src, 0, dst, 0, 4 * sizeof(uint32_t));
+ std::atomic<uint8_t> callbacks = 0;
+ device.CreateComputePipelineAsync(
+ &desc, wgpu::CallbackMode::AllowSpontaneous,
+ [&callbacks](wgpu::CreatePipelineAsyncStatus status, wgpu::ComputePipeline pipeline,
+ const char*) {
+ EXPECT_EQ(status, wgpu::CreatePipelineAsyncStatus::Success);
+ EXPECT_NE(pipeline, nullptr);
+ callbacks++;
+ });
- wgpu::CommandBuffer commands = encoder.Finish();
- device.GetQueue().Submit(1, &commands);
+ device.PopErrorScope(
+ wgpu::CallbackMode::AllowSpontaneous,
+ [&callbacks](wgpu::PopErrorScopeStatus status, wgpu::ErrorType type, const char*) {
+ EXPECT_EQ(status, wgpu::PopErrorScopeStatus::Success);
+ EXPECT_EQ(type, wgpu::ErrorType::NoError);
+ callbacks++;
+ });
- bool done = false;
- dst.MapAsync(
- wgpu::MapMode::Read, 0, 4 * sizeof(uint32_t),
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- EXPECT_EQ(status, WGPUBufferMapAsyncStatus_Success);
- *static_cast<bool*>(userdata) = true;
- },
- &done);
-
- // Note: we can't actually test this if Tick moves over to
- // wgpuInstanceProcessEvents. We can still test that object creation works
- // without crashing.
- while (!done) {
- device.Tick();
+ while (callbacks != 2) {
utils::USleep(100);
}
-
- const uint32_t* mapping = static_cast<const uint32_t*>(dst.GetConstMappedRange());
- EXPECT_EQ(mapping[0], 1u);
- EXPECT_EQ(mapping[1], 2u);
- EXPECT_EQ(mapping[2], 3u);
- EXPECT_EQ(mapping[3], 4u);
}
};
diff --git a/src/dawn/tests/end2end/DeviceLifetimeTests.cpp b/src/dawn/tests/end2end/DeviceLifetimeTests.cpp
index a1e0338..dbc194f 100644
--- a/src/dawn/tests/end2end/DeviceLifetimeTests.cpp
+++ b/src/dawn/tests/end2end/DeviceLifetimeTests.cpp
@@ -28,11 +28,20 @@
#include <utility>
#include "dawn/tests/DawnTest.h"
+#include "dawn/tests/MockCallback.h"
#include "dawn/utils/WGPUHelpers.h"
namespace dawn {
namespace {
+using testing::_;
+using testing::HasSubstr;
+using testing::Invoke;
+using testing::MockCppCallback;
+using testing::Return;
+
+using MockMapAsyncCallback = MockCppCallback<void (*)(wgpu::MapAsyncStatus, const char*)>;
+
class DeviceLifetimeTests : public DawnTest {};
// Test that the device can be dropped before its queue.
@@ -50,17 +59,10 @@
queue.Submit(1, &commandBuffer);
// Ask for an onSubmittedWorkDone callback and drop the device.
- queue.OnSubmittedWorkDone(
- [](WGPUQueueWorkDoneStatus status, void*) {
- // There is a bug in DeviceBase::Destroy(). If all submitted work is done when
- // OnSubmittedWorkDone() is being called, the callback will be resolved with
- // DeviceLost, otherwise the callback will be resolved with Success.
- // TODO(dawn:1640): fix DeviceBase::Destroy() to always reslove the callback
- // with success.
- EXPECT_TRUE(status == WGPUQueueWorkDoneStatus_Success ||
- status == WGPUQueueWorkDoneStatus_DeviceLost);
- },
- nullptr);
+ queue.OnSubmittedWorkDone(wgpu::CallbackMode::AllowProcessEvents,
+ [](wgpu::QueueWorkDoneStatus status) {
+ EXPECT_EQ(status, wgpu::QueueWorkDoneStatus::Success);
+ });
device = nullptr;
}
@@ -72,28 +74,14 @@
wgpu::CommandBuffer commandBuffer = encoder.Finish();
queue.Submit(1, &commandBuffer);
- struct Userdata {
- wgpu::Device device;
- bool done;
- };
// Ask for an onSubmittedWorkDone callback and drop the device inside the callback.
- Userdata data = Userdata{std::move(device), false};
- queue.OnSubmittedWorkDone(
- [](WGPUQueueWorkDoneStatus status, void* userdata) {
- EXPECT_EQ(status, WGPUQueueWorkDoneStatus_Success);
- static_cast<Userdata*>(userdata)->device = nullptr;
- static_cast<Userdata*>(userdata)->done = true;
- },
- &data);
+ queue.OnSubmittedWorkDone(wgpu::CallbackMode::AllowProcessEvents,
+ [this](wgpu::QueueWorkDoneStatus status) {
+ EXPECT_EQ(status, wgpu::QueueWorkDoneStatus::Success);
+ this->device = nullptr;
+ });
- while (!data.done) {
- // WaitABit no longer can call tick since we've moved the device from the fixture into the
- // userdata.
- if (data.device) {
- data.device.Tick();
- }
- WaitABit();
- }
+ WaitForAllOperations();
}
// Test that the device can be dropped while a popErrorScope callback is in flight.
@@ -116,7 +104,7 @@
}
}
-// Test that the device can be dropped inside an onSubmittedWorkDone callback.
+// Test that the device can be dropped inside an popErrorScope callback.
TEST_P(DeviceLifetimeTests, DroppedInsidePopErrorScope) {
struct Userdata {
wgpu::Device device;
@@ -159,14 +147,14 @@
desc.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst;
wgpu::Buffer buffer = device.CreateBuffer(&desc);
- buffer.MapAsync(
- wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
- [](WGPUBufferMapAsyncStatus status, void*) {
- EXPECT_EQ(status, WGPUBufferMapAsyncStatus_DestroyedBeforeCallback);
- },
- nullptr);
+ MockMapAsyncCallback cb;
+ EXPECT_CALL(cb, Call(wgpu::MapAsyncStatus::Aborted, _)).Times(1);
+
+ buffer.MapAsync(wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
+ wgpu::CallbackMode::AllowProcessEvents, cb.Callback());
device = nullptr;
+ WaitForAllOperations();
}
// Test that the device can be dropped before a mapped buffer created from it.
@@ -176,18 +164,7 @@
desc.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst;
wgpu::Buffer buffer = device.CreateBuffer(&desc);
- bool done = false;
- buffer.MapAsync(
- wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- EXPECT_EQ(status, WGPUBufferMapAsyncStatus_Success);
- *static_cast<bool*>(userdata) = true;
- },
- &done);
-
- while (!done) {
- WaitABit();
- }
+ MapAsyncAndWait(buffer, wgpu::MapMode::Read, 0, wgpu::kWholeMapSize);
device = nullptr;
}
@@ -213,18 +190,12 @@
device = nullptr;
- bool done = false;
- buffer.MapAsync(
- wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- EXPECT_EQ(status, WGPUBufferMapAsyncStatus_DeviceLost);
- *static_cast<bool*>(userdata) = true;
- },
- &done);
+ MockMapAsyncCallback cb;
+ EXPECT_CALL(cb, Call(wgpu::MapAsyncStatus::Error, HasSubstr("lost"))).Times(1);
- while (!done) {
- WaitABit();
- }
+ buffer.MapAsync(wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
+ wgpu::CallbackMode::AllowProcessEvents, cb.Callback());
+ WaitForAllOperations();
}
// Test that the device can be dropped before a buffer created from it, then mapping the buffer
@@ -237,35 +208,23 @@
device = nullptr;
- struct UserData {
- wgpu::Buffer buffer;
- bool done = false;
- };
-
- UserData userData;
- userData.buffer = buffer;
-
// First mapping.
- buffer.MapAsync(
- wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
- [](WGPUBufferMapAsyncStatus status, void* userdataPtr) {
- EXPECT_EQ(status, WGPUBufferMapAsyncStatus_DeviceLost);
- auto userdata = static_cast<UserData*>(userdataPtr);
+ buffer.MapAsync(wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
+ wgpu::CallbackMode::AllowProcessEvents,
+ [&buffer](wgpu::MapAsyncStatus status, const char* message) {
+ EXPECT_EQ(status, wgpu::MapAsyncStatus::Error);
+ EXPECT_THAT(message, HasSubstr("lost"));
- // Second mapping.
- userdata->buffer.MapAsync(
- wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
- [](WGPUBufferMapAsyncStatus status, void* userdataPtr) {
- EXPECT_EQ(status, WGPUBufferMapAsyncStatus_DeviceLost);
- *static_cast<bool*>(userdataPtr) = true;
- },
- &userdata->done);
- },
- &userData);
+ // Second mapping
+ buffer.MapAsync(wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
+ wgpu::CallbackMode::AllowProcessEvents,
+ [](wgpu::MapAsyncStatus status, const char* message) {
+ EXPECT_EQ(status, wgpu::MapAsyncStatus::Error);
+ EXPECT_THAT(message, HasSubstr("lost"));
+ });
+ });
- while (!userData.done) {
- WaitABit();
- }
+ WaitForAllOperations();
}
// Test that the device can be dropped inside a buffer map callback.
@@ -275,40 +234,22 @@
desc.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::CopyDst;
wgpu::Buffer buffer = device.CreateBuffer(&desc);
- struct Userdata {
- wgpu::Device device;
- wgpu::Buffer buffer;
- bool wire;
- bool done;
- };
+ buffer.MapAsync(wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
+ wgpu::CallbackMode::AllowProcessEvents,
+ [this, buffer](wgpu::MapAsyncStatus status, const char*) {
+ EXPECT_EQ(status, wgpu::MapAsyncStatus::Success);
+ device = nullptr;
- // Ask for a mapAsync callback and drop the device inside the callback.
- Userdata data = Userdata{std::move(device), buffer, UsesWire(), false};
- buffer.MapAsync(
- wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- EXPECT_EQ(status, WGPUBufferMapAsyncStatus_Success);
- auto* data = static_cast<Userdata*>(userdata);
- data->device = nullptr;
- data->done = true;
+ // Mapped data should be null since the buffer is implicitly destroyed.
+ // TODO(crbug.com/dawn/1424): On the wire client, we don't track device
+ // child objects so the mapped data is still available when the device is
+ // destroyed.
+ if (!UsesWire()) {
+ EXPECT_EQ(buffer.GetConstMappedRange(), nullptr);
+ }
+ });
- // Mapped data should be null since the buffer is implicitly destroyed.
- // TODO(crbug.com/dawn/1424): On the wire client, we don't track device child objects so
- // the mapped data is still available when the device is destroyed.
- if (!data->wire) {
- EXPECT_EQ(data->buffer.GetConstMappedRange(), nullptr);
- }
- },
- &data);
-
- while (!data.done) {
- // WaitABit no longer can call tick since we've moved the device from the fixture into the
- // userdata.
- if (data.device) {
- data.device.Tick();
- }
- WaitABit();
- }
+ WaitForAllOperations();
// Mapped data should be null since the buffer is implicitly destroyed.
// TODO(crbug.com/dawn/1424): On the wire client, we don't track device child objects so the
diff --git a/src/dawn/tests/end2end/DeviceLostTests.cpp b/src/dawn/tests/end2end/DeviceLostTests.cpp
index 9c58a0e..d6cfd24 100644
--- a/src/dawn/tests/end2end/DeviceLostTests.cpp
+++ b/src/dawn/tests/end2end/DeviceLostTests.cpp
@@ -41,17 +41,11 @@
using testing::_;
using testing::Exactly;
-using testing::MockCallback;
+using testing::HasSubstr;
+using testing::MockCppCallback;
-class MockQueueWorkDoneCallback {
- public:
- MOCK_METHOD(void, Call, (WGPUQueueWorkDoneStatus status, void* userdata));
-};
-
-static std::unique_ptr<MockQueueWorkDoneCallback> mockQueueWorkDoneCallback;
-static void ToMockQueueWorkDone(WGPUQueueWorkDoneStatus status, void* userdata) {
- mockQueueWorkDoneCallback->Call(status, userdata);
-}
+using MockMapAsyncCallback = MockCppCallback<void (*)(wgpu::MapAsyncStatus, const char*)>;
+using MockQueueWorkDoneCallback = MockCppCallback<void (*)(wgpu::QueueWorkDoneStatus)>;
static const int fakeUserData = 0;
@@ -60,12 +54,10 @@
void SetUp() override {
DawnTest::SetUp();
DAWN_TEST_UNSUPPORTED_IF(UsesWire());
- mockQueueWorkDoneCallback = std::make_unique<MockQueueWorkDoneCallback>();
}
void TearDown() override {
instance.ProcessEvents(); // Flush all callbacks.
- mockQueueWorkDoneCallback = nullptr;
DawnTest::TearDown();
}
@@ -74,28 +66,13 @@
EXPECT_EQ(&fakeUserData, userdata);
}
- void MapAsyncAndWait(const wgpu::Buffer& buffer,
- wgpu::MapMode mode,
- size_t offset,
- size_t size) {
- bool done = false;
- buffer.MapAsync(
- mode, offset, size,
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
- *static_cast<bool*>(userdata) = true;
- },
- &done);
-
- while (!done) {
- WaitABit();
- }
- }
-
template <typename T>
void ExpectObjectIsError(const T& object) {
EXPECT_TRUE(dawn::native::CheckIsErrorForTesting(object.Get()));
}
+
+ MockQueueWorkDoneCallback mWorkDoneCb;
+ MockMapAsyncCallback mMapAsyncCb;
};
// Test that DeviceLostCallback is invoked when LostForTestimg is called
@@ -259,10 +236,13 @@
wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);
LoseDeviceForTesting();
- buffer.MapAsync(wgpu::MapMode::Write, 0, 4, MapFailCallback, const_cast<int*>(&fakeUserData));
+
+ EXPECT_CALL(mMapAsyncCb, Call(wgpu::MapAsyncStatus::Error, HasSubstr("is lost"))).Times(1);
+ buffer.MapAsync(wgpu::MapMode::Write, 0, 4, wgpu::CallbackMode::AllowProcessEvents,
+ mMapAsyncCb.Callback());
}
-// Test that BufferMapAsync for writing calls back with device lost status when device lost after
+// Test that BufferMapAsync for writing calls back with success when device lost after
// mapping
TEST_P(DeviceLostTest, BufferMapAsyncBeforeLossFailsForWriting) {
wgpu::BufferDescriptor bufferDescriptor;
@@ -270,9 +250,12 @@
bufferDescriptor.usage = wgpu::BufferUsage::MapWrite;
wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);
- buffer.MapAsync(wgpu::MapMode::Write, 0, 4, MapFailCallback, const_cast<int*>(&fakeUserData));
+ EXPECT_CALL(mMapAsyncCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ buffer.MapAsync(wgpu::MapMode::Write, 0, 4, wgpu::CallbackMode::AllowProcessEvents,
+ mMapAsyncCb.Callback());
LoseDeviceForTesting();
+ WaitForAllOperations();
}
// Test that buffer.Unmap after device is lost
@@ -307,10 +290,13 @@
wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);
LoseDeviceForTesting();
- buffer.MapAsync(wgpu::MapMode::Read, 0, 4, MapFailCallback, const_cast<int*>(&fakeUserData));
+
+ EXPECT_CALL(mMapAsyncCb, Call(wgpu::MapAsyncStatus::Error, HasSubstr("is lost"))).Times(1);
+ buffer.MapAsync(wgpu::MapMode::Read, 0, 4, wgpu::CallbackMode::AllowProcessEvents,
+ mMapAsyncCb.Callback());
}
-// Test that BufferMapAsync for reading calls back with device lost status when device lost after
+// Test that BufferMapAsync for reading calls back with success when device lost after
// mapping
TEST_P(DeviceLostTest, BufferMapAsyncBeforeLossFailsForReading) {
wgpu::BufferDescriptor bufferDescriptor;
@@ -319,9 +305,12 @@
wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);
- buffer.MapAsync(wgpu::MapMode::Read, 0, 4, MapFailCallback, const_cast<int*>(&fakeUserData));
+ EXPECT_CALL(mMapAsyncCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ buffer.MapAsync(wgpu::MapMode::Read, 0, 4, wgpu::CallbackMode::AllowProcessEvents,
+ mMapAsyncCb.Callback());
LoseDeviceForTesting();
+ WaitForAllOperations();
}
// Test that WriteBuffer after device is lost
@@ -412,22 +401,20 @@
ExpectObjectIsError(encoder.Finish());
}
-// Test that QueueOnSubmittedWorkDone after device is lost.
+// Test QueueOnSubmittedWorkDone after device is lost.
TEST_P(DeviceLostTest, QueueOnSubmittedWorkDoneAfterDeviceLost) {
LoseDeviceForTesting();
- // callback should have device lost status
- EXPECT_CALL(*mockQueueWorkDoneCallback, Call(WGPUQueueWorkDoneStatus_DeviceLost, nullptr))
- .Times(1);
- queue.OnSubmittedWorkDone(ToMockQueueWorkDone, nullptr);
+ // Callback should have success status
+ EXPECT_CALL(mWorkDoneCb, Call(wgpu::QueueWorkDoneStatus::Success));
+ queue.OnSubmittedWorkDone(wgpu::CallbackMode::AllowProcessEvents, mWorkDoneCb.Callback());
}
-// Test that QueueOnSubmittedWorkDone when the device is lost after calling OnSubmittedWorkDone
+// Test QueueOnSubmittedWorkDone when the device is lost after calling OnSubmittedWorkDone
TEST_P(DeviceLostTest, QueueOnSubmittedWorkDoneBeforeLossFails) {
- // callback should have device lost status
- EXPECT_CALL(*mockQueueWorkDoneCallback, Call(WGPUQueueWorkDoneStatus_DeviceLost, nullptr))
- .Times(1);
- queue.OnSubmittedWorkDone(ToMockQueueWorkDone, nullptr);
+ // Callback should have success status
+ EXPECT_CALL(mWorkDoneCb, Call(wgpu::QueueWorkDoneStatus::Success));
+ queue.OnSubmittedWorkDone(wgpu::CallbackMode::AllowProcessEvents, mWorkDoneCb.Callback());
LoseDeviceForTesting();
}
diff --git a/src/dawn/tests/end2end/EventTests.cpp b/src/dawn/tests/end2end/EventTests.cpp
index a84f5fc..28e215b 100644
--- a/src/dawn/tests/end2end/EventTests.cpp
+++ b/src/dawn/tests/end2end/EventTests.cpp
@@ -195,24 +195,12 @@
}
}
- wgpu::Future OnSubmittedWorkDone(WGPUQueueWorkDoneStatus expectedStatus) {
- struct Userdata {
- EventCompletionTests* self;
- WGPUQueueWorkDoneStatus expectedStatus;
- };
- Userdata* userdata = new Userdata{this, expectedStatus};
-
- return testQueue.OnSubmittedWorkDone({
- nullptr,
- GetCallbackMode(),
- [](WGPUQueueWorkDoneStatus status, void* userdata) {
- Userdata* u = reinterpret_cast<Userdata*>(userdata);
- u->self->mCallbacksCompletedCount++;
- ASSERT_EQ(status, u->expectedStatus);
- delete u;
- },
- userdata,
- });
+ wgpu::Future OnSubmittedWorkDone(wgpu::QueueWorkDoneStatus expectedStatus) {
+ return testQueue.OnSubmittedWorkDone(
+ GetCallbackMode(), [this, expectedStatus](wgpu::QueueWorkDoneStatus status) {
+ mCallbacksCompletedCount++;
+ ASSERT_EQ(status, expectedStatus);
+ });
}
void TestWaitAll(bool loopOnlyOnce = false) {
@@ -345,14 +333,14 @@
// WorkDone event after submitting some trivial work.
TEST_P(EventCompletionTests, WorkDoneSimple) {
TrivialSubmit();
- TrackForTest(OnSubmittedWorkDone(WGPUQueueWorkDoneStatus_Success));
+ TrackForTest(OnSubmittedWorkDone(wgpu::QueueWorkDoneStatus::Success));
TestWaitAll();
}
// WorkDone event before device loss, wait afterward.
TEST_P(EventCompletionTests, WorkDoneAcrossDeviceLoss) {
TrivialSubmit();
- TrackForTest(OnSubmittedWorkDone(WGPUQueueWorkDoneStatus_Success));
+ TrackForTest(OnSubmittedWorkDone(wgpu::QueueWorkDoneStatus::Success));
TestWaitAll();
}
@@ -360,33 +348,33 @@
TEST_P(EventCompletionTests, WorkDoneAfterDeviceLoss) {
TrivialSubmit();
LoseTestDevice();
- TrackForTest(OnSubmittedWorkDone(WGPUQueueWorkDoneStatus_Success));
+ TrackForTest(OnSubmittedWorkDone(wgpu::QueueWorkDoneStatus::Success));
TestWaitAll();
}
// WorkDone event twice after submitting some trivial work.
TEST_P(EventCompletionTests, WorkDoneTwice) {
TrivialSubmit();
- TrackForTest(OnSubmittedWorkDone(WGPUQueueWorkDoneStatus_Success));
- TrackForTest(OnSubmittedWorkDone(WGPUQueueWorkDoneStatus_Success));
+ TrackForTest(OnSubmittedWorkDone(wgpu::QueueWorkDoneStatus::Success));
+ TrackForTest(OnSubmittedWorkDone(wgpu::QueueWorkDoneStatus::Success));
TestWaitAll();
}
// WorkDone event without ever having submitted any work.
TEST_P(EventCompletionTests, WorkDoneNoWork) {
- TrackForTest(OnSubmittedWorkDone(WGPUQueueWorkDoneStatus_Success));
+ TrackForTest(OnSubmittedWorkDone(wgpu::QueueWorkDoneStatus::Success));
TestWaitAll();
- TrackForTest(OnSubmittedWorkDone(WGPUQueueWorkDoneStatus_Success));
- TrackForTest(OnSubmittedWorkDone(WGPUQueueWorkDoneStatus_Success));
+ TrackForTest(OnSubmittedWorkDone(wgpu::QueueWorkDoneStatus::Success));
+ TrackForTest(OnSubmittedWorkDone(wgpu::QueueWorkDoneStatus::Success));
TestWaitAll();
}
// WorkDone event after all work has completed already.
TEST_P(EventCompletionTests, WorkDoneAlreadyCompleted) {
TrivialSubmit();
- TrackForTest(OnSubmittedWorkDone(WGPUQueueWorkDoneStatus_Success));
+ TrackForTest(OnSubmittedWorkDone(wgpu::QueueWorkDoneStatus::Success));
TestWaitAll();
- TrackForTest(OnSubmittedWorkDone(WGPUQueueWorkDoneStatus_Success));
+ TrackForTest(OnSubmittedWorkDone(wgpu::QueueWorkDoneStatus::Success));
TestWaitAll();
}
@@ -396,9 +384,9 @@
DAWN_TEST_UNSUPPORTED_IF(GetCallbackMode() != wgpu::CallbackMode::WaitAnyOnly);
TrivialSubmit();
- wgpu::Future f1 = OnSubmittedWorkDone(WGPUQueueWorkDoneStatus_Success);
+ wgpu::Future f1 = OnSubmittedWorkDone(wgpu::QueueWorkDoneStatus::Success);
TrivialSubmit();
- wgpu::Future f2 = OnSubmittedWorkDone(WGPUQueueWorkDoneStatus_Success);
+ wgpu::Future f2 = OnSubmittedWorkDone(wgpu::QueueWorkDoneStatus::Success);
// When using WaitAny, normally callback ordering guarantees would guarantee f1 completes before
// f2. But if we wait on f2 first, then f2 is allowed to complete first because f1 still hasn't
@@ -409,8 +397,8 @@
TestWaitAll(/*loopOnlyOnce=*/true);
}
-constexpr WGPUQueueWorkDoneStatus kStatusUninitialized =
- static_cast<WGPUQueueWorkDoneStatus>(INT32_MAX);
+constexpr wgpu::QueueWorkDoneStatus kStatusUninitialized =
+ static_cast<wgpu::QueueWorkDoneStatus>(INT32_MAX);
TEST_P(EventCompletionTests, WorkDoneDropInstanceBeforeEvent) {
// TODO(crbug.com/dawn/1987): Wire does not implement instance destruction correctly yet.
@@ -419,22 +407,18 @@
UseSecondInstance();
testInstance = nullptr; // Drop the last external ref to the instance.
- WGPUQueueWorkDoneStatus status = kStatusUninitialized;
- testQueue.OnSubmittedWorkDone({nullptr, GetCallbackMode(),
- [](WGPUQueueWorkDoneStatus status, void* userdata) {
- *reinterpret_cast<WGPUQueueWorkDoneStatus*>(userdata) =
- status;
- },
- &status});
+ wgpu::QueueWorkDoneStatus status = kStatusUninitialized;
+ testQueue.OnSubmittedWorkDone(GetCallbackMode(),
+ [&status](wgpu::QueueWorkDoneStatus result) { status = result; });
if (IsSpontaneous()) {
// TODO(crbug.com/dawn/2059): Once Spontaneous is implemented, this should no longer expect
// the callback to be cleaned up immediately (and should expect it to happen on a future
// Tick).
- ASSERT_THAT(status, AnyOf(Eq(WGPUQueueWorkDoneStatus_Success),
- Eq(WGPUQueueWorkDoneStatus_InstanceDropped)));
+ ASSERT_THAT(status, AnyOf(Eq(wgpu::QueueWorkDoneStatus::Success),
+ Eq(wgpu::QueueWorkDoneStatus::InstanceDropped)));
} else {
- ASSERT_EQ(status, WGPUQueueWorkDoneStatus_InstanceDropped);
+ ASSERT_EQ(status, wgpu::QueueWorkDoneStatus::InstanceDropped);
}
}
@@ -444,13 +428,9 @@
UseSecondInstance();
- WGPUQueueWorkDoneStatus status = kStatusUninitialized;
- testQueue.OnSubmittedWorkDone({nullptr, GetCallbackMode(),
- [](WGPUQueueWorkDoneStatus status, void* userdata) {
- *reinterpret_cast<WGPUQueueWorkDoneStatus*>(userdata) =
- status;
- },
- &status});
+ wgpu::QueueWorkDoneStatus status = kStatusUninitialized;
+ testQueue.OnSubmittedWorkDone(GetCallbackMode(),
+ [&status](wgpu::QueueWorkDoneStatus result) { status = result; });
if (IsSpontaneous()) {
testInstance = nullptr; // Drop the last external ref to the instance.
@@ -458,12 +438,12 @@
// TODO(crbug.com/dawn/2059): Once Spontaneous is implemented, this should no longer expect
// the callback to be cleaned up immediately (and should expect it to happen on a future
// Tick).
- ASSERT_THAT(status, AnyOf(Eq(WGPUQueueWorkDoneStatus_Success),
- Eq(WGPUQueueWorkDoneStatus_InstanceDropped)));
+ ASSERT_THAT(status, AnyOf(Eq(wgpu::QueueWorkDoneStatus::Success),
+ Eq(wgpu::QueueWorkDoneStatus::InstanceDropped)));
} else {
ASSERT_EQ(status, kStatusUninitialized);
testInstance = nullptr; // Drop the last external ref to the instance.
- ASSERT_EQ(status, WGPUQueueWorkDoneStatus_InstanceDropped);
+ ASSERT_EQ(status, wgpu::QueueWorkDoneStatus::InstanceDropped);
}
}
@@ -527,8 +507,7 @@
for (uint64_t timeout : {uint64_t(1), uint64_t(0), UINT64_MAX}) {
wgpu::FutureWaitInfo info{device2.GetQueue().OnSubmittedWorkDone(
- {nullptr, wgpu::CallbackMode::WaitAnyOnly, [](WGPUQueueWorkDoneStatus, void*) {},
- nullptr})};
+ wgpu::CallbackMode::WaitAnyOnly, [](wgpu::QueueWorkDoneStatus) {})};
wgpu::WaitStatus status = instance2.WaitAny(1, &info, timeout);
if (timeout == 0) {
ASSERT_TRUE(status == wgpu::WaitStatus::Success ||
@@ -563,9 +542,8 @@
for (size_t count : {kTimedWaitAnyMaxCountDefault, kTimedWaitAnyMaxCountDefault + 1}) {
std::vector<wgpu::FutureWaitInfo> infos;
for (size_t i = 0; i < count; ++i) {
- infos.push_back(
- {queue2.OnSubmittedWorkDone({nullptr, wgpu::CallbackMode::WaitAnyOnly,
- [](WGPUQueueWorkDoneStatus, void*) {}, nullptr})});
+ infos.push_back({queue2.OnSubmittedWorkDone(wgpu::CallbackMode::WaitAnyOnly,
+ [](wgpu::QueueWorkDoneStatus) {})});
}
wgpu::WaitStatus status = instance2.WaitAny(infos.size(), infos.data(), timeout);
if (timeout == 0) {
@@ -609,10 +587,10 @@
for (uint64_t timeout : {uint64_t(0), uint64_t(1)}) {
std::vector<wgpu::FutureWaitInfo> infos{{
- {queue2.OnSubmittedWorkDone({nullptr, wgpu::CallbackMode::WaitAnyOnly,
- [](WGPUQueueWorkDoneStatus, void*) {}, nullptr})},
- {queue3.OnSubmittedWorkDone({nullptr, wgpu::CallbackMode::WaitAnyOnly,
- [](WGPUQueueWorkDoneStatus, void*) {}, nullptr})},
+ {queue2.OnSubmittedWorkDone(wgpu::CallbackMode::WaitAnyOnly,
+ [](wgpu::QueueWorkDoneStatus) {})},
+ {queue3.OnSubmittedWorkDone(wgpu::CallbackMode::WaitAnyOnly,
+ [](wgpu::QueueWorkDoneStatus) {})},
}};
wgpu::WaitStatus status = instance2.WaitAny(infos.size(), infos.data(), timeout);
if (timeout == 0) {
@@ -642,8 +620,8 @@
// events call we were crashing.
TEST_P(FutureTests, MixedSourcePolling) {
// OnSubmittedWorkDone is implemented via a queue serial.
- device.GetQueue().OnSubmittedWorkDone({nullptr, wgpu::CallbackMode::AllowProcessEvents,
- [](WGPUQueueWorkDoneStatus, void*) {}, nullptr});
+ device.GetQueue().OnSubmittedWorkDone(wgpu::CallbackMode::AllowProcessEvents,
+ [](wgpu::QueueWorkDoneStatus) {});
// PopErrorScope is implemented via a signal.
device.PushErrorScope(wgpu::ErrorFilter::Validation);
diff --git a/src/dawn/tests/end2end/MultithreadTests.cpp b/src/dawn/tests/end2end/MultithreadTests.cpp
index 6a2fbea..b6d22dd 100644
--- a/src/dawn/tests/end2end/MultithreadTests.cpp
+++ b/src/dawn/tests/end2end/MultithreadTests.cpp
@@ -202,25 +202,18 @@
constexpr uint32_t kSize = static_cast<uint32_t>(kDataSize * sizeof(uint32_t));
utils::RunInParallel(10, [=, &myData = std::as_const(myData)](uint32_t) {
- wgpu::Buffer buffer;
- std::atomic<bool> mapCompleted(false);
-
// Create buffer and request mapping.
- buffer = CreateBuffer(kSize, wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc);
+ wgpu::Buffer buffer =
+ CreateBuffer(kSize, wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc);
- buffer.MapAsync(
- wgpu::MapMode::Write, 0, kSize,
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- EXPECT_EQ(WGPUBufferMapAsyncStatus_Success, status);
- (*static_cast<std::atomic<bool>*>(userdata)) = true;
- },
- &mapCompleted);
+ wgpu::FutureWaitInfo waitInfo = {
+ buffer.MapAsync(wgpu::MapMode::Write, 0, kSize, wgpu::CallbackMode::AllowProcessEvents,
+ [](wgpu::MapAsyncStatus status, const char*) {
+ ASSERT_EQ(status, wgpu::MapAsyncStatus::Success);
+ })};
// Wait for the mapping to complete
- while (!mapCompleted.load()) {
- device.Tick();
- FlushWire();
- }
+ ASSERT_EQ(instance.WaitAny(1, &waitInfo, UINT64_MAX), wgpu::WaitStatus::Success);
// Buffer is mapped, write into it and unmap .
memcpy(buffer.GetMappedRange(0, kSize), myData.data(), kSize);
diff --git a/src/dawn/tests/end2end/NonzeroBufferCreationTests.cpp b/src/dawn/tests/end2end/NonzeroBufferCreationTests.cpp
index b562c37..264adb1 100644
--- a/src/dawn/tests/end2end/NonzeroBufferCreationTests.cpp
+++ b/src/dawn/tests/end2end/NonzeroBufferCreationTests.cpp
@@ -33,23 +33,7 @@
namespace dawn {
namespace {
-class NonzeroBufferCreationTests : public DawnTest {
- public:
- void MapReadAsyncAndWait(wgpu::Buffer buffer, uint64_t offset, uint64_t size) {
- bool done = false;
- buffer.MapAsync(
- wgpu::MapMode::Read, offset, size,
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
- *static_cast<bool*>(userdata) = true;
- },
- &done);
-
- while (!done) {
- WaitABit();
- }
- }
-};
+class NonzeroBufferCreationTests : public DawnTest {};
// Verify that each byte of the buffer has all been initialized to 1 with the toggle enabled when it
// is created with CopyDst usage.
@@ -111,7 +95,7 @@
EXPECT_EQ(0, memcmp(mappedData, expectedData.data(), kSize));
buffer.Unmap();
- MapReadAsyncAndWait(buffer, 0, kSize);
+ MapAsyncAndWait(buffer, wgpu::MapMode::Read, 0, kSize);
mappedData = static_cast<const uint8_t*>(buffer.GetConstMappedRange());
EXPECT_EQ(0, memcmp(mappedData, expectedData.data(), kSize));
buffer.Unmap();
diff --git a/src/dawn/tests/end2end/QueueTimelineTests.cpp b/src/dawn/tests/end2end/QueueTimelineTests.cpp
index 787bcce..d89c30f 100644
--- a/src/dawn/tests/end2end/QueueTimelineTests.cpp
+++ b/src/dawn/tests/end2end/QueueTimelineTests.cpp
@@ -28,61 +28,30 @@
#include <memory>
#include "dawn/tests/DawnTest.h"
+#include "dawn/tests/MockCallback.h"
#include "gmock/gmock.h"
namespace dawn {
namespace {
+using testing::_;
using testing::InSequence;
+using testing::MockCppCallback;
-class MockMapCallback {
- public:
- MOCK_METHOD(void, Call, (WGPUBufferMapAsyncStatus status, void* userdata));
-};
-
-static std::unique_ptr<MockMapCallback> mockMapCallback;
-static void ToMockMapCallback(WGPUBufferMapAsyncStatus status, void* userdata) {
- EXPECT_EQ(status, WGPUBufferMapAsyncStatus_Success);
- mockMapCallback->Call(status, userdata);
-}
-
-class MockQueueWorkDoneCallback {
- public:
- MOCK_METHOD(void, Call, (WGPUQueueWorkDoneStatus status, void* userdata));
-};
-
-static std::unique_ptr<MockQueueWorkDoneCallback> mockQueueWorkDoneCallback;
-static void ToMockQueueWorkDone(WGPUQueueWorkDoneStatus status, void* userdata) {
- mockQueueWorkDoneCallback->Call(status, userdata);
-}
-
-static std::unique_ptr<MockQueueWorkDoneCallback> mockQueueWorkDoneCallback1;
-static void ToMockQueueWorkDone1(WGPUQueueWorkDoneStatus status, void* userdata) {
- mockQueueWorkDoneCallback1->Call(status, userdata);
-}
+using MockMapAsyncCallback = MockCppCallback<void (*)(wgpu::MapAsyncStatus, const char*)>;
+using MockQueueWorkDoneCallback = MockCppCallback<void (*)(wgpu::QueueWorkDoneStatus)>;
class QueueTimelineTests : public DawnTest {
protected:
void SetUp() override {
DawnTest::SetUp();
- mockMapCallback = std::make_unique<MockMapCallback>();
- mockQueueWorkDoneCallback = std::make_unique<MockQueueWorkDoneCallback>();
- mockQueueWorkDoneCallback1 = std::make_unique<MockQueueWorkDoneCallback>();
-
wgpu::BufferDescriptor descriptor;
descriptor.size = 4;
descriptor.usage = wgpu::BufferUsage::MapRead;
mMapReadBuffer = device.CreateBuffer(&descriptor);
}
- void TearDown() override {
- mockMapCallback = nullptr;
- mockQueueWorkDoneCallback = nullptr;
- mockQueueWorkDoneCallback1 = nullptr;
- DawnTest::TearDown();
- }
-
wgpu::Buffer mMapReadBuffer;
};
@@ -90,13 +59,17 @@
// when queue.OnSubmittedWorkDone is called after mMapReadBuffer.MapAsync. The callback order should
// happen in the order the functions are called.
TEST_P(QueueTimelineTests, MapRead_OnWorkDone) {
+ MockMapAsyncCallback mockMapAsyncCb;
+ MockQueueWorkDoneCallback mockQueueWorkDoneCb;
+
InSequence sequence;
- EXPECT_CALL(*mockMapCallback, Call(WGPUBufferMapAsyncStatus_Success, this)).Times(1);
- EXPECT_CALL(*mockQueueWorkDoneCallback, Call(WGPUQueueWorkDoneStatus_Success, this)).Times(1);
+ EXPECT_CALL(mockMapAsyncCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ EXPECT_CALL(mockQueueWorkDoneCb, Call(wgpu::QueueWorkDoneStatus::Success)).Times(1);
- mMapReadBuffer.MapAsync(wgpu::MapMode::Read, 0, wgpu::kWholeMapSize, ToMockMapCallback, this);
-
- queue.OnSubmittedWorkDone(ToMockQueueWorkDone, this);
+ mMapReadBuffer.MapAsync(wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
+ wgpu::CallbackMode::AllowProcessEvents, mockMapAsyncCb.Callback());
+ queue.OnSubmittedWorkDone(wgpu::CallbackMode::AllowProcessEvents,
+ mockQueueWorkDoneCb.Callback());
WaitForAllOperations();
mMapReadBuffer.Unmap();
@@ -104,12 +77,17 @@
// Test that the OnSubmittedWorkDone callbacks should happen in the order the functions are called.
TEST_P(QueueTimelineTests, OnWorkDone_OnWorkDone) {
- InSequence sequence;
- EXPECT_CALL(*mockQueueWorkDoneCallback, Call(WGPUQueueWorkDoneStatus_Success, this)).Times(1);
- EXPECT_CALL(*mockQueueWorkDoneCallback1, Call(WGPUQueueWorkDoneStatus_Success, this)).Times(1);
+ MockQueueWorkDoneCallback mockQueueWorkDoneCb1;
+ MockQueueWorkDoneCallback mockQueueWorkDoneCb2;
- queue.OnSubmittedWorkDone(ToMockQueueWorkDone, this);
- queue.OnSubmittedWorkDone(ToMockQueueWorkDone1, this);
+ InSequence sequence;
+ EXPECT_CALL(mockQueueWorkDoneCb1, Call(wgpu::QueueWorkDoneStatus::Success)).Times(1);
+ EXPECT_CALL(mockQueueWorkDoneCb2, Call(wgpu::QueueWorkDoneStatus::Success)).Times(1);
+
+ queue.OnSubmittedWorkDone(wgpu::CallbackMode::AllowProcessEvents,
+ mockQueueWorkDoneCb1.Callback());
+ queue.OnSubmittedWorkDone(wgpu::CallbackMode::AllowProcessEvents,
+ mockQueueWorkDoneCb2.Callback());
WaitForAllOperations();
}
diff --git a/src/dawn/tests/perf_tests/DawnPerfTest.cpp b/src/dawn/tests/perf_tests/DawnPerfTest.cpp
index c5178ed..5e93bfe 100644
--- a/src/dawn/tests/perf_tests/DawnPerfTest.cpp
+++ b/src/dawn/tests/perf_tests/DawnPerfTest.cpp
@@ -265,11 +265,8 @@
submittedIterations++;
mTest->queue.OnSubmittedWorkDone(
- [](WGPUQueueWorkDoneStatus, void* userdata) {
- uint64_t* counter = static_cast<uint64_t*>(userdata);
- (*counter)++;
- },
- &finishedIterations);
+ wgpu::CallbackMode::AllowProcessEvents,
+ [&finishedIterations](wgpu::QueueWorkDoneStatus) { finishedIterations++; });
if (mRunning) {
++mNumStepsPerformed;
diff --git a/src/dawn/tests/perf_tests/DawnPerfTest.h b/src/dawn/tests/perf_tests/DawnPerfTest.h
index 2ad3379..063963c 100644
--- a/src/dawn/tests/perf_tests/DawnPerfTest.h
+++ b/src/dawn/tests/perf_tests/DawnPerfTest.h
@@ -185,12 +185,9 @@
void ComputeGPUElapsedTime() {
bool done = false;
- mReadbackBuffer.MapAsync(
- wgpu::MapMode::Read, 0, sizeof(uint64_t) * kTimestampQueryCount,
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- *static_cast<bool*>(userdata) = true;
- },
- &done);
+ mReadbackBuffer.MapAsync(wgpu::MapMode::Read, 0, sizeof(uint64_t) * kTimestampQueryCount,
+ wgpu::CallbackMode::AllowProcessEvents,
+ [&done](wgpu::MapAsyncStatus, const char*) { done = true; });
while (!done) {
DawnTestWithParams<Params>::WaitABit();
}
diff --git a/src/dawn/tests/perf_tests/UniformBufferUpdatePerf.cpp b/src/dawn/tests/perf_tests/UniformBufferUpdatePerf.cpp
index 659af9d..401da1e 100644
--- a/src/dawn/tests/perf_tests/UniformBufferUpdatePerf.cpp
+++ b/src/dawn/tests/perf_tests/UniformBufferUpdatePerf.cpp
@@ -310,17 +310,13 @@
// Return the staging buffer once it's done with the last usage and re-mapped.
if (GetParam().uploadMethod == UploadMethod::MultipleStagingBuffer) {
- CallbackData* callbackData = new CallbackData({this, stagingBuffer});
- stagingBuffer.MapAsync(
- wgpu::MapMode::Write, 0, GetBufferSize(),
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- CallbackData* data = static_cast<CallbackData*>(userdata);
- if (status == WGPUBufferMapAsyncStatus::WGPUBufferMapAsyncStatus_Success) {
- data->self->ReturnStagingBuffer(data->buffer);
- }
- delete data;
- },
- callbackData);
+ stagingBuffer.MapAsync(wgpu::MapMode::Write, 0, GetBufferSize(),
+ wgpu::CallbackMode::AllowProcessEvents,
+ [this, stagingBuffer](wgpu::MapAsyncStatus status, const char*) {
+ if (status == wgpu::MapAsyncStatus::Success) {
+ this->ReturnStagingBuffer(stagingBuffer);
+ }
+ });
}
switch (GetParam().uniformBuffer) {
@@ -330,16 +326,12 @@
break;
case UniformBuffer::Multiple:
// Return the uniform buffer once it's done with the last submit.
- CallbackData* callbackData = new CallbackData({this, uniformBuffer});
- queue.OnSubmittedWorkDone(
- [](WGPUQueueWorkDoneStatus status, void* userdata) {
- CallbackData* data = static_cast<CallbackData*>(userdata);
- if (status == WGPUQueueWorkDoneStatus::WGPUQueueWorkDoneStatus_Success) {
- data->self->ReturnUniformBuffer(data->buffer);
- }
- delete data;
- },
- callbackData);
+ queue.OnSubmittedWorkDone(wgpu::CallbackMode::AllowProcessEvents,
+ [this, uniformBuffer](wgpu::QueueWorkDoneStatus status) {
+ if (status == wgpu::QueueWorkDoneStatus::Success) {
+ this->ReturnUniformBuffer(uniformBuffer);
+ }
+ });
break;
}
diff --git a/src/dawn/tests/unittests/native/DestroyObjectTests.cpp b/src/dawn/tests/unittests/native/DestroyObjectTests.cpp
index 3e35b3d..361a613 100644
--- a/src/dawn/tests/unittests/native/DestroyObjectTests.cpp
+++ b/src/dawn/tests/unittests/native/DestroyObjectTests.cpp
@@ -62,12 +62,15 @@
using ::testing::ByMove;
using ::testing::InSequence;
using ::testing::Mock;
-using testing::MockCallback;
+using testing::MockCppCallback;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::StrictMock;
using ::testing::Test;
+using MockMapAsyncCallback =
+ StrictMock<MockCppCallback<void (*)(wgpu::MapAsyncStatus, const char*)>>;
+
static constexpr std::string_view kComputeShader = R"(
@compute @workgroup_size(1) fn main() {}
)";
@@ -235,7 +238,7 @@
desc.size = 16;
desc.usage = wgpu::BufferUsage::MapRead;
- StrictMock<MockCallback<wgpu::BufferMapCallback>> cb;
+ MockMapAsyncCallback cb;
EXPECT_CALL(cb, Call).Times(1);
Ref<BufferMock> bufferMock = AcquireRef(new BufferMock(mDeviceMock, &desc));
{
@@ -247,8 +250,9 @@
{
EXPECT_CALL(*mDeviceMock, CreateBufferImpl).WillOnce(Return(ByMove(std::move(bufferMock))));
wgpu::Buffer buffer = device.CreateBuffer(ToCppAPI(&desc));
- buffer.MapAsync(wgpu::MapMode::Read, 0, 16, cb.Callback(), cb.MakeUserdata(this));
- device.Tick();
+ buffer.MapAsync(wgpu::MapMode::Read, 0, 16, wgpu::CallbackMode::AllowProcessEvents,
+ cb.Callback());
+ ProcessEvents();
EXPECT_TRUE(FromAPI(buffer.Get())->IsAlive());
buffer.Destroy();
@@ -263,7 +267,7 @@
desc.size = 16;
desc.usage = wgpu::BufferUsage::MapRead;
- StrictMock<MockCallback<wgpu::BufferMapCallback>> cb;
+ MockMapAsyncCallback cb;
EXPECT_CALL(cb, Call).Times(1);
Ref<BufferMock> bufferMock = AcquireRef(new BufferMock(mDeviceMock, &desc));
{
@@ -277,8 +281,9 @@
EXPECT_CALL(*mDeviceMock, CreateBufferImpl).WillOnce(Return(ByMove(std::move(bufferMock))));
wgpu::Buffer buffer = device.CreateBuffer(ToCppAPI(&desc));
- buffer.MapAsync(wgpu::MapMode::Read, 0, 16, cb.Callback(), cb.MakeUserdata(this));
- device.Tick();
+ buffer.MapAsync(wgpu::MapMode::Read, 0, 16, wgpu::CallbackMode::AllowProcessEvents,
+ cb.Callback());
+ ProcessEvents();
EXPECT_TRUE(FromAPI(buffer.Get())->IsAlive());
}
diff --git a/src/dawn/tests/unittests/validation/BufferValidationTests.cpp b/src/dawn/tests/unittests/validation/BufferValidationTests.cpp
index d1b520f..32f6562 100644
--- a/src/dawn/tests/unittests/validation/BufferValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/BufferValidationTests.cpp
@@ -30,21 +30,19 @@
#include <vector>
#include "dawn/common/Platform.h"
+#include "dawn/tests/MockCallback.h"
#include "dawn/tests/unittests/validation/ValidationTest.h"
#include "gmock/gmock.h"
using testing::_;
-using testing::InvokeWithoutArgs;
+using testing::HasSubstr;
+using testing::Invoke;
+using testing::MockCppCallback;
+using testing::TestParamInfo;
+using testing::Values;
+using testing::WithParamInterface;
-class MockBufferMapAsyncCallback {
- public:
- MOCK_METHOD(void, Call, (WGPUBufferMapAsyncStatus status, void* userdata));
-};
-
-static std::unique_ptr<MockBufferMapAsyncCallback> mockBufferMapAsyncCallback;
-static void ToMockBufferMapAsyncCallback(WGPUBufferMapAsyncStatus status, void* userdata) {
- mockBufferMapAsyncCallback->Call(status, userdata);
-}
+using MockMapAsyncCallback = MockCppCallback<void (*)(wgpu::MapAsyncStatus, const char*)>;
class BufferValidationTest : public ValidationTest {
protected:
@@ -73,29 +71,12 @@
return device.CreateBuffer(&descriptor);
}
- void AssertMapAsyncError(wgpu::Buffer buffer, wgpu::MapMode mode, size_t offset, size_t size) {
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_ValidationError, _))
- .Times(1);
-
- ASSERT_DEVICE_ERROR(
- buffer.MapAsync(mode, offset, size, ToMockBufferMapAsyncCallback, nullptr));
- }
-
wgpu::Queue queue;
void SetUp() override {
ValidationTest::SetUp();
-
- mockBufferMapAsyncCallback = std::make_unique<MockBufferMapAsyncCallback>();
queue = device.GetQueue();
}
-
- void TearDown() override {
- // Delete mocks so that expectations are checked
- mockBufferMapAsyncCallback = nullptr;
-
- ValidationTest::TearDown();
- }
};
// Test case where creation should succeed
@@ -184,469 +165,396 @@
}
}
-// Test the success case for mapping buffer for reading
-TEST_F(BufferValidationTest, MapAsync_ReadSuccess) {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
+class BufferMappingValidationTest : public BufferValidationTest,
+ public WithParamInterface<wgpu::MapMode> {
+ protected:
+ wgpu::Buffer CreateBuffer(uint64_t size) {
+ switch (GetParam()) {
+ case wgpu::MapMode::Read:
+ return CreateMapReadBuffer(size);
+ case wgpu::MapMode::Write:
+ return CreateMapWriteBuffer(size);
+ default:
+ DAWN_UNREACHABLE();
+ }
+ DAWN_UNREACHABLE();
+ }
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
+ wgpu::Buffer CreateMappedAtCreationBuffer(uint64_t size) {
+ switch (GetParam()) {
+ case wgpu::MapMode::Read:
+ return BufferMappedAtCreation(size, wgpu::BufferUsage::MapRead);
+ case wgpu::MapMode::Write:
+ return BufferMappedAtCreation(size, wgpu::BufferUsage::MapWrite);
+ default:
+ DAWN_UNREACHABLE();
+ }
+ DAWN_UNREACHABLE();
+ }
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _)).Times(1);
+ void AssertMapAsyncError(wgpu::Buffer buffer,
+ wgpu::MapMode mode,
+ size_t offset,
+ size_t size,
+ bool deviceError = true) {
+ // We use a new mock callback here so that the validation on the call happens as soon as the
+ // scope of this call ends. This is possible since we are using Spontaneous mode.
+ MockMapAsyncCallback mockCb;
+
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Error, _)).Times(1);
+ if (deviceError) {
+ ASSERT_DEVICE_ERROR(buffer.MapAsync(
+ mode, offset, size, wgpu::CallbackMode::AllowSpontaneous, mockCb.Callback()));
+ } else {
+ buffer.MapAsync(mode, offset, size, wgpu::CallbackMode::AllowSpontaneous,
+ mockCb.Callback());
+ }
+ }
+};
+
+INSTANTIATE_TEST_SUITE_P(,
+ BufferMappingValidationTest,
+ testing::Values(wgpu::MapMode::Read, wgpu::MapMode::Write),
+ [](const TestParamInfo<BufferMappingValidationTest::ParamType>& info) {
+ switch (info.param) {
+ case wgpu::MapMode::Read:
+ return "Read";
+ case wgpu::MapMode::Write:
+ return "Write";
+ default:
+ DAWN_UNREACHABLE();
+ }
+ DAWN_UNREACHABLE();
+ });
+
+// Test the success case for mapping buffer.
+TEST_P(BufferMappingValidationTest, MapAsync_Success) {
+ wgpu::Buffer buffer = CreateBuffer(4);
+
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+
+ buffer.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents, mockCb.Callback());
WaitForAllOperations();
-
- buf.Unmap();
-}
-
-// Test the success case for mapping buffer for writing
-TEST_F(BufferValidationTest, MapAsync_WriteSuccess) {
- wgpu::Buffer buf = CreateMapWriteBuffer(4);
-
- buf.MapAsync(wgpu::MapMode::Write, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
-
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _)).Times(1);
- WaitForAllOperations();
-
- buf.Unmap();
+ buffer.Unmap();
}
// Test map async with a buffer that's an error
-TEST_F(BufferValidationTest, MapAsync_ErrorBuffer) {
+TEST_P(BufferMappingValidationTest, MapAsync_ErrorBuffer) {
wgpu::BufferDescriptor desc;
desc.size = 4;
desc.usage = wgpu::BufferUsage::MapRead | wgpu::BufferUsage::MapWrite;
wgpu::Buffer buffer;
ASSERT_DEVICE_ERROR(buffer = device.CreateBuffer(&desc));
- AssertMapAsyncError(buffer, wgpu::MapMode::Read, 0, 4);
- AssertMapAsyncError(buffer, wgpu::MapMode::Write, 0, 4);
+ AssertMapAsyncError(buffer, GetParam(), 0, 4);
}
// Test map async with an invalid offset and size alignment.
-TEST_F(BufferValidationTest, MapAsync_OffsetSizeAlignment) {
+TEST_P(BufferMappingValidationTest, MapAsync_OffsetSizeAlignment) {
// Control case, offset aligned to 8 and size to 4 is valid
{
- wgpu::Buffer buffer = CreateMapReadBuffer(12);
- buffer.MapAsync(wgpu::MapMode::Read, 8, 4, nullptr, nullptr);
- }
- {
- wgpu::Buffer buffer = CreateMapWriteBuffer(12);
- buffer.MapAsync(wgpu::MapMode::Write, 8, 4, nullptr, nullptr);
+ wgpu::Buffer buffer = CreateBuffer(12);
+
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ buffer.MapAsync(GetParam(), 8, 4, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
+ WaitForAllOperations();
}
// Error case, offset aligned to 4 is an error.
{
- wgpu::Buffer buffer = CreateMapReadBuffer(12);
- AssertMapAsyncError(buffer, wgpu::MapMode::Read, 4, 4);
- }
- {
- wgpu::Buffer buffer = CreateMapWriteBuffer(12);
- AssertMapAsyncError(buffer, wgpu::MapMode::Write, 4, 4);
+ wgpu::Buffer buffer = CreateBuffer(12);
+ AssertMapAsyncError(buffer, GetParam(), 4, 4);
}
// Error case, size aligned to 2 is an error.
{
- wgpu::Buffer buffer = CreateMapReadBuffer(8);
- AssertMapAsyncError(buffer, wgpu::MapMode::Read, 0, 6);
- }
- {
- wgpu::Buffer buffer = CreateMapWriteBuffer(8);
- AssertMapAsyncError(buffer, wgpu::MapMode::Write, 0, 6);
+ wgpu::Buffer buffer = CreateBuffer(8);
+ AssertMapAsyncError(buffer, GetParam(), 0, 6);
}
}
// Test map async with an invalid offset and size OOB checks
-TEST_F(BufferValidationTest, MapAsync_OffsetSizeOOB) {
+TEST_P(BufferMappingValidationTest, MapAsync_OffsetSizeOOB) {
// Valid case: full buffer is ok.
{
- wgpu::Buffer buffer = CreateMapReadBuffer(8);
- buffer.MapAsync(wgpu::MapMode::Read, 0, 8, nullptr, nullptr);
- }
+ wgpu::Buffer buffer = CreateBuffer(8);
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ buffer.MapAsync(GetParam(), 0, 8, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
+ WaitForAllOperations();
+ }
// Valid case: range in the middle of the buffer is ok.
{
- wgpu::Buffer buffer = CreateMapReadBuffer(16);
- buffer.MapAsync(wgpu::MapMode::Read, 8, 4, nullptr, nullptr);
- }
+ wgpu::Buffer buffer = CreateBuffer(16);
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ buffer.MapAsync(GetParam(), 8, 4, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
+ WaitForAllOperations();
+ }
// 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);
+ wgpu::Buffer buffer = CreateBuffer(8);
+
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ buffer.MapAsync(GetParam(), 8, 0, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
+ WaitForAllOperations();
}
// 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);
+ wgpu::Buffer buffer = CreateBuffer(12);
+ AssertMapAsyncError(buffer, GetParam(), 16, 0);
}
-
// Error case, offset + size is larger than the buffer
{
- wgpu::Buffer buffer = CreateMapReadBuffer(12);
- AssertMapAsyncError(buffer, wgpu::MapMode::Read, 8, 8);
+ wgpu::Buffer buffer = CreateBuffer(12);
+ AssertMapAsyncError(buffer, GetParam(), 8, 8);
}
-
// Error case, offset + size is larger than the buffer, overflow case.
{
- wgpu::Buffer buffer = CreateMapReadBuffer(12);
- AssertMapAsyncError(buffer, wgpu::MapMode::Read, 8,
- std::numeric_limits<size_t>::max() & ~size_t(7));
+ wgpu::Buffer buffer = CreateBuffer(12);
+ AssertMapAsyncError(buffer, GetParam(), 8, std::numeric_limits<size_t>::max() & ~size_t(7));
}
}
// Test map async with a buffer that has the wrong usage
-TEST_F(BufferValidationTest, MapAsync_WrongUsage) {
+TEST_P(BufferMappingValidationTest, MapAsync_WrongUsage) {
{
wgpu::BufferDescriptor desc;
desc.usage = wgpu::BufferUsage::Vertex;
desc.size = 4;
wgpu::Buffer buffer = device.CreateBuffer(&desc);
- AssertMapAsyncError(buffer, wgpu::MapMode::Read, 0, 4);
- AssertMapAsyncError(buffer, wgpu::MapMode::Write, 0, 4);
+ AssertMapAsyncError(buffer, GetParam(), 0, 4);
}
{
- wgpu::Buffer buffer = CreateMapReadBuffer(4);
- AssertMapAsyncError(buffer, wgpu::MapMode::Write, 0, 4);
- }
- {
- wgpu::Buffer buffer = CreateMapWriteBuffer(4);
- AssertMapAsyncError(buffer, wgpu::MapMode::Read, 0, 4);
+ wgpu::Buffer buffer =
+ GetParam() == wgpu::MapMode::Read ? CreateMapWriteBuffer(4) : CreateMapReadBuffer(4);
+ AssertMapAsyncError(buffer, GetParam(), 0, 4);
}
}
// Test map async with a wrong mode
-TEST_F(BufferValidationTest, MapAsync_WrongMode) {
+TEST_P(BufferMappingValidationTest, MapAsync_WrongMode) {
{
- wgpu::Buffer buffer = CreateMapReadBuffer(4);
+ wgpu::Buffer buffer = CreateBuffer(4);
AssertMapAsyncError(buffer, wgpu::MapMode::None, 0, 4);
}
{
- wgpu::Buffer buffer = CreateMapReadBuffer(4);
+ wgpu::Buffer buffer = CreateBuffer(4);
AssertMapAsyncError(buffer, wgpu::MapMode::Read | wgpu::MapMode::Write, 0, 4);
}
}
// Test map async with a buffer that's already mapped
-TEST_F(BufferValidationTest, MapAsync_AlreadyMapped) {
+TEST_P(BufferMappingValidationTest, MapAsync_AlreadyMapped) {
{
- wgpu::Buffer buffer = CreateMapReadBuffer(4);
- buffer.MapAsync(wgpu::MapMode::Read, 0, 4, nullptr, nullptr);
+ wgpu::Buffer buffer = CreateBuffer(4);
+
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ buffer.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
WaitForAllOperations();
- AssertMapAsyncError(buffer, wgpu::MapMode::Read, 0, 4);
+
+ AssertMapAsyncError(buffer, GetParam(), 0, 4);
}
{
- wgpu::Buffer buffer = BufferMappedAtCreation(4, wgpu::BufferUsage::MapRead);
- AssertMapAsyncError(buffer, wgpu::MapMode::Read, 0, 4);
- }
- {
- wgpu::Buffer buffer = CreateMapWriteBuffer(4);
- buffer.MapAsync(wgpu::MapMode::Write, 0, 4, nullptr, nullptr);
- WaitForAllOperations();
- AssertMapAsyncError(buffer, wgpu::MapMode::Write, 0, 4);
- }
- {
- wgpu::Buffer buffer = BufferMappedAtCreation(4, wgpu::BufferUsage::MapWrite);
- AssertMapAsyncError(buffer, wgpu::MapMode::Write, 0, 4);
+ wgpu::Buffer buffer = CreateMappedAtCreationBuffer(4);
+ AssertMapAsyncError(buffer, GetParam(), 0, 4);
}
}
// Test MapAsync() immediately causes a pending map error
-TEST_F(BufferValidationTest, MapAsync_PendingMap) {
- // Read + overlapping range
+TEST_P(BufferMappingValidationTest, MapAsync_PendingMap) {
+ // Note that in the wire, we currently don't generate a validation error while in native we do.
+ // If eventually we add a way to inject errors on the wire, we may be able to make this behavior
+ // more aligned.
+ bool validationError = !UsesWire();
+
+ // Overlapping range
{
- wgpu::Buffer buffer = CreateMapReadBuffer(4);
+ wgpu::Buffer buffer = CreateBuffer(4);
+
// The first map async call should succeed while the second one should fail
- buffer.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, this);
- EXPECT_CALL(*mockBufferMapAsyncCallback,
- Call(WGPUBufferMapAsyncStatus_MappingAlreadyPending, this + 1))
- .Times(1);
- buffer.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, this + 1);
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, this))
- .Times(1);
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ buffer.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
+
+ AssertMapAsyncError(buffer, GetParam(), 0, 4, validationError);
WaitForAllOperations();
}
- // Read + non-overlapping range
+ // Non-overlapping range
{
- wgpu::Buffer buffer = CreateMapReadBuffer(16);
- // The first map async call should succeed while the second one should fail
- buffer.MapAsync(wgpu::MapMode::Read, 0, 8, ToMockBufferMapAsyncCallback, this);
- EXPECT_CALL(*mockBufferMapAsyncCallback,
- Call(WGPUBufferMapAsyncStatus_MappingAlreadyPending, this + 1))
- .Times(1);
- buffer.MapAsync(wgpu::MapMode::Read, 8, 8, ToMockBufferMapAsyncCallback, this + 1);
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, this))
- .Times(1);
- WaitForAllOperations();
- }
+ wgpu::Buffer buffer = CreateBuffer(16);
- // Write + overlapping range
- {
- wgpu::Buffer buffer = CreateMapWriteBuffer(4);
// The first map async call should succeed while the second one should fail
- buffer.MapAsync(wgpu::MapMode::Write, 0, 4, ToMockBufferMapAsyncCallback, this);
- EXPECT_CALL(*mockBufferMapAsyncCallback,
- Call(WGPUBufferMapAsyncStatus_MappingAlreadyPending, this + 1))
- .Times(1);
- buffer.MapAsync(wgpu::MapMode::Write, 0, 4, ToMockBufferMapAsyncCallback, this + 1);
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, this))
- .Times(1);
- WaitForAllOperations();
- }
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ buffer.MapAsync(GetParam(), 0, 8, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
- // Write + non-overlapping range
- {
- wgpu::Buffer buffer = CreateMapWriteBuffer(16);
- // The first map async call should succeed while the second one should fail
- buffer.MapAsync(wgpu::MapMode::Write, 0, 8, ToMockBufferMapAsyncCallback, this);
- EXPECT_CALL(*mockBufferMapAsyncCallback,
- Call(WGPUBufferMapAsyncStatus_MappingAlreadyPending, this + 1))
- .Times(1);
- buffer.MapAsync(wgpu::MapMode::Write, 8, 8, ToMockBufferMapAsyncCallback, this + 1);
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, this))
- .Times(1);
+ AssertMapAsyncError(buffer, GetParam(), 8, 8, validationError);
WaitForAllOperations();
}
}
// Test map async with a buffer that's destroyed
-TEST_F(BufferValidationTest, MapAsync_Destroy) {
- {
- wgpu::Buffer buffer = CreateMapReadBuffer(4);
- buffer.Destroy();
- AssertMapAsyncError(buffer, wgpu::MapMode::Read, 0, 4);
- }
- {
- wgpu::Buffer buffer = CreateMapWriteBuffer(4);
- buffer.Destroy();
- AssertMapAsyncError(buffer, wgpu::MapMode::Write, 0, 4);
- }
+TEST_P(BufferMappingValidationTest, MapAsync_Destroy) {
+ wgpu::Buffer buffer = CreateBuffer(4);
+ buffer.Destroy();
+ AssertMapAsyncError(buffer, GetParam(), 0, 4);
}
// Test map async but unmapping before the result is ready.
-TEST_F(BufferValidationTest, MapAsync_UnmapBeforeResult) {
- {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
+TEST_P(BufferMappingValidationTest, MapAsync_UnmapBeforeResult) {
+ wgpu::Buffer buffer = CreateBuffer(4);
- EXPECT_CALL(*mockBufferMapAsyncCallback,
- Call(WGPUBufferMapAsyncStatus_UnmappedBeforeCallback, _))
- .Times(1);
- buf.Unmap();
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Aborted, HasSubstr("unmapped"))).Times(1);
- // The callback shouldn't be called again.
- WaitForAllOperations();
- }
- {
- wgpu::Buffer buf = CreateMapWriteBuffer(4);
- buf.MapAsync(wgpu::MapMode::Write, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
-
- EXPECT_CALL(*mockBufferMapAsyncCallback,
- Call(WGPUBufferMapAsyncStatus_UnmappedBeforeCallback, _))
- .Times(1);
- buf.Unmap();
-
- // The callback shouldn't be called again.
- WaitForAllOperations();
- }
+ buffer.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents, mockCb.Callback());
+ buffer.Unmap();
+ WaitForAllOperations();
}
// When a MapAsync is cancelled with Unmap it might still be in flight, test doing a new request
// works as expected and we don't get the cancelled request's data.
-TEST_F(BufferValidationTest, MapAsync_UnmapBeforeResultAndMapAgain) {
- {
- wgpu::Buffer buf = CreateMapReadBuffer(16);
- buf.MapAsync(wgpu::MapMode::Read, 0, 8, ToMockBufferMapAsyncCallback, this + 0);
+TEST_P(BufferMappingValidationTest, MapAsync_UnmapBeforeResultAndMapAgain) {
+ wgpu::Buffer buffer = CreateBuffer(16);
- EXPECT_CALL(*mockBufferMapAsyncCallback,
- Call(WGPUBufferMapAsyncStatus_UnmappedBeforeCallback, this + 0))
- .Times(1);
- buf.Unmap();
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Aborted, HasSubstr("unmapped"))).Times(1);
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
- buf.MapAsync(wgpu::MapMode::Read, 8, 8, ToMockBufferMapAsyncCallback, this + 1);
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, this + 1))
- .Times(1);
- WaitForAllOperations();
+ buffer.MapAsync(GetParam(), 0, 8, wgpu::CallbackMode::AllowProcessEvents, mockCb.Callback());
+ buffer.Unmap();
+ buffer.MapAsync(GetParam(), 8, 8, wgpu::CallbackMode::AllowProcessEvents, mockCb.Callback());
- // Check that only the second MapAsync had an effect
- ASSERT_EQ(nullptr, buf.GetConstMappedRange(0));
- ASSERT_NE(nullptr, buf.GetConstMappedRange(8));
- }
- {
- wgpu::Buffer buf = CreateMapWriteBuffer(16);
- buf.MapAsync(wgpu::MapMode::Write, 0, 8, ToMockBufferMapAsyncCallback, this + 0);
+ WaitForAllOperations();
- EXPECT_CALL(*mockBufferMapAsyncCallback,
- Call(WGPUBufferMapAsyncStatus_UnmappedBeforeCallback, this + 0))
- .Times(1);
- buf.Unmap();
-
- buf.MapAsync(wgpu::MapMode::Write, 8, 8, ToMockBufferMapAsyncCallback, this + 1);
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, this + 1))
- .Times(1);
- WaitForAllOperations();
-
- // Check that only the second MapAsync had an effect
- ASSERT_EQ(nullptr, buf.GetConstMappedRange(0));
- ASSERT_NE(nullptr, buf.GetConstMappedRange(8));
- }
+ // Check that only the second MapAsync had an effect
+ ASSERT_EQ(nullptr, buffer.GetConstMappedRange(0));
+ ASSERT_NE(nullptr, buffer.GetConstMappedRange(8));
}
// Test map async but destroying before the result is ready.
-TEST_F(BufferValidationTest, MapAsync_DestroyBeforeResult) {
- {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
+TEST_P(BufferMappingValidationTest, MapAsync_DestroyBeforeResult) {
+ wgpu::Buffer buffer = CreateBuffer(4);
- EXPECT_CALL(*mockBufferMapAsyncCallback,
- Call(WGPUBufferMapAsyncStatus_DestroyedBeforeCallback, _))
- .Times(1);
- buf.Destroy();
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Aborted, HasSubstr("destroyed"))).Times(1);
- // The callback shouldn't be called again.
- WaitForAllOperations();
- }
- {
- wgpu::Buffer buf = CreateMapWriteBuffer(4);
- buf.MapAsync(wgpu::MapMode::Write, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
-
- EXPECT_CALL(*mockBufferMapAsyncCallback,
- Call(WGPUBufferMapAsyncStatus_DestroyedBeforeCallback, _))
- .Times(1);
- buf.Destroy();
-
- // The callback shouldn't be called again.
- WaitForAllOperations();
- }
+ buffer.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents, mockCb.Callback());
+ buffer.Destroy();
+ WaitForAllOperations();
}
// Test that the MapCallback isn't fired twice when unmap() is called inside the callback
-TEST_F(BufferValidationTest, MapAsync_UnmapCalledInCallback) {
- {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
+TEST_P(BufferMappingValidationTest, MapAsync_UnmapCalledInCallback) {
+ wgpu::Buffer buffer = CreateBuffer(4);
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _))
- .WillOnce(InvokeWithoutArgs([&] { buf.Unmap(); }));
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).WillOnce(Invoke([&] {
+ buffer.Unmap();
+ }));
- WaitForAllOperations();
- }
- {
- wgpu::Buffer buf = CreateMapWriteBuffer(4);
- buf.MapAsync(wgpu::MapMode::Write, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
-
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _))
- .WillOnce(InvokeWithoutArgs([&] { buf.Unmap(); }));
-
- WaitForAllOperations();
- }
+ buffer.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents, mockCb.Callback());
+ WaitForAllOperations();
}
// Test that the MapCallback isn't fired twice when destroy() is called inside the callback
-TEST_F(BufferValidationTest, MapAsync_DestroyCalledInCallback) {
- {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
+TEST_P(BufferMappingValidationTest, MapAsync_DestroyCalledInCallback) {
+ wgpu::Buffer buffer = CreateBuffer(4);
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _))
- .WillOnce(InvokeWithoutArgs([&] { buf.Destroy(); }));
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).WillOnce(Invoke([&] {
+ buffer.Destroy();
+ }));
- WaitForAllOperations();
- }
- {
- wgpu::Buffer buf = CreateMapWriteBuffer(4);
- buf.MapAsync(wgpu::MapMode::Write, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
-
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _))
- .WillOnce(InvokeWithoutArgs([&] { buf.Destroy(); }));
-
- WaitForAllOperations();
- }
+ buffer.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents, mockCb.Callback());
+ WaitForAllOperations();
}
// Test MapAsync call in MapAsync success callback
-// This test is disabled now because there seems to be a reeantrancy bug in the
-// FlushWire call. See https://dawn-review.googlesource.com/c/dawn/+/116220 for the details.
-TEST_F(BufferValidationTest, DISABLED_MapAsync_MapAsyncInMapAsyncSuccessCallback) {
- // Test MapAsync call in MapAsync validation success callback
- {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
+TEST_P(BufferMappingValidationTest, MapAsync_RetryInSuccessCallback) {
+ wgpu::Buffer buffer = CreateBuffer(4);
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _))
- .WillOnce(InvokeWithoutArgs([&] {
- EXPECT_CALL(*mockBufferMapAsyncCallback,
- Call(WGPUBufferMapAsyncStatus_ValidationError, _));
- // Should cause validation error because of already mapped buffer
- ASSERT_DEVICE_ERROR(
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr));
- }));
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).WillOnce(Invoke([&] {
+ // MapAsync call on destroyed buffer should be invalid
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Error, HasSubstr("already mapped")))
+ .Times(1);
+ ASSERT_DEVICE_ERROR(buffer.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowSpontaneous,
+ mockCb.Callback()));
+ }));
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
- WaitForAllOperations();
- // we need another wire flush to make the MapAsync in the callback to the server
- WaitForAllOperations();
- }
+ buffer.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents, mockCb.Callback());
+ WaitForAllOperations();
}
-// Test MapAsync call in MapAsync rejection callback
-TEST_F(BufferValidationTest, MapAsync_MapAsyncInMapAsyncRejectionCallback) {
- // Test MapAsync call in MapAsync validation error callback
- {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
+// Test MapAsync call in MapAsync validation error callback
+TEST_P(BufferMappingValidationTest, MapAsync_RetryInErrorCallback) {
+ wgpu::Buffer buffer = CreateBuffer(4);
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_ValidationError, _))
- .WillOnce(InvokeWithoutArgs([&] {
- // Retry with valid parameter and it should succeed
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _));
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
- }));
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Error, _)).WillOnce(Invoke([&] {
+ // Retry with valid parameter and it should succeed
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ buffer.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
+ }));
- // Write map mode on read buffer is invalid and it should reject with validation error
- ASSERT_DEVICE_ERROR(
- buf.MapAsync(wgpu::MapMode::Write, 0, 4, ToMockBufferMapAsyncCallback, nullptr));
+ // Wrong map mode on buffer is invalid and it should reject with validation error
+ ASSERT_DEVICE_ERROR(buffer.MapAsync(
+ GetParam() == wgpu::MapMode::Read ? wgpu::MapMode::Write : wgpu::MapMode::Read, 0, 4,
+ wgpu::CallbackMode::AllowProcessEvents, mockCb.Callback()));
+ WaitForAllOperations();
+}
- WaitForAllOperations();
- // we need another wire flush to make the MapAsync in the callback to the server
- WaitForAllOperations();
- }
+// Test MapAsync call in MapAsync unmapped callback
+TEST_P(BufferMappingValidationTest, MapAsync_RetryInUnmappedCallback) {
+ wgpu::Buffer buffer = CreateBuffer(4);
- // Test MapAsync call in MapAsync Unmapped before callback callback
- {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Aborted, _)).WillOnce(Invoke([&] {
+ // MapAsync call on unmapped buffer should be valid
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ buffer.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
+ }));
- EXPECT_CALL(*mockBufferMapAsyncCallback,
- Call(WGPUBufferMapAsyncStatus_UnmappedBeforeCallback, _))
- .WillOnce(InvokeWithoutArgs([&] {
- // MapAsync call on unmapped buffer should be valid
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _));
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
- }));
+ buffer.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents, mockCb.Callback());
+ buffer.Unmap();
+ WaitForAllOperations();
+}
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
- buf.Unmap();
- WaitForAllOperations();
- WaitForAllOperations();
- }
+// Test MapAsync call in MapAsync destroyed callback
+TEST_P(BufferMappingValidationTest, MapAsync_RetryInDestroyedCallback) {
+ wgpu::Buffer buffer = CreateBuffer(4);
- // Test MapAsync call in MapAsync Destroyed before callback callback
- {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Aborted, _)).WillOnce(Invoke([&] {
+ // MapAsync call on destroyed buffer should be invalid
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Error, HasSubstr("destroyed"))).Times(1);
+ ASSERT_DEVICE_ERROR(buffer.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowSpontaneous,
+ mockCb.Callback()));
+ }));
- EXPECT_CALL(*mockBufferMapAsyncCallback,
- Call(WGPUBufferMapAsyncStatus_DestroyedBeforeCallback, _))
- .WillOnce(InvokeWithoutArgs([&] {
- // MapAsync call on destroyed buffer should be invalid
- EXPECT_CALL(*mockBufferMapAsyncCallback,
- Call(WGPUBufferMapAsyncStatus_ValidationError, _));
- ASSERT_DEVICE_ERROR(
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr));
- }));
-
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
- buf.Destroy();
- WaitForAllOperations();
- WaitForAllOperations();
- }
+ buffer.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents, mockCb.Callback());
+ buffer.Destroy();
+ WaitForAllOperations();
}
// Test the success case for mappedAtCreation
@@ -676,22 +584,16 @@
}
// Test that it is valid to Destroy an unmapped buffer
-TEST_F(BufferValidationTest, DestroyUnmappedBuffer) {
- {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
- buf.Destroy();
- }
- {
- wgpu::Buffer buf = CreateMapWriteBuffer(4);
- buf.Destroy();
- }
+TEST_P(BufferMappingValidationTest, DestroyUnmappedBuffer) {
+ wgpu::Buffer buffer = CreateBuffer(4);
+ buffer.Destroy();
}
// Test that it is valid to Destroy a destroyed buffer
-TEST_F(BufferValidationTest, DestroyDestroyedBuffer) {
- wgpu::Buffer buf = CreateMapWriteBuffer(4);
- buf.Destroy();
- buf.Destroy();
+TEST_P(BufferMappingValidationTest, DestroyDestroyedBuffer) {
+ wgpu::Buffer buffer = CreateBuffer(4);
+ buffer.Destroy();
+ buffer.Destroy();
}
// Test that it is valid to Unmap an error buffer
@@ -706,32 +608,24 @@
}
// Test that it is valid to Unmap a destroyed buffer
-TEST_F(BufferValidationTest, UnmapDestroyedBuffer) {
- {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
- buf.Destroy();
- buf.Unmap();
- }
- {
- wgpu::Buffer buf = CreateMapWriteBuffer(4);
- buf.Destroy();
- buf.Unmap();
- }
+TEST_P(BufferMappingValidationTest, UnmapDestroyedBuffer) {
+ wgpu::Buffer buffer = CreateBuffer(4);
+ buffer.Destroy();
+ buffer.Unmap();
}
// Test that unmap then mapping a destroyed buffer is an error.
// Regression test for crbug.com/1388920.
-TEST_F(BufferValidationTest, MapDestroyedBufferAfterUnmap) {
+TEST_P(BufferMappingValidationTest, MapDestroyedBufferAfterUnmap) {
wgpu::Buffer buffer = CreateMapReadBuffer(4);
buffer.Destroy();
buffer.Unmap();
- ASSERT_DEVICE_ERROR(buffer.MapAsync(
- wgpu::MapMode::Read, 0, wgpu::kWholeMapSize,
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- EXPECT_EQ(WGPUBufferMapAsyncStatus_ValidationError, status);
- },
- nullptr));
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Error, HasSubstr("destroyed"))).Times(1);
+ ASSERT_DEVICE_ERROR(buffer.MapAsync(GetParam(), 0, wgpu::kWholeMapSize,
+ wgpu::CallbackMode::AllowSpontaneous, mockCb.Callback()));
+
WaitForAllOperations();
}
@@ -767,7 +661,10 @@
wgpu::Buffer bufA = device.CreateBuffer(&descriptorA);
wgpu::Buffer bufB = device.CreateBuffer(&descriptorB);
- bufA.MapAsync(wgpu::MapMode::Write, 0, 4, nullptr, nullptr);
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ bufA.MapAsync(wgpu::MapMode::Write, 0, 4, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
encoder.CopyBufferToBuffer(bufA, 0, bufB, 0, 4);
@@ -779,7 +676,10 @@
wgpu::Buffer bufA = device.CreateBuffer(&descriptorA);
wgpu::Buffer bufB = device.CreateBuffer(&descriptorB);
- bufB.MapAsync(wgpu::MapMode::Read, 0, 4, nullptr, nullptr);
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ bufB.MapAsync(wgpu::MapMode::Read, 0, 4, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
encoder.CopyBufferToBuffer(bufA, 0, bufB, 0, 4);
@@ -844,31 +744,25 @@
}
// Test that it is valid to call Unmap on a buffer that is not mapped
-TEST_F(BufferValidationTest, UnmapUnmappedBuffer) {
- {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
- // Buffer starts unmapped. Unmap shouldn't fail.
- buf.Unmap();
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, nullptr, nullptr);
- buf.Unmap();
- // Unmapping a second time shouldn't fail.
- buf.Unmap();
- }
- {
- wgpu::Buffer buf = CreateMapWriteBuffer(4);
- // Buffer starts unmapped. Unmap shouldn't fail.
- buf.Unmap();
- buf.MapAsync(wgpu::MapMode::Write, 0, 4, nullptr, nullptr);
- buf.Unmap();
- // Unmapping a second time shouldn't fail.
- buf.Unmap();
- }
+TEST_P(BufferMappingValidationTest, UnmapUnmappedBuffer) {
+ wgpu::Buffer buffer = CreateBuffer(4);
+
+ // Buffer starts unmapped. Unmap shouldn't fail.
+ buffer.Unmap();
+
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call).Times(1);
+ buffer.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowSpontaneous, mockCb.Callback());
+ buffer.Unmap();
+
+ // Unmapping a second time shouldn't fail.
+ buffer.Unmap();
}
// Test that it is invalid to call GetMappedRange on an unmapped buffer.
TEST_F(BufferValidationTest, GetMappedRange_OnUnmappedBuffer) {
- // Unmapped at creation case.
{
+ // Unmapped at creation case.
wgpu::BufferDescriptor desc;
desc.size = 4;
desc.usage = wgpu::BufferUsage::CopySrc;
@@ -886,33 +780,21 @@
ASSERT_EQ(nullptr, buf.GetMappedRange());
ASSERT_EQ(nullptr, buf.GetConstMappedRange());
}
+}
- // Unmapped after MapAsync read case.
- {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
+// Test that it is invalid to call GetMappedRange on an unmapped buffer.
+TEST_P(BufferMappingValidationTest, GetMappedRange_OnUnmappedBuffer) {
+ // Unmapped after valid mapping.
+ wgpu::Buffer buf = CreateBuffer(4);
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _))
- .Times(1);
- WaitForAllOperations();
- buf.Unmap();
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ buf.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents, mockCb.Callback());
+ WaitForAllOperations();
+ buf.Unmap();
- ASSERT_EQ(nullptr, buf.GetMappedRange());
- ASSERT_EQ(nullptr, buf.GetConstMappedRange());
- }
-
- // Unmapped after MapAsync write case.
- {
- wgpu::Buffer buf = CreateMapWriteBuffer(4);
- buf.MapAsync(wgpu::MapMode::Write, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _))
- .Times(1);
- WaitForAllOperations();
- buf.Unmap();
-
- ASSERT_EQ(nullptr, buf.GetMappedRange());
- ASSERT_EQ(nullptr, buf.GetConstMappedRange());
- }
+ ASSERT_EQ(nullptr, buf.GetMappedRange());
+ ASSERT_EQ(nullptr, buf.GetConstMappedRange());
}
// Test that it is invalid to call GetMappedRange on a destroyed buffer.
@@ -937,41 +819,31 @@
ASSERT_EQ(nullptr, buf.GetMappedRange());
ASSERT_EQ(nullptr, buf.GetConstMappedRange());
}
+}
- // Destroyed after MapAsync read case.
- {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
+// Test that it is invalid to call GetMappedRange on a destroyed buffer.
+TEST_P(BufferMappingValidationTest, GetMappedRange_OnDestroyedBuffer) {
+ // Destroyed after MapAsync case.
+ wgpu::Buffer buf = CreateBuffer(4);
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _))
- .Times(1);
- WaitForAllOperations();
- buf.Destroy();
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ buf.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents, mockCb.Callback());
+ WaitForAllOperations();
+ buf.Destroy();
- ASSERT_EQ(nullptr, buf.GetMappedRange());
- ASSERT_EQ(nullptr, buf.GetConstMappedRange());
- }
-
- // Destroyed after MapAsync write case.
- {
- wgpu::Buffer buf = CreateMapWriteBuffer(4);
- buf.MapAsync(wgpu::MapMode::Write, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _))
- .Times(1);
- WaitForAllOperations();
- buf.Destroy();
-
- ASSERT_EQ(nullptr, buf.GetMappedRange());
- ASSERT_EQ(nullptr, buf.GetConstMappedRange());
- }
+ ASSERT_EQ(nullptr, buf.GetMappedRange());
+ ASSERT_EQ(nullptr, buf.GetConstMappedRange());
}
// Test that it is invalid to call GetMappedRange on a buffer after MapAsync for reading
TEST_F(BufferValidationTest, GetMappedRange_NonConstOnMappedForReading) {
wgpu::Buffer buf = CreateMapReadBuffer(4);
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _)).Times(1);
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ buf.MapAsync(wgpu::MapMode::Read, 0, 4, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
WaitForAllOperations();
ASSERT_EQ(nullptr, buf.GetMappedRange());
@@ -985,25 +857,20 @@
ASSERT_NE(buffer.GetConstMappedRange(), nullptr);
ASSERT_EQ(buffer.GetConstMappedRange(), buffer.GetMappedRange());
}
+}
- // GetMappedRange after MapAsync for reading case.
- {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
+// Test valid cases to call GetMappedRange on a buffer.
+TEST_P(BufferMappingValidationTest, GetMappedRange_ValidBufferStateCases) {
+ // GetMappedRange after MapAsync case.
+ wgpu::Buffer buf = CreateBuffer(4);
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, nullptr, nullptr);
- WaitForAllOperations();
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ buf.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents, mockCb.Callback());
+ WaitForAllOperations();
- ASSERT_NE(buf.GetConstMappedRange(), nullptr);
- }
-
- // GetMappedRange after MapAsync for writing case.
- {
- wgpu::Buffer buf = CreateMapWriteBuffer(4);
-
- buf.MapAsync(wgpu::MapMode::Write, 0, 4, nullptr, nullptr);
- WaitForAllOperations();
-
- ASSERT_NE(buf.GetConstMappedRange(), nullptr);
+ ASSERT_NE(buf.GetConstMappedRange(), nullptr);
+ if (GetParam() == wgpu::MapMode::Write) {
ASSERT_EQ(buf.GetConstMappedRange(), buf.GetMappedRange());
}
}
@@ -1057,102 +924,116 @@
}
// Test validation of the GetMappedRange parameters
-TEST_F(BufferValidationTest, GetMappedRange_OffsetSizeOOB) {
+TEST_P(BufferMappingValidationTest, GetMappedRange_OffsetSizeOOB) {
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(11);
+
// Valid case: full range is ok
{
- wgpu::Buffer buffer = CreateMapWriteBuffer(8);
- buffer.MapAsync(wgpu::MapMode::Write, 0, 8, nullptr, nullptr);
+ wgpu::Buffer buffer = CreateBuffer(8);
+ buffer.MapAsync(GetParam(), 0, 8, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
WaitForAllOperations();
- EXPECT_NE(buffer.GetMappedRange(0, 8), nullptr);
+ EXPECT_NE(buffer.GetConstMappedRange(0, 8), nullptr);
}
// Valid case: full range is ok with defaulted MapAsync size
{
- wgpu::Buffer buffer = CreateMapWriteBuffer(8);
- buffer.MapAsync(wgpu::MapMode::Write, 0, wgpu::kWholeMapSize, nullptr, nullptr);
+ wgpu::Buffer buffer = CreateBuffer(8);
+ buffer.MapAsync(GetParam(), 0, wgpu::kWholeMapSize, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
WaitForAllOperations();
- EXPECT_NE(buffer.GetMappedRange(0, 8), nullptr);
+ EXPECT_NE(buffer.GetConstMappedRange(0, 8), nullptr);
}
// Valid case: full range is ok with defaulted MapAsync size and defaulted GetMappedRangeSize
{
- wgpu::Buffer buffer = CreateMapWriteBuffer(8);
- buffer.MapAsync(wgpu::MapMode::Write, 0, wgpu::kWholeMapSize, nullptr, nullptr);
+ wgpu::Buffer buffer = CreateBuffer(8);
+ buffer.MapAsync(GetParam(), 0, wgpu::kWholeMapSize, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
WaitForAllOperations();
- EXPECT_NE(buffer.GetMappedRange(0, wgpu::kWholeMapSize), nullptr);
+ EXPECT_NE(buffer.GetConstMappedRange(0, wgpu::kWholeMapSize), nullptr);
}
// Valid case: empty range at the end is ok
{
- wgpu::Buffer buffer = CreateMapWriteBuffer(8);
- buffer.MapAsync(wgpu::MapMode::Write, 0, 8, nullptr, nullptr);
+ wgpu::Buffer buffer = CreateBuffer(8);
+ buffer.MapAsync(GetParam(), 0, 8, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
WaitForAllOperations();
- EXPECT_NE(buffer.GetMappedRange(8, 0), nullptr);
+ EXPECT_NE(buffer.GetConstMappedRange(8, 0), nullptr);
}
// Valid case: range in the middle is ok.
{
- wgpu::Buffer buffer = CreateMapWriteBuffer(16);
- buffer.MapAsync(wgpu::MapMode::Write, 0, 16, nullptr, nullptr);
+ wgpu::Buffer buffer = CreateBuffer(16);
+ buffer.MapAsync(GetParam(), 0, 16, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
WaitForAllOperations();
- EXPECT_NE(buffer.GetMappedRange(8, 4), nullptr);
+ EXPECT_NE(buffer.GetConstMappedRange(8, 4), nullptr);
}
// Error case: offset is larger than the mapped range (even with size = 0)
{
- wgpu::Buffer buffer = CreateMapWriteBuffer(8);
- buffer.MapAsync(wgpu::MapMode::Write, 0, 8, nullptr, nullptr);
+ wgpu::Buffer buffer = CreateBuffer(8);
+ buffer.MapAsync(GetParam(), 0, 8, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
WaitForAllOperations();
- EXPECT_EQ(buffer.GetMappedRange(9, 0), nullptr);
- EXPECT_EQ(buffer.GetMappedRange(16, 0), nullptr);
- EXPECT_EQ(buffer.GetMappedRange(std::numeric_limits<size_t>::max(), 0), nullptr);
+ EXPECT_EQ(buffer.GetConstMappedRange(9, 0), nullptr);
+ EXPECT_EQ(buffer.GetConstMappedRange(16, 0), nullptr);
+ EXPECT_EQ(buffer.GetConstMappedRange(std::numeric_limits<size_t>::max(), 0), nullptr);
}
// Error case: offset is larger than the buffer size (even with size = 0)
{
- wgpu::Buffer buffer = CreateMapWriteBuffer(16);
- buffer.MapAsync(wgpu::MapMode::Write, 8, 8, nullptr, nullptr);
+ wgpu::Buffer buffer = CreateBuffer(16);
+ buffer.MapAsync(GetParam(), 8, 8, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
WaitForAllOperations();
- EXPECT_EQ(buffer.GetMappedRange(16, 4), nullptr);
- EXPECT_EQ(buffer.GetMappedRange(24, 0), nullptr);
- EXPECT_EQ(buffer.GetMappedRange(std::numeric_limits<size_t>::max(), 0), nullptr);
+ EXPECT_EQ(buffer.GetConstMappedRange(16, 4), nullptr);
+ EXPECT_EQ(buffer.GetConstMappedRange(24, 0), nullptr);
+ EXPECT_EQ(buffer.GetConstMappedRange(std::numeric_limits<size_t>::max(), 0), nullptr);
}
// Error case: offset + size is larger than the mapped range
{
- wgpu::Buffer buffer = CreateMapWriteBuffer(12);
- buffer.MapAsync(wgpu::MapMode::Write, 0, 12, nullptr, nullptr);
+ wgpu::Buffer buffer = CreateBuffer(12);
+ buffer.MapAsync(GetParam(), 0, 12, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
WaitForAllOperations();
- EXPECT_EQ(buffer.GetMappedRange(8, 5), nullptr);
- EXPECT_EQ(buffer.GetMappedRange(8, 8), nullptr);
+ EXPECT_EQ(buffer.GetConstMappedRange(8, 5), nullptr);
+ EXPECT_EQ(buffer.GetConstMappedRange(8, 8), nullptr);
}
// Error case: offset + size is larger than the mapped range, overflow case
{
- wgpu::Buffer buffer = CreateMapWriteBuffer(12);
- buffer.MapAsync(wgpu::MapMode::Write, 0, 12, nullptr, nullptr);
+ wgpu::Buffer buffer = CreateBuffer(12);
+ buffer.MapAsync(GetParam(), 0, 12, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
WaitForAllOperations();
// set size to (max - 1) to avoid being equal to kWholeMapSize
- EXPECT_EQ(buffer.GetMappedRange(8, std::numeric_limits<size_t>::max() - 1), nullptr);
+ EXPECT_EQ(buffer.GetConstMappedRange(8, std::numeric_limits<size_t>::max() - 1), nullptr);
}
// Error case: size is larger than the mapped range when using default kWholeMapSize
{
- wgpu::Buffer buffer = CreateMapWriteBuffer(12);
- buffer.MapAsync(wgpu::MapMode::Write, 0, 8, nullptr, nullptr);
+ wgpu::Buffer buffer = CreateBuffer(12);
+ buffer.MapAsync(GetParam(), 0, 8, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
WaitForAllOperations();
- EXPECT_EQ(buffer.GetMappedRange(0), nullptr);
+ EXPECT_EQ(buffer.GetConstMappedRange(0), nullptr);
}
// Error case: offset is before the start of the range (even with size = 0)
{
- wgpu::Buffer buffer = CreateMapWriteBuffer(12);
- buffer.MapAsync(wgpu::MapMode::Write, 8, 4, nullptr, nullptr);
+ wgpu::Buffer buffer = CreateBuffer(12);
+ buffer.MapAsync(GetParam(), 8, 4, wgpu::CallbackMode::AllowProcessEvents,
+ mockCb.Callback());
WaitForAllOperations();
- EXPECT_EQ(buffer.GetMappedRange(7, 4), nullptr);
- EXPECT_EQ(buffer.GetMappedRange(0, 4), nullptr);
- EXPECT_EQ(buffer.GetMappedRange(0, 12), nullptr);
- EXPECT_EQ(buffer.GetMappedRange(0, 0), nullptr);
+ EXPECT_EQ(buffer.GetConstMappedRange(7, 4), nullptr);
+ EXPECT_EQ(buffer.GetConstMappedRange(0, 4), nullptr);
+ EXPECT_EQ(buffer.GetConstMappedRange(0, 12), nullptr);
+ EXPECT_EQ(buffer.GetConstMappedRange(0, 0), nullptr);
}
}
@@ -1229,122 +1110,6 @@
// Test that GetMapState() shows expected buffer map state
TEST_F(BufferValidationTest, GetMapState) {
- // MapRead + MapAsync + Unmap
- {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _))
- .Times(1);
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
- EXPECT_EQ(wgpu::BufferMapState::Pending, buf.GetMapState());
- WaitForAllOperations();
- EXPECT_EQ(wgpu::BufferMapState::Mapped, buf.GetMapState());
- buf.Unmap();
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- }
-
- // MapRead + MapAsync + Unmap before the callback
- {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- EXPECT_CALL(*mockBufferMapAsyncCallback,
- Call(WGPUBufferMapAsyncStatus_UnmappedBeforeCallback, _))
- .Times(1);
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
- EXPECT_EQ(wgpu::BufferMapState::Pending, buf.GetMapState());
- buf.Unmap();
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- WaitForAllOperations();
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- }
-
- // MapRead + MapAsync + Destroy
- {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _))
- .Times(1);
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
- EXPECT_EQ(wgpu::BufferMapState::Pending, buf.GetMapState());
- WaitForAllOperations();
- EXPECT_EQ(wgpu::BufferMapState::Mapped, buf.GetMapState());
- buf.Destroy();
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- }
-
- // MapRead + MapAsync + Destroy before the callback
- {
- wgpu::Buffer buf = CreateMapReadBuffer(4);
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- EXPECT_CALL(*mockBufferMapAsyncCallback,
- Call(WGPUBufferMapAsyncStatus_DestroyedBeforeCallback, _))
- .Times(1);
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
- EXPECT_EQ(wgpu::BufferMapState::Pending, buf.GetMapState());
- buf.Destroy();
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- WaitForAllOperations();
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- }
-
- // MapWrite + MapAsync + Unmap
- {
- wgpu::Buffer buf = CreateMapWriteBuffer(4);
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _))
- .Times(1);
- buf.MapAsync(wgpu::MapMode::Write, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
- EXPECT_EQ(wgpu::BufferMapState::Pending, buf.GetMapState());
- WaitForAllOperations();
- EXPECT_EQ(wgpu::BufferMapState::Mapped, buf.GetMapState());
- buf.Unmap();
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- }
-
- // MapWrite + MapAsync + Unmap before the callback
- {
- wgpu::Buffer buf = CreateMapWriteBuffer(4);
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- EXPECT_CALL(*mockBufferMapAsyncCallback,
- Call(WGPUBufferMapAsyncStatus_UnmappedBeforeCallback, _))
- .Times(1);
- buf.MapAsync(wgpu::MapMode::Write, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
- EXPECT_EQ(wgpu::BufferMapState::Pending, buf.GetMapState());
- buf.Unmap();
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- WaitForAllOperations();
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- }
-
- // MapWrite + MapAsync + Destroy
- {
- wgpu::Buffer buf = CreateMapWriteBuffer(4);
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- EXPECT_CALL(*mockBufferMapAsyncCallback, Call(WGPUBufferMapAsyncStatus_Success, _))
- .Times(1);
- buf.MapAsync(wgpu::MapMode::Write, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
- EXPECT_EQ(wgpu::BufferMapState::Pending, buf.GetMapState());
- WaitForAllOperations();
- EXPECT_EQ(wgpu::BufferMapState::Mapped, buf.GetMapState());
- buf.Destroy();
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- }
-
- // MapWrite + MapAsync + Destroy before the callback
- {
- wgpu::Buffer buf = CreateMapWriteBuffer(4);
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- EXPECT_CALL(*mockBufferMapAsyncCallback,
- Call(WGPUBufferMapAsyncStatus_DestroyedBeforeCallback, _))
- .Times(1);
- buf.MapAsync(wgpu::MapMode::Write, 0, 4, ToMockBufferMapAsyncCallback, nullptr);
- EXPECT_EQ(wgpu::BufferMapState::Pending, buf.GetMapState());
- buf.Destroy();
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- WaitForAllOperations();
- EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
- }
-
// MappedAtCreation + Unmap
{
wgpu::Buffer buf = BufferMappedAtCreation(4, wgpu::BufferUsage::CopySrc);
@@ -1362,6 +1127,77 @@
}
}
+// Test that GetMapState() shows expected buffer map state
+TEST_P(BufferMappingValidationTest, GetMapState) {
+ // MapAsync + Unmap
+ {
+ wgpu::Buffer buf = CreateBuffer(4);
+ EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
+
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ buf.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents, mockCb.Callback());
+ EXPECT_EQ(wgpu::BufferMapState::Pending, buf.GetMapState());
+
+ WaitForAllOperations();
+ EXPECT_EQ(wgpu::BufferMapState::Mapped, buf.GetMapState());
+
+ buf.Unmap();
+ EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
+ }
+
+ // MapAsync + Unmap before the callback
+ {
+ wgpu::Buffer buf = CreateBuffer(4);
+ EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
+
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Aborted, _)).Times(1);
+ buf.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents, mockCb.Callback());
+ EXPECT_EQ(wgpu::BufferMapState::Pending, buf.GetMapState());
+
+ buf.Unmap();
+ EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
+
+ WaitForAllOperations();
+ EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
+ }
+
+ // MapAsync + Destroy
+ {
+ wgpu::Buffer buf = CreateBuffer(4);
+ EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
+
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1);
+ buf.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents, mockCb.Callback());
+ EXPECT_EQ(wgpu::BufferMapState::Pending, buf.GetMapState());
+
+ WaitForAllOperations();
+ EXPECT_EQ(wgpu::BufferMapState::Mapped, buf.GetMapState());
+
+ buf.Destroy();
+ EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
+ }
+
+ // MapAsync + Destroy before the callback
+ {
+ wgpu::Buffer buf = CreateBuffer(4);
+ EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
+
+ MockMapAsyncCallback mockCb;
+ EXPECT_CALL(mockCb, Call(wgpu::MapAsyncStatus::Aborted, _)).Times(1);
+ buf.MapAsync(GetParam(), 0, 4, wgpu::CallbackMode::AllowProcessEvents, mockCb.Callback());
+ EXPECT_EQ(wgpu::BufferMapState::Pending, buf.GetMapState());
+
+ buf.Destroy();
+ EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
+
+ WaitForAllOperations();
+ EXPECT_EQ(wgpu::BufferMapState::Unmapped, buf.GetMapState());
+ }
+}
+
class BufferMapExtendedUsagesValidationTest : public BufferValidationTest {
protected:
void SetUp() override {
diff --git a/src/dawn/tests/unittests/validation/QueueOnSubmittedWorkDoneValidationTests.cpp b/src/dawn/tests/unittests/validation/QueueOnSubmittedWorkDoneValidationTests.cpp
index 610fe22..c68d4da 100644
--- a/src/dawn/tests/unittests/validation/QueueOnSubmittedWorkDoneValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/QueueOnSubmittedWorkDoneValidationTests.cpp
@@ -27,36 +27,28 @@
#include <memory>
+#include "dawn/tests/MockCallback.h"
#include "dawn/tests/unittests/validation/ValidationTest.h"
#include "gmock/gmock.h"
-class MockQueueWorkDoneCallback {
- public:
- MOCK_METHOD(void, Call, (WGPUQueueWorkDoneStatus status, void* userdata));
-};
+namespace dawn {
+namespace {
-static std::unique_ptr<MockQueueWorkDoneCallback> mockQueueWorkDoneCallback;
-static void ToMockQueueWorkDone(WGPUQueueWorkDoneStatus status, void* userdata) {
- mockQueueWorkDoneCallback->Call(status, userdata);
-}
+using testing::MockCppCallback;
class QueueOnSubmittedWorkDoneValidationTests : public ValidationTest {
protected:
- void SetUp() override {
- ValidationTest::SetUp();
- mockQueueWorkDoneCallback = std::make_unique<MockQueueWorkDoneCallback>();
- }
-
- void TearDown() override {
- mockQueueWorkDoneCallback = nullptr;
- ValidationTest::TearDown();
- }
+ MockCppCallback<void (*)(wgpu::QueueWorkDoneStatus)> mWorkDoneCb;
};
// Test that OnSubmittedWorkDone can be called as soon as the queue is created.
TEST_F(QueueOnSubmittedWorkDoneValidationTests, CallBeforeSubmits) {
- EXPECT_CALL(*mockQueueWorkDoneCallback, Call(WGPUQueueWorkDoneStatus_Success, this)).Times(1);
- device.GetQueue().OnSubmittedWorkDone(ToMockQueueWorkDone, this);
+ EXPECT_CALL(mWorkDoneCb, Call(wgpu::QueueWorkDoneStatus::Success)).Times(1);
+ device.GetQueue().OnSubmittedWorkDone(wgpu::CallbackMode::AllowProcessEvents,
+ mWorkDoneCb.Callback());
WaitForAllOperations();
}
+
+} // anonymous namespace
+} // namespace dawn
diff --git a/src/dawn/tests/unittests/validation/QueueSubmitValidationTests.cpp b/src/dawn/tests/unittests/validation/QueueSubmitValidationTests.cpp
index a4ffce5..9a34660 100644
--- a/src/dawn/tests/unittests/validation/QueueSubmitValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/QueueSubmitValidationTests.cpp
@@ -68,12 +68,13 @@
}
// Map the buffer, submitting when the buffer is mapped should fail
- buffer.MapAsync(wgpu::MapMode::Write, 0, kBufferSize, nullptr, nullptr);
+ buffer.MapAsync(wgpu::MapMode::Write, 0, kBufferSize, wgpu::CallbackMode::AllowProcessEvents,
+ [](wgpu::MapAsyncStatus, const char*) {});
// Try submitting before the callback is fired.
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
- WaitForAllOperations(device);
+ WaitForAllOperations();
{
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
@@ -132,7 +133,8 @@
wgpu::Queue queue = device.GetQueue();
// Map the source buffer to force a failure
- buffer.MapAsync(wgpu::MapMode::Write, 0, kBufferSize, nullptr, nullptr);
+ buffer.MapAsync(wgpu::MapMode::Write, 0, kBufferSize, wgpu::CallbackMode::AllowProcessEvents,
+ [](wgpu::MapAsyncStatus, const char*) {});
// Submitting a command buffer with a mapped buffer should fail
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
@@ -152,23 +154,14 @@
descriptor.usage = wgpu::BufferUsage::MapWrite;
wgpu::Buffer buffer = device.CreateBuffer(&descriptor);
- struct CallbackData {
- wgpu::Device device;
- wgpu::Buffer buffer;
- } callbackData = {device, buffer};
+ buffer.MapAsync(wgpu::MapMode::Write, 0, descriptor.size,
+ wgpu::CallbackMode::AllowProcessEvents,
+ [buffer, queue = device.GetQueue()](wgpu::MapAsyncStatus, const char*) {
+ buffer.Unmap();
+ queue.Submit(0, nullptr);
+ });
- const auto callback = [](WGPUBufferMapAsyncStatus status, void* userdata) {
- CallbackData* data = reinterpret_cast<CallbackData*>(userdata);
-
- data->buffer.Unmap();
-
- wgpu::Queue queue = data->device.GetQueue();
- queue.Submit(0, nullptr);
- };
-
- buffer.MapAsync(wgpu::MapMode::Write, 0, descriptor.size, callback, &callbackData);
-
- WaitForAllOperations(device);
+ WaitForAllOperations();
}
// Test that submitting in a render pipeline creation callback doesn't cause re-entrance
@@ -195,7 +188,7 @@
device.GetQueue().Submit(0, nullptr);
});
- WaitForAllOperations(device);
+ WaitForAllOperations();
}
// Test that submitting in a compute pipeline creation callback doesn't cause re-entrance
@@ -213,7 +206,7 @@
device.GetQueue().Submit(0, nullptr);
});
- WaitForAllOperations(device);
+ WaitForAllOperations();
}
// Test that buffers in unused compute pass bindgroups are still checked for in
diff --git a/src/dawn/tests/unittests/validation/QueueWriteBufferValidationTests.cpp b/src/dawn/tests/unittests/validation/QueueWriteBufferValidationTests.cpp
index d0a12ad..0a04eaf 100644
--- a/src/dawn/tests/unittests/validation/QueueWriteBufferValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/QueueWriteBufferValidationTests.cpp
@@ -133,7 +133,8 @@
descriptor.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::MapRead;
wgpu::Buffer buf = device.CreateBuffer(&descriptor);
- buf.MapAsync(wgpu::MapMode::Read, 0, 4, nullptr, nullptr);
+ buf.MapAsync(wgpu::MapMode::Read, 0, 4, wgpu::CallbackMode::AllowProcessEvents,
+ [](wgpu::MapAsyncStatus, const char*) {});
uint32_t value = 0;
ASSERT_DEVICE_ERROR(queue.WriteBuffer(buf, 0, &value, sizeof(value)));
}
diff --git a/src/dawn/tests/unittests/validation/ValidationTest.cpp b/src/dawn/tests/unittests/validation/ValidationTest.cpp
index 2472044..7786b01 100644
--- a/src/dawn/tests/unittests/validation/ValidationTest.cpp
+++ b/src/dawn/tests/unittests/validation/ValidationTest.cpp
@@ -266,24 +266,6 @@
} while (dawn::native::InstanceProcessEvents(mDawnInstance->Get()) || !mWireHelper->IsIdle());
}
-void ValidationTest::WaitForAllOperations(const wgpu::Device& waitDevice) {
- bool done = false;
- waitDevice.GetQueue().OnSubmittedWorkDone(
- [](WGPUQueueWorkDoneStatus, void* userdata) { *static_cast<bool*>(userdata) = true; },
- &done);
-
- // Force the currently submitted operations to completed.
- while (!done) {
- instance.ProcessEvents();
- FlushWire();
- }
-
- // TODO(cwallez@chromium.org): It's not clear why we need this additional tick. Investigate it
- // once WebGPU has defined the ordering of callbacks firing.
- waitDevice.Tick();
- FlushWire();
-}
-
const dawn::native::ToggleInfo* ValidationTest::GetToggleInfo(const char* name) const {
return mDawnInstance->GetToggleInfo(name);
}
diff --git a/src/dawn/tests/unittests/validation/ValidationTest.h b/src/dawn/tests/unittests/validation/ValidationTest.h
index 3485585..a5e5e20 100644
--- a/src/dawn/tests/unittests/validation/ValidationTest.h
+++ b/src/dawn/tests/unittests/validation/ValidationTest.h
@@ -144,11 +144,7 @@
bool UsesWire() const;
void FlushWire();
-
- // TODO: crbug.com/42241461 - Remove overload that passes a device once we update tests to use
- // new entry points.
void WaitForAllOperations();
- void WaitForAllOperations(const wgpu::Device& device);
// Helper functions to create objects to test validation.
diff --git a/src/dawn/tests/white_box/D3D12ResidencyTests.cpp b/src/dawn/tests/white_box/D3D12ResidencyTests.cpp
index a6a09f0..ebef69c 100644
--- a/src/dawn/tests/white_box/D3D12ResidencyTests.cpp
+++ b/src/dawn/tests/white_box/D3D12ResidencyTests.cpp
@@ -229,13 +229,12 @@
// Calling MapAsync for reading should make the buffer resident.
bool done = false;
- buffer.MapAsync(
- wgpu::MapMode::Read, 0, sizeof(uint32_t),
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
- *static_cast<bool*>(userdata) = true;
- },
- &done);
+ buffer.MapAsync(wgpu::MapMode::Read, 0, sizeof(uint32_t),
+ wgpu::CallbackMode::AllowProcessEvents,
+ [&done](wgpu::MapAsyncStatus status, const char*) {
+ ASSERT_EQ(status, wgpu::MapAsyncStatus::Success);
+ done = true;
+ });
EXPECT_TRUE(CheckIfBufferIsResident(buffer));
while (!done) {
@@ -275,13 +274,12 @@
// Calling MapAsync for writing should make the buffer resident.
bool done = false;
- buffer.MapAsync(
- wgpu::MapMode::Write, 0, sizeof(uint32_t),
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
- *static_cast<bool*>(userdata) = true;
- },
- &done);
+ buffer.MapAsync(wgpu::MapMode::Write, 0, sizeof(uint32_t),
+ wgpu::CallbackMode::AllowProcessEvents,
+ [&done](wgpu::MapAsyncStatus status, const char*) {
+ ASSERT_EQ(status, wgpu::MapAsyncStatus::Success);
+ done = true;
+ });
EXPECT_TRUE(CheckIfBufferIsResident(buffer));
while (!done) {
diff --git a/src/dawn/tests/white_box/SharedBufferMemoryTests.cpp b/src/dawn/tests/white_box/SharedBufferMemoryTests.cpp
index b580837..a7d9a9e 100644
--- a/src/dawn/tests/white_box/SharedBufferMemoryTests.cpp
+++ b/src/dawn/tests/white_box/SharedBufferMemoryTests.cpp
@@ -49,23 +49,6 @@
return features;
}
-void SharedBufferMemoryTests::MapAsyncAndWait(const wgpu::Buffer& buffer,
- wgpu::MapMode mode,
- uint32_t bufferSize) {
- bool done = false;
- buffer.MapAsync(
- mode, 0, bufferSize,
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
- *static_cast<bool*>(userdata) = true;
- },
- &done);
-
- while (!done) {
- WaitABit();
- }
-}
-
wgpu::Texture Create2DTexture(wgpu::Device device,
uint32_t width,
uint32_t height,
@@ -231,13 +214,12 @@
memory.BeginAccess(buffer, &desc);
bool done = false;
- buffer.MapAsync(
- wgpu::MapMode::Write, 0, sizeof(uint32_t),
- [](WGPUBufferMapAsyncStatus status, void* userdata) {
- ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
- *static_cast<bool*>(userdata) = true;
- },
- &done);
+ buffer.MapAsync(wgpu::MapMode::Write, 0, sizeof(uint32_t),
+ wgpu::CallbackMode::AllowProcessEvents,
+ [&done](wgpu::MapAsyncStatus status, const char*) {
+ ASSERT_EQ(status, wgpu::MapAsyncStatus::Success);
+ done = true;
+ });
// Calling EndAccess should generate an error even if the buffer has not completed being mapped.
wgpu::SharedBufferMemoryEndAccessState state;
@@ -279,7 +261,11 @@
wgpu::Buffer sharedBuffer = memory.CreateBuffer();
// Mapping a buffer without calling BeginAccess should cause an error.
- ASSERT_DEVICE_ERROR(sharedBuffer.MapAsync(wgpu::MapMode::Write, 0, 4, nullptr, nullptr));
+ ASSERT_DEVICE_ERROR(sharedBuffer.MapAsync(wgpu::MapMode::Write, 0, 4,
+ wgpu::CallbackMode::AllowProcessEvents,
+ [](wgpu::MapAsyncStatus status, const char*) {
+ ASSERT_EQ(status, wgpu::MapAsyncStatus::Error);
+ }));
}
// Ensure multiple buffers created from a SharedBufferMemory cannot be accessed simultaneously.
@@ -362,7 +348,7 @@
beginAccessDesc.initialized = false;
memory.BeginAccess(buffer, &beginAccessDesc);
- MapAsyncAndWait(buffer, wgpu::MapMode::Write, kBufferSize);
+ MapAsyncAndWait(buffer, wgpu::MapMode::Write, 0, kBufferSize);
uint32_t* mappedData = static_cast<uint32_t*>(buffer.GetMappedRange(0, kBufferSize));
memcpy(mappedData, &kBufferData, kBufferSize);
@@ -441,7 +427,7 @@
memory.BeginAccess(buffer, &beginAccessDesc);
EXPECT_BUFFER_U32_EQ(kBufferData, buffer, 0);
- MapAsyncAndWait(buffer, wgpu::MapMode::Write, kBufferSize);
+ MapAsyncAndWait(buffer, wgpu::MapMode::Write, 0, kBufferSize);
uint32_t* mappedData = static_cast<uint32_t*>(buffer.GetMappedRange(0, kBufferSize));
memcpy(mappedData, &kBufferData2, kBufferSize);
@@ -462,7 +448,7 @@
beginAccessDesc.initialized = true;
memory.BeginAccess(buffer, &beginAccessDesc);
- MapAsyncAndWait(buffer, wgpu::MapMode::Read, kBufferSize);
+ MapAsyncAndWait(buffer, wgpu::MapMode::Read, 0, kBufferSize);
const uint32_t* mappedData =
static_cast<const uint32_t*>(buffer.GetConstMappedRange(0, kBufferSize));
@@ -478,7 +464,7 @@
wgpu::CommandBuffer commandBuffer = encoder.Finish();
queue.Submit(1, &commandBuffer);
- MapAsyncAndWait(buffer, wgpu::MapMode::Read, kBufferSize);
+ MapAsyncAndWait(buffer, wgpu::MapMode::Read, 0, kBufferSize);
mappedData = static_cast<const uint32_t*>(buffer.GetConstMappedRange(0, kBufferSize));
ASSERT_EQ(*mappedData, kBufferData2);
diff --git a/src/dawn/tests/white_box/SharedBufferMemoryTests.h b/src/dawn/tests/white_box/SharedBufferMemoryTests.h
index d7e3b14..9f631a3 100644
--- a/src/dawn/tests/white_box/SharedBufferMemoryTests.h
+++ b/src/dawn/tests/white_box/SharedBufferMemoryTests.h
@@ -64,9 +64,6 @@
public:
void SetUp() override;
std::vector<wgpu::FeatureName> GetRequiredFeatures() override;
-
- protected:
- void MapAsyncAndWait(const wgpu::Buffer& buffer, wgpu::MapMode mode, uint32_t bufferSize);
};
} // namespace dawn