Revert "[dawn] Removes old non-overridden non-Future entry." This reverts commit fa07f3046419775df4d2f8fb5b0a9c5078399d4e. Reason for revert: Breaking Dawn->Chromium roll, need to update MLDrift. Original change's description: > [dawn] Removes old non-overridden non-Future entry. > > - Removes/Renames the following entry points and their > corresponding old Callbacks and CallbackInfos: > - ShaderModule::GetCompilationInfo > - Device::Create*PipelineAsync > - Device::PopErrorScope > - Buffer::MapAsync > - Queue::OnSubmittedWorkDone > - Note that "overridden" entry points will be removed in > multi-CL changes since those refer to entry points > where users may be manually overriding the C proc table. > > Bug: 369445924 > Change-Id: I074cac71587b64555288e44c9f483d9426c7abd0 > Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/216314 > Reviewed-by: Kai Ninomiya <kainino@chromium.org> > Commit-Queue: Loko Kung <lokokung@google.com> Bug: 369445924 Change-Id: Ia93ea22936c5a37ba9d86fb9a34d10b1c5ebcbff Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/220294 Commit-Queue: Loko Kung <lokokung@google.com> Reviewed-by: Jiawei Shao <jiawei.shao@intel.com> Reviewed-by: Loko Kung <lokokung@google.com> Auto-Submit: Loko Kung <lokokung@google.com>
diff --git a/generator/templates/mock_api.cpp b/generator/templates/mock_api.cpp index e976aef..dc5c9e1 100644 --- a/generator/templates/mock_api.cpp +++ b/generator/templates/mock_api.cpp
@@ -98,7 +98,10 @@ object->m{{Suffix}}Userdata = userdata; {% endfor %} - {% if method.name.get() not in LegacyCallbackFunctions %} + {% if method.name.get() == 'pop error scope' %} + //* Currently special casing popErrorScope since it has an old callback type. + On{{Suffix}}({{-as_varName(type.name)}}, {.nextInChain = nullptr, .mode = WGPUCallbackMode_AllowProcessEvents, .callback = nullptr, .oldCallback = oldCallback, .userdata = userdata}); + {% elif method.name.get() not in LegacyCallbackFunctions %} On{{Suffix}}( {{-as_varName(type.name)}} {%- for arg in method.arguments if arg.type.category != 'function pointer' and arg.type.name.get() != 'void *' -%}
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json index e4712d5..85cacb8 100644 --- a/src/dawn/dawn.json +++ b/src/dawn/dawn.json
@@ -600,6 +600,18 @@ "methods": [ { "name": "map async", + "args": [ + {"name": "mode", "type": "map mode"}, + {"name": "offset", "type": "size_t"}, + {"name": "size", "type": "size_t"}, + {"name": "callback", "type": "buffer map callback"}, + {"name": "userdata", "type": "void *"} + ] + }, + { + "name": "map async f", + "_comment": "TODO(crbug.com/dawn/2021): This is dawn/emscripten-only until we rename it to replace the old API. See bug for details.", + "tags": ["dawn", "emscripten"], "returns": "future", "args": [ {"name": "mode", "type": "map mode"}, @@ -609,6 +621,18 @@ ] }, { + "name": "map async 2", + "_comment": "TODO(crbug.com/dawn/2021): This is dawn/emscripten-only until we rename it to replace the old API. See bug for details.", + "tags": ["dawn", "emscripten"], + "returns": "future", + "args": [ + {"name": "mode", "type": "map mode"}, + {"name": "offset", "type": "size_t"}, + {"name": "size", "type": "size_t"}, + {"name": "callback info", "type": "buffer map callback info 2"} + ] + }, + { "name": "get mapped range", "returns": "void *", "args": [ @@ -682,6 +706,13 @@ ] }, "buffer map callback": { + "category": "function pointer", + "args": [ + {"name": "status", "type": "buffer map async status"}, + {"name": "userdata", "type": "void *"} + ] + }, + "buffer map callback 2": { "category": "callback function", "args": [ {"name": "status", "type": "map async status"}, @@ -689,10 +720,35 @@ ] }, "buffer map callback info": { + "category": "structure", + "extensible": "in", + "members": [ + {"name": "mode", "type": "callback mode"}, + {"name": "callback", "type": "buffer map callback"}, + {"name": "userdata", "type": "void *"} + ] + }, + "buffer map callback info 2": { "category": "callback info", "members": [ {"name": "mode", "type": "callback mode"}, - {"name": "callback", "type": "buffer map callback"} + {"name": "callback", "type": "buffer map callback 2"} + ] + }, + "buffer map async status": { + "category": "enum", + "emscripten_no_enum_table": true, + "values": [ + {"value": 1, "name": "success"}, + {"value": 2, "name": "instance dropped"}, + {"value": 3, "name": "validation error"}, + {"value": 4, "name": "unknown"}, + {"value": 5, "name": "device lost"}, + {"value": 6, "name": "destroyed before callback"}, + {"value": 7, "name": "unmapped before callback"}, + {"value": 8, "name": "mapping already pending"}, + {"value": 9, "name": "offset out of range"}, + {"value": 10, "name": "size out of range"} ] }, "map async status": { @@ -937,6 +993,14 @@ ] }, "compilation info callback": { + "category": "function pointer", + "args": [ + {"name": "status", "type": "compilation info request status"}, + {"name": "compilation info", "type": "compilation info", "annotation": "const*"}, + {"name": "userdata", "type": "void *"} + ] + }, + "compilation info callback 2": { "category": "callback function", "args": [ {"name": "status", "type": "compilation info request status"}, @@ -944,10 +1008,19 @@ ] }, "compilation info callback info": { + "category": "structure", + "extensible": "in", + "members": [ + {"name": "mode", "type": "callback mode"}, + {"name": "callback", "type": "compilation info callback"}, + {"name": "userdata", "type": "void *", "default": "nullptr"} + ] + }, + "compilation info callback info 2": { "category": "callback info", "members": [ {"name": "mode", "type": "callback mode"}, - {"name": "callback", "type": "compilation info callback"} + {"name": "callback", "type": "compilation info callback 2"} ] }, "compilation info request status": { @@ -1137,6 +1210,15 @@ ] }, "create compute pipeline async callback": { + "category": "function pointer", + "args": [ + {"name": "status", "type": "create pipeline async status"}, + {"name": "pipeline", "type": "compute pipeline", "optional": true}, + {"name": "message", "type": "string view"}, + {"name": "userdata", "type": "void *"} + ] + }, + "create compute pipeline async callback 2": { "category": "callback function", "args": [ {"name": "status", "type": "create pipeline async status"}, @@ -1145,10 +1227,19 @@ ] }, "create compute pipeline async callback info": { + "category": "structure", + "extensible": "in", + "members": [ + {"name": "mode", "type": "callback mode"}, + {"name": "callback", "type": "create compute pipeline async callback"}, + {"name": "userdata", "type": "void *"} + ] + }, + "create compute pipeline async callback info 2": { "category": "callback info", "members": [ {"name": "mode", "type": "callback mode"}, - {"name": "callback", "type": "create compute pipeline async callback"} + {"name": "callback", "type": "create compute pipeline async callback 2"} ] }, "create pipeline async status": { @@ -1165,6 +1256,15 @@ ] }, "create render pipeline async callback": { + "category": "function pointer", + "args": [ + {"name": "status", "type": "create pipeline async status"}, + {"name": "pipeline", "type": "render pipeline", "optional": true}, + {"name": "message", "type": "string view"}, + {"name": "userdata", "type": "void *"} + ] + }, + "create render pipeline async callback 2": { "category": "callback function", "args": [ {"name": "status", "type": "create pipeline async status"}, @@ -1173,10 +1273,19 @@ ] }, "create render pipeline async callback info": { + "category": "structure", + "extensible": "in", + "members": [ + {"name": "mode", "type": "callback mode"}, + {"name": "callback", "type": "create render pipeline async callback"}, + {"name": "userdata", "type": "void *"} + ] + }, + "create render pipeline async callback info 2": { "category": "callback info", "members": [ {"name": "mode", "type": "callback mode"}, - {"name": "callback", "type": "create render pipeline async callback"} + {"name": "callback", "type": "create render pipeline async callback 2"} ] }, "cull mode": { @@ -1245,6 +1354,17 @@ }, { "name": "create compute pipeline async", + "returns": "void", + "args": [ + {"name": "descriptor", "type": "compute pipeline descriptor", "annotation": "const*"}, + {"name": "callback", "type": "create compute pipeline async callback"}, + {"name": "userdata", "type": "void *"} + ] + }, + { + "name": "create compute pipeline async f", + "_comment": "TODO(crbug.com/dawn/2021): This is dawn/emscripten-only until we rename it to replace the old API. See bug for details.", + "tags": ["dawn", "emscripten"], "returns": "future", "args": [ {"name": "descriptor", "type": "compute pipeline descriptor", "annotation": "const*"}, @@ -1252,6 +1372,16 @@ ] }, { + "name": "create compute pipeline async 2", + "_comment": "TODO(crbug.com/dawn/2021): This is dawn/emscripten-only until we rename it to replace the old API. See bug for details.", + "tags": ["dawn", "emscripten"], + "returns": "future", + "args": [ + {"name": "descriptor", "type": "compute pipeline descriptor", "annotation": "const*"}, + {"name": "callback info", "type": "create compute pipeline async callback info 2"} + ] + }, + { "name": "create external texture", "returns": "external texture", "tags": ["dawn"], @@ -1280,6 +1410,17 @@ }, { "name": "create render pipeline async", + "returns": "void", + "args": [ + {"name": "descriptor", "type": "render pipeline descriptor", "annotation": "const*"}, + {"name": "callback", "type": "create render pipeline async callback"}, + {"name": "userdata", "type": "void *"} + ] + }, + { + "name": "create render pipeline async f", + "_comment": "TODO(crbug.com/dawn/2021): This is dawn/emscripten-only until we rename it to replace the old API. See bug for details.", + "tags": ["dawn", "emscripten"], "returns": "future", "args": [ {"name": "descriptor", "type": "render pipeline descriptor", "annotation": "const*"}, @@ -1287,6 +1428,16 @@ ] }, { + "name": "create render pipeline async 2", + "_comment": "TODO(crbug.com/dawn/2021): This is dawn/emscripten-only until we rename it to replace the old API. See bug for details.", + "tags": ["dawn", "emscripten"], + "returns": "future", + "args": [ + {"name": "descriptor", "type": "render pipeline descriptor", "annotation": "const*"}, + {"name": "callback info", "type": "create render pipeline async callback info 2"} + ] + }, + { "name": "create render bundle encoder", "returns": "render bundle encoder", "args": [ @@ -1456,12 +1607,30 @@ { "name": "pop error scope", "no autolock": true, + "args": [ + {"name": "old callback", "type": "error callback"}, + {"name": "userdata", "type": "void *"} + ] + }, + { + "name": "pop error scope f", + "_comment": "TODO(crbug.com/dawn/2021): This is dawn/emscripten-only until we rename it to replace the old API. See bug for details.", + "tags": ["dawn", "emscripten"], "returns": "future", "args": [ {"name": "callback info", "type": "pop error scope callback info"} ] }, { + "name": "pop error scope 2", + "_comment": "TODO(crbug.com/dawn/2021): This is dawn/emscripten-only until we rename it to replace the old API. See bug for details.", + "tags": ["dawn", "emscripten"], + "returns": "future", + "args": [ + {"name": "callback info", "type": "pop error scope callback info 2"} + ] + }, + { "name": "set label", "returns": "void", "args": [ @@ -1572,6 +1741,15 @@ ] }, "pop error scope callback": { + "category": "function pointer", + "args": [ + {"name": "status", "type": "pop error scope status"}, + {"name": "type", "type": "error type"}, + {"name": "message", "type": "string view"}, + {"name": "userdata", "type": "void *"} + ] + }, + "pop error scope callback 2": { "category": "callback function", "args": [ {"name": "status", "type": "pop error scope status"}, @@ -1580,10 +1758,20 @@ ] }, "pop error scope callback info": { + "category": "structure", + "extensible": "in", + "members": [ + {"name": "mode", "type": "callback mode", "default": "wait any only"}, + {"name": "callback", "type": "pop error scope callback"}, + {"name": "old callback", "type": "error callback", "_comment": "TODO(crbug.com/dawn/2021) Deprecate this field once we have moved callers to use the new callback signature."}, + {"name": "userdata", "type": "void *", "default": "nullptr"} + ] + }, + "pop error scope callback info 2": { "category": "callback info", "members": [ {"name": "mode", "type": "callback mode"}, - {"name": "callback", "type": "pop error scope callback"} + {"name": "callback", "type": "pop error scope callback 2"} ] }, "limits": { @@ -2760,12 +2948,31 @@ }, { "name": "on submitted work done", + "tags": ["dawn", "upstream"], + "args": [ + {"name": "callback", "type": "queue work done callback"}, + {"name": "userdata", "type": "void *"} + ] + }, + { + "name": "on submitted work done f", + "_comment": "TODO(crbug.com/dawn/2021): This is dawn/emscripten-only until we rename it to replace the old API. See bug for details.", + "tags": ["dawn", "emscripten"], "returns": "future", "args": [ {"name": "callback info", "type": "queue work done callback info"} ] }, { + "name": "on submitted work done 2", + "_comment": "TODO(crbug.com/dawn/2021): This is dawn/emscripten-only until we rename it to replace the old API. See bug for details.", + "tags": ["dawn", "emscripten"], + "returns": "future", + "args": [ + {"name": "callback info", "type": "queue work done callback info 2"} + ] + }, + { "name": "write buffer", "args": [ {"name": "buffer", "type": "buffer"}, @@ -2823,16 +3030,32 @@ ] }, "queue work done callback": { + "category": "function pointer", + "args": [ + {"name": "status", "type": "queue work done status"}, + {"name": "userdata", "type": "void *"} + ] + }, + "queue work done callback 2": { "category": "callback function", "args": [ {"name": "status", "type": "queue work done status"} ] }, "queue work done callback info": { + "category": "structure", + "extensible": "in", + "members": [ + {"name": "mode", "type": "callback mode"}, + {"name": "callback", "type": "queue work done callback"}, + {"name": "userdata", "type": "void *"} + ] + }, + "queue work done callback info 2": { "category": "callback info", "members": [ {"name": "mode", "type": "callback mode"}, - {"name": "callback", "type": "queue work done callback"} + {"name": "callback", "type": "queue work done callback 2"} ] }, "queue work done status": { @@ -2842,7 +3065,8 @@ {"value": 1, "name": "success"}, {"value": 2, "name": "instance dropped"}, {"value": 3, "name": "error"}, - {"value": 4, "name": "unknown"} + {"value": 4, "name": "unknown"}, + {"value": 5, "name": "device lost"} ] }, @@ -3472,12 +3696,30 @@ "methods": [ { "name": "get compilation info", + "args": [ + {"name": "callback", "type": "compilation info callback"}, + {"name": "userdata", "type": "void *"} + ] + }, + { + "name": "get compilation info f", + "_comment": "TODO(crbug.com/dawn/2021): This is dawn/emscripten-only until we rename it to replace the old API. See bug for details.", + "tags": ["dawn", "emscripten"], "returns": "future", "args": [ {"name": "callback info", "type": "compilation info callback info"} ] }, { + "name": "get compilation info 2", + "_comment": "TODO(crbug.com/dawn/2021): This is dawn/emscripten-only until we rename it to replace the old API. See bug for details.", + "tags": ["dawn", "emscripten"], + "returns": "future", + "args": [ + {"name": "callback info", "type": "compilation info callback info 2"} + ] + }, + { "name": "set label", "returns": "void", "args": [
diff --git a/src/dawn/dawn_wire.json b/src/dawn/dawn_wire.json index cc67fcd..97b23ea 100644 --- a/src/dawn/dawn_wire.json +++ b/src/dawn/dawn_wire.json
@@ -37,7 +37,8 @@ { "name": "future", "type": "future" }, { "name": "mode", "type": "map mode" }, { "name": "offset", "type": "uint64_t"}, - { "name": "size", "type": "uint64_t"} + { "name": "size", "type": "uint64_t"}, + { "name": "userdata count", "type": "uint8_t", "_comment": "TODO(crbug.com/dawn/2509): Remove this once Chromium overrides the correct functions in the proc table."} ], "buffer update mapped data": [ { "name": "buffer id", "type": "ObjectId", "id_type": "buffer" }, @@ -81,7 +82,8 @@ "queue on submitted work done": [ { "name": "queue id", "type": "ObjectId", "id_type": "queue" }, { "name": "event manager handle", "type": "ObjectHandle" }, - { "name": "future", "type": "future" } + { "name": "future", "type": "future" }, + { "name": "userdata count", "type": "uint8_t", "_comment": "TODO(crbug.com/dawn/2509): Remove this once Chromium overrides the correct functions in the proc table."} ], "queue write buffer": [ {"name": "queue id", "type": "ObjectId", "id_type": "queue" }, @@ -130,8 +132,10 @@ "buffer map async callback": [ { "name": "event manager", "type": "ObjectHandle" }, { "name": "future", "type": "future" }, - { "name": "status", "type": "map async status" }, + { "name": "status", "type": "buffer map async status" }, + { "name": "status2", "type": "map async status" }, { "name": "message", "type": "string view" }, + { "name": "userdata count", "type": "uint8_t", "_comment": "TODO(crbug.com/dawn/2509): Remove this once Chromium overrides the correct functions in the proc table."}, { "name": "read data update info length", "type": "uint64_t" }, { "name": "read data update info", "type": "uint8_t", "annotation": "const*", "length": "read data update info length", "skip_serialize": true } ], @@ -224,6 +228,8 @@ "AdapterRequestDeviceF", "AdapterRequestDevice2", "BufferMapAsync", + "BufferMapAsyncF", + "BufferMapAsync2", "BufferGetConstMappedRange", "BufferGetMappedRange", "BufferGetMapState", @@ -231,7 +237,11 @@ "BufferGetUsage", "DeviceCreateBuffer", "DeviceCreateComputePipelineAsync", + "DeviceCreateComputePipelineAsyncF", + "DeviceCreateComputePipelineAsync2", "DeviceCreateRenderPipelineAsync", + "DeviceCreateRenderPipelineAsyncF", + "DeviceCreateRenderPipelineAsync2", "DeviceGetAdapter", "DeviceGetAdapterInfo", "DeviceGetFeatures", @@ -249,9 +259,13 @@ "InstanceRequestAdapterF", "InstanceRequestAdapter2", "ShaderModuleGetCompilationInfo", + "ShaderModuleGetCompilationInfoF", + "ShaderModuleGetCompilationInfo2", "QuerySetGetType", "QuerySetGetCount", "QueueOnSubmittedWorkDone", + "QueueOnSubmittedWorkDoneF", + "QueueOnSubmittedWorkDone2", "QueueWriteBuffer", "QueueWriteTexture", "SurfaceGetCapabilities",
diff --git a/src/dawn/native/Buffer.cpp b/src/dawn/native/Buffer.cpp index 0b70008..c38e2a7 100644 --- a/src/dawn/native/Buffer.cpp +++ b/src/dawn/native/Buffer.cpp
@@ -59,6 +59,34 @@ namespace dawn::native { namespace { +struct MapRequestTask : TrackTaskCallback { + MapRequestTask(dawn::platform::Platform* platform, Ref<BufferBase> buffer, MapRequestID id) + : TrackTaskCallback(platform), buffer(std::move(buffer)), id(id) {} + ~MapRequestTask() override = default; + + private: + void FinishImpl() override { + { + // This is called from a callback, and no lock will be held by default. Hence, we need + // to lock the mutex now because mSerial might be changed by another thread. + auto deviceLock(buffer->GetDevice()->GetScopedLock()); + DAWN_ASSERT(mSerial != kMaxExecutionSerial); + TRACE_EVENT1(mPlatform, General, "Buffer::TaskInFlight::Finished", "serial", + uint64_t(mSerial)); + } + buffer->CallbackOnMapRequestCompleted(id, WGPUBufferMapAsyncStatus_Success); + } + void HandleDeviceLossImpl() override { + buffer->CallbackOnMapRequestCompleted(id, WGPUBufferMapAsyncStatus_DeviceLost); + } + void HandleShutDownImpl() override { + buffer->CallbackOnMapRequestCompleted(id, WGPUBufferMapAsyncStatus_DestroyedBeforeCallback); + } + + Ref<BufferBase> buffer; + MapRequestID id; +}; + class ErrorBuffer final : public BufferBase { public: ErrorBuffer(DeviceBase* device, const BufferDescriptor* descriptor) @@ -155,7 +183,106 @@ } // anonymous namespace -struct BufferBase::MapAsyncEvent final : public EventManager::TrackedEvent { +struct BufferBase::MapAsyncEvent : public EventManager::TrackedEvent { + MapAsyncEvent(wgpu::CallbackMode mode, QueueBase* queue, ExecutionSerial serial) + : TrackedEvent(mode, queue, serial) {} + // TODO(crbug.com/42241006): Note that currently this constructor is used for errors because a + // dropped device can result in failure when trying to get the queue. While using this fixes the + // problem, it causes an unintentional side-effect where it is possible to run into a + // UnsupportedMixedSource error on WaitAny even if we are only using a single device with + // MapAsync calls. This will be fixed once we correctly implement mixed sources. + explicit MapAsyncEvent(wgpu::CallbackMode mode) + : TrackedEvent(mode, SystemEvent::CreateSignaled()) {} + + virtual void UnmapEarly(wgpu::BufferMapAsyncStatus status) = 0; +}; + +struct BufferBase::MapAsyncEvent1 final : public BufferBase::MapAsyncEvent { + // MapAsyncEvent stores a raw pointer to the buffer so that it can + // update the buffer's map state when it completes. + // If the map completes early (error, unmap, destroy), then the buffer + // is no longer needed and we store the early status instead. + // The raw pointer is safe because the early status is set to destroyed + // before the buffer is dropped. + // Note: this could be an atomic + spin lock on a sentinel enum if the mutex + // cost is high. + MutexProtected<std::variant<BufferBase*, wgpu::BufferMapAsyncStatus>> mBufferOrEarlyStatus; + + WGPUBufferMapCallback mCallback; + raw_ptr<void> mUserdata; + + // Create an event backed by the given queue execution serial. + MapAsyncEvent1(DeviceBase* device, + BufferBase* buffer, + const BufferMapCallbackInfo& callbackInfo, + ExecutionSerial serial) + : MapAsyncEvent(callbackInfo.mode, device->GetQueue(), serial), + mBufferOrEarlyStatus(buffer), + mCallback(callbackInfo.callback), + mUserdata(callbackInfo.userdata) { + TRACE_EVENT_ASYNC_BEGIN0(device->GetPlatform(), General, "Buffer::APIMapAsync", + uint64_t(serial)); + } + + // Create an event that's ready at creation (for errors, etc.) + MapAsyncEvent1(DeviceBase* device, + const BufferMapCallbackInfo& callbackInfo, + wgpu::BufferMapAsyncStatus earlyStatus) + : MapAsyncEvent(callbackInfo.mode, device->GetQueue(), kBeginningOfGPUTime), + mBufferOrEarlyStatus(earlyStatus), + mCallback(callbackInfo.callback), + mUserdata(callbackInfo.userdata) { + TRACE_EVENT_ASYNC_BEGIN0(device->GetPlatform(), General, "Buffer::APIMapAsync", + uint64_t(kBeginningOfGPUTime)); + } + + ~MapAsyncEvent1() override { EnsureComplete(EventCompletionType::Shutdown); } + + void Complete(EventCompletionType completionType) override { + if (const auto* queueAndSerial = std::get_if<QueueAndSerial>(&GetCompletionData())) { + TRACE_EVENT_ASYNC_END0(queueAndSerial->queue->GetDevice()->GetPlatform(), General, + "Buffer::APIMapAsync", + uint64_t(queueAndSerial->completionSerial)); + } + + if (completionType == EventCompletionType::Shutdown) { + mCallback(ToAPI(wgpu::BufferMapAsyncStatus::InstanceDropped), mUserdata); + return; + } + + wgpu::BufferMapAsyncStatus status = wgpu::BufferMapAsyncStatus::Success; + Ref<MapAsyncEvent> pendingMapEvent; + + // Lock the buffer / early status. This may race with UnmapEarly which occurs + // when the buffer is unmapped or destroyed. + mBufferOrEarlyStatus.Use([&](auto bufferOrEarlyStatus) { + if (auto* earlyStatus = + std::get_if<wgpu::BufferMapAsyncStatus>(&*bufferOrEarlyStatus)) { + // Assign the early status, if it was set. + status = *earlyStatus; + } else if (auto** buffer = std::get_if<BufferBase*>(&*bufferOrEarlyStatus)) { + // Set the buffer state to Mapped if this pending map succeeded. + // TODO(crbug.com/dawn/831): in order to be thread safe, mutation of the + // state and pending map event needs to be atomic w.r.t. UnmapInternal. + DAWN_ASSERT((*buffer)->mState == BufferState::PendingMap); + (*buffer)->mState = BufferState::Mapped; + + pendingMapEvent = std::move((*buffer)->mPendingMapEvent); + } + }); + mCallback(ToAPI(status), mUserdata); + } + + // Set the buffer early status because it was unmapped early due to Unmap or Destroy. + // This can race with Complete such that the early status is ignored, but this is OK + // because we will still unmap the buffer. It will be as-if the application called + // Unmap/Destroy just after the map event completed. + void UnmapEarly(wgpu::BufferMapAsyncStatus status) override { + mBufferOrEarlyStatus.Use([&](auto bufferOrEarlyStatus) { *bufferOrEarlyStatus = status; }); + } +}; + +struct BufferBase::MapAsyncEvent2 final : public BufferBase::MapAsyncEvent { // MapAsyncEvent stores a raw pointer to the buffer so that it can update the buffer's map state // when it completes. If the map completes early (error, unmap, destroy), then the buffer is no // longer needed and we store the early status instead. The raw pointer is safe because the @@ -167,18 +294,18 @@ }; MutexProtected<std::variant<BufferBase*, BufferErrorData>> mBufferOrError; - WGPUBufferMapCallback mCallback; + WGPUBufferMapCallback2 mCallback; raw_ptr<void> mUserdata1; raw_ptr<void> mUserdata2; // Create an event backed by the given queue execution serial. - MapAsyncEvent(DeviceBase* device, - BufferBase* buffer, - const WGPUBufferMapCallbackInfo& callbackInfo, - ExecutionSerial serial) - : TrackedEvent(static_cast<wgpu::CallbackMode>(callbackInfo.mode), - device->GetQueue(), - serial), + MapAsyncEvent2(DeviceBase* device, + BufferBase* buffer, + const WGPUBufferMapCallbackInfo2& callbackInfo, + ExecutionSerial serial) + : MapAsyncEvent(static_cast<wgpu::CallbackMode>(callbackInfo.mode), + device->GetQueue(), + serial), mBufferOrError(buffer), mCallback(callbackInfo.callback), mUserdata1(callbackInfo.userdata1), @@ -188,13 +315,16 @@ } // Create an event that's ready at creation (for errors, etc.) - MapAsyncEvent(DeviceBase* device, - const WGPUBufferMapCallbackInfo& callbackInfo, - const std::string& message, - WGPUMapAsyncStatus status) - : TrackedEvent(static_cast<wgpu::CallbackMode>(callbackInfo.mode), - SystemEvent::CreateSignaled()), - mBufferOrError(BufferErrorData{status, message}), + MapAsyncEvent2(DeviceBase* device, + const WGPUBufferMapCallbackInfo2& callbackInfo, + const std::string& message, + WGPUBufferMapAsyncStatus status) + : MapAsyncEvent(static_cast<wgpu::CallbackMode>(callbackInfo.mode)), + mBufferOrError(BufferErrorData{ + status == WGPUBufferMapAsyncStatus_ValidationError ? WGPUMapAsyncStatus_Error + : status == WGPUBufferMapAsyncStatus_DeviceLost ? WGPUMapAsyncStatus_Aborted + : WGPUMapAsyncStatus_Unknown, + message}), mCallback(callbackInfo.callback), mUserdata1(callbackInfo.userdata1), mUserdata2(callbackInfo.userdata2) { @@ -202,7 +332,7 @@ uint64_t(kBeginningOfGPUTime)); } - ~MapAsyncEvent() override { EnsureComplete(EventCompletionType::Shutdown); } + ~MapAsyncEvent2() override { EnsureComplete(EventCompletionType::Shutdown); } void Complete(EventCompletionType completionType) override { if (const auto* queueAndSerial = std::get_if<QueueAndSerial>(&GetCompletionData())) { @@ -255,9 +385,21 @@ // This can race with Complete such that the early status is ignored, but this is OK // because we will still unmap the buffer. It will be as-if the application called // Unmap/Destroy just after the map event completed. - void UnmapEarly(WGPUMapAsyncStatus status, std::string_view message) { + void UnmapEarly(wgpu::BufferMapAsyncStatus status) override { + auto StatusToMessage = [](wgpu::BufferMapAsyncStatus status) { + switch (status) { + case wgpu::BufferMapAsyncStatus::DeviceLost: + return "Device was lost."; + case wgpu::BufferMapAsyncStatus::DestroyedBeforeCallback: + return "Buffer was destroyed before mapping was resolved."; + case wgpu::BufferMapAsyncStatus::UnmappedBeforeCallback: + return "Buffer was unmapped before mapping was resolved."; + default: + DAWN_UNREACHABLE(); + } + }; mBufferOrError.Use([&](auto bufferOrError) { - *bufferOrError = BufferErrorData{status, std::string(message)}; + *bufferOrError = BufferErrorData{WGPUMapAsyncStatus_Aborted, StatusToMessage(status)}; }); } }; @@ -368,14 +510,12 @@ // is implicitly destroyed. This case is thread-safe because there are no // other threads using the buffer since there are no other live refs. if (mState == BufferState::Mapped || mState == BufferState::PendingMap) { - UnmapInternal(WGPUMapAsyncStatus_Aborted, - "Buffer was destroyed before mapping was resolved."); + UnmapInternal(WGPUBufferMapAsyncStatus_DestroyedBeforeCallback); } else if (mState == BufferState::MappedAtCreation) { if (mStagingBuffer != nullptr) { mStagingBuffer = nullptr; } else if (mSize != 0) { - UnmapInternal(WGPUMapAsyncStatus_Aborted, - "Buffer was destroyed before mapping was resolved."); + UnmapInternal(WGPUBufferMapAsyncStatus_DestroyedBeforeCallback); } } @@ -529,10 +669,151 @@ DAWN_UNREACHABLE(); } -Future BufferBase::APIMapAsync(wgpu::MapMode mode, - size_t offset, - size_t size, - const WGPUBufferMapCallbackInfo& callbackInfo) { +std::function<void()> BufferBase::PrepareMappingCallback(MapRequestID mapID, + WGPUBufferMapAsyncStatus status) { + DAWN_ASSERT(!IsError()); + + if (mMapCallback != nullptr && mapID == mLastMapID) { + auto callback = std::move(mMapCallback); + void* userdata = std::move(mMapUserdata); + WGPUBufferMapAsyncStatus actualStatus; + if (GetDevice()->IsLost()) { + actualStatus = WGPUBufferMapAsyncStatus_DeviceLost; + } else { + actualStatus = status; + } + + // Tag the callback as fired before firing it, otherwise it could fire a second time if + // for example buffer.Unmap() is called before the MapRequestTask completes. + mMapCallback = nullptr; + mMapUserdata = nullptr; + + return std::bind(callback, actualStatus, userdata); + } + + return [] {}; +} + +void BufferBase::APIMapAsync(wgpu::MapMode mode, + size_t offset, + 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) { + if (callback) { + GetDevice()->GetCallbackTaskManager()->AddCallbackTask( + callback, WGPUBufferMapAsyncStatus_MappingAlreadyPending, userdata); + } + return; + } + + // Handle the defaulting of size required by WebGPU, even if in webgpu_cpp.h it is not + // possible to default the function argument (because there is the callback later in the + // argument list) + if ((size == wgpu::kWholeMapSize) && (offset <= mSize)) { + size = mSize - offset; + } + + WGPUBufferMapAsyncStatus status; + if (GetDevice()->ConsumedError(ValidateMapAsync(mode, offset, size, &status), + "calling %s.MapAsync(%s, %u, %u, ...).", this, mode, offset, + size)) { + if (callback) { + GetDevice()->GetCallbackTaskManager()->AddCallbackTask(callback, status, userdata); + } + return; + } + DAWN_ASSERT(!IsError()); + + mLastMapID++; + mMapMode = mode; + mMapOffset = offset; + mMapSize = size; + mMapCallback = callback; + mMapUserdata = userdata; + mState = BufferState::PendingMap; + + if (GetDevice()->ConsumedError(MapAsyncImpl(mode, offset, size))) { + GetDevice()->GetCallbackTaskManager()->AddCallbackTask( + PrepareMappingCallback(mLastMapID, WGPUBufferMapAsyncStatus_DeviceLost)); + return; + } + std::unique_ptr<MapRequestTask> request = + std::make_unique<MapRequestTask>(GetDevice()->GetPlatform(), this, mLastMapID); + TRACE_EVENT1(GetDevice()->GetPlatform(), General, "Buffer::APIMapAsync", "serial", + uint64_t(mLastUsageSerial)); + GetDevice()->GetQueue()->TrackTask(std::move(request), mLastUsageSerial); +} + +Future BufferBase::APIMapAsyncF(wgpu::MapMode mode, + 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); + + Ref<EventManager::TrackedEvent> event; + std::optional<wgpu::BufferMapAsyncStatus> earlyStatus; + { + // TODO(crbug.com/dawn/831) Manually acquire device lock instead of relying on code-gen for + // re-entrancy. + auto deviceLock(GetDevice()->GetScopedLock()); + + // Handle the defaulting of size required by WebGPU, even if in webgpu_cpp.h it is not + // possible to default the function argument (because there is the callback later in the + // argument list) + if ((size == wgpu::kWholeMapSize) && (offset <= mSize)) { + size = mSize - offset; + } + + earlyStatus = [&]() -> std::optional<wgpu::BufferMapAsyncStatus> { + if (mState == BufferState::PendingMap) { + return wgpu::BufferMapAsyncStatus::MappingAlreadyPending; + } + WGPUBufferMapAsyncStatus status; + if (GetDevice()->ConsumedError(ValidateMapAsync(mode, offset, size, &status), + "calling %s.MapAsync(%s, %u, %u, ...).", this, mode, + offset, size)) { + return static_cast<wgpu::BufferMapAsyncStatus>(status); + } + if (GetDevice()->ConsumedError(MapAsyncImpl(mode, offset, size))) { + return wgpu::BufferMapAsyncStatus::DeviceLost; + } + return std::nullopt; + }(); + + if (earlyStatus) { + event = AcquireRef(new MapAsyncEvent1(GetDevice(), callbackInfo, *earlyStatus)); + } else { + mMapMode = mode; + mMapOffset = offset; + mMapSize = size; + mState = BufferState::PendingMap; + mPendingMapEvent = + AcquireRef(new MapAsyncEvent1(GetDevice(), this, callbackInfo, mLastUsageSerial)); + event = mPendingMapEvent; + } + } + + FutureID futureID = GetInstance()->GetEventManager()->TrackEvent(std::move(event)); + return {futureID}; +} + +Future BufferBase::APIMapAsync2(wgpu::MapMode mode, + size_t offset, + size_t size, + const WGPUBufferMapCallbackInfo2& callbackInfo) { // 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); @@ -550,7 +831,7 @@ size = mSize - offset; } - WGPUMapAsyncStatus status = WGPUMapAsyncStatus_Error; + WGPUBufferMapAsyncStatus status = WGPUBufferMapAsyncStatus_ValidationError; MaybeError maybeError = [&]() -> MaybeError { DAWN_INVALID_IF(mState == BufferState::PendingMap, "%s already has an outstanding map pending.", this); @@ -562,7 +843,7 @@ if (maybeError.IsError()) { auto error = maybeError.AcquireError(); event = AcquireRef( - new MapAsyncEvent(GetDevice(), callbackInfo, error->GetMessage(), status)); + new MapAsyncEvent2(GetDevice(), callbackInfo, error->GetMessage(), status)); [[maybe_unused]] bool hadError = GetDevice()->ConsumedError( std::move(error), "calling %s.MapAsync(%s, %u, %u, ...).", this, mode, offset, size); @@ -572,7 +853,7 @@ mMapSize = size; mState = BufferState::PendingMap; mPendingMapEvent = - AcquireRef(new MapAsyncEvent(GetDevice(), this, callbackInfo, mLastUsageSerial)); + AcquireRef(new MapAsyncEvent2(GetDevice(), this, callbackInfo, mLastUsageSerial)); event = mPendingMapEvent; } } @@ -640,18 +921,23 @@ if (mState == BufferState::MappedAtCreation && mStagingBuffer != nullptr) { DAWN_TRY(CopyFromStagingBuffer()); } - UnmapInternal(WGPUMapAsyncStatus_Aborted, "Buffer was unmapped before mapping was resolved."); + UnmapInternal(WGPUBufferMapAsyncStatus_UnmappedBeforeCallback); return {}; } -void BufferBase::UnmapInternal(WGPUMapAsyncStatus status, std::string_view message) { +void BufferBase::UnmapInternal(WGPUBufferMapAsyncStatus callbackStatus) { // Unmaps resources on the backend. if (mState == BufferState::PendingMap) { // TODO(crbug.com/dawn/831): in order to be thread safe, mutation of the // state and pending map event needs to be atomic w.r.t. MapAsyncEvent::Complete. Ref<MapAsyncEvent> pendingMapEvent = std::move(mPendingMapEvent); - pendingMapEvent->UnmapEarly(status, message); - GetInstance()->GetEventManager()->SetFutureReady(pendingMapEvent.Get()); + if (pendingMapEvent != nullptr) { + pendingMapEvent->UnmapEarly(static_cast<wgpu::BufferMapAsyncStatus>(callbackStatus)); + GetInstance()->GetEventManager()->SetFutureReady(pendingMapEvent.Get()); + } else { + GetDevice()->GetCallbackTaskManager()->AddCallbackTask( + PrepareMappingCallback(mLastMapID, callbackStatus)); + } UnmapImpl(); } else if (mState == BufferState::Mapped) { UnmapImpl(); @@ -667,11 +953,11 @@ MaybeError BufferBase::ValidateMapAsync(wgpu::MapMode mode, size_t offset, size_t size, - WGPUMapAsyncStatus* status) const { - *status = WGPUMapAsyncStatus_Aborted; + WGPUBufferMapAsyncStatus* status) const { + *status = WGPUBufferMapAsyncStatus_DeviceLost; DAWN_TRY(GetDevice()->ValidateIsAlive()); - *status = WGPUMapAsyncStatus_Error; + *status = WGPUBufferMapAsyncStatus_ValidationError; DAWN_TRY(GetDevice()->ValidateObject(this)); DAWN_INVALID_IF(uint64_t(offset) > mSize, @@ -716,7 +1002,7 @@ wgpu::BufferUsage::MapWrite); } - *status = WGPUMapAsyncStatus_Success; + *status = WGPUBufferMapAsyncStatus_Success; return {}; } @@ -775,6 +1061,22 @@ return {}; } +void BufferBase::CallbackOnMapRequestCompleted(MapRequestID mapID, + WGPUBufferMapAsyncStatus status) { + { + // This is called from a callback, and no lock will be held by default. Hence, we need to + // lock the mutex now because this will modify the buffer's states. + auto deviceLock(GetDevice()->GetScopedLock()); + if (mapID == mLastMapID && status == WGPUBufferMapAsyncStatus_Success && + mState == BufferState::PendingMap) { + mState = BufferState::Mapped; + } + } + + auto cb = PrepareMappingCallback(mapID, status); + cb(); +} + bool BufferBase::NeedsInitialization() const { return !mIsDataInitialized && GetDevice()->IsToggleEnabled(Toggle::LazyClearResourceOnFirstUse); }
diff --git a/src/dawn/native/Buffer.h b/src/dawn/native/Buffer.h index cc7d3d6..7f130e6 100644 --- a/src/dawn/native/Buffer.h +++ b/src/dawn/native/Buffer.h
@@ -95,6 +95,7 @@ wgpu::BufferUsage GetUsage() const; MaybeError MapAtCreation(); + void CallbackOnMapRequestCompleted(MapRequestID mapID, WGPUBufferMapAsyncStatus status); MaybeError ValidateCanUseOnQueueNow() const; @@ -118,10 +119,19 @@ void DumpMemoryStatistics(dawn::native::MemoryDump* dump, const char* prefix) const; // Dawn API - Future APIMapAsync(wgpu::MapMode mode, - size_t offset, - size_t size, - const WGPUBufferMapCallbackInfo& callbackInfo); + void APIMapAsync(wgpu::MapMode mode, + size_t offset, + size_t size, + WGPUBufferMapCallback callback, + void* userdata); + Future APIMapAsyncF(wgpu::MapMode mode, + size_t offset, + size_t size, + const BufferMapCallbackInfo& callbackInfo); + Future APIMapAsync2(wgpu::MapMode mode, + size_t offset, + size_t size, + const WGPUBufferMapCallbackInfo2& callbackInfo); void* APIGetMappedRange(size_t offset, size_t size); const void* APIGetConstMappedRange(size_t offset, size_t size); void APIUnmap(); @@ -145,6 +155,9 @@ ExecutionSerial mLastUsageSerial = ExecutionSerial(0); private: + std::function<void()> PrepareMappingCallback(MapRequestID mapID, + WGPUBufferMapAsyncStatus status); + virtual MaybeError MapAtCreationImpl() = 0; virtual MaybeError MapAsyncImpl(wgpu::MapMode mode, size_t offset, size_t size) = 0; virtual void UnmapImpl() = 0; @@ -155,10 +168,10 @@ MaybeError ValidateMapAsync(wgpu::MapMode mode, size_t offset, size_t size, - WGPUMapAsyncStatus* status) const; + WGPUBufferMapAsyncStatus* status) const; MaybeError ValidateUnmap() const; bool CanGetMappedRange(bool writable, size_t offset, size_t size) const; - void UnmapInternal(WGPUMapAsyncStatus status, std::string_view message); + void UnmapInternal(WGPUBufferMapAsyncStatus callbackStatus); const uint64_t mSize = 0; const wgpu::BufferUsage mUsage = wgpu::BufferUsage::None; @@ -174,11 +187,16 @@ // i.e. buffer->mStagingBuffer->mStagingBuffer... is not possible. Ref<BufferBase> mStagingBuffer; + WGPUBufferMapCallback mMapCallback = nullptr; + raw_ptr<void> mMapUserdata = nullptr; + MapRequestID mLastMapID = MapRequestID(0); wgpu::MapMode mMapMode = wgpu::MapMode::None; size_t mMapOffset = 0; size_t mMapSize = 0; struct MapAsyncEvent; + struct MapAsyncEvent1; + struct MapAsyncEvent2; Ref<MapAsyncEvent> mPendingMapEvent; };
diff --git a/src/dawn/native/CreatePipelineAsyncEvent.cpp b/src/dawn/native/CreatePipelineAsyncEvent.cpp index 4b79627..854c7ff 100644 --- a/src/dawn/native/CreatePipelineAsyncEvent.cpp +++ b/src/dawn/native/CreatePipelineAsyncEvent.cpp
@@ -54,15 +54,15 @@ template <> const char* CreatePipelineAsyncEvent< ComputePipelineBase, - WGPUCreateComputePipelineAsyncCallbackInfo>::kDawnHistogramMetricsSuccess = + WGPUCreateComputePipelineAsyncCallbackInfo2>::kDawnHistogramMetricsSuccess = "CreateComputePipelineSuccess"; template <> const char* CreatePipelineAsyncEvent<ComputePipelineBase, - WGPUCreateComputePipelineAsyncCallbackInfo>::kDawnHistogramMetricsUS = + WGPUCreateComputePipelineAsyncCallbackInfo2>::kDawnHistogramMetricsUS = "CreateComputePipelineUS"; template <> -void CreatePipelineAsyncEvent<ComputePipelineBase, WGPUCreateComputePipelineAsyncCallbackInfo>:: +void CreatePipelineAsyncEvent<ComputePipelineBase, WGPUCreateComputePipelineAsyncCallbackInfo2>:: AddOrGetCachedPipeline() { DeviceBase* device = mPipeline->GetDevice(); auto deviceLock(device->GetScopedLock()); @@ -74,16 +74,16 @@ template <> const char* CreatePipelineAsyncEvent< RenderPipelineBase, - WGPUCreateRenderPipelineAsyncCallbackInfo>::kDawnHistogramMetricsSuccess = + WGPUCreateRenderPipelineAsyncCallbackInfo2>::kDawnHistogramMetricsSuccess = "CreateRenderPipelineSuccess"; template <> const char* CreatePipelineAsyncEvent<RenderPipelineBase, - WGPUCreateRenderPipelineAsyncCallbackInfo>::kDawnHistogramMetricsUS = + WGPUCreateRenderPipelineAsyncCallbackInfo2>::kDawnHistogramMetricsUS = "CreateRenderPipelineUS"; template <> -void CreatePipelineAsyncEvent<RenderPipelineBase, - WGPUCreateRenderPipelineAsyncCallbackInfo>::AddOrGetCachedPipeline() { +void CreatePipelineAsyncEvent<RenderPipelineBase, WGPUCreateRenderPipelineAsyncCallbackInfo2>:: + AddOrGetCachedPipeline() { DeviceBase* device = mPipeline->GetDevice(); auto deviceLock(device->GetScopedLock()); if (device->GetState() == DeviceBase::State::Alive) { @@ -234,8 +234,8 @@ } template class CreatePipelineAsyncEvent<ComputePipelineBase, - WGPUCreateComputePipelineAsyncCallbackInfo>; + WGPUCreateComputePipelineAsyncCallbackInfo2>; template class CreatePipelineAsyncEvent<RenderPipelineBase, - WGPUCreateRenderPipelineAsyncCallbackInfo>; + WGPUCreateRenderPipelineAsyncCallbackInfo2>; } // namespace dawn::native
diff --git a/src/dawn/native/CreatePipelineAsyncEvent.h b/src/dawn/native/CreatePipelineAsyncEvent.h index b2fefa6..e2ae039 100644 --- a/src/dawn/native/CreatePipelineAsyncEvent.h +++ b/src/dawn/native/CreatePipelineAsyncEvent.h
@@ -103,9 +103,9 @@ }; using CreateComputePipelineAsyncEvent = - CreatePipelineAsyncEvent<ComputePipelineBase, WGPUCreateComputePipelineAsyncCallbackInfo>; + CreatePipelineAsyncEvent<ComputePipelineBase, WGPUCreateComputePipelineAsyncCallbackInfo2>; using CreateRenderPipelineAsyncEvent = - CreatePipelineAsyncEvent<RenderPipelineBase, WGPUCreateRenderPipelineAsyncCallbackInfo>; + CreatePipelineAsyncEvent<RenderPipelineBase, WGPUCreateRenderPipelineAsyncCallbackInfo2>; } // namespace dawn::native
diff --git a/src/dawn/native/Device.cpp b/src/dawn/native/Device.cpp index 8c7209f..316b6b1 100644 --- a/src/dawn/native/Device.cpp +++ b/src/dawn/native/Device.cpp
@@ -852,21 +852,45 @@ mErrorScopeStack->Push(filter); } -Future DeviceBase::APIPopErrorScope(const WGPUPopErrorScopeCallbackInfo& callbackInfo) { +void DeviceBase::APIPopErrorScope(wgpu::ErrorCallback callback, void* userdata) { + static wgpu::ErrorCallback kDefaultCallback = [](WGPUErrorType, WGPUStringView, void*) {}; + + APIPopErrorScope2({nullptr, WGPUCallbackMode_AllowProcessEvents, + [](WGPUPopErrorScopeStatus, WGPUErrorType type, WGPUStringView message, + void* callback, void* userdata) { + auto cb = reinterpret_cast<wgpu::ErrorCallback>(callback); + cb(type, message, userdata); + }, + reinterpret_cast<void*>(callback != nullptr ? callback : kDefaultCallback), + userdata}); +} + +Future DeviceBase::APIPopErrorScopeF(const PopErrorScopeCallbackInfo& callbackInfo) { + return APIPopErrorScope2({ToAPI(callbackInfo.nextInChain), ToAPI(callbackInfo.mode), + [](WGPUPopErrorScopeStatus status, WGPUErrorType type, + WGPUStringView message, void* callback, void* userdata) { + auto cb = reinterpret_cast<WGPUPopErrorScopeCallback>(callback); + cb(status, type, message, userdata); + }, + reinterpret_cast<void*>(callbackInfo.callback), + callbackInfo.userdata}); +} + +Future DeviceBase::APIPopErrorScope2(const WGPUPopErrorScopeCallbackInfo2& callbackInfo) { struct PopErrorScopeEvent final : public EventManager::TrackedEvent { - WGPUPopErrorScopeCallback mCallback; + WGPUPopErrorScopeCallback2 mCallback; raw_ptr<void> mUserdata1; raw_ptr<void> mUserdata2; std::optional<ErrorScope> mScope; - PopErrorScopeEvent(const WGPUPopErrorScopeCallbackInfo& callbackInfo, + PopErrorScopeEvent(const WGPUPopErrorScopeCallbackInfo2& callbackInfo, std::optional<ErrorScope>&& scope) : TrackedEvent(static_cast<wgpu::CallbackMode>(callbackInfo.mode), TrackedEvent::Completed{}), mCallback(callbackInfo.callback), mUserdata1(callbackInfo.userdata1), mUserdata2(callbackInfo.userdata2), - mScope(std::move(scope)) {} + mScope(scope) {} ~PopErrorScopeEvent() override { EnsureComplete(EventCompletionType::Shutdown); } @@ -1326,9 +1350,42 @@ } return ReturnToAPI(std::move(result)); } -Future DeviceBase::APICreateComputePipelineAsync( +void DeviceBase::APICreateComputePipelineAsync(const ComputePipelineDescriptor* descriptor, + WGPUCreateComputePipelineAsyncCallback callback, + void* userdata) { + GetInstance()->EmitDeprecationWarning( + "Old CreateComputePipelineAsync APIs are deprecated. If using C please pass a CallbackInfo " + "struct that has two userdatas. Otherwise, if using C++, please use templated helpers."); + + APICreateComputePipelineAsync2( + descriptor, {nullptr, WGPUCallbackMode_AllowProcessEvents, + [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline pipeline, + WGPUStringView message, void* callback, void* userdata) { + auto cb = + reinterpret_cast<WGPUCreateComputePipelineAsyncCallback>(callback); + cb(status, pipeline, message, userdata); + }, + reinterpret_cast<void*>(callback), userdata}); +} +Future DeviceBase::APICreateComputePipelineAsyncF( const ComputePipelineDescriptor* descriptor, - const WGPUCreateComputePipelineAsyncCallbackInfo& callbackInfo) { + const CreateComputePipelineAsyncCallbackInfo& callbackInfo) { + GetInstance()->EmitDeprecationWarning( + "Old CreateComputePipelineAsync APIs are deprecated. If using C please pass a CallbackInfo " + "struct that has two userdatas. Otherwise, if using C++, please use templated helpers."); + return APICreateComputePipelineAsync2( + descriptor, {ToAPI(callbackInfo.nextInChain), ToAPI(callbackInfo.mode), + [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline pipeline, + WGPUStringView message, void* callback, void* userdata) { + auto cb = + reinterpret_cast<WGPUCreateComputePipelineAsyncCallback>(callback); + cb(status, pipeline, message, userdata); + }, + reinterpret_cast<void*>(callbackInfo.callback), callbackInfo.userdata}); +} +Future DeviceBase::APICreateComputePipelineAsync2( + const ComputePipelineDescriptor* descriptor, + const WGPUCreateComputePipelineAsyncCallbackInfo2& callbackInfo) { utils::TraceLabel label = utils::GetLabelForTrace(descriptor->label); TRACE_EVENT1(GetPlatform(), General, "DeviceBase::APICreateComputePipelineAsync", "label", label.label); @@ -1395,9 +1452,42 @@ } return ReturnToAPI(std::move(result)); } -Future DeviceBase::APICreateRenderPipelineAsync( +void DeviceBase::APICreateRenderPipelineAsync(const RenderPipelineDescriptor* descriptor, + WGPUCreateRenderPipelineAsyncCallback callback, + void* userdata) { + GetInstance()->EmitDeprecationWarning( + "Old CreateRenderPipelineAsync APIs are deprecated. If using C please pass a CallbackInfo " + "struct that has two userdatas. Otherwise, if using C++, please use templated helpers."); + + APICreateRenderPipelineAsync2( + descriptor, {nullptr, WGPUCallbackMode_AllowProcessEvents, + [](WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline pipeline, + WGPUStringView message, void* callback, void* userdata) { + auto cb = + reinterpret_cast<WGPUCreateRenderPipelineAsyncCallback>(callback); + cb(status, pipeline, message, userdata); + }, + reinterpret_cast<void*>(callback), userdata}); +} +Future DeviceBase::APICreateRenderPipelineAsyncF( const RenderPipelineDescriptor* descriptor, - const WGPUCreateRenderPipelineAsyncCallbackInfo& callbackInfo) { + const CreateRenderPipelineAsyncCallbackInfo& callbackInfo) { + GetInstance()->EmitDeprecationWarning( + "Old CreateRenderPipelineAsync APIs are deprecated. If using C please pass a CallbackInfo " + "struct that has two userdatas. Otherwise, if using C++, please use templated helpers."); + return APICreateRenderPipelineAsync2( + descriptor, {ToAPI(callbackInfo.nextInChain), ToAPI(callbackInfo.mode), + [](WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline pipeline, + WGPUStringView message, void* callback, void* userdata) { + auto cb = + reinterpret_cast<WGPUCreateRenderPipelineAsyncCallback>(callback); + cb(status, pipeline, message, userdata); + }, + reinterpret_cast<void*>(callbackInfo.callback), callbackInfo.userdata}); +} +Future DeviceBase::APICreateRenderPipelineAsync2( + const RenderPipelineDescriptor* descriptor, + const WGPUCreateRenderPipelineAsyncCallbackInfo2& callbackInfo) { utils::TraceLabel label = utils::GetLabelForTrace(descriptor->label); TRACE_EVENT1(GetPlatform(), General, "DeviceBase::APICreateRenderPipelineAsync", "label", label.label);
diff --git a/src/dawn/native/Device.h b/src/dawn/native/Device.h index b6b6d8d..f0275b1 100644 --- a/src/dawn/native/Device.h +++ b/src/dawn/native/Device.h
@@ -242,12 +242,23 @@ ComputePipelineBase* APICreateComputePipeline(const ComputePipelineDescriptor* descriptor); PipelineLayoutBase* APICreatePipelineLayout(const PipelineLayoutDescriptor* descriptor); QuerySetBase* APICreateQuerySet(const QuerySetDescriptor* descriptor); - Future APICreateComputePipelineAsync( + void APICreateComputePipelineAsync(const ComputePipelineDescriptor* descriptor, + WGPUCreateComputePipelineAsyncCallback callback, + void* userdata); + Future APICreateComputePipelineAsyncF( const ComputePipelineDescriptor* descriptor, - const WGPUCreateComputePipelineAsyncCallbackInfo& callbackInfo); - Future APICreateRenderPipelineAsync( + const CreateComputePipelineAsyncCallbackInfo& callbackInfo); + Future APICreateComputePipelineAsync2( + const ComputePipelineDescriptor* descriptor, + const WGPUCreateComputePipelineAsyncCallbackInfo2& callbackInfo); + void APICreateRenderPipelineAsync(const RenderPipelineDescriptor* descriptor, + WGPUCreateRenderPipelineAsyncCallback callback, + void* userdata); + Future APICreateRenderPipelineAsyncF(const RenderPipelineDescriptor* descriptor, + const CreateRenderPipelineAsyncCallbackInfo& callbackInfo); + Future APICreateRenderPipelineAsync2( const RenderPipelineDescriptor* descriptor, - const WGPUCreateRenderPipelineAsyncCallbackInfo& callbackInfo); + const WGPUCreateRenderPipelineAsyncCallbackInfo2& callbackInfo); RenderBundleEncoder* APICreateRenderBundleEncoder( const RenderBundleEncoderDescriptor* descriptor); RenderPipelineBase* APICreateRenderPipeline(const RenderPipelineDescriptor* descriptor); @@ -289,7 +300,9 @@ void APISetUncapturedErrorCallback(wgpu::ErrorCallback callback, void* userdata); void APISetLoggingCallback(wgpu::LoggingCallback callback, void* userdata); void APIPushErrorScope(wgpu::ErrorFilter filter); - Future APIPopErrorScope(const WGPUPopErrorScopeCallbackInfo& callbackInfo); + void APIPopErrorScope(wgpu::ErrorCallback callback, void* userdata); + Future APIPopErrorScopeF(const PopErrorScopeCallbackInfo& callbackInfo); + Future APIPopErrorScope2(const WGPUPopErrorScopeCallbackInfo2& callbackInfo); MaybeError ValidateIsAlive() const;
diff --git a/src/dawn/native/Queue.cpp b/src/dawn/native/Queue.cpp index 5f47ca8..cc8ef36 100644 --- a/src/dawn/native/Queue.cpp +++ b/src/dawn/native/Queue.cpp
@@ -155,6 +155,33 @@ return uploadHandle; } +struct SubmittedWorkDone : TrackTaskCallback { + SubmittedWorkDone(dawn::platform::Platform* platform, + WGPUQueueWorkDoneCallback callback, + void* userdata) + : TrackTaskCallback(platform), mCallback(callback), mUserdata(userdata) {} + ~SubmittedWorkDone() override = default; + + private: + void FinishImpl() override { + DAWN_ASSERT(mCallback != nullptr); + DAWN_ASSERT(mSerial != kMaxExecutionSerial); + TRACE_EVENT1(mPlatform, General, "Queue::SubmittedWorkDone::Finished", "serial", + uint64_t(mSerial)); + mCallback(WGPUQueueWorkDoneStatus_Success, mUserdata.ExtractAsDangling()); + mCallback = nullptr; + } + void HandleDeviceLossImpl() override { + DAWN_ASSERT(mCallback != nullptr); + mCallback(WGPUQueueWorkDoneStatus_DeviceLost, mUserdata.ExtractAsDangling()); + mCallback = nullptr; + } + void HandleShutDownImpl() override { HandleDeviceLossImpl(); } + + WGPUQueueWorkDoneCallback mCallback = nullptr; + raw_ptr<void> mUserdata; +}; + class ErrorQueue : public QueueBase { public: explicit ErrorQueue(DeviceBase* device, StringView label) @@ -230,15 +257,55 @@ ityp::span<uint32_t, CommandBufferBase* const>(commands, commandCount)); } -Future QueueBase::APIOnSubmittedWorkDone(const WGPUQueueWorkDoneCallbackInfo& callbackInfo) { +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))) { + GetDevice()->GetCallbackTaskManager()->AddCallbackTask( + [callback, status, userdata] { callback(ToAPI(status), userdata); }); + return; + } + + std::unique_ptr<SubmittedWorkDone> task = + std::make_unique<SubmittedWorkDone>(GetDevice()->GetPlatform(), callback, userdata); + + // Technically we only need to wait for previously submitted work but OnSubmittedWorkDone is + // also used to make sure ALL queue work is finished in tests, so we also wait for pending + // commands (this is non-observable outside of tests so it's ok to do deviate a bit from the + // spec). + TrackTaskAfterEventualFlush(std::move(task)); + + TRACE_EVENT1(GetDevice()->GetPlatform(), General, "Queue::APIOnSubmittedWorkDone", "serial", + uint64_t(GetPendingCommandSerial())); +} + +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) { + auto cb = reinterpret_cast<WGPUQueueWorkDoneCallback>(callback); + cb(status, userdata); + }, + reinterpret_cast<void*>(callbackInfo.callback), callbackInfo.userdata}); +} + +Future QueueBase::APIOnSubmittedWorkDone2(const WGPUQueueWorkDoneCallbackInfo2& callbackInfo) { struct WorkDoneEvent final : public EventManager::TrackedEvent { std::optional<WGPUQueueWorkDoneStatus> mEarlyStatus; - WGPUQueueWorkDoneCallback mCallback; + WGPUQueueWorkDoneCallback2 mCallback; raw_ptr<void> mUserdata1; raw_ptr<void> mUserdata2; // Create an event backed by the given queue execution serial. - WorkDoneEvent(const WGPUQueueWorkDoneCallbackInfo& callbackInfo, + WorkDoneEvent(const WGPUQueueWorkDoneCallbackInfo2& callbackInfo, QueueBase* queue, ExecutionSerial serial) : TrackedEvent(static_cast<wgpu::CallbackMode>(callbackInfo.mode), queue, serial), @@ -247,7 +314,7 @@ mUserdata2(callbackInfo.userdata2) {} // Create an event that's ready at creation (for errors, etc.) - WorkDoneEvent(const WGPUQueueWorkDoneCallbackInfo& callbackInfo, + WorkDoneEvent(const WGPUQueueWorkDoneCallbackInfo2& callbackInfo, QueueBase* queue, wgpu::QueueWorkDoneStatus earlyStatus) : TrackedEvent(static_cast<wgpu::CallbackMode>(callbackInfo.mode), @@ -283,8 +350,15 @@ // re-entrancy. auto deviceLock(GetDevice()->GetScopedLock()); - wgpu::QueueWorkDoneStatus validationEarlyStatus = wgpu::QueueWorkDoneStatus::Success; + wgpu::QueueWorkDoneStatus validationEarlyStatus; if (GetDevice()->ConsumedError(ValidateOnSubmittedWorkDone(&validationEarlyStatus))) { + // TODO(crbug.com/dawn/2021): This is here to pretend that things succeed when the + // device is lost. When the old OnSubmittedWorkDone is removed then we can update + // ValidateOnSubmittedWorkDone to just return the correct thing here. + if (validationEarlyStatus == wgpu::QueueWorkDoneStatus::DeviceLost) { + validationEarlyStatus = wgpu::QueueWorkDoneStatus::Success; + } + // Note: if the callback is spontaneous, it'll get called in here. event = AcquireRef(new WorkDoneEvent(callbackInfo, this, validationEarlyStatus)); } else { @@ -567,6 +641,7 @@ } MaybeError QueueBase::ValidateOnSubmittedWorkDone(wgpu::QueueWorkDoneStatus* status) const { + *status = wgpu::QueueWorkDoneStatus::DeviceLost; DAWN_TRY(GetDevice()->ValidateIsAlive()); *status = wgpu::QueueWorkDoneStatus::Error;
diff --git a/src/dawn/native/Queue.h b/src/dawn/native/Queue.h index 71dcdcd..36ec006 100644 --- a/src/dawn/native/Queue.h +++ b/src/dawn/native/Queue.h
@@ -73,7 +73,9 @@ // Dawn API void APISubmit(uint32_t commandCount, CommandBufferBase* const* commands); - Future APIOnSubmittedWorkDone(const WGPUQueueWorkDoneCallbackInfo& callbackInfo); + void APIOnSubmittedWorkDone(WGPUQueueWorkDoneCallback callback, void* userdata); + Future APIOnSubmittedWorkDoneF(const QueueWorkDoneCallbackInfo& callbackInfo); + Future APIOnSubmittedWorkDone2(const WGPUQueueWorkDoneCallbackInfo2& callbackInfo); void APIWriteBuffer(BufferBase* buffer, uint64_t bufferOffset, const void* data, size_t size); void APIWriteTexture(const ImageCopyTexture* destination, const void* data,
diff --git a/src/dawn/native/ShaderModule.cpp b/src/dawn/native/ShaderModule.cpp index 9d47730..97b3129 100644 --- a/src/dawn/native/ShaderModule.cpp +++ b/src/dawn/native/ShaderModule.cpp
@@ -1584,17 +1584,58 @@ return mTintData.Use([&](auto tintData) { return tintData->tintProgramRecreateCount; }); } -Future ShaderModuleBase::APIGetCompilationInfo( - const WGPUCompilationInfoCallbackInfo& callbackInfo) { +namespace { + +void DefaultGetCompilationInfoCallback(WGPUCompilationInfoRequestStatus status, + const WGPUCompilationInfo* compilationInfo, + void* callback, + void* userdata) { + if (callback == nullptr) { + DAWN_ASSERT(userdata == nullptr); + return; + } + auto cb = reinterpret_cast<WGPUCompilationInfoCallback>(callback); + cb(status, compilationInfo, userdata); +} + +} // anonymous namespace + +void ShaderModuleBase::APIGetCompilationInfo(wgpu::CompilationInfoCallback callback, + void* userdata) { + GetInstance()->EmitDeprecationWarning( + "Old GetCompilationInfo APIs are deprecated. If using C please pass a CallbackInfo struct " + "that has two userdatas. Otherwise, if using C++, please use templated helpers."); + + if (callback == nullptr) { + return; + } + APIGetCompilationInfo2({nullptr, WGPUCallbackMode_AllowSpontaneous, + &DefaultGetCompilationInfoCallback, reinterpret_cast<void*>(callback), + userdata}); +} + +Future ShaderModuleBase::APIGetCompilationInfoF(const CompilationInfoCallbackInfo& callbackInfo) { + GetInstance()->EmitDeprecationWarning( + "Old GetCompilationInfo APIs are deprecated. If using C please pass a CallbackInfo struct " + "that has two userdatas. Otherwise, if using C++, please use templated helpers."); + + return APIGetCompilationInfo2({ToAPI(callbackInfo.nextInChain), ToAPI(callbackInfo.mode), + &DefaultGetCompilationInfoCallback, + reinterpret_cast<void*>(callbackInfo.callback), + callbackInfo.userdata}); +} + +Future ShaderModuleBase::APIGetCompilationInfo2( + const WGPUCompilationInfoCallbackInfo2& callbackInfo) { struct CompilationInfoEvent final : public EventManager::TrackedEvent { - WGPUCompilationInfoCallback mCallback; + WGPUCompilationInfoCallback2 mCallback; raw_ptr<void> mUserdata1; raw_ptr<void> mUserdata2; // Need to keep a Ref of the compilation messages in case the ShaderModule goes away before // the callback happens. Ref<ShaderModuleBase> mShaderModule; - CompilationInfoEvent(const WGPUCompilationInfoCallbackInfo& callbackInfo, + CompilationInfoEvent(const WGPUCompilationInfoCallbackInfo2& callbackInfo, Ref<ShaderModuleBase> shaderModule) : TrackedEvent(static_cast<wgpu::CallbackMode>(callbackInfo.mode), TrackedEvent::Completed{}),
diff --git a/src/dawn/native/ShaderModule.h b/src/dawn/native/ShaderModule.h index 9ae9217..3d371c8 100644 --- a/src/dawn/native/ShaderModule.h +++ b/src/dawn/native/ShaderModule.h
@@ -348,7 +348,9 @@ Ref<TintProgram> GetTintProgramForTesting() const; int GetTintProgramRecreateCountForTesting() const; - Future APIGetCompilationInfo(const WGPUCompilationInfoCallbackInfo& callbackInfo); + void APIGetCompilationInfo(wgpu::CompilationInfoCallback callback, void* userdata); + Future APIGetCompilationInfoF(const CompilationInfoCallbackInfo& callbackInfo); + Future APIGetCompilationInfo2(const WGPUCompilationInfoCallbackInfo2& callbackInfo); void InjectCompilationMessages(std::unique_ptr<OwnedCompilationMessages> compilationMessages); OwnedCompilationMessages* GetCompilationMessages() const;
diff --git a/src/dawn/tests/end2end/BufferTests.cpp b/src/dawn/tests/end2end/BufferTests.cpp index bfa76f1..5f79c9a 100644 --- a/src/dawn/tests/end2end/BufferTests.cpp +++ b/src/dawn/tests/end2end/BufferTests.cpp
@@ -48,7 +48,7 @@ using testing::MockCppCallback; using testing::StrictMock; -using MockMapAsyncCallback = MockCppCallback<wgpu::BufferMapCallback<void>*>; +using MockMapAsyncCallback = MockCppCallback<wgpu::BufferMapCallback2<void>*>; using FutureCallbackMode = wgpu::CallbackMode; DAWN_TEST_PARAM_STRUCT(BufferMappingTestParams, FutureCallbackMode); @@ -66,7 +66,7 @@ wgpu::MapMode mode, size_t offset, size_t size, - wgpu::BufferMapCallback<> cb = nullptr) { + wgpu::BufferMapCallback2<> cb = nullptr) { wgpu::Future future; if (cb) {
diff --git a/src/dawn/tests/end2end/DeviceLostTests.cpp b/src/dawn/tests/end2end/DeviceLostTests.cpp index 6d0b5f7..ddb6eb3 100644 --- a/src/dawn/tests/end2end/DeviceLostTests.cpp +++ b/src/dawn/tests/end2end/DeviceLostTests.cpp
@@ -44,8 +44,10 @@ using testing::HasSubstr; using testing::MockCppCallback; -using MockMapAsyncCallback = MockCppCallback<wgpu::BufferMapCallback<void>*>; -using MockQueueWorkDoneCallback = MockCppCallback<wgpu::QueueWorkDoneCallback<void>*>; +using MockMapAsyncCallback = MockCppCallback<void (*)(wgpu::MapAsyncStatus, wgpu::StringView)>; +using MockQueueWorkDoneCallback = MockCppCallback<void (*)(wgpu::QueueWorkDoneStatus)>; + +static const int fakeUserData = 0; class DeviceLostTest : public DawnTest { protected: @@ -61,6 +63,11 @@ } } + static void MapFailCallback(WGPUBufferMapAsyncStatus status, void* userdata) { + EXPECT_EQ(WGPUBufferMapAsyncStatus_DeviceLost, status); + EXPECT_EQ(&fakeUserData, userdata); + } + template <typename T> void ExpectObjectIsError(const T& object) { EXPECT_TRUE(dawn::native::CheckIsErrorForTesting(object.Get()));
diff --git a/src/dawn/tests/unittests/native/AllowedErrorTests.cpp b/src/dawn/tests/unittests/native/AllowedErrorTests.cpp index b9ac911..dbbc373 100644 --- a/src/dawn/tests/unittests/native/AllowedErrorTests.cpp +++ b/src/dawn/tests/unittests/native/AllowedErrorTests.cpp
@@ -59,9 +59,9 @@ using ::testing::Test; using MockComputePipelineAsyncCallback = - MockCppCallback<wgpu::CreateComputePipelineAsyncCallback<void>*>; + MockCppCallback<wgpu::CreateComputePipelineAsyncCallback2<void>*>; using MockRenderPipelineAsyncCallback = - MockCppCallback<wgpu::CreateRenderPipelineAsyncCallback<void>*>; + MockCppCallback<wgpu::CreateRenderPipelineAsyncCallback2<void>*>; static constexpr char kOomErrorMessage[] = "Out of memory error"; static constexpr char kInternalErrorMessage[] = "Internal error";
diff --git a/src/dawn/tests/unittests/wire/WireBufferMappingTests.cpp b/src/dawn/tests/unittests/wire/WireBufferMappingTests.cpp index f11b748..d301be3 100644 --- a/src/dawn/tests/unittests/wire/WireBufferMappingTests.cpp +++ b/src/dawn/tests/unittests/wire/WireBufferMappingTests.cpp
@@ -69,7 +69,7 @@ DAWN_WIRE_FUTURE_TEST_PARAM_STRUCT(WireBufferParam, MapMode); using WireBufferMappingTestBase = - WireFutureTestWithParams<wgpu::BufferMapCallback<void>*, WireBufferParam>; + WireFutureTestWithParams<wgpu::BufferMapCallback2<void>*, WireBufferParam>; // General mapping tests that either do not care about the specific mapping mode, or apply to both. class WireBufferMappingTests : public WireBufferMappingTestBase { @@ -146,10 +146,10 @@ uint32_t bufferContent = 31337; EXPECT_CALL( - api, OnBufferMapAsync(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) + api, OnBufferMapAsync2(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Success, - kEmptyOutputStringView); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Success, + kEmptyOutputStringView); })); ExpectMappedRangeCall(kBufferSize, &bufferContent); addExpectations(); @@ -188,10 +188,10 @@ MapAsync(mapMode, 0, kBufferSize); EXPECT_CALL( - api, OnBufferMapAsync(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) + api, OnBufferMapAsync2(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Error, - ToOutputStringView("Validation error")); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Error, + ToOutputStringView("Validation error")); })); // Ensure that the server had a chance to respond if relevant. @@ -232,10 +232,10 @@ uint32_t bufferContent = 31337; EXPECT_CALL( - api, OnBufferMapAsync(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) + api, OnBufferMapAsync2(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Success, - kEmptyOutputStringView); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Success, + kEmptyOutputStringView); })); ExpectMappedRangeCall(kBufferSize, &bufferContent); @@ -275,10 +275,10 @@ MapAsync(mapMode, 0, kBufferSize); EXPECT_CALL(api, - OnBufferMapAsync(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) + OnBufferMapAsync2(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Error, - ToOutputStringView("Validation error")); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Error, + ToOutputStringView("Validation error")); })); FlushClient(); @@ -403,10 +403,10 @@ MapAsync(wgpu::MapMode::Read, 0, kBufferSize); uint32_t bufferContent = 31337; - EXPECT_CALL(api, OnBufferMapAsync(apiBuffer, WGPUMapMode_Read, 0, kBufferSize, _)) + EXPECT_CALL(api, OnBufferMapAsync2(apiBuffer, WGPUMapMode_Read, 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Success, - kEmptyOutputStringView); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Success, + kEmptyOutputStringView); })); EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer, 0, kBufferSize)) .WillOnce(Return(&bufferContent)); @@ -433,10 +433,10 @@ MapAsync(wgpu::MapMode::Read, 0, kBufferSize); uint32_t bufferContent = 31337; - EXPECT_CALL(api, OnBufferMapAsync(apiBuffer, WGPUMapMode_Read, 0, kBufferSize, _)) + EXPECT_CALL(api, OnBufferMapAsync2(apiBuffer, WGPUMapMode_Read, 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Success, - kEmptyOutputStringView); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Success, + kEmptyOutputStringView); })); EXPECT_CALL(api, BufferGetConstMappedRange(apiBuffer, 0, kBufferSize)) .WillOnce(Return(&bufferContent)); @@ -452,10 +452,10 @@ // Map failure while the buffer is already mapped MapAsync(wgpu::MapMode::Read, 0, kBufferSize); - EXPECT_CALL(api, OnBufferMapAsync(apiBuffer, WGPUMapMode_Read, 0, kBufferSize, _)) + EXPECT_CALL(api, OnBufferMapAsync2(apiBuffer, WGPUMapMode_Read, 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Error, - ToOutputStringView("Already mapped")); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Error, + ToOutputStringView("Already mapped")); })); FlushClient(); @@ -489,10 +489,10 @@ uint32_t serverBufferContent = 31337; uint32_t updatedContent = 4242; - EXPECT_CALL(api, OnBufferMapAsync(apiBuffer, WGPUMapMode_Write, 0, kBufferSize, _)) + EXPECT_CALL(api, OnBufferMapAsync2(apiBuffer, WGPUMapMode_Write, 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Success, - kEmptyOutputStringView); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Success, + kEmptyOutputStringView); })); EXPECT_CALL(api, BufferGetMappedRange(apiBuffer, 0, kBufferSize)) .WillOnce(Return(&serverBufferContent)); @@ -527,10 +527,10 @@ MapAsync(wgpu::MapMode::Write, 0, kBufferSize); uint32_t bufferContent = 31337; - EXPECT_CALL(api, OnBufferMapAsync(apiBuffer, WGPUMapMode_Write, 0, kBufferSize, _)) + EXPECT_CALL(api, OnBufferMapAsync2(apiBuffer, WGPUMapMode_Write, 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Success, - kEmptyOutputStringView); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Success, + kEmptyOutputStringView); })); EXPECT_CALL(api, BufferGetMappedRange(apiBuffer, 0, kBufferSize)) .WillOnce(Return(&bufferContent)); @@ -545,10 +545,10 @@ // Map failure while the buffer is already mapped MapAsync(wgpu::MapMode::Write, 0, kBufferSize); - EXPECT_CALL(api, OnBufferMapAsync(apiBuffer, WGPUMapMode_Write, 0, kBufferSize, _)) + EXPECT_CALL(api, OnBufferMapAsync2(apiBuffer, WGPUMapMode_Write, 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Error, - ToOutputStringView("Already mapped")); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Error, + ToOutputStringView("Already mapped")); })); FlushClient(); @@ -630,10 +630,10 @@ MapAsync(wgpu::MapMode::Write, 0, kBufferSize); - EXPECT_CALL(api, OnBufferMapAsync(apiBuffer, WGPUMapMode_Write, 0, kBufferSize, _)) + EXPECT_CALL(api, OnBufferMapAsync2(apiBuffer, WGPUMapMode_Write, 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Success, - kEmptyOutputStringView); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Success, + kEmptyOutputStringView); })); EXPECT_CALL(api, BufferGetMappedRange(apiBuffer, 0, kBufferSize)) .WillOnce(Return(&apiBufferData)); @@ -664,10 +664,10 @@ // Note that the validation logic is entirely on the native side so we inject the validation // error here and flush the server response to mock the expected behavior. - EXPECT_CALL(api, OnBufferMapAsync(apiBuffer, WGPUMapMode_Write, 0, kBufferSize, _)) + EXPECT_CALL(api, OnBufferMapAsync2(apiBuffer, WGPUMapMode_Write, 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Error, - ToOutputStringView("Already mapped")); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Error, + ToOutputStringView("Already mapped")); })); FlushClient(); @@ -735,10 +735,10 @@ uint32_t bufferContent = 0; EXPECT_CALL(api, - OnBufferMapAsync(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) + OnBufferMapAsync2(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Success, - kEmptyOutputStringView); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Success, + kEmptyOutputStringView); })); ExpectMappedRangeCall(kBufferSize, &bufferContent); @@ -771,10 +771,10 @@ // Calls for the first successful map. uint32_t bufferContent = 0; EXPECT_CALL(api, - OnBufferMapAsync(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) + OnBufferMapAsync2(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Success, - kEmptyOutputStringView); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Success, + kEmptyOutputStringView); })); ExpectMappedRangeCall(kBufferSize, &bufferContent); @@ -823,10 +823,10 @@ ASSERT_EQ(buffer.GetMapState(), wgpu::BufferMapState::Unmapped); EXPECT_CALL( - api, OnBufferMapAsync(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) + api, OnBufferMapAsync2(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Success, - kEmptyOutputStringView); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Success, + kEmptyOutputStringView); })); ExpectMappedRangeCall(kBufferSize, &bufferContent); MapAsync(mapMode, 0, kBufferSize); @@ -861,10 +861,10 @@ // Server-side error case { EXPECT_CALL( - api, OnBufferMapAsync(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) + api, OnBufferMapAsync2(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Error, - ToOutputStringView("Error")); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Error, + ToOutputStringView("Error")); })); // Map state should initially be unmapped. @@ -901,10 +901,10 @@ uint32_t bufferContent = 0; EXPECT_CALL(api, - OnBufferMapAsync(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) + OnBufferMapAsync2(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Success, - kEmptyOutputStringView); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Success, + kEmptyOutputStringView); })); ExpectMappedRangeCall(kBufferSize, &bufferContent); @@ -932,10 +932,10 @@ uint32_t bufferContent = 0; EXPECT_CALL(api, - OnBufferMapAsync(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) + OnBufferMapAsync2(apiBuffer, static_cast<WGPUMapMode>(mapMode), 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Success, - kEmptyOutputStringView); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Success, + kEmptyOutputStringView); })); ExpectMappedRangeCall(kBufferSize, &bufferContent);
diff --git a/src/dawn/tests/unittests/wire/WireCreatePipelineAsyncTests.cpp b/src/dawn/tests/unittests/wire/WireCreatePipelineAsyncTests.cpp index 9542443..396345c 100644 --- a/src/dawn/tests/unittests/wire/WireCreatePipelineAsyncTests.cpp +++ b/src/dawn/tests/unittests/wire/WireCreatePipelineAsyncTests.cpp
@@ -51,7 +51,7 @@ using testing::SizedString; using WireCreateComputePipelineAsyncTestBase = - WireFutureTest<wgpu::CreateComputePipelineAsyncCallback<void>*>; + WireFutureTest<wgpu::CreateComputePipelineAsyncCallback2<void>*>; class WireCreateComputePipelineAsyncTest : public WireCreateComputePipelineAsyncTestBase { protected: void CreateComputePipelineAsync(wgpu::ComputePipelineDescriptor const* desc) { @@ -95,7 +95,7 @@ }; using WireCreateRenderPipelineAsyncTestBase = - WireFutureTest<wgpu::CreateRenderPipelineAsyncCallback<void>*>; + WireFutureTest<wgpu::CreateRenderPipelineAsyncCallback2<void>*>; class WireCreateRenderPipelineAsyncTest : public WireCreateRenderPipelineAsyncTestBase { protected: void CreateRenderPipelineAsync(wgpu::RenderPipelineDescriptor const* desc) { @@ -149,11 +149,11 @@ TEST_P(WireCreateComputePipelineAsyncTest, CreateSuccess) { CreateComputePipelineAsync(&mDescriptor); - EXPECT_CALL(api, OnDeviceCreateComputePipelineAsync(apiDevice, _, _)) + EXPECT_CALL(api, OnDeviceCreateComputePipelineAsync2(apiDevice, _, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallDeviceCreateComputePipelineAsyncCallback(apiDevice, - WGPUCreatePipelineAsyncStatus_Success, - apiPipeline, kEmptyOutputStringView); + api.CallDeviceCreateComputePipelineAsync2Callback(apiDevice, + WGPUCreatePipelineAsyncStatus_Success, + apiPipeline, kEmptyOutputStringView); })); FlushClient(); @@ -171,11 +171,11 @@ TEST_P(WireCreateRenderPipelineAsyncTest, CreateSuccess) { CreateRenderPipelineAsync(&mDescriptor); - EXPECT_CALL(api, OnDeviceCreateRenderPipelineAsync(apiDevice, _, _)) + EXPECT_CALL(api, OnDeviceCreateRenderPipelineAsync2(apiDevice, _, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallDeviceCreateRenderPipelineAsyncCallback(apiDevice, - WGPUCreatePipelineAsyncStatus_Success, - apiPipeline, kEmptyOutputStringView); + api.CallDeviceCreateRenderPipelineAsync2Callback(apiDevice, + WGPUCreatePipelineAsyncStatus_Success, + apiPipeline, kEmptyOutputStringView); })); FlushClient(); @@ -193,9 +193,9 @@ TEST_P(WireCreateComputePipelineAsyncTest, CreateError) { CreateComputePipelineAsync(&mDescriptor); - EXPECT_CALL(api, OnDeviceCreateComputePipelineAsync(apiDevice, _, _)) + EXPECT_CALL(api, OnDeviceCreateComputePipelineAsync2(apiDevice, _, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallDeviceCreateComputePipelineAsyncCallback( + api.CallDeviceCreateComputePipelineAsync2Callback( apiDevice, WGPUCreatePipelineAsyncStatus_ValidationError, nullptr, ToOutputStringView("Some error message")); })); @@ -215,9 +215,9 @@ TEST_P(WireCreateRenderPipelineAsyncTest, CreateError) { CreateRenderPipelineAsync(&mDescriptor); - EXPECT_CALL(api, OnDeviceCreateRenderPipelineAsync(apiDevice, _, _)) + EXPECT_CALL(api, OnDeviceCreateRenderPipelineAsync2(apiDevice, _, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallDeviceCreateRenderPipelineAsyncCallback( + api.CallDeviceCreateRenderPipelineAsync2Callback( apiDevice, WGPUCreatePipelineAsyncStatus_ValidationError, nullptr, ToOutputStringView("Some error message")); })); @@ -238,11 +238,11 @@ TEST_P(WireCreateComputePipelineAsyncTest, CreateThenDisconnect) { CreateComputePipelineAsync(&mDescriptor); - EXPECT_CALL(api, OnDeviceCreateComputePipelineAsync(apiDevice, _, _)) + EXPECT_CALL(api, OnDeviceCreateComputePipelineAsync2(apiDevice, _, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallDeviceCreateComputePipelineAsyncCallback(apiDevice, - WGPUCreatePipelineAsyncStatus_Success, - apiPipeline, kEmptyOutputStringView); + api.CallDeviceCreateComputePipelineAsync2Callback(apiDevice, + WGPUCreatePipelineAsyncStatus_Success, + apiPipeline, kEmptyOutputStringView); })); FlushClient(); @@ -260,11 +260,11 @@ TEST_P(WireCreateRenderPipelineAsyncTest, CreateThenDisconnect) { CreateRenderPipelineAsync(&mDescriptor); - EXPECT_CALL(api, OnDeviceCreateRenderPipelineAsync(apiDevice, _, _)) + EXPECT_CALL(api, OnDeviceCreateRenderPipelineAsync2(apiDevice, _, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallDeviceCreateRenderPipelineAsyncCallback(apiDevice, - WGPUCreatePipelineAsyncStatus_Success, - apiPipeline, kEmptyOutputStringView); + api.CallDeviceCreateRenderPipelineAsync2Callback(apiDevice, + WGPUCreatePipelineAsyncStatus_Success, + apiPipeline, kEmptyOutputStringView); })); FlushClient();
diff --git a/src/dawn/tests/unittests/wire/WireErrorCallbackTests.cpp b/src/dawn/tests/unittests/wire/WireErrorCallbackTests.cpp index eb6a692..4fc1c3d 100644 --- a/src/dawn/tests/unittests/wire/WireErrorCallbackTests.cpp +++ b/src/dawn/tests/unittests/wire/WireErrorCallbackTests.cpp
@@ -126,7 +126,7 @@ FlushServer(); } -using WirePopErrorScopeCallbackTestBase = WireFutureTest<wgpu::PopErrorScopeCallback<void>*>; +using WirePopErrorScopeCallbackTestBase = WireFutureTest<wgpu::PopErrorScopeCallback2<void>*>; class WirePopErrorScopeCallbackTests : public WirePopErrorScopeCallbackTestBase { protected: void PopErrorScope() { @@ -153,10 +153,10 @@ for (const auto& [type, filter] : kErrorTypeAndFilters) { PushErrorScope(filter); PopErrorScope(); - EXPECT_CALL(api, OnDevicePopErrorScope(apiDevice, _)).WillOnce([&] { - api.CallDevicePopErrorScopeCallback(apiDevice, WGPUPopErrorScopeStatus_Success, - static_cast<WGPUErrorType>(type), - ToOutputStringView("Some error message")); + EXPECT_CALL(api, OnDevicePopErrorScope2(apiDevice, _)).WillOnce([&] { + api.CallDevicePopErrorScope2Callback(apiDevice, WGPUPopErrorScopeStatus_Success, + static_cast<WGPUErrorType>(type), + ToOutputStringView("Some error message")); }); FlushClient(); @@ -176,7 +176,7 @@ PushErrorScope(wgpu::ErrorFilter::Validation); PopErrorScope(); - EXPECT_CALL(api, OnDevicePopErrorScope(apiDevice, _)).Times(1); + EXPECT_CALL(api, OnDevicePopErrorScope2(apiDevice, _)).Times(1); FlushClient(); FlushFutures(); @@ -198,10 +198,10 @@ PushErrorScope(wgpu::ErrorFilter::Validation); PopErrorScope(); - EXPECT_CALL(api, OnDevicePopErrorScope(apiDevice, _)).WillOnce(InvokeWithoutArgs([&] { - api.CallDevicePopErrorScopeCallback(apiDevice, WGPUPopErrorScopeStatus_Success, - WGPUErrorType_Validation, - ToOutputStringView("Some error message")); + EXPECT_CALL(api, OnDevicePopErrorScope2(apiDevice, _)).WillOnce(InvokeWithoutArgs([&] { + api.CallDevicePopErrorScope2Callback(apiDevice, WGPUPopErrorScopeStatus_Success, + WGPUErrorType_Validation, + ToOutputStringView("Some error message")); })); FlushClient(); @@ -219,10 +219,10 @@ TEST_P(WirePopErrorScopeCallbackTests, EmptyStack) { PopErrorScope(); - EXPECT_CALL(api, OnDevicePopErrorScope(apiDevice, _)).WillOnce(InvokeWithoutArgs([&] { - api.CallDevicePopErrorScopeCallback(apiDevice, WGPUPopErrorScopeStatus_Success, - WGPUErrorType_NoError, - ToOutputStringView("No error scopes to pop")); + EXPECT_CALL(api, OnDevicePopErrorScope2(apiDevice, _)).WillOnce(InvokeWithoutArgs([&] { + api.CallDevicePopErrorScope2Callback(apiDevice, WGPUPopErrorScopeStatus_Success, + WGPUErrorType_NoError, + ToOutputStringView("No error scopes to pop")); })); FlushClient();
diff --git a/src/dawn/tests/unittests/wire/WireMemoryTransferServiceTests.cpp b/src/dawn/tests/unittests/wire/WireMemoryTransferServiceTests.cpp index b5b962b..d80b89b 100644 --- a/src/dawn/tests/unittests/wire/WireMemoryTransferServiceTests.cpp +++ b/src/dawn/tests/unittests/wire/WireMemoryTransferServiceTests.cpp
@@ -340,10 +340,10 @@ // Mode independent expectations. EXPECT_CALL(api, - OnBufferMapAsync(apiBuffer, static_cast<WGPUMapMode>(mode), 0, kBufferSize, _)) + OnBufferMapAsync2(apiBuffer, static_cast<WGPUMapMode>(mode), 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Success, - kEmptyOutputStringView); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Success, + kEmptyOutputStringView); })); EXPECT_CALL(mMapAsyncCb, Call(wgpu::MapAsyncStatus::Success, _)).Times(1); @@ -471,7 +471,7 @@ uint32_t mSerializeCreateInfo = kDataGenerator++; static constexpr size_t kDataSize = sizeof(uint32_t); - StrictMock<MockCppCallback<wgpu::BufferMapCallback<void>*>> mMapAsyncCb; + StrictMock<MockCppCallback<wgpu::BufferMapCallback2<void>*>> mMapAsyncCb; StrictMock<wire::server::MockMemoryTransferService> mServerMTS; StrictMock<wire::client::MockMemoryTransferService> mClientMTS; @@ -614,10 +614,11 @@ mMapAsyncCb.Callback()); // Make the server respond to the callback with an error. - EXPECT_CALL(api, OnBufferMapAsync(apiBuffer, static_cast<WGPUMapMode>(mode), 0, kBufferSize, _)) + EXPECT_CALL(api, + OnBufferMapAsync2(apiBuffer, static_cast<WGPUMapMode>(mode), 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Error, - ToOutputStringView("Validation error")); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Error, + ToOutputStringView("Validation error")); })); FlushClient(); @@ -657,10 +658,11 @@ } // Set mode independent expectations for the map async call now. - EXPECT_CALL(api, OnBufferMapAsync(apiBuffer, static_cast<WGPUMapMode>(mode), 0, kBufferSize, _)) + EXPECT_CALL(api, + OnBufferMapAsync2(apiBuffer, static_cast<WGPUMapMode>(mode), 0, kBufferSize, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallBufferMapAsyncCallback(apiBuffer, WGPUMapAsyncStatus_Success, - kEmptyOutputStringView); + api.CallBufferMapAsync2Callback(apiBuffer, WGPUMapAsyncStatus_Success, + kEmptyOutputStringView); })); switch (mode) {
diff --git a/src/dawn/tests/unittests/wire/WireQueueTests.cpp b/src/dawn/tests/unittests/wire/WireQueueTests.cpp index b1a2477..fa3d1db 100644 --- a/src/dawn/tests/unittests/wire/WireQueueTests.cpp +++ b/src/dawn/tests/unittests/wire/WireQueueTests.cpp
@@ -39,7 +39,7 @@ using testing::InvokeWithoutArgs; using testing::Return; -using WireQueueTestBase = WireFutureTest<wgpu::QueueWorkDoneCallback<void>*>; +using WireQueueTestBase = WireFutureTest<wgpu::QueueWorkDoneCallback2<void>*>; class WireQueueTests : public WireQueueTestBase { protected: void OnSubmittedWorkDone() { @@ -54,8 +54,8 @@ TEST_P(WireQueueTests, OnSubmittedWorkDoneSuccess) { OnSubmittedWorkDone(); - EXPECT_CALL(api, OnQueueOnSubmittedWorkDone(apiQueue, _)).WillOnce(InvokeWithoutArgs([&] { - api.CallQueueOnSubmittedWorkDoneCallback(apiQueue, WGPUQueueWorkDoneStatus_Success); + EXPECT_CALL(api, OnQueueOnSubmittedWorkDone2(apiQueue, _)).WillOnce(InvokeWithoutArgs([&] { + api.CallQueueOnSubmittedWorkDone2Callback(apiQueue, WGPUQueueWorkDoneStatus_Success); })); FlushClient(); FlushFutures(); @@ -71,8 +71,8 @@ TEST_P(WireQueueTests, OnSubmittedWorkDoneError) { OnSubmittedWorkDone(); - EXPECT_CALL(api, OnQueueOnSubmittedWorkDone(apiQueue, _)).WillOnce(InvokeWithoutArgs([&] { - api.CallQueueOnSubmittedWorkDoneCallback(apiQueue, WGPUQueueWorkDoneStatus_Error); + EXPECT_CALL(api, OnQueueOnSubmittedWorkDone2(apiQueue, _)).WillOnce(InvokeWithoutArgs([&] { + api.CallQueueOnSubmittedWorkDone2Callback(apiQueue, WGPUQueueWorkDoneStatus_Error); })); FlushClient(); FlushFutures(); @@ -93,8 +93,8 @@ OnSubmittedWorkDone(); - EXPECT_CALL(api, OnQueueOnSubmittedWorkDone(apiQueue, _)).WillOnce(InvokeWithoutArgs([&] { - api.CallQueueOnSubmittedWorkDoneCallback(apiQueue, WGPUQueueWorkDoneStatus_Error); + EXPECT_CALL(api, OnQueueOnSubmittedWorkDone2(apiQueue, _)).WillOnce(InvokeWithoutArgs([&] { + api.CallQueueOnSubmittedWorkDone2Callback(apiQueue, WGPUQueueWorkDoneStatus_Error); })); FlushClient(); FlushFutures(); @@ -112,8 +112,8 @@ TEST_P(WireQueueTests, OnSubmittedWorkDoneBeforeDisconnectBeforeReply) { OnSubmittedWorkDone(); - EXPECT_CALL(api, OnQueueOnSubmittedWorkDone(apiQueue, _)).WillOnce(InvokeWithoutArgs([&] { - api.CallQueueOnSubmittedWorkDoneCallback(apiQueue, WGPUQueueWorkDoneStatus_Error); + EXPECT_CALL(api, OnQueueOnSubmittedWorkDone2(apiQueue, _)).WillOnce(InvokeWithoutArgs([&] { + api.CallQueueOnSubmittedWorkDone2Callback(apiQueue, WGPUQueueWorkDoneStatus_Error); })); FlushClient(); @@ -141,8 +141,8 @@ static constexpr size_t kNumRequests = 10; OnSubmittedWorkDone(); - EXPECT_CALL(api, OnQueueOnSubmittedWorkDone(apiQueue, _)).WillOnce(InvokeWithoutArgs([&] { - api.CallQueueOnSubmittedWorkDoneCallback(apiQueue, WGPUQueueWorkDoneStatus_Error); + EXPECT_CALL(api, OnQueueOnSubmittedWorkDone2(apiQueue, _)).WillOnce(InvokeWithoutArgs([&] { + api.CallQueueOnSubmittedWorkDone2Callback(apiQueue, WGPUQueueWorkDoneStatus_Error); })); FlushClient();
diff --git a/src/dawn/tests/unittests/wire/WireShaderModuleTests.cpp b/src/dawn/tests/unittests/wire/WireShaderModuleTests.cpp index 9455b0d..dd89a96 100644 --- a/src/dawn/tests/unittests/wire/WireShaderModuleTests.cpp +++ b/src/dawn/tests/unittests/wire/WireShaderModuleTests.cpp
@@ -40,7 +40,7 @@ using testing::Mock; using testing::Return; -using WireShaderModuleTestBase = WireFutureTest<wgpu::CompilationInfoCallback<void>*>; +using WireShaderModuleTestBase = WireFutureTest<wgpu::CompilationInfoCallback2<void>*>; class WireShaderModuleTests : public WireShaderModuleTestBase { protected: void GetCompilationInfo() { @@ -90,9 +90,9 @@ TEST_P(WireShaderModuleTests, GetCompilationInfo) { GetCompilationInfo(); - EXPECT_CALL(api, OnShaderModuleGetCompilationInfo(apiShaderModule, _)) + EXPECT_CALL(api, OnShaderModuleGetCompilationInfo2(apiShaderModule, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallShaderModuleGetCompilationInfoCallback( + api.CallShaderModuleGetCompilationInfo2Callback( apiShaderModule, WGPUCompilationInfoRequestStatus_Success, reinterpret_cast<const WGPUCompilationInfo*>(&mCompilationInfo)); })); @@ -127,9 +127,9 @@ TEST_P(WireShaderModuleTests, GetCompilationInfoBeforeDisconnect) { GetCompilationInfo(); - EXPECT_CALL(api, OnShaderModuleGetCompilationInfo(apiShaderModule, _)) + EXPECT_CALL(api, OnShaderModuleGetCompilationInfo2(apiShaderModule, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallShaderModuleGetCompilationInfoCallback( + api.CallShaderModuleGetCompilationInfo2Callback( apiShaderModule, WGPUCompilationInfoRequestStatus_Success, reinterpret_cast<const WGPUCompilationInfo*>(&mCompilationInfo)); })); @@ -163,9 +163,9 @@ GetCompilationInfo(); - EXPECT_CALL(api, OnShaderModuleGetCompilationInfo(apiShaderModule, _)) + EXPECT_CALL(api, OnShaderModuleGetCompilationInfo2(apiShaderModule, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallShaderModuleGetCompilationInfoCallback( + api.CallShaderModuleGetCompilationInfo2Callback( apiShaderModule, WGPUCompilationInfoRequestStatus_Success, reinterpret_cast<const WGPUCompilationInfo*>(&mCompilationInfo)); })); @@ -192,9 +192,9 @@ GetCompilationInfo(); - EXPECT_CALL(api, OnShaderModuleGetCompilationInfo(apiShaderModule, _)) + EXPECT_CALL(api, OnShaderModuleGetCompilationInfo2(apiShaderModule, _)) .WillOnce(InvokeWithoutArgs([&] { - api.CallShaderModuleGetCompilationInfoCallback( + api.CallShaderModuleGetCompilationInfo2Callback( apiShaderModule, WGPUCompilationInfoRequestStatus_Success, reinterpret_cast<const WGPUCompilationInfo*>(&mCompilationInfo)); }));
diff --git a/src/dawn/wire/client/Buffer.cpp b/src/dawn/wire/client/Buffer.cpp index a4afb34..784b039 100644 --- a/src/dawn/wire/client/Buffer.cpp +++ b/src/dawn/wire/client/Buffer.cpp
@@ -62,6 +62,157 @@ MapAsyncEvent(const WGPUBufferMapCallbackInfo& callbackInfo, Ref<Buffer> buffer) : TrackedEvent(callbackInfo.mode), mCallback(callbackInfo.callback), + mUserdata(callbackInfo.userdata), + mBuffer(std::move(buffer)) { + DAWN_ASSERT(mBuffer != nullptr); + } + + EventType GetType() override { return kType; } + + bool IsPendingRequest(FutureID futureID) { + return mBuffer->mPendingMapRequest && mBuffer->mPendingMapRequest->futureID == futureID; + } + + WireResult ReadyHook(FutureID futureID, + WGPUBufferMapAsyncStatus status, + uint64_t readDataUpdateInfoLength = 0, + const uint8_t* readDataUpdateInfo = nullptr) { + auto FailRequest = [this]() -> WireResult { + mStatus = WGPUBufferMapAsyncStatus_Unknown; + return WireResult::FatalError; + }; + + // Handling for different statuses. + switch (status) { + case WGPUBufferMapAsyncStatus_MappingAlreadyPending: { + DAWN_ASSERT(!IsPendingRequest(futureID)); + mStatus = status; + break; + } + + // For client-side rejection errors, we clear the pending request now since they always + // take precedence. + case WGPUBufferMapAsyncStatus_DestroyedBeforeCallback: + case WGPUBufferMapAsyncStatus_UnmappedBeforeCallback: { + mStatus = status; + mBuffer->mPendingMapRequest = std::nullopt; + break; + } + + case WGPUBufferMapAsyncStatus_Success: { + if (!IsPendingRequest(futureID)) { + // If a success occurs (which must come from the server), but it does not + // correspond to the pending request, the pending request must have been + // rejected early and hence the status must be set. + DAWN_ASSERT(mStatus); + break; + } + mStatus = status; + auto& pending = mBuffer->mPendingMapRequest.value(); + if (!pending.type) { + return FailRequest(); + } + switch (*pending.type) { + case MapRequestType::Read: { + if (readDataUpdateInfoLength > std::numeric_limits<size_t>::max()) { + // This is the size of data deserialized from the command stream, which + // must be CPU-addressable. + return FailRequest(); + } + + // Validate to prevent bad map request; buffer destroyed during map request + if (mBuffer->mReadHandle == nullptr) { + return FailRequest(); + } + // Update user map data with server returned data + if (!mBuffer->mReadHandle->DeserializeDataUpdate( + readDataUpdateInfo, static_cast<size_t>(readDataUpdateInfoLength), + pending.offset, pending.size)) { + return FailRequest(); + } + mBuffer->mMappedData = const_cast<void*>(mBuffer->mReadHandle->GetData()); + break; + } + case MapRequestType::Write: { + if (mBuffer->mWriteHandle == nullptr) { + return FailRequest(); + } + mBuffer->mMappedData = mBuffer->mWriteHandle->GetData(); + break; + } + } + mBuffer->mMappedOffset = pending.offset; + mBuffer->mMappedSize = pending.size; + break; + } + + // All other statuses are server-side status. + default: { + if (!IsPendingRequest(futureID)) { + break; + } + mStatus = status; + } + } + return WireResult::Success; + } + + private: + void CompleteImpl(FutureID futureID, EventCompletionType completionType) override { + WGPUBufferMapAsyncStatus status = completionType == EventCompletionType::Shutdown + ? WGPUBufferMapAsyncStatus_DeviceLost + : WGPUBufferMapAsyncStatus_Success; + if (mStatus) { + status = *mStatus; + } + + auto Callback = [this, &status]() { + if (mCallback) { + mCallback(status, mUserdata.ExtractAsDangling()); + } + }; + + if (!IsPendingRequest(futureID)) { + DAWN_ASSERT(status != WGPUBufferMapAsyncStatus_Success); + return Callback(); + } + + // Device destruction/loss implicitly makes the map requests aborted. + if (!mBuffer->mDevice->IsAlive()) { + status = WGPUBufferMapAsyncStatus_DestroyedBeforeCallback; + } + + if (status == WGPUBufferMapAsyncStatus_Success) { + DAWN_ASSERT(mBuffer->mPendingMapRequest->type); + switch (*mBuffer->mPendingMapRequest->type) { + case MapRequestType::Read: + mBuffer->mMappedState = MapState::MappedForRead; + break; + case MapRequestType::Write: + mBuffer->mMappedState = MapState::MappedForWrite; + break; + } + } + mBuffer->mPendingMapRequest = std::nullopt; + return Callback(); + } + + WGPUBufferMapCallback mCallback; + raw_ptr<void> mUserdata; + + std::optional<WGPUBufferMapAsyncStatus> mStatus; + + // Reference to the buffer to handle the internal states. + Ref<Buffer> mBuffer; +}; + +class Buffer::MapAsyncEvent2 : public TrackedEvent { + public: + static constexpr EventType kType = EventType::MapAsync; + + MapAsyncEvent2(const WGPUBufferMapCallbackInfo2& callbackInfo, Ref<Buffer> buffer) + : TrackedEvent(callbackInfo.mode), + mCallback(callbackInfo.callback), mUserdata1(callbackInfo.userdata1), mUserdata2(callbackInfo.userdata2), mBuffer(buffer) { @@ -171,7 +322,7 @@ return Callback(); } - WGPUBufferMapCallback mCallback; + WGPUBufferMapCallback2 mCallback; raw_ptr<void> mUserdata1; raw_ptr<void> mUserdata2; @@ -307,30 +458,61 @@ } void Buffer::WillDropLastExternalRef() { - SetFutureStatus(WGPUMapAsyncStatus_Aborted, - "Buffer was destroyed before mapping was resolved."); + SetFutureStatus(WGPUBufferMapAsyncStatus_DestroyedBeforeCallback); } ObjectType Buffer::GetObjectType() const { return ObjectType::Buffer; } -void Buffer::SetFutureStatus(WGPUMapAsyncStatus status, std::string_view message) { +void Buffer::SetFutureStatus(WGPUBufferMapAsyncStatus status) { if (!mPendingMapRequest) { return; } FutureID futureID = mPendingMapRequest->futureID; + bool isNewEntryPoint = mPendingMapRequest->isNewEntryPoint; mPendingMapRequest = std::nullopt; - DAWN_CHECK(GetEventManager().SetFutureReady<MapAsyncEvent>( - futureID, status, ToOutputStringView(message)) == WireResult::Success); + if (isNewEntryPoint) { + auto [newStatus, message] = + [](WGPUBufferMapAsyncStatus status) -> std::pair<WGPUMapAsyncStatus, std::string_view> { + switch (status) { + case WGPUBufferMapAsyncStatus_DestroyedBeforeCallback: + return {WGPUMapAsyncStatus_Aborted, + "Buffer was destroyed before mapping was resolved."}; + case WGPUBufferMapAsyncStatus_UnmappedBeforeCallback: + return {WGPUMapAsyncStatus_Aborted, + "Buffer was unmapped before mapping was resolved."}; + default: + DAWN_UNREACHABLE(); + } + }(status); + + DAWN_CHECK(GetEventManager().SetFutureReady<MapAsyncEvent2>( + futureID, newStatus, ToOutputStringView(message)) == WireResult::Success); + } else { + DAWN_CHECK(GetEventManager().SetFutureReady<MapAsyncEvent>(futureID, status) == + WireResult::Success); + } } -WGPUFuture Buffer::MapAsync(WGPUMapMode mode, - size_t offset, - size_t size, - const WGPUBufferMapCallbackInfo& callbackInfo) { +void Buffer::MapAsync(WGPUMapMode mode, + size_t offset, + size_t size, + WGPUBufferMapCallback callback, + void* userdata) { + WGPUBufferMapCallbackInfo callbackInfo = {}; + callbackInfo.mode = WGPUCallbackMode_AllowSpontaneous; + callbackInfo.callback = callback; + callbackInfo.userdata = userdata; + MapAsyncF(mode, offset, size, callbackInfo); +} + +WGPUFuture Buffer::MapAsyncF(WGPUMapMode mode, + size_t offset, + size_t size, + const WGPUBufferMapCallbackInfo& callbackInfo) { Client* client = GetClient(); auto [futureIDInternal, tracked] = GetEventManager().TrackEvent(std::make_unique<MapAsyncEvent>(callbackInfo, this)); @@ -340,6 +522,52 @@ if (mPendingMapRequest) { [[maybe_unused]] auto id = GetEventManager().SetFutureReady<MapAsyncEvent>( + futureIDInternal, WGPUBufferMapAsyncStatus_MappingAlreadyPending); + return {futureIDInternal}; + } + + // Handle the defaulting of size required by WebGPU. + if ((size == WGPU_WHOLE_MAP_SIZE) && (offset <= mSize)) { + size = mSize - offset; + } + + // Set up the request structure that will hold information while this mapping is in flight. + std::optional<MapRequestType> mapMode; + if (mode & WGPUMapMode_Read) { + mapMode = MapRequestType::Read; + } else if (mode & WGPUMapMode_Write) { + mapMode = MapRequestType::Write; + } + + mPendingMapRequest = {futureIDInternal, offset, size, mapMode, false}; + + // Serialize the command to send to the server. + BufferMapAsyncCmd cmd; + cmd.bufferId = GetWireId(); + cmd.eventManagerHandle = GetEventManagerHandle(); + cmd.future = {futureIDInternal}; + cmd.mode = mode; + cmd.offset = offset; + cmd.size = size; + cmd.userdataCount = 1; + + client->SerializeCommand(cmd); + return {futureIDInternal}; +} + +WGPUFuture Buffer::MapAsync2(WGPUMapMode mode, + size_t offset, + size_t size, + const WGPUBufferMapCallbackInfo2& callbackInfo) { + Client* client = GetClient(); + auto [futureIDInternal, tracked] = + GetEventManager().TrackEvent(std::make_unique<MapAsyncEvent2>(callbackInfo, this)); + if (!tracked) { + return {futureIDInternal}; + } + + if (mPendingMapRequest) { + [[maybe_unused]] auto id = GetEventManager().SetFutureReady<MapAsyncEvent2>( futureIDInternal, WGPUMapAsyncStatus_Error, ToOutputStringView("Buffer already has an outstanding map pending.")); return {futureIDInternal}; @@ -358,7 +586,7 @@ mapMode = MapRequestType::Write; } - mPendingMapRequest = {futureIDInternal, offset, size, mapMode}; + mPendingMapRequest = {futureIDInternal, offset, size, mapMode, true}; // Serialize the command to send to the server. BufferMapAsyncCmd cmd; @@ -368,6 +596,7 @@ cmd.mode = mode; cmd.offset = offset; cmd.size = size; + cmd.userdataCount = 2; client->SerializeCommand(cmd); return {futureIDInternal}; @@ -375,13 +604,21 @@ WireResult Client::DoBufferMapAsyncCallback(ObjectHandle eventManager, WGPUFuture future, - WGPUMapAsyncStatus status, + WGPUBufferMapAsyncStatus status, + WGPUMapAsyncStatus status2, WGPUStringView message, + uint8_t userdataCount, uint64_t readDataUpdateInfoLength, const uint8_t* readDataUpdateInfo) { - return GetEventManager(eventManager) - .SetFutureReady<Buffer::MapAsyncEvent>(future.id, status, message, readDataUpdateInfoLength, - readDataUpdateInfo); + if (userdataCount == 1) { + return GetEventManager(eventManager) + .SetFutureReady<Buffer::MapAsyncEvent>(future.id, status, readDataUpdateInfoLength, + readDataUpdateInfo); + } else { + return GetEventManager(eventManager) + .SetFutureReady<Buffer::MapAsyncEvent2>(future.id, status2, message, + readDataUpdateInfoLength, readDataUpdateInfo); + } } void* Buffer::GetMappedRange(size_t offset, size_t size) { @@ -457,7 +694,7 @@ cmd.self = ToAPI(this); client->SerializeCommand(cmd); - SetFutureStatus(WGPUMapAsyncStatus_Aborted, "Buffer was unmapped before mapping was resolved."); + SetFutureStatus(WGPUBufferMapAsyncStatus_UnmappedBeforeCallback); } void Buffer::Destroy() { @@ -470,8 +707,7 @@ cmd.self = ToAPI(this); client->SerializeCommand(cmd); - SetFutureStatus(WGPUMapAsyncStatus_Aborted, - "Buffer was destroyed before mapping was resolved."); + SetFutureStatus(WGPUBufferMapAsyncStatus_DestroyedBeforeCallback); } WGPUBufferUsage Buffer::GetUsage() const {
diff --git a/src/dawn/wire/client/Buffer.h b/src/dawn/wire/client/Buffer.h index f8e48f4..533635d 100644 --- a/src/dawn/wire/client/Buffer.h +++ b/src/dawn/wire/client/Buffer.h
@@ -57,10 +57,19 @@ ObjectType GetObjectType() const override; - WGPUFuture MapAsync(WGPUMapMode mode, - size_t offset, - size_t size, - const WGPUBufferMapCallbackInfo& callbackInfo); + void MapAsync(WGPUMapMode mode, + size_t offset, + size_t size, + WGPUBufferMapCallback callback, + void* userdata); + WGPUFuture MapAsyncF(WGPUMapMode mode, + size_t offset, + size_t size, + const WGPUBufferMapCallbackInfo& callbackInfo); + WGPUFuture MapAsync2(WGPUMapMode mode, + size_t offset, + size_t size, + const WGPUBufferMapCallbackInfo2& callbackInfo); void* GetMappedRange(size_t offset, size_t size); const void* GetConstMappedRange(size_t offset, size_t size); void Unmap(); @@ -76,11 +85,12 @@ private: friend class Client; class MapAsyncEvent; + class MapAsyncEvent2; void WillDropLastExternalRef() override; // Prepares the callbacks to be called and potentially calls them - void SetFutureStatus(WGPUMapAsyncStatus status, std::string_view message); + void SetFutureStatus(WGPUBufferMapAsyncStatus status); bool IsMappedForReading() const; bool IsMappedForWriting() const; @@ -102,6 +112,9 @@ // Because validation for request type is validated via the backend, we use an optional type // here. This is nullopt when an invalid request type is passed to the wire. std::optional<MapRequestType> type; + // Currently needs an additional boolean to indicate which entry point was used for the map. + // TODO(crbug.com/42241461): Remove this once we don't need to support both on the wire. + bool isNewEntryPoint = false; }; enum class MapState { Unmapped,
diff --git a/src/dawn/wire/client/Device.cpp b/src/dawn/wire/client/Device.cpp index 1b4960e..4677663 100644 --- a/src/dawn/wire/client/Device.cpp +++ b/src/dawn/wire/client/Device.cpp
@@ -46,7 +46,7 @@ public: static constexpr EventType kType = EventType::PopErrorScope; - explicit PopErrorScopeEvent(const WGPUPopErrorScopeCallbackInfo& callbackInfo) + explicit PopErrorScopeEvent(const WGPUPopErrorScopeCallbackInfo2& callbackInfo) : TrackedEvent(callbackInfo.mode), mCallback(callbackInfo.callback), mUserdata1(callbackInfo.userdata1), @@ -72,7 +72,7 @@ } } - WGPUPopErrorScopeCallback mCallback; + WGPUPopErrorScopeCallback2 mCallback; raw_ptr<void> mUserdata1; raw_ptr<void> mUserdata2; @@ -145,11 +145,11 @@ using CreateComputePipelineEvent = CreatePipelineEventBase<ComputePipeline, EventType::CreateComputePipeline, - WGPUCreateComputePipelineAsyncCallbackInfo>; + WGPUCreateComputePipelineAsyncCallbackInfo2>; using CreateRenderPipelineEvent = CreatePipelineEventBase<RenderPipeline, EventType::CreateRenderPipeline, - WGPUCreateRenderPipelineAsyncCallbackInfo>; + WGPUCreateRenderPipelineAsyncCallbackInfo2>; static constexpr WGPUUncapturedErrorCallbackInfo2 kEmptyUncapturedErrorCallbackInfo = { nullptr, nullptr, nullptr, nullptr}; @@ -348,7 +348,30 @@ .SetFutureReady<Device::DeviceLostEvent>(future.id, reason, message); } -WGPUFuture Device::PopErrorScope(const WGPUPopErrorScopeCallbackInfo& callbackInfo) { +void Device::PopErrorScope(WGPUErrorCallback callback, void* userdata) { + static WGPUErrorCallback kDefaultCallback = [](WGPUErrorType, WGPUStringView, void*) {}; + + PopErrorScope2({nullptr, WGPUCallbackMode_AllowSpontaneous, + [](WGPUPopErrorScopeStatus, WGPUErrorType type, WGPUStringView message, + void* callback, void* userdata) { + auto cb = reinterpret_cast<WGPUErrorCallback>(callback); + cb(type, message, userdata); + }, + reinterpret_cast<void*>(callback != nullptr ? callback : kDefaultCallback), + userdata}); +} + +WGPUFuture Device::PopErrorScopeF(const WGPUPopErrorScopeCallbackInfo& callbackInfo) { + return PopErrorScope2({callbackInfo.nextInChain, callbackInfo.mode, + [](WGPUPopErrorScopeStatus status, WGPUErrorType type, + WGPUStringView message, void* callback, void* userdata) { + auto cb = reinterpret_cast<WGPUPopErrorScopeCallback>(callback); + cb(status, type, message, userdata); + }, + reinterpret_cast<void*>(callbackInfo.callback), callbackInfo.userdata}); +} + +WGPUFuture Device::PopErrorScope2(const WGPUPopErrorScopeCallbackInfo2& callbackInfo) { Client* client = GetClient(); auto [futureIDInternal, tracked] = GetEventManager().TrackEvent(std::make_unique<PopErrorScopeEvent>(callbackInfo)); @@ -415,8 +438,8 @@ } template <typename Event, typename Cmd, typename CallbackInfo, typename Descriptor> -WGPUFuture Device::CreatePipelineAsync(Descriptor const* descriptor, - const CallbackInfo& callbackInfo) { +WGPUFuture Device::CreatePipelineAsyncF(Descriptor const* descriptor, + const CallbackInfo& callbackInfo) { using Pipeline = typename Event::Pipeline; Client* client = GetClient(); @@ -438,10 +461,38 @@ return {futureIDInternal}; } -WGPUFuture Device::CreateComputePipelineAsync( +void Device::CreateComputePipelineAsync(WGPUComputePipelineDescriptor const* descriptor, + WGPUCreateComputePipelineAsyncCallback callback, + void* userdata) { + CreateComputePipelineAsync2( + descriptor, {nullptr, WGPUCallbackMode_AllowSpontaneous, + [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline pipeline, + WGPUStringView message, void* callback, void* userdata) { + auto cb = + reinterpret_cast<WGPUCreateComputePipelineAsyncCallback>(callback); + cb(status, pipeline, message, userdata); + }, + reinterpret_cast<void*>(callback), userdata}); +} + +WGPUFuture Device::CreateComputePipelineAsyncF( WGPUComputePipelineDescriptor const* descriptor, const WGPUCreateComputePipelineAsyncCallbackInfo& callbackInfo) { - return CreatePipelineAsync<CreateComputePipelineEvent, DeviceCreateComputePipelineAsyncCmd>( + return CreateComputePipelineAsync2( + descriptor, {callbackInfo.nextInChain, callbackInfo.mode, + [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline pipeline, + WGPUStringView message, void* callback, void* userdata) { + auto cb = + reinterpret_cast<WGPUCreateComputePipelineAsyncCallback>(callback); + cb(status, pipeline, message, userdata); + }, + reinterpret_cast<void*>(callbackInfo.callback), callbackInfo.userdata}); +} + +WGPUFuture Device::CreateComputePipelineAsync2( + WGPUComputePipelineDescriptor const* descriptor, + const WGPUCreateComputePipelineAsyncCallbackInfo2& callbackInfo) { + return CreatePipelineAsyncF<CreateComputePipelineEvent, DeviceCreateComputePipelineAsyncCmd>( descriptor, callbackInfo); } @@ -453,10 +504,38 @@ .SetFutureReady<CreateComputePipelineEvent>(future.id, status, message); } -WGPUFuture Device::CreateRenderPipelineAsync( +void Device::CreateRenderPipelineAsync(WGPURenderPipelineDescriptor const* descriptor, + WGPUCreateRenderPipelineAsyncCallback callback, + void* userdata) { + CreateRenderPipelineAsync2( + descriptor, {nullptr, WGPUCallbackMode_AllowSpontaneous, + [](WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline pipeline, + WGPUStringView message, void* callback, void* userdata) { + auto cb = + reinterpret_cast<WGPUCreateRenderPipelineAsyncCallback>(callback); + cb(status, pipeline, message, userdata); + }, + reinterpret_cast<void*>(callback), userdata}); +} + +WGPUFuture Device::CreateRenderPipelineAsyncF( WGPURenderPipelineDescriptor const* descriptor, const WGPUCreateRenderPipelineAsyncCallbackInfo& callbackInfo) { - return CreatePipelineAsync<CreateRenderPipelineEvent, DeviceCreateRenderPipelineAsyncCmd>( + return CreateRenderPipelineAsync2( + descriptor, {callbackInfo.nextInChain, callbackInfo.mode, + [](WGPUCreatePipelineAsyncStatus status, WGPURenderPipeline pipeline, + WGPUStringView message, void* callback, void* userdata) { + auto cb = + reinterpret_cast<WGPUCreateRenderPipelineAsyncCallback>(callback); + cb(status, pipeline, message, userdata); + }, + reinterpret_cast<void*>(callbackInfo.callback), callbackInfo.userdata}); +} + +WGPUFuture Device::CreateRenderPipelineAsync2( + WGPURenderPipelineDescriptor const* descriptor, + const WGPUCreateRenderPipelineAsyncCallbackInfo2& callbackInfo) { + return CreatePipelineAsyncF<CreateRenderPipelineEvent, DeviceCreateRenderPipelineAsyncCmd>( descriptor, callbackInfo); }
diff --git a/src/dawn/wire/client/Device.h b/src/dawn/wire/client/Device.h index 5efef24..5f7a1a4 100644 --- a/src/dawn/wire/client/Device.h +++ b/src/dawn/wire/client/Device.h
@@ -67,16 +67,30 @@ // WebGPU API void SetLoggingCallback(WGPULoggingCallback errorCallback, void* errorUserdata); void InjectError(WGPUErrorType type, WGPUStringView message); - WGPUFuture PopErrorScope(const WGPUPopErrorScopeCallbackInfo& callbackInfo); + void PopErrorScope(WGPUErrorCallback callback, void* userdata); + WGPUFuture PopErrorScopeF(const WGPUPopErrorScopeCallbackInfo& callbackInfo); + WGPUFuture PopErrorScope2(const WGPUPopErrorScopeCallbackInfo2& callbackInfo); WGPUBuffer CreateBuffer(const WGPUBufferDescriptor* descriptor); WGPUBuffer CreateErrorBuffer(const WGPUBufferDescriptor* descriptor); - WGPUFuture CreateComputePipelineAsync( + void CreateComputePipelineAsync(WGPUComputePipelineDescriptor const* descriptor, + WGPUCreateComputePipelineAsyncCallback callback, + void* userdata); + WGPUFuture CreateComputePipelineAsyncF( WGPUComputePipelineDescriptor const* descriptor, const WGPUCreateComputePipelineAsyncCallbackInfo& callbackInfo); - WGPUFuture CreateRenderPipelineAsync( + WGPUFuture CreateComputePipelineAsync2( + WGPUComputePipelineDescriptor const* descriptor, + const WGPUCreateComputePipelineAsyncCallbackInfo2& callbackInfo); + void CreateRenderPipelineAsync(WGPURenderPipelineDescriptor const* descriptor, + WGPUCreateRenderPipelineAsyncCallback callback, + void* userdata); + WGPUFuture CreateRenderPipelineAsyncF( WGPURenderPipelineDescriptor const* descriptor, const WGPUCreateRenderPipelineAsyncCallbackInfo& callbackInfo); + WGPUFuture CreateRenderPipelineAsync2( + WGPURenderPipelineDescriptor const* descriptor, + const WGPUCreateRenderPipelineAsyncCallbackInfo2& callbackInfo); WGPUStatus GetLimits(WGPUSupportedLimits* limits) const; WGPUFuture GetLostFuture(); @@ -94,7 +108,7 @@ typename Cmd, typename CallbackInfo = typename Event::CallbackInfo, typename Descriptor = decltype(std::declval<Cmd>().descriptor)> - WGPUFuture CreatePipelineAsync(Descriptor const* descriptor, const CallbackInfo& callbackInfo); + WGPUFuture CreatePipelineAsyncF(Descriptor const* descriptor, const CallbackInfo& callbackInfo); LimitsAndFeatures mLimitsAndFeatures;
diff --git a/src/dawn/wire/client/Queue.cpp b/src/dawn/wire/client/Queue.cpp index e5093dc..2680e16 100644 --- a/src/dawn/wire/client/Queue.cpp +++ b/src/dawn/wire/client/Queue.cpp
@@ -41,7 +41,7 @@ public: static constexpr EventType kType = EventType::WorkDone; - explicit WorkDoneEvent(const WGPUQueueWorkDoneCallbackInfo& callbackInfo) + explicit WorkDoneEvent(const WGPUQueueWorkDoneCallbackInfo2& callbackInfo) : TrackedEvent(callbackInfo.mode), mCallback(callbackInfo.callback), mUserdata1(callbackInfo.userdata1), @@ -59,6 +59,9 @@ if (completionType == EventCompletionType::Shutdown) { mStatus = WGPUQueueWorkDoneStatus_InstanceDropped; } + if (mStatus == WGPUQueueWorkDoneStatus_DeviceLost) { + mStatus = WGPUQueueWorkDoneStatus_Success; + } void* userdata1 = mUserdata1.ExtractAsDangling(); void* userdata2 = mUserdata2.ExtractAsDangling(); if (mCallback) { @@ -66,7 +69,7 @@ } } - WGPUQueueWorkDoneCallback mCallback; + WGPUQueueWorkDoneCallback2 mCallback; raw_ptr<void> mUserdata1; raw_ptr<void> mUserdata2; @@ -87,7 +90,41 @@ return GetEventManager(eventManager).SetFutureReady<WorkDoneEvent>(future.id, status); } -WGPUFuture Queue::OnSubmittedWorkDone(const WGPUQueueWorkDoneCallbackInfo& callbackInfo) { +void Queue::OnSubmittedWorkDone(WGPUQueueWorkDoneCallback callback, void* userdata) { + OnSubmittedWorkDoneF({nullptr, WGPUCallbackMode_AllowSpontaneous, callback, userdata}); +} + +WGPUFuture Queue::OnSubmittedWorkDoneF(const WGPUQueueWorkDoneCallbackInfo& callbackInfo) { + // 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); + + Client* client = GetClient(); + auto [futureIDInternal, tracked] = + GetEventManager().TrackEvent(std::make_unique<WorkDoneEvent>(WGPUQueueWorkDoneCallbackInfo2{ + callbackInfo.nextInChain, callbackInfo.mode, + [](WGPUQueueWorkDoneStatus status, void* callback, void* userdata) { + auto cb = reinterpret_cast<WGPUQueueWorkDoneCallback>(callback); + cb(status, userdata); + }, + reinterpret_cast<void*>(callbackInfo.callback != nullptr ? callbackInfo.callback + : nullptr), + callbackInfo.userdata})); + if (!tracked) { + return {futureIDInternal}; + } + + QueueOnSubmittedWorkDoneCmd cmd; + cmd.queueId = GetWireId(); + cmd.eventManagerHandle = GetEventManagerHandle(); + cmd.future = {futureIDInternal}; + cmd.userdataCount = 1; + + client->SerializeCommand(cmd); + return {futureIDInternal}; +} + +WGPUFuture Queue::OnSubmittedWorkDone2(const WGPUQueueWorkDoneCallbackInfo2& callbackInfo) { // 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); @@ -103,6 +140,7 @@ cmd.queueId = GetWireId(); cmd.eventManagerHandle = GetEventManagerHandle(); cmd.future = {futureIDInternal}; + cmd.userdataCount = 2; client->SerializeCommand(cmd); return {futureIDInternal};
diff --git a/src/dawn/wire/client/Queue.h b/src/dawn/wire/client/Queue.h index 0f95a42..bec29d7 100644 --- a/src/dawn/wire/client/Queue.h +++ b/src/dawn/wire/client/Queue.h
@@ -43,7 +43,9 @@ ObjectType GetObjectType() const override; // Dawn API - WGPUFuture OnSubmittedWorkDone(const WGPUQueueWorkDoneCallbackInfo& callbackInfo); + void OnSubmittedWorkDone(WGPUQueueWorkDoneCallback callback, void* userdata); + WGPUFuture OnSubmittedWorkDoneF(const WGPUQueueWorkDoneCallbackInfo& callbackInfo); + WGPUFuture OnSubmittedWorkDone2(const WGPUQueueWorkDoneCallbackInfo2& callbackInfo); void WriteBuffer(WGPUBuffer cBuffer, uint64_t bufferOffset, const void* data, size_t size); void WriteTexture(const WGPUImageCopyTexture* destination, const void* data,
diff --git a/src/dawn/wire/client/ShaderModule.cpp b/src/dawn/wire/client/ShaderModule.cpp index 79fea77..614489b 100644 --- a/src/dawn/wire/client/ShaderModule.cpp +++ b/src/dawn/wire/client/ShaderModule.cpp
@@ -40,7 +40,7 @@ public: static constexpr EventType kType = EventType::CompilationInfo; - CompilationInfoEvent(const WGPUCompilationInfoCallbackInfo& callbackInfo, + CompilationInfoEvent(const WGPUCompilationInfoCallbackInfo2& callbackInfo, Ref<ShaderModule> shader) : TrackedEvent(callbackInfo.mode), mCallback(callbackInfo.callback), @@ -102,7 +102,7 @@ } } - WGPUCompilationInfoCallback mCallback; + WGPUCompilationInfoCallback2 mCallback; raw_ptr<void> mUserdata1; raw_ptr<void> mUserdata2; @@ -117,7 +117,39 @@ return ObjectType::ShaderModule; } -WGPUFuture ShaderModule::GetCompilationInfo(const WGPUCompilationInfoCallbackInfo& callbackInfo) { +namespace { + +void DefaultGetCompilationInfoCallback(WGPUCompilationInfoRequestStatus status, + const WGPUCompilationInfo* compilationInfo, + void* callback, + void* userdata) { + if (callback == nullptr) { + DAWN_ASSERT(userdata == nullptr); + return; + } + auto cb = reinterpret_cast<WGPUCompilationInfoCallback>(callback); + cb(status, compilationInfo, userdata); +} + +} // anonymous namespace + +void ShaderModule::GetCompilationInfo(WGPUCompilationInfoCallback callback, void* userdata) { + if (callback == nullptr) { + DAWN_ASSERT(userdata == nullptr); + return; + } + GetCompilationInfo2({nullptr, WGPUCallbackMode_AllowSpontaneous, + &DefaultGetCompilationInfoCallback, reinterpret_cast<void*>(callback), + userdata}); +} + +WGPUFuture ShaderModule::GetCompilationInfoF(const WGPUCompilationInfoCallbackInfo& callbackInfo) { + return GetCompilationInfo2( + {callbackInfo.nextInChain, callbackInfo.mode, &DefaultGetCompilationInfoCallback, + reinterpret_cast<void*>(callbackInfo.callback), callbackInfo.userdata}); +} + +WGPUFuture ShaderModule::GetCompilationInfo2(const WGPUCompilationInfoCallbackInfo2& callbackInfo) { auto [futureIDInternal, tracked] = GetEventManager().TrackEvent(std::make_unique<CompilationInfoEvent>(callbackInfo, this)); if (!tracked) {
diff --git a/src/dawn/wire/client/ShaderModule.h b/src/dawn/wire/client/ShaderModule.h index a278196..d0558f6 100644 --- a/src/dawn/wire/client/ShaderModule.h +++ b/src/dawn/wire/client/ShaderModule.h
@@ -44,7 +44,9 @@ ObjectType GetObjectType() const override; - WGPUFuture GetCompilationInfo(const WGPUCompilationInfoCallbackInfo& callbackInfo); + void GetCompilationInfo(WGPUCompilationInfoCallback callback, void* userdata); + WGPUFuture GetCompilationInfoF(const WGPUCompilationInfoCallbackInfo& callbackInfo); + WGPUFuture GetCompilationInfo2(const WGPUCompilationInfoCallbackInfo2& callbackInfo); private: friend class Client;
diff --git a/src/dawn/wire/server/Server.h b/src/dawn/wire/server/Server.h index 0241d31..4f0702f 100644 --- a/src/dawn/wire/server/Server.h +++ b/src/dawn/wire/server/Server.h
@@ -129,6 +129,7 @@ uint64_t offset; uint64_t size; WGPUMapMode mode; + uint8_t userdataCount; }; struct ErrorScopeUserdata : CallbackUserdata { @@ -264,9 +265,10 @@ WGPUPopErrorScopeStatus status, WGPUErrorType type, WGPUStringView message); - void OnBufferMapAsyncCallback(MapUserdata* userdata, - WGPUMapAsyncStatus status, - WGPUStringView message); + void OnBufferMapAsyncCallback(MapUserdata* userdata, WGPUBufferMapAsyncStatus status); + void OnBufferMapAsyncCallback2(MapUserdata* userdata, + WGPUMapAsyncStatus status, + WGPUStringView message); void OnQueueWorkDone(QueueWorkDoneUserdata* userdata, WGPUQueueWorkDoneStatus status); void OnCreateComputePipelineAsyncCallback(CreatePipelineAsyncUserData* userdata, WGPUCreatePipelineAsyncStatus status,
diff --git a/src/dawn/wire/server/ServerBuffer.cpp b/src/dawn/wire/server/ServerBuffer.cpp index 24fe5f5..e639966 100644 --- a/src/dawn/wire/server/ServerBuffer.cpp +++ b/src/dawn/wire/server/ServerBuffer.cpp
@@ -71,7 +71,8 @@ WGPUFuture future, WGPUMapMode mode, uint64_t offset64, - uint64_t size64) { + uint64_t size64, + uint8_t userdataCount) { // These requests are just forwarded to the buffer, with userdata containing what the // client will require in the return command. std::unique_ptr<MapUserdata> userdata = MakeUserdata<MapUserdata>(); @@ -80,6 +81,7 @@ userdata->bufferObj = buffer->handle; userdata->future = future; userdata->mode = mode; + userdata->userdataCount = userdataCount; // Make sure that the deserialized offset and size are no larger than // std::numeric_limits<size_t>::max() so that they are CPU-addressable, and size is not @@ -87,13 +89,11 @@ // client does the default size computation, we should always have a valid actual size here // in server. All other invalid actual size can be caught by dawn native side validation. if (offset64 > std::numeric_limits<size_t>::max()) { - static constexpr WGPUStringView kOffsetOutOfRange = {"Buffer offset was out of range.", 31}; - OnBufferMapAsyncCallback(userdata.get(), WGPUMapAsyncStatus_Error, kOffsetOutOfRange); + OnBufferMapAsyncCallback(userdata.get(), WGPUBufferMapAsyncStatus_OffsetOutOfRange); return WireResult::Success; } if (size64 >= WGPU_WHOLE_MAP_SIZE) { - static constexpr WGPUStringView kSizeOutOfRange = {"Buffer size was out of range.", 29}; - OnBufferMapAsyncCallback(userdata.get(), WGPUMapAsyncStatus_Error, kSizeOutOfRange); + OnBufferMapAsyncCallback(userdata.get(), WGPUBufferMapAsyncStatus_SizeOutOfRange); return WireResult::Success; } @@ -103,10 +103,16 @@ userdata->offset = offset; userdata->size = size; - mProcs.bufferMapAsync( - buffer->handle, mode, offset, size, - {nullptr, WGPUCallbackMode_AllowSpontaneous, - ForwardToServer2<&Server::OnBufferMapAsyncCallback>, userdata.release(), nullptr}); + if (userdataCount == 1) { + mProcs.bufferMapAsync(buffer->handle, mode, offset, size, + ForwardToServer<&Server::OnBufferMapAsyncCallback>, + userdata.release()); + } else { + mProcs.bufferMapAsync2( + buffer->handle, mode, offset, size, + {nullptr, WGPUCallbackMode_AllowSpontaneous, + ForwardToServer2<&Server::OnBufferMapAsyncCallback2>, userdata.release(), nullptr}); + } return WireResult::Success; } @@ -219,9 +225,65 @@ return WireResult::Success; } -void Server::OnBufferMapAsyncCallback(MapUserdata* data, - WGPUMapAsyncStatus status, - WGPUStringView message) { +void Server::OnBufferMapAsyncCallback(MapUserdata* data, WGPUBufferMapAsyncStatus status) { + // Skip sending the callback if the buffer has already been destroyed. + Known<WGPUBuffer> buffer; + if (Objects<WGPUBuffer>().Get(data->buffer.id, &buffer) != WireResult::Success || + buffer->generation != data->buffer.generation) { + return; + } + + bool isRead = data->mode & WGPUMapMode_Read; + bool isSuccess = status == WGPUBufferMapAsyncStatus_Success; + + ReturnBufferMapAsyncCallbackCmd cmd = {}; + cmd.eventManager = data->eventManager; + cmd.future = data->future; + cmd.status = status; + cmd.message = kEmptyOutputStringView; + cmd.readDataUpdateInfoLength = 0; + cmd.readDataUpdateInfo = nullptr; + cmd.userdataCount = 1; + + const void* readData = nullptr; + size_t readDataUpdateInfoLength = 0; + if (isSuccess) { + if (isRead) { + // Get the serialization size of the message to initialize ReadHandle data. + readData = mProcs.bufferGetConstMappedRange(data->bufferObj, data->offset, data->size); + readDataUpdateInfoLength = + buffer->readHandle->SizeOfSerializeDataUpdate(data->offset, data->size); + cmd.readDataUpdateInfoLength = readDataUpdateInfoLength; + } else { + DAWN_ASSERT(data->mode & WGPUMapMode_Write); + // The in-flight map request returned successfully. + buffer->mapWriteState = BufferMapWriteState::Mapped; + // Set the target of the WriteHandle to the mapped buffer data. + // writeHandle Target always refers to the buffer base address. + // but we call getMappedRange exactly with the range of data that is potentially + // modified (i.e. we don't want getMappedRange(0, wholeBufferSize) if only a + // subset of the buffer is actually mapped) in case the implementation does some + // range tracking. + buffer->writeHandle->SetTarget(static_cast<uint8_t*>(mProcs.bufferGetMappedRange( + data->bufferObj, data->offset, data->size)) - + data->offset); + } + } + + SerializeCommand(cmd, CommandExtension{readDataUpdateInfoLength, [&](char* readHandleBuffer) { + if (isSuccess && isRead) { + // The in-flight map request returned + // successfully. + buffer->readHandle->SerializeDataUpdate( + readData, data->offset, data->size, + readHandleBuffer); + } + }}); +} + +void Server::OnBufferMapAsyncCallback2(MapUserdata* data, + WGPUMapAsyncStatus status, + WGPUStringView message) { // Skip sending the callback if the buffer has already been destroyed. Known<WGPUBuffer> buffer; if (Objects<WGPUBuffer>().Get(data->buffer.id, &buffer) != WireResult::Success || @@ -235,10 +297,11 @@ ReturnBufferMapAsyncCallbackCmd cmd = {}; cmd.eventManager = data->eventManager; cmd.future = data->future; - cmd.status = status; + cmd.status2 = status; cmd.message = message; cmd.readDataUpdateInfoLength = 0; cmd.readDataUpdateInfo = nullptr; + cmd.userdataCount = 2; const void* readData = nullptr; size_t readDataUpdateInfoLength = 0;
diff --git a/src/dawn/wire/server/ServerDevice.cpp b/src/dawn/wire/server/ServerDevice.cpp index dda48bc..f428677 100644 --- a/src/dawn/wire/server/ServerDevice.cpp +++ b/src/dawn/wire/server/ServerDevice.cpp
@@ -72,9 +72,9 @@ userdata->eventManager = eventManager; userdata->future = future; - mProcs.devicePopErrorScope(device->handle, {nullptr, WGPUCallbackMode_AllowProcessEvents, - ForwardToServer2<&Server::OnDevicePopErrorScope>, - userdata.release(), nullptr}); + mProcs.devicePopErrorScope2(device->handle, {nullptr, WGPUCallbackMode_AllowProcessEvents, + ForwardToServer2<&Server::OnDevicePopErrorScope>, + userdata.release(), nullptr}); return WireResult::Success; } @@ -107,7 +107,7 @@ userdata->future = future; userdata->pipelineObjectID = pipeline.id; - mProcs.deviceCreateComputePipelineAsync( + mProcs.deviceCreateComputePipelineAsync2( device->handle, descriptor, {nullptr, WGPUCallbackMode_AllowProcessEvents, ForwardToServer2<&Server::OnCreateComputePipelineAsyncCallback>, userdata.release(), @@ -149,7 +149,7 @@ userdata->future = future; userdata->pipelineObjectID = pipeline.id; - mProcs.deviceCreateRenderPipelineAsync( + mProcs.deviceCreateRenderPipelineAsync2( device->handle, descriptor, {nullptr, WGPUCallbackMode_AllowProcessEvents, ForwardToServer2<&Server::OnCreateRenderPipelineAsyncCallback>, userdata.release(),
diff --git a/src/dawn/wire/server/ServerQueue.cpp b/src/dawn/wire/server/ServerQueue.cpp index 2eba81a..338a3b5 100644 --- a/src/dawn/wire/server/ServerQueue.cpp +++ b/src/dawn/wire/server/ServerQueue.cpp
@@ -43,15 +43,22 @@ WireResult Server::DoQueueOnSubmittedWorkDone(Known<WGPUQueue> queue, ObjectHandle eventManager, - WGPUFuture future) { + WGPUFuture future, + uint8_t userdataCount) { auto userdata = MakeUserdata<QueueWorkDoneUserdata>(); userdata->queue = queue.AsHandle(); userdata->eventManager = eventManager; userdata->future = future; - mProcs.queueOnSubmittedWorkDone( - queue->handle, {nullptr, WGPUCallbackMode_AllowProcessEvents, - ForwardToServer2<&Server::OnQueueWorkDone>, userdata.release(), nullptr}); + if (userdataCount == 1) { + mProcs.queueOnSubmittedWorkDone(queue->handle, ForwardToServer<&Server::OnQueueWorkDone>, + userdata.release()); + } else { + mProcs.queueOnSubmittedWorkDone2( + queue->handle, + {nullptr, WGPUCallbackMode_AllowProcessEvents, + ForwardToServer2<&Server::OnQueueWorkDone>, userdata.release(), nullptr}); + } return WireResult::Success; }
diff --git a/src/dawn/wire/server/ServerShaderModule.cpp b/src/dawn/wire/server/ServerShaderModule.cpp index 969022b..effb4e0 100644 --- a/src/dawn/wire/server/ServerShaderModule.cpp +++ b/src/dawn/wire/server/ServerShaderModule.cpp
@@ -38,7 +38,7 @@ userdata->eventManager = eventManager; userdata->future = future; - mProcs.shaderModuleGetCompilationInfo( + mProcs.shaderModuleGetCompilationInfo2( shaderModule->handle, {nullptr, WGPUCallbackMode_AllowProcessEvents, ForwardToServer2<&Server::OnShaderModuleGetCompilationInfo>, userdata.release(), nullptr});
diff --git a/third_party/emdawnwebgpu/webgpu.cpp b/third_party/emdawnwebgpu/webgpu.cpp index 8e6d041..1c44642 100644 --- a/third_party/emdawnwebgpu/webgpu.cpp +++ b/third_party/emdawnwebgpu/webgpu.cpp
@@ -641,7 +641,7 @@ WGPUFuture MapAsync(WGPUMapMode mode, size_t offset, size_t size, - WGPUBufferMapCallbackInfo callbackInfo); + WGPUBufferMapCallbackInfo2 callbackInfo); void Unmap(); private: @@ -714,7 +714,7 @@ public: WGPUShaderModuleImpl(const EventSource* source); - WGPUFuture GetCompilationInfo(WGPUCompilationInfoCallbackInfo callbackInfo); + WGPUFuture GetCompilationInfo(WGPUCompilationInfoCallbackInfo2 callbackInfo); private: friend class CompilationInfoEvent; @@ -751,7 +751,7 @@ CompilationInfoEvent(InstanceID instance, WGPUShaderModule shader, - const WGPUCompilationInfoCallbackInfo& callbackInfo) + const WGPUCompilationInfoCallbackInfo2& callbackInfo) : TrackedEvent(instance, callbackInfo.mode), mCallback(callbackInfo.callback), mUserdata1(callbackInfo.userdata1), @@ -789,7 +789,7 @@ } private: - WGPUCompilationInfoCallback mCallback = nullptr; + WGPUCompilationInfoCallback2 mCallback = nullptr; void* mUserdata1 = nullptr; void* mUserdata2 = nullptr; @@ -848,11 +848,11 @@ using CreateComputePipelineEvent = CreatePipelineEventBase<WGPUComputePipeline, EventType::CreateComputePipeline, - WGPUCreateComputePipelineAsyncCallbackInfo>; + WGPUCreateComputePipelineAsyncCallbackInfo2>; using CreateRenderPipelineEvent = CreatePipelineEventBase<WGPURenderPipeline, EventType::CreateRenderPipeline, - WGPUCreateRenderPipelineAsyncCallbackInfo>; + WGPUCreateRenderPipelineAsyncCallbackInfo2>; class DeviceLostEvent final : public TrackedEvent { public: @@ -908,7 +908,7 @@ static constexpr EventType kType = EventType::PopErrorScope; PopErrorScopeEvent(InstanceID instance, - const WGPUPopErrorScopeCallbackInfo& callbackInfo) + const WGPUPopErrorScopeCallbackInfo2& callbackInfo) : TrackedEvent(instance, callbackInfo.mode), mCallback(callbackInfo.callback), mUserdata1(callbackInfo.userdata1), @@ -939,7 +939,7 @@ } private: - WGPUPopErrorScopeCallback mCallback = nullptr; + WGPUPopErrorScopeCallback2 mCallback = nullptr; void* mUserdata1 = nullptr; void* mUserdata2 = nullptr; @@ -954,7 +954,7 @@ MapAsyncEvent(InstanceID instance, WGPUBuffer buffer, - const WGPUBufferMapCallbackInfo& callbackInfo) + const WGPUBufferMapCallbackInfo2& callbackInfo) : TrackedEvent(instance, callbackInfo.mode), mCallback(callbackInfo.callback), mUserdata1(callbackInfo.userdata1), @@ -1001,7 +1001,7 @@ } private: - WGPUBufferMapCallback mCallback = nullptr; + WGPUBufferMapCallback2 mCallback = nullptr; void* mUserdata1 = nullptr; void* mUserdata2 = nullptr; @@ -1109,7 +1109,7 @@ static constexpr EventType kType = EventType::WorkDone; WorkDoneEvent(InstanceID instance, - const WGPUQueueWorkDoneCallbackInfo& callbackInfo) + const WGPUQueueWorkDoneCallbackInfo2& callbackInfo) : TrackedEvent(instance, callbackInfo.mode), mCallback(callbackInfo.callback), mUserdata1(callbackInfo.userdata1), @@ -1129,7 +1129,7 @@ } private: - WGPUQueueWorkDoneCallback mCallback = nullptr; + WGPUQueueWorkDoneCallback2 mCallback = nullptr; void* mUserdata1 = nullptr; void* mUserdata2 = nullptr; @@ -1306,7 +1306,7 @@ WGPUFuture WGPUBufferImpl::MapAsync(WGPUMapMode mode, size_t offset, size_t size, - WGPUBufferMapCallbackInfo callbackInfo) { + WGPUBufferMapCallbackInfo2 callbackInfo) { auto [futureId, tracked] = GetEventManager().TrackEvent( std::make_unique<MapAsyncEvent>(GetInstanceId(), this, callbackInfo)); if (!tracked) { @@ -1450,7 +1450,7 @@ : EventSource(source) {} WGPUFuture WGPUShaderModuleImpl::GetCompilationInfo( - WGPUCompilationInfoCallbackInfo callbackInfo) { + WGPUCompilationInfoCallbackInfo2 callbackInfo) { auto [futureId, tracked] = GetEventManager().TrackEvent(std::make_unique<CompilationInfoEvent>( GetInstanceId(), this, callbackInfo)); @@ -1612,11 +1612,11 @@ return buffer->GetMappedRange(offset, size); } -WGPUFuture wgpuBufferMapAsync(WGPUBuffer buffer, - WGPUMapMode mode, - size_t offset, - size_t size, - WGPUBufferMapCallbackInfo callbackInfo) { +WGPUFuture wgpuBufferMapAsync2(WGPUBuffer buffer, + WGPUMapMode mode, + size_t offset, + size_t size, + WGPUBufferMapCallbackInfo2 callbackInfo) { return buffer->MapAsync(mode, offset, size, callbackInfo); } @@ -1651,10 +1651,29 @@ return buffer; } -WGPUFuture wgpuDeviceCreateComputePipelineAsync( +void wgpuDeviceCreateComputePipelineAsync( WGPUDevice device, const WGPUComputePipelineDescriptor* descriptor, - WGPUCreateComputePipelineAsyncCallbackInfo callbackInfo) { + WGPUCreateComputePipelineAsyncCallback callback, + void* userdata) { + WGPUCreateComputePipelineAsyncCallbackInfo2 callbackInfo = {}; + callbackInfo.mode = WGPUCallbackMode_AllowSpontaneous; + callbackInfo.callback = + [](WGPUCreatePipelineAsyncStatus status, WGPUComputePipeline pipeline, + WGPUStringView message, void* callback, void* userdata) { + auto cb = + reinterpret_cast<WGPUCreateComputePipelineAsyncCallback>(callback); + cb(status, pipeline, message, userdata); + }; + callbackInfo.userdata1 = reinterpret_cast<void*>(callback); + callbackInfo.userdata2 = userdata; + wgpuDeviceCreateComputePipelineAsync2(device, descriptor, callbackInfo); +} + +WGPUFuture wgpuDeviceCreateComputePipelineAsync2( + WGPUDevice device, + const WGPUComputePipelineDescriptor* descriptor, + WGPUCreateComputePipelineAsyncCallbackInfo2 callbackInfo) { auto [futureId, tracked] = GetEventManager().TrackEvent(std::make_unique<CreateComputePipelineEvent>( device->GetInstanceId(), callbackInfo)); @@ -1666,10 +1685,29 @@ return WGPUFuture{futureId}; } -WGPUFuture wgpuDeviceCreateRenderPipelineAsync( +void wgpuDeviceCreateRenderPipelineAsync( WGPUDevice device, const WGPURenderPipelineDescriptor* descriptor, - WGPUCreateRenderPipelineAsyncCallbackInfo callbackInfo) { + WGPUCreateRenderPipelineAsyncCallback callback, + void* userdata) { + WGPUCreateRenderPipelineAsyncCallbackInfo2 callbackInfo = {}; + callbackInfo.mode = WGPUCallbackMode_AllowSpontaneous; + callbackInfo.callback = [](WGPUCreatePipelineAsyncStatus status, + WGPURenderPipeline pipeline, + WGPUStringView message, void* callback, + void* userdata) { + auto cb = reinterpret_cast<WGPUCreateRenderPipelineAsyncCallback>(callback); + cb(status, pipeline, message, userdata); + }; + callbackInfo.userdata1 = reinterpret_cast<void*>(callback); + callbackInfo.userdata2 = userdata; + wgpuDeviceCreateRenderPipelineAsync2(device, descriptor, callbackInfo); +} + +WGPUFuture wgpuDeviceCreateRenderPipelineAsync2( + WGPUDevice device, + const WGPURenderPipelineDescriptor* descriptor, + WGPUCreateRenderPipelineAsyncCallbackInfo2 callbackInfo) { auto [futureId, tracked] = GetEventManager().TrackEvent(std::make_unique<CreateRenderPipelineEvent>( device->GetInstanceId(), callbackInfo)); @@ -1701,8 +1739,9 @@ return device->GetQueue(); } -WGPUFuture wgpuDevicePopErrorScope(WGPUDevice device, - WGPUPopErrorScopeCallbackInfo callbackInfo) { +WGPUFuture wgpuDevicePopErrorScope2( + WGPUDevice device, + WGPUPopErrorScopeCallbackInfo2 callbackInfo) { auto [futureId, tracked] = GetEventManager().TrackEvent(std::make_unique<PopErrorScopeEvent>( device->GetInstanceId(), callbackInfo)); @@ -1773,9 +1812,9 @@ // Methods of Queue // ---------------------------------------------------------------------------- -WGPUFuture wgpuQueueOnSubmittedWorkDone( +WGPUFuture wgpuQueueOnSubmittedWorkDone2( WGPUQueue queue, - WGPUQueueWorkDoneCallbackInfo callbackInfo) { + WGPUQueueWorkDoneCallbackInfo2 callbackInfo) { auto [futureId, tracked] = GetEventManager().TrackEvent( std::make_unique<WorkDoneEvent>(queue->GetInstanceId(), callbackInfo)); if (!tracked) { @@ -1810,9 +1849,9 @@ // Methods of ShaderModule // ---------------------------------------------------------------------------- -WGPUFuture wgpuShaderModuleGetCompilationInfo( +WGPUFuture wgpuShaderModuleGetCompilationInfo2( WGPUShaderModule shader, - WGPUCompilationInfoCallbackInfo callbackInfo) { + WGPUCompilationInfoCallbackInfo2 callbackInfo) { return shader->GetCompilationInfo(callbackInfo); }
diff --git a/tools/android/BUILD.gn b/tools/android/BUILD.gn index de900b1..0e7abd8 100644 --- a/tools/android/BUILD.gn +++ b/tools/android/BUILD.gn
@@ -62,8 +62,11 @@ "java/android/dawn/BufferBindingLayout.kt", "java/android/dawn/BufferBindingType.kt", "java/android/dawn/BufferDescriptor.kt", + "java/android/dawn/BufferMapAsyncStatus.kt", "java/android/dawn/BufferMapCallback.kt", + "java/android/dawn/BufferMapCallback2.kt", "java/android/dawn/BufferMapCallbackInfo.kt", + "java/android/dawn/BufferMapCallbackInfo2.kt", "java/android/dawn/BufferMapState.kt", "java/android/dawn/BufferUsage.kt", "java/android/dawn/CallbackMode.kt", @@ -77,7 +80,9 @@ "java/android/dawn/CompareFunction.kt", "java/android/dawn/CompilationInfo.kt", "java/android/dawn/CompilationInfoCallback.kt", + "java/android/dawn/CompilationInfoCallback2.kt", "java/android/dawn/CompilationInfoCallbackInfo.kt", + "java/android/dawn/CompilationInfoCallbackInfo2.kt", "java/android/dawn/CompilationInfoRequestStatus.kt", "java/android/dawn/CompilationMessage.kt", "java/android/dawn/CompilationMessageType.kt", @@ -91,10 +96,14 @@ "java/android/dawn/ConstantEntry.kt", "java/android/dawn/Constants.kt", "java/android/dawn/CreateComputePipelineAsyncCallback.kt", + "java/android/dawn/CreateComputePipelineAsyncCallback2.kt", "java/android/dawn/CreateComputePipelineAsyncCallbackInfo.kt", + "java/android/dawn/CreateComputePipelineAsyncCallbackInfo2.kt", "java/android/dawn/CreatePipelineAsyncStatus.kt", "java/android/dawn/CreateRenderPipelineAsyncCallback.kt", + "java/android/dawn/CreateRenderPipelineAsyncCallback2.kt", "java/android/dawn/CreateRenderPipelineAsyncCallbackInfo.kt", + "java/android/dawn/CreateRenderPipelineAsyncCallbackInfo2.kt", "java/android/dawn/CullMode.kt", "java/android/dawn/DepthStencilState.kt", "java/android/dawn/Device.kt", @@ -134,7 +143,9 @@ "java/android/dawn/PipelineLayout.kt", "java/android/dawn/PipelineLayoutDescriptor.kt", "java/android/dawn/PopErrorScopeCallback.kt", + "java/android/dawn/PopErrorScopeCallback2.kt", "java/android/dawn/PopErrorScopeCallbackInfo.kt", + "java/android/dawn/PopErrorScopeCallbackInfo2.kt", "java/android/dawn/PopErrorScopeStatus.kt", "java/android/dawn/PowerPreference.kt", "java/android/dawn/PresentMode.kt", @@ -147,7 +158,9 @@ "java/android/dawn/Queue.kt", "java/android/dawn/QueueDescriptor.kt", "java/android/dawn/QueueWorkDoneCallback.kt", + "java/android/dawn/QueueWorkDoneCallback2.kt", "java/android/dawn/QueueWorkDoneCallbackInfo.kt", + "java/android/dawn/QueueWorkDoneCallbackInfo2.kt", "java/android/dawn/QueueWorkDoneStatus.kt", "java/android/dawn/RenderBundle.kt", "java/android/dawn/RenderBundleDescriptor.kt",
diff --git a/tools/android/webgpu/src/test/java/android/dawn/MappedNamedConstantsTest.kt b/tools/android/webgpu/src/test/java/android/dawn/MappedNamedConstantsTest.kt index 886ca44..be7a490 100644 --- a/tools/android/webgpu/src/test/java/android/dawn/MappedNamedConstantsTest.kt +++ b/tools/android/webgpu/src/test/java/android/dawn/MappedNamedConstantsTest.kt
@@ -21,6 +21,7 @@ BlendFactor::class, BlendOperation::class, BufferBindingType::class, + BufferMapAsyncStatus::class, BufferMapState::class, BufferUsage::class, CallbackMode::class,