[WGPUFuture] Use C++ types for Futures in Dawn native.
- Adds conversion for value structure types in arguments and return
types in the native ProcTable.
Bug: dawn:1987
Change-Id: I2f7a7edad242779edf8350c86b90a5e56b138675
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/151781
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Loko Kung <lokokung@google.com>
diff --git a/generator/templates/dawn/native/ProcTable.cpp b/generator/templates/dawn/native/ProcTable.cpp
index 4c5ea08..3339f3a 100644
--- a/generator/templates/dawn/native/ProcTable.cpp
+++ b/generator/templates/dawn/native/ProcTable.cpp
@@ -49,6 +49,8 @@
{% set varName = as_varName(arg.name) %}
{% if arg.type.category in ["enum", "bitmask"] and arg.annotation == "value" %}
auto {{varName}}_ = static_cast<{{as_frontendType(arg.type)}}>({{varName}});
+ {% elif arg.type.category == "structure" and arg.annotation == "value" %}
+ auto {{varName}}_ = *reinterpret_cast<{{as_frontendType(arg.type)}}*>(&{{varName}});
{% elif arg.annotation != "value" or arg.type.category == "object" %}
auto {{varName}}_ = reinterpret_cast<{{decorate("", as_frontendType(arg.type), arg)}}>({{varName}});
{% else %}
@@ -79,6 +81,8 @@
{% if method.return_type.name.canonical_case() != "void" %}
{% if method.return_type.category in ["object", "enum", "bitmask"] %}
return ToAPI(result);
+ {% elif method.return_type.category in ["structure"] %}
+ return *ToAPI(&result);
{% else %}
return result;
{% endif %}
diff --git a/src/dawn/common/FutureUtils.cpp b/src/dawn/common/FutureUtils.cpp
index 93e02a1..6c46b38 100644
--- a/src/dawn/common/FutureUtils.cpp
+++ b/src/dawn/common/FutureUtils.cpp
@@ -18,6 +18,7 @@
namespace dawn {
+// TODO(crbug.com/dawn/2052) Remove this when we use an enum instead of a bitmask.
CallbackMode ValidateAndFlattenCallbackMode(WGPUCallbackModeFlags mode) {
switch (mode) {
case WGPUCallbackMode_Spontaneous:
diff --git a/src/dawn/common/FutureUtils.h b/src/dawn/common/FutureUtils.h
index a062735..c08c4bd 100644
--- a/src/dawn/common/FutureUtils.h
+++ b/src/dawn/common/FutureUtils.h
@@ -35,7 +35,7 @@
};
// Flattened version of the wgpu::CallbackMode flags.
-// (This will disappear when that API changes to use an enum instead of flags.)
+// TODO(crbug.com/dawn/2052) Remove when API changes to use an enum instead of flags.
enum class [[nodiscard]] CallbackMode {
Spontaneous,
Future,
@@ -43,7 +43,6 @@
ProcessEvents,
ProcessEventsOrSpontaneous,
};
-
CallbackMode ValidateAndFlattenCallbackMode(WGPUCallbackModeFlags mode);
} // namespace dawn
diff --git a/src/dawn/native/EventManager.cpp b/src/dawn/native/EventManager.cpp
index 18e134f..3c52b11 100644
--- a/src/dawn/native/EventManager.cpp
+++ b/src/dawn/native/EventManager.cpp
@@ -108,8 +108,9 @@
mTrackers.reset();
}
-FutureID EventManager::TrackEvent(WGPUCallbackModeFlags mode, Ref<TrackedEvent>&& future) {
- switch (ValidateAndFlattenCallbackMode(mode)) {
+FutureID EventManager::TrackEvent(wgpu::CallbackMode mode, Ref<TrackedEvent>&& future) {
+ // TODO(crbug.com/dawn/2052) Can remove the validation on the mode once it's an enum.
+ switch (ValidateAndFlattenCallbackMode(static_cast<WGPUCallbackModeFlags>(mode))) {
case CallbackMode::Spontaneous:
// We don't need to track the future because some other code is responsible for
// completing it, and we aren't returning an ID so we don't need to be able to query it.
@@ -163,7 +164,7 @@
for (TrackedFutureWaitInfo& future : futures) {
if (future.ready) {
- DAWN_ASSERT(future.event->mCallbackMode & WGPUCallbackMode_ProcessEvents);
+ DAWN_ASSERT(future.event->mCallbackMode & wgpu::CallbackMode::ProcessEvents);
future.event->EnsureComplete(EventCompletionType::Ready);
}
}
@@ -242,7 +243,7 @@
// Set completed before calling the callback.
infos[future.indexInInfos].completed = true;
// TODO(crbug.com/dawn/2066): Guarantee the event ordering from the JS spec.
- DAWN_ASSERT(future.event->mCallbackMode & WGPUCallbackMode_Future);
+ DAWN_ASSERT(future.event->mCallbackMode & wgpu::CallbackMode::Future);
future.event->EnsureComplete(EventCompletionType::Ready);
}
}
@@ -253,7 +254,7 @@
// EventManager::TrackedEvent
EventManager::TrackedEvent::TrackedEvent(DeviceBase* device,
- WGPUCallbackModeFlags callbackMode,
+ wgpu::CallbackMode callbackMode,
SystemEventReceiver&& receiver)
: mDevice(device), mCallbackMode(callbackMode), mReceiver(std::move(receiver)) {}
@@ -277,7 +278,7 @@
}
void EventManager::TrackedEvent::CompleteIfSpontaneous() {
- if (mCallbackMode & WGPUCallbackMode_Spontaneous) {
+ if (mCallbackMode & wgpu::CallbackMode::Spontaneous) {
bool alreadyComplete = mCompleted.exchange(true);
// If it was already complete, but there was an error, we have no place
// to report it, so DAWN_ASSERT. This shouldn't happen.
diff --git a/src/dawn/native/EventManager.h b/src/dawn/native/EventManager.h
index 59b2471..122f376 100644
--- a/src/dawn/native/EventManager.h
+++ b/src/dawn/native/EventManager.h
@@ -62,7 +62,7 @@
class TrackedEvent;
// Track a TrackedEvent and give it a FutureID.
- [[nodiscard]] FutureID TrackEvent(WGPUCallbackModeFlags mode, Ref<TrackedEvent>&&);
+ [[nodiscard]] FutureID TrackEvent(wgpu::CallbackMode mode, Ref<TrackedEvent>&&);
void ProcessPollEvents();
[[nodiscard]] wgpu::WaitStatus WaitAny(size_t count,
FutureWaitInfo* infos,
@@ -99,7 +99,7 @@
// Note: TrackedEvents are (currently) only for Device events. Events like RequestAdapter and
// RequestDevice complete immediately in dawn native, so should never need to be tracked.
TrackedEvent(DeviceBase* device,
- WGPUCallbackModeFlags callbackMode,
+ wgpu::CallbackMode callbackMode,
SystemEventReceiver&& receiver);
public:
@@ -125,7 +125,7 @@
// This is OK because the instance will clear out the EventManager on shutdown.
// TODO(crbug.com/dawn/2067): This is a bit fragile. Is it possible to remove the ref cycle?
Ref<DeviceBase> mDevice;
- WGPUCallbackModeFlags mCallbackMode;
+ wgpu::CallbackMode mCallbackMode;
#if DAWN_ENABLE_ASSERTS
std::atomic<bool> mCurrentlyBeingWaited;
diff --git a/src/dawn/native/Queue.cpp b/src/dawn/native/Queue.cpp
index 08b1373..6c1c3ca 100644
--- a/src/dawn/native/Queue.cpp
+++ b/src/dawn/native/Queue.cpp
@@ -179,13 +179,13 @@
};
struct WorkDoneEvent final : public EventManager::TrackedEvent {
- std::optional<WGPUQueueWorkDoneStatus> mEarlyStatus;
+ std::optional<wgpu::QueueWorkDoneStatus> mEarlyStatus;
WGPUQueueWorkDoneCallback mCallback;
void* mUserdata;
// Create an event backed by the given SystemEventReceiver.
WorkDoneEvent(DeviceBase* device,
- const WGPUQueueWorkDoneCallbackInfo& callbackInfo,
+ const QueueWorkDoneCallbackInfo& callbackInfo,
SystemEventReceiver&& receiver)
: TrackedEvent(device, callbackInfo.mode, std::move(receiver)),
mCallback(callbackInfo.callback),
@@ -193,9 +193,12 @@
// Create an event that's ready at creation (for errors, etc.)
WorkDoneEvent(DeviceBase* device,
- const WGPUQueueWorkDoneCallbackInfo& callbackInfo,
- WGPUQueueWorkDoneStatus earlyStatus)
- : WorkDoneEvent(device, callbackInfo, SystemEventReceiver::CreateAlreadySignaled()) {
+ const QueueWorkDoneCallbackInfo& callbackInfo,
+ wgpu::QueueWorkDoneStatus earlyStatus)
+ : TrackedEvent(device, callbackInfo.mode, SystemEventReceiver::CreateAlreadySignaled()),
+ mEarlyStatus(earlyStatus),
+ mCallback(callbackInfo.callback),
+ mUserdata(callbackInfo.userdata) {
CompleteIfSpontaneous();
}
@@ -207,14 +210,14 @@
void Complete(EventCompletionType completionType) override {
// WorkDoneEvent has no error cases other than the mEarlyStatus ones.
- WGPUQueueWorkDoneStatus status = WGPUQueueWorkDoneStatus_Success;
+ wgpu::QueueWorkDoneStatus status = wgpu::QueueWorkDoneStatus::Success;
if (completionType == EventCompletionType::Shutdown) {
- status = WGPUQueueWorkDoneStatus_Unknown;
+ status = wgpu::QueueWorkDoneStatus::Unknown;
} else if (mEarlyStatus) {
status = mEarlyStatus.value();
}
- mCallback(status, mUserdata);
+ mCallback(ToAPI(status), mUserdata);
}
};
@@ -266,10 +269,10 @@
WGPUQueueWorkDoneCallback callback,
void* userdata) {
// The error status depends on the type of error so we let the validation function choose it
- WGPUQueueWorkDoneStatus status;
+ wgpu::QueueWorkDoneStatus status;
if (GetDevice()->ConsumedError(ValidateOnSubmittedWorkDone(signalValue, &status))) {
GetDevice()->GetCallbackTaskManager()->AddCallbackTask(
- [callback, status, userdata] { callback(status, userdata); });
+ [callback, status, userdata] { callback(ToAPI(status), userdata); });
return;
}
@@ -286,20 +289,20 @@
uint64_t(GetDevice()->GetPendingCommandSerial()));
}
-WGPUFuture QueueBase::APIOnSubmittedWorkDoneF(const WGPUQueueWorkDoneCallbackInfo& callbackInfo) {
+Future QueueBase::APIOnSubmittedWorkDoneF(const QueueWorkDoneCallbackInfo& 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);
Ref<EventManager::TrackedEvent> event;
- WGPUQueueWorkDoneStatus validationEarlyStatus;
+ wgpu::QueueWorkDoneStatus validationEarlyStatus;
if (GetDevice()->ConsumedError(ValidateOnSubmittedWorkDone(0, &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 == WGPUQueueWorkDoneStatus_DeviceLost) {
- validationEarlyStatus = WGPUQueueWorkDoneStatus_Success;
+ if (validationEarlyStatus == wgpu::QueueWorkDoneStatus::DeviceLost) {
+ validationEarlyStatus = wgpu::QueueWorkDoneStatus::Success;
}
// Note: if the callback is spontaneous, it'll get called in here.
@@ -311,7 +314,7 @@
FutureID futureID =
GetInstance()->GetEventManager()->TrackEvent(callbackInfo.mode, std::move(event));
- return WGPUFuture{futureID};
+ return {futureID};
}
SystemEventReceiver QueueBase::InsertWorkDoneEvent() {
@@ -588,11 +591,11 @@
}
MaybeError QueueBase::ValidateOnSubmittedWorkDone(uint64_t signalValue,
- WGPUQueueWorkDoneStatus* status) const {
- *status = WGPUQueueWorkDoneStatus_DeviceLost;
+ wgpu::QueueWorkDoneStatus* status) const {
+ *status = wgpu::QueueWorkDoneStatus::DeviceLost;
DAWN_TRY(GetDevice()->ValidateIsAlive());
- *status = WGPUQueueWorkDoneStatus_Error;
+ *status = wgpu::QueueWorkDoneStatus::Error;
DAWN_TRY(GetDevice()->ValidateObject(this));
DAWN_INVALID_IF(signalValue != 0, "SignalValue (%u) is not 0.", signalValue);
diff --git a/src/dawn/native/Queue.h b/src/dawn/native/Queue.h
index 2564c7e..ce473f8 100644
--- a/src/dawn/native/Queue.h
+++ b/src/dawn/native/Queue.h
@@ -60,7 +60,7 @@
void APIOnSubmittedWorkDone(uint64_t signalValue,
WGPUQueueWorkDoneCallback callback,
void* userdata);
- WGPUFuture APIOnSubmittedWorkDoneF(const WGPUQueueWorkDoneCallbackInfo& callbackInfo);
+ Future APIOnSubmittedWorkDoneF(const QueueWorkDoneCallbackInfo& callbackInfo);
void APIWriteBuffer(BufferBase* buffer, uint64_t bufferOffset, const void* data, size_t size);
void APIWriteTexture(const ImageCopyTexture* destination,
const void* data,
@@ -129,7 +129,7 @@
MaybeError ValidateSubmit(uint32_t commandCount, CommandBufferBase* const* commands) const;
MaybeError ValidateOnSubmittedWorkDone(uint64_t signalValue,
- WGPUQueueWorkDoneStatus* status) const;
+ wgpu::QueueWorkDoneStatus* status) const;
MaybeError ValidateWriteTexture(const ImageCopyTexture* destination,
size_t dataSize,
const TextureDataLayout& dataLayout,