WebGPU Headers
The WebGPU C API
 
Loading...
Searching...
No Matches
Asynchronous Operations

Asynchronous operations in webgpu.h return a WGPUFuture. This is an opaque handle which applications may use to poll or wait for completion of the asynchronous operation.

On all implementations of webgpu.h, it must be possible to react to async operations without undue latency or spin-waiting.

Creation

All asynchronous operations start when the application calls an asynchronous webgpu.h function. These functions return WGPUFuture, and take in their arguments a CallbackInfo struct like WGPURequestDeviceCallbackInfo or WGPUBufferMapCallbackInfo. CallbackInfo structs have the following members:

  • a WGPUChainedStruct const * nextInChain pointer, for extensions.
  • a WGPUCallbackMode mode enum.
  • a callback function pointer. For example:
    typedef void (*WGPUBufferMapCallback)(
    WGPUMapAsyncStatus status,
    char const * message,
    WGPU_NULLABLE void* userdata1,
    WGPU_NULLABLE void* userdata2) WGPU_FUNCTION_ATTRIBUTE;
  • Two application-owned userdata members.
    void* userdata1
    void* userdata2

The callback function pointer is called when the application observes completion of the asynchronous operation. The userdata1 and userdata2 members are passed back to the application as the last two arguments in the callback function. Callbacks might not be called unless the application explicitly flushes them in order to observe completion. The point in time a callback is called depends on the WGPUCallbackMode of the operation. webgpu.h provides three callback modes: WGPUCallbackMode_WaitAnyOnly, WGPUCallbackMode_AllowProcessEvents, and WGPUCallbackMode_AllowSpontaneous.

0x00000001 Callbacks created with WGPUCallbackMode_WaitAnyOnly:

  • fire when the asynchronous operation's future is passed to a call to wgpuInstanceWaitAny AND the operation has already completed or it completes inside the call to wgpuInstanceWaitAny.

    0x00000002 Callbacks created with WGPUCallbackMode_AllowProcessEvents:

  • fire for the same reasons as callbacks created with WGPUCallbackMode_WaitAnyOnly
  • fire inside a call to wgpuInstanceProcessEvents if the asynchronous operation is complete.

    0x00000003 Callbacks created with WGPUCallbackMode_AllowSpontaneous:

  • fire for the same reasons as callbacks created with WGPUCallbackMode_AllowProcessEvents
  • may fire spontaneously on an arbitrary or application thread, when the WebGPU implementations discovers that the asynchronous operation is complete.

    Implementations should fire spontaneous callbacks as soon as possible.

Note
Because spontaneous callbacks may fire at an arbitrary time on an arbitrary thread, applications should take extra care when acquiring locks or mutating state inside the callback. It undefined behavior to re-entrantly call into the webgpu.h API if the callback fires while inside the callstack of another webgpu.h function that is not wgpuInstanceWaitAny or wgpuInstanceProcessEvents.

wgpuInstanceWaitAny

WGPUWaitStatus wgpuInstanceWaitAny(WGPUInstance, size_t futureCount, WGPUFutureWaitInfo * futures, uint64_t timeoutNS)

Waits on any WGPUFuture in the list of futures to complete for timeoutNS nanoseconds. Returns when at least one WGPUFuture is completed or timeoutNS elapses, whichever is first. If timeoutNS is zero, all futures are polled once, without blocking.

Returns WGPUWaitStatus_Success if at least one WGPUFuture completes. WGPUFutureWaitInfo::completed is set to true for all completed futures. See WGPUWaitStatus for other status codes.

Within this call, for any WGPUFutures that completed, their respective callbacks will fire.

Timed Wait

Use of timed waits (timeoutNS > 0), must be enabled on the WGPUInstance in wgpuCreateInstance with WGPUInstanceFeatures::timedWaitAnyEnable, and the number of futures waited on must be less than or equal to WGPUInstanceFeatures::timedWaitAnyMaxCount. Supported instance features may be queried using wgpuGetInstanceFeatures.

Mixed Sources

Asynchronous operations may originate from different sources. There are CPU-timeline operations and there are Queue-timeline operations. Within a timed wait, it is only valid to wait on WGPUFutures originating from a single WGPUQueue. Waiting on two futures from different queues, or waiting on a Queue-timeline future and some other CPU-timeline future is an error.

CPU-Timeline Operations

  • wgpuInstanceRequestAdapter
  • wgpuAdapterRequestDevice
  • wgpuShaderModuleGetCompilationInfo
  • wgpuDeviceCreateRenderPipelineAsync
  • wgpuDeviceCreateComputePipelineAsync
  • wgpuDevicePopErrorScope

Queue-Timeline Operations

  • wgpuBufferMapAsync
  • wgpuQueueOnSubmittedWorkDone

wgpuInstanceProcessEvents

void wgpuInstanceProcessEvents(WGPUInstance)

Processes asynchronous events on this WGPUInstance, calling any callbacks for asynchronous operations created with WGPUCallbackMode_AllowProcessEvents that have completed. This is a non-blocking operation.

Device Events

Device events are slightly different in that their callback info (WGPUDeviceLostCallbackInfo and WGPUUncapturedErrorCallbackInfo) are passed on the WGPUDeviceDescriptor, instead of in a function argument. There is no WGPUFuture returned for either callback.

Todo
Add a getter for the device lost WGPUFuture. See discussion at https://github.com/webgpu-native/webgpu-headers/issues/199#issuecomment-1866850031.

The WGPUUncapturedErrorCallbackInfo does not have a callback mode member. It is always as-if it were WGPUCallbackMode_AllowSpontaneous. Note also that the uncaptured error callback is a repeating callback that fires multiple times, unlike other callbacks in webgpu.h.

The uncaptured error callback is guaranteed not to fire after the device becomes lost. When the device is lost, it is an appropriate time for the application to free userdata variables for the uncaptured error callback. Note that the device becomes lost before the actual device lost callback fires. First the device state transitions to lost, then the device lost callback fires. The timing of the callback depends on the device lost callback mode.