Modules

WebGPU

moduleextensionexperimentalSource

Available on macOS, Linux, Windows, Wasm

#import "Extensions/WebGPU";

WebGPU through the standard C API (webgpu.h). Natively the calls go to wgpu-native; in the browser playground they go to the page's WebGPU.

The wgpu* procedures and WGPU* types are the C API as is. The module adds what that API leaves to the platform: webgpu_request_adapter and webgpu_request_device wait for the asynchronous requests, webgpu_create_surface makes a surface for a window, webgpu_surface_format picks a format for it, and webgpu_present shows a frame.

Example↗
instance := wgpuCreateInstance(null);
adapter := webgpu_request_adapter(instance);
device := webgpu_request_device(instance, adapter);
queue := wgpuDeviceGetQueue(device);

This one is only checked to compile, not run.

Procedures#

General#

() -> bool

Whether WebGPU can be used here. Natively it is always true, though there may still be no adapter. In the browser it is false when the page has no WebGPU or can't suspend the program while it waits, so a program can fall back instead of failing at its first call.

if !webgpu_available() {
    print("this browser has no WebGPU\n");
    return;
}
↗

This one is only checked to compile, not run.

webgpu_waitexperimentalSource
(instance: WGPUInstance, done: *bool)

Processes events until done is set by a callback created with mode .AllowProcessEvents or .AllowSpontaneous. Natively it polls wgpu-native and sleeps a little once the wait gets long; in the browser each poll lets the page run.

instance := wgpuCreateInstance(null);
done := false;
// ... start something whose callback sets `done` ...
webgpu_wait(instance, *done);
↗

This one is only checked to compile, not run.

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

Maps size bytes of buffer at offset for reading (.Read) or writing (.Write) and waits until they are mapped. wgpuBufferGetConstMappedRange or wgpuBufferGetMappedRange then give the bytes, and wgpuBufferUnmap ends the mapping. Returns false, and logs why, when mapping failed.

instance := wgpuCreateInstance(null);
buffer: WGPUBuffer;
if webgpu_map_buffer(instance, buffer, .Read) {
    bytes := wgpuBufferGetConstMappedRange(buffer, 0, 64);
    // ... read from bytes ...
    wgpuBufferUnmap(buffer);
}
↗

This one is only checked to compile, not run.

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

Copies the base level of a 2D texture back to the CPU and returns its bytes, rows packed one after another. The texture needs the .CopySrc usage and can't be multisampled. Free the result with array_free. It submits its own command buffer and waits, so use it for screenshots and tests rather than every frame. Returns an empty array, and logs why, on failure.

instance := wgpuCreateInstance(null);
device: WGPUDevice;
queue: WGPUQueue;
texture: WGPUTexture;
pixels := webgpu_read_texture(instance, device, queue, texture, 256, 256);
defer array_free(pixels);
↗

This one is only checked to compile, not run.

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

Pops the device's innermost error scope and waits for it. Returns the type of the first error the scope caught (.NoError for none) and its message, which lives in temporary storage.

instance := wgpuCreateInstance(null);
device: WGPUDevice;
wgpuDevicePushErrorScope(device, .Validation);
// ... calls that might be invalid ...
type, message := webgpu_pop_error_scope(instance, device);
if type != .NoError print("%\n", message);
↗

This one is only checked to compile, not run.

webgpu_create_surfaceexperimentalmacOS, Linux, Windows onlySource
(instance: WGPUInstance, window: Window_Type) -> WGPUSurface

Makes a surface for a Window_Creation window. It's native only; in the browser, pass the canvas to wgpuInstanceCreateSurface. Returns null, and logs why, when the window is invalid.

#import "Window_Creation";

instance := wgpuCreateInstance(null);
window := create_window(800, 600, "gpu");
surface := webgpu_create_surface(instance, window);

This one is only checked to compile, not run.

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

The format to configure surface with: one it supports that is not sRGB, unless srgb is set, so colours mean the same everywhere. Natively a surface usually lists an sRGB format first, where the GPU converts the shader's output on write; a browser canvas has only plain formats. A shader that writes already encoded colours wants srgb = false; one that writes linear colours wants srgb = true and must encode them itself where the surface has no sRGB format (see webgpu_format_is_srgb). Returns .Undefined when the surface lists none.

surface: WGPUSurface;
adapter: WGPUAdapter;
format := webgpu_surface_format(surface, adapter);
↗

This one is only checked to compile, not run.

webgpu_canvas_sizeexperimentalWasm onlysince 0.28.0Source
() -> (width: s32, height: s32)

Browser only: the size in pixels of the page's canvas. It changes when the page resizes the canvas, so compare it each frame and configure the surface again.

width, height := webgpu_canvas_size();
↗

