Modules

WebGPU

moduleSource
macOSLinuxWindowswasm

#import "Extensions/WebGPU";

WebGPU through the standard C API (webgpu.h). Natively the procedures call wgpu-native; in the browser playground they go to the page's WebGPU. On top of webgpu.h, the module adds what it leaves to the platform: a surface for a window, waiting for asynchronous requests, and frame pacing.

Procedures#

General#

() -> bool

Whether WebGPU can be used here. Natively wgpu-native is linked, so this is true (an adapter may still be missing: webgpu_request_adapter returns null then). In the browser it is false when the page has no WebGPU or cannot suspend the program while it waits (JSPI); a program can then do something else instead of failing at its first wgpu call.

(view: WGPUStringView) -> string

A view the implementation wrote (an adapter's name, an error message), as a Jai string that borrows its bytes.

(instance: WGPUInstance, done: *bool)

Process events until done is set (by a callback with mode .AllowProcessEvents or .AllowSpontaneous). Natively this polls wgpu-native and sleeps a little between polls once the wait gets long; in the browser each poll gives the page a turn (and other Jai threads run meanwhile, see docs/extensions/webgpu.md).

(instance: WGPUInstance, options: *WGPURequestAdapterOptions = null) -> WGPUAdapter

Request an adapter and wait for it; null when there is none.

(instance: WGPUInstance, adapter: WGPUAdapter, descriptor: *WGPUDeviceDescriptor = null) -> WGPUDevice

Request a device and wait for it; null on failure. Uncaptured errors are printed unless the descriptor sets its own callback.

(instance: WGPUInstance, buffer: WGPUBuffer, mode: WGPUMapMode, offset: u64 = 0, size: u64 = WGPU_WHOLE_MAP_SIZE) -> bool

Map size bytes of buffer at offset for reading (.Read) or writing (.Write) and wait until they are; then wgpuBufferGetConstMappedRange / wgpuBufferGetMappedRange give the bytes and wgpuBufferUnmap ends it. False (and the reason logged) when mapping failed.

(instance: WGPUInstance, device: WGPUDevice, queue: WGPUQueue, texture: WGPUTexture, width: s32, height: s32, bytes_per_pixel := 4) -> [] u8

Copy the base mip of a 2D texture (width x height, bytes_per_pixel per texel, such as 4 for rgba8 or bgra8) back to the CPU and return its bytes, rows packed one after another with no padding. The texture needs the .CopySrc usage and must not be multisampled. The caller frees the result with array_free. It submits its own command buffer and waits for it, so it stalls the frame: use it for screenshots and tests, not for per-frame work. Empty (and the reason logged) when the copy or the mapping failed.

(instance: WGPUInstance, device: WGPUDevice) -> (WGPUErrorType, message: string)

Pop the device's innermost error scope (wgpuDevicePushErrorScope) and wait for it: the type of the first error it caught (.NoError for none), and its message (temporary storage).

(surface: WGPUSurface, adapter: WGPUAdapter, srgb := false) -> WGPUTextureFormat

The texture format to configure surface with: one the surface supports that is not sRGB (unless srgb), so colors mean the same everywhere. Natively a surface usually lists an sRGB format first (bgra8unorm-srgb), where the GPU converts the shader's output to sRGB on write; the browser's canvas has only plain formats. A shader that writes already-encoded colors (or applies gamma itself) wants srgb = false; one that writes linear colors wants srgb = true, and must then encode them itself where the surface has no sRGB format (check with webgpu_format_is_srgb). .Undefined when the surface reports no formats, or is null.

(format: WGPUTextureFormat) -> bool

Whether writes to format are sRGB-encoded by the GPU.

webgpu_canvas_sizewasmsince 0.28.0
() -> (width: s32, height: s32)

Browser-only size of the page's canvas (the surface wgpuInstanceCreateSurface(instance, null) draws into), in pixels. It changes when the page resizes the canvas: compare it each frame and configure the surface again.

webgpu_window_sizemacOSLinuxWindows
(window: Window_Type) -> (width: s32, height: s32)

Native-only size of the surface window shows, in pixels.

(surface: WGPUSurface)

Show the frame drawn into the surface's current texture and wait until the next one is due. Natively that is wgpuSurfacePresent (a FIFO surface blocks for vsync). The browser presents on its own; there this suspends the program until the page's next animation frame (other Jai threads run meanwhile) and then runs the callbacks with mode .AllowSpontaneous that finished.

Generated wasm#

Constants#

:: #library "libwgpu_native"

wgpu-native, from target/native-libs (see docs/extensions/webgpu.md). Unused in the browser.

:: cast(WGPUSurfaceGetCurrentTextureStatus) 0x0003_0001

wgpu-native's own wgpuSurfaceGetCurrentTexture status (wgpu.h, not webgpu.h): the window is not visible, so there is no texture this frame. Only its Metal backend reports it, instead of blocking for up to a second; skip the frame (handle events, wait a little) and try again.