gpu: make requestDevice callback-based, add waitForDevice helper

Previously we were attempting to turn WebGPU async functions, which are
exposed by `webgpu.h` as callbacks, into Zig async functions.

This in practice turns out harder than expected. For example, `Buffer.mapAsync`
/ `wgpuBufferMapAsync` cannot easily be exposed as a Zig async function for a few
reasons:

1. The callback is merely guaranteed to be called once the buffer's content is ready to
   be accessed via `wgpuBufferGetMappedRange` - but there is no strict guarantee about
   when that is. It could be 1-3 frames later, in theory, I believe.
2. The non-deterministic timing means that one would wish to poll "has the async function
   returned?" but this isn't trivial without our own scheduler.
3. Zig has a fair amount of async rework in the future that is coming, and I imagine it
   will be one of the later things that is fully supported by the WebAssembly backend
   (but I am speculating) - so it seems wise to punt on this until later.

Instead, we are now retaining async functions as callback-based ones, with a helper in
this case to wait for the callback to be invoked. For `wgpuBufferMapAsync` we will just
have the callback approach.

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
Stephen Gutekanst 2022-03-15 10:42:14 -07:00 committed by Stephen Gutekanst
parent 890dd57296
commit aab99b5474
4 changed files with 74 additions and 41 deletions

View file

@ -49,10 +49,15 @@ pub const RequestAdapterErrorCode = Interface.RequestAdapterErrorCode;
pub const RequestAdapterError = Interface.RequestAdapterError;
pub const RequestAdapterResponse = Interface.RequestAdapterResponse;
pub const Adapter = @import("Adapter.zig");
pub const RequestDeviceErrorCode = Adapter.RequestDeviceErrorCode;
pub const RequestDeviceError = Adapter.RequesatDeviceError;
pub const RequestDeviceCallback = Adapter.RequestDeviceCallback;
pub const RequestDeviceResponse = Adapter.RequestDeviceResponse;
pub const NativeInstance = @import("NativeInstance.zig");
// Interfaces
pub const Adapter = @import("Adapter.zig");
pub const Device = @import("Device.zig");
pub const Surface = @import("Surface.zig");
pub const Queue = @import("Queue.zig");