This one is only checked to compile, not run.

webgpu_window_sizeexperimentalmacOS, Linux, Windows onlySource
(window: Window_Type) -> (width: s32, height: s32)

Native only: the size in pixels of the surface window shows.

#import "Window_Creation";

window: Window_Type;
width, height := webgpu_window_size(window);

This one is only checked to compile, not run.

(surface: WGPUSurface)

Shows the frame drawn into the surface's current texture and waits until the next one is due. Natively that is wgpuSurfacePresent, which blocks for vsync on a FIFO surface. In the browser it waits for the page's next animation frame.

surface: WGPUSurface;
while true {
    // ... draw into the surface's current texture ...
    webgpu_present(surface);
}
↗

This one is only checked to compile, not run.

Generated wasm#

Generated#

Foreign#

Types#

WGPUBackendTypeenumforeignexperimentalSource
:: enum
Undefined
Null
WebGPU
D3D11
D3D12
Metal
Vulkan
OpenGL
OpenGLES
WGPUBlendFactorenumforeignexperimentalSource
:: enum
Undefined
Zero
One
Src
OneMinusSrc
SrcAlpha
OneMinusSrcAlpha
Dst
OneMinusDst
DstAlpha
OneMinusDstAlpha
SrcAlphaSaturated
Constant
OneMinusConstant
Src1
OneMinusSrc1
Src1Alpha
OneMinusSrc1Alpha
WGPUCompareFunctionenumforeignexperimentalSource
:: enum
Undefined
Never
Less
Equal
LessEqual
Greater
NotEqual
GreaterEqual
Always
WGPUErrorTypeenumforeignexperimentalSource
:: enum
NoError
Validation
OutOfMemory
Internal
Unknown
WGPUFeatureNameenumforeignexperimentalSource
:: enum
CoreFeaturesAndLimits
DepthClipControl
Depth32FloatStencil8
TextureCompressionBC
TextureCompressionBCSliced3D
TextureCompressionETC2
TextureCompressionASTC
TextureCompressionASTCSliced3D
TimestampQuery
IndirectFirstInstance
ShaderF16
RG11B10UfloatRenderable
BGRA8UnormStorage
Float32Filterable
Float32Blendable
ClipDistances
DualSourceBlending
Subgroups
TextureFormatsTier1
TextureFormatsTier2
PrimitiveIndex
TextureComponentSwizzle
WGPUSTypeenumforeignexperimentalSource
:: enum
ShaderSourceSPIRV
ShaderSourceWGSL
RenderPassMaxDrawCount
SurfaceSourceMetalLayer
SurfaceSourceWindowsHWND
SurfaceSourceXlibWindow
SurfaceSourceWaylandSurface
SurfaceSourceAndroidNativeWindow
SurfaceSourceXCBWindow
SurfaceColorManagement
RequestAdapterWebXROptions
TextureComponentSwizzleDescriptor
ExternalTextureBindingLayout
ExternalTextureBindingEntry
CompatibilityModeLimits
TextureBindingViewDimension
WGPUStencilOperationenumforeignexperimentalSource
:: enum
Undefined
Keep
Zero
Replace
Invert
IncrementClamp
DecrementClamp
IncrementWrap
DecrementWrap
WGPUTextureFormatenumforeignexperimentalSource
:: enum
Undefined
R8Unorm
R8Snorm
R8Uint
R8Sint
R16Unorm
R16Snorm
R16Uint
R16Sint
R16Float
RG8Unorm
RG8Snorm
RG8Uint
RG8Sint
R32Float
R32Uint
R32Sint
RG16Unorm
RG16Snorm
RG16Uint
RG16Sint
RG16Float
RGBA8Unorm
RGBA8UnormSrgb
RGBA8Snorm
RGBA8Uint
RGBA8Sint
BGRA8Unorm
BGRA8UnormSrgb
RGB10A2Uint
RGB10A2Unorm
RG11B10Ufloat
RGB9E5Ufloat
RG32Float
RG32Uint
RG32Sint
RGBA16Unorm
RGBA16Snorm
RGBA16Uint
RGBA16Sint
RGBA16Float
RGBA32Float
RGBA32Uint
RGBA32Sint
Stencil8
Depth16Unorm
Depth24Plus
Depth24PlusStencil8
Depth32Float
Depth32FloatStencil8
BC1RGBAUnorm
BC1RGBAUnormSrgb
BC2RGBAUnorm
BC2RGBAUnormSrgb
BC3RGBAUnorm
BC3RGBAUnormSrgb
BC4RUnorm
BC4RSnorm
BC5RGUnorm
BC5RGSnorm
BC6HRGBUfloat
BC6HRGBFloat
BC7RGBAUnorm
BC7RGBAUnormSrgb
ETC2RGB8Unorm
ETC2RGB8UnormSrgb
ETC2RGB8A1Unorm
ETC2RGB8A1UnormSrgb
ETC2RGBA8Unorm
ETC2RGBA8UnormSrgb
EACR11Unorm
EACR11Snorm
EACRG11Unorm
EACRG11Snorm
ASTC4x4Unorm
ASTC4x4UnormSrgb
ASTC5x4Unorm
ASTC5x4UnormSrgb
ASTC5x5Unorm
ASTC5x5UnormSrgb
ASTC6x5Unorm
ASTC6x5UnormSrgb
ASTC6x6Unorm
ASTC6x6UnormSrgb
ASTC8x5Unorm
ASTC8x5UnormSrgb
ASTC8x6Unorm
ASTC8x6UnormSrgb
ASTC8x8Unorm
ASTC8x8UnormSrgb
ASTC10x5Unorm
ASTC10x5UnormSrgb
ASTC10x6Unorm
ASTC10x6UnormSrgb
ASTC10x8Unorm
ASTC10x8UnormSrgb
ASTC10x10Unorm
ASTC10x10UnormSrgb
ASTC12x10Unorm
ASTC12x10UnormSrgb
ASTC12x12Unorm
ASTC12x12UnormSrgb
WGPUVertexFormatenumforeignexperimentalSource
:: enum
Uint8
Uint8x2
Uint8x4
Sint8
Sint8x2
Sint8x4
Unorm8
Unorm8x2
Unorm8x4
Snorm8
Snorm8x2
Snorm8x4
Uint16
Uint16x2
Uint16x4
Sint16
Sint16x2
Sint16x4
Unorm16
Unorm16x2
Unorm16x4
Snorm16
Snorm16x2
Snorm16x4
Float16
Float16x2
Float16x4
Float32
Float32x2
Float32x3
Float32x4
Uint32
Uint32x2
Uint32x3
Uint32x4
Sint32
Sint32x2
Sint32x3
Sint32x4
Unorm10_10_10_2
Unorm8x4BGRA
WGPUWGSLLanguageFeatureNameenumforeignexperimentalSource
:: enum
ReadonlyAndReadwriteStorageTextures
Packed4x8IntegerDotProduct
UnrestrictedPointerParameters
PointerCompositeAccess
UniformBufferStandardLayout
SubgroupId
TextureAndSamplerLet
SubgroupUniformity
TextureFormatsTier1
LinearIndexing
WGPUBufferUsageenum flagsforeignexperimentalSource
:: enum_flags
None
MapRead
MapWrite
CopySrc
CopyDst
Index
Vertex
Uniform
Storage
Indirect
QueryResolve
WGPUTextureUsageenum flagsforeignexperimentalSource
:: enum_flags
None
CopySrc
CopyDst
TextureBinding
StorageBinding
RenderAttachment
TransientAttachment
WGPUColorstructforeignexperimentalSource
:: struct
r: float64
g: float64
b: float64
a: float64
WGPUExtent3DstructforeignexperimentalSource
:: struct
width: u32
height: u32
depthOrArrayLayers: u32
WGPULimitsstructforeignexperimentalSource
:: struct
nextInChain: *WGPUChainedStruct
maxTextureDimension1D: u32
maxTextureDimension2D: u32
maxTextureDimension3D: u32
maxTextureArrayLayers: u32
maxBindGroups: u32
maxBindGroupsPlusVertexBuffers: u32
maxBindingsPerBindGroup: u32
maxDynamicUniformBuffersPerPipelineLayout: u32
maxDynamicStorageBuffersPerPipelineLayout: u32
maxSampledTexturesPerShaderStage: u32
maxSamplersPerShaderStage: u32
maxStorageBuffersPerShaderStage: u32
maxStorageTexturesPerShaderStage: u32
maxUniformBuffersPerShaderStage: u32
maxUniformBufferBindingSize: u64
maxStorageBufferBindingSize: u64
minUniformBufferOffsetAlignment: u32
minStorageBufferOffsetAlignment: u32
maxVertexBuffers: u32
maxBufferSize: u64
maxVertexAttributes: u32
maxVertexBufferArrayStride: u32
maxInterStageShaderVariables: u32
maxColorAttachments: u32
maxColorAttachmentBytesPerSample: u32
maxComputeWorkgroupStorageSize: u32
maxComputeInvocationsPerWorkgroup: u32
maxComputeWorkgroupSizeX: u32
maxComputeWorkgroupSizeY: u32
maxComputeWorkgroupSizeZ: u32
maxComputeWorkgroupsPerDimension: u32
maxImmediateSize: u32

Constants#

libwgpuexperimentalSource
:: #library "libwgpu_native"

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

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.