[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,