Skip to main content

Crate wasdk_wgpu

Crate wasdk_wgpu 

Source
Expand description

A wgpu backend over the engine’s wasi:webgpu, for a program built as a component.

wgpu’s custom feature lets an external crate implement its dispatch traits. This crate implements them over the wasdk::webgpu bindings, so anything written against the wgpu API (valo, and the Waft UI framework through it) runs in a component unchanged. wasi:webgpu mirrors the WebGPU specification, so the object model mirrors wgpu’s own browser backend: each wgpu object owns the wasi resource behind it and drops it with itself, and descriptors borrow those resources from their owners for the duration of a call.

ⓘ
let instance = wasdk_wgpu::instance();
let adapter = instance.request_adapter(&wgpu::RequestAdapterOptions::default()).await?;
let (device, queue) = adapter.request_device(&wgpu::DeviceDescriptor::default()).await?;

// A view is the window a surface is made for, shared by the program and the surface:
let view = wasdk_wgpu::SharedView::new(view);
let surface = instance.create_surface(view.clone())?;
let metrics = view.metrics();
let config = surface.get_default_config(&adapter, metrics.width, metrics.height).unwrap();
surface.configure(&device, &config);

// Each frame:
let wgpu::CurrentSurfaceTexture::Success(frame) = surface.get_current_texture() else { .. };
// ...draw into `frame.texture` and submit...
view.set_layers(&layers); // a program with composition layers
queue.present(frame); // presents the view

// A video frame's hardware buffer is sampled through a texture imported of it on the device:
let video_texture = wasdk_wgpu::import_texture(&device, &video_frame.hardware_buffer());

§Drawing on a view

A view is drawn on through wgpu’s surface, the one way this crate draws on one, as a browser’s canvas is (surface): a SharedView is the window Instance::create_surface takes, its handle a WebCanvasWindowHandle pointing at it, so a framework’s renderer that makes its surface from a window’s handles runs unchanged. The surface offers the engine’s canvas format, which the canvas is drawn in, PresentMode::Fifo, opaque and premultiplied alpha, and drawing into, sampling and copying its textures; configure sets the view’s canvas to the size configured, which its textures are from then on whatever the view’s own size, and configures a canvas context of the view’s against the device, its view formats passed through, of which the engine serves the format’s sRGB counterpart. Queue::present presents the view, with the layers it holds beneath it (view.set_layers); a frame dropped without a present is not presented.

§What the boundary cannot express

wasi:webgpu@0.3.0-rc.2 is the WebGPU API and nothing beyond it. Everything wgpu offers past WebGPU panics at the call with a message naming the gap, or returns the error where the wgpu signature has one. The complete list:

  • Surfaces on anything but a view. Instance::create_surface with a window handle that is not a SharedView’s, or a target that is not a window handle: wgpu gives a backend of its own no way to make the CreateSurfaceError it would answer. A surface’s present modes but Fifo and the automatic ones, its alpha modes PostMultiplied and Inherit, and colour spaces a WebGPU canvas has no name for (ExtendedSrgbLinear, Bt2100Pq, Bt2100Hlg).
  • as_hal and pipeline caches. There is no hal underneath; create_pipeline_cache and a cache in a pipeline descriptor.
  • Ray tracing. BLAS/TLAS creation, compaction and builds, BindingType::AccelerationStructure, BufferUsages::BLAS_INPUT | TLAS_INPUT.
  • External textures. create_external_texture, BindingType::ExternalTexture.
  • Shader sources other than WGSL. SPIR-V, GLSL, naga IR, and every passthrough language but WGSL.
  • Binding arrays. BindGroupLayoutEntry::count, BindingResource::*Array.
  • Transient attachments. TextureUsages::TRANSIENT_ATTACHMENT is a hint the host rejects, so it is stripped, as wgpu’s browser backend strips it.
  • Browser-only entry points. Queue::copy_external_image_to_texture and a mapped range’s as_uint8array, which exist on wgpu’s API only for the web.
  • Mesh shaders. create_mesh_pipeline, draw_mesh_tasks*.
  • multi_draw_*_count. Plain multi_draw_indirect is unrolled into draws, as on the web.
  • Timestamps inside encoders and passes (write_timestamp): WebGPU writes them only at pass boundaries (timestamp_writes). Pipeline statistics queries.
  • clear_texture.
  • Values without a WebGPU name: texture formats R64Uint, NV12, P010 and HDR ASTC; Float64* vertex formats; TextureUsages::STORAGE_ATOMIC; StorageTextureAccess::Atomic; AddressMode::ClampToBorder and SamplerDescriptor::border_color; TextureAspect::Plane*; PolygonMode::Line | Point and conservative rasterization; multiview; shader stages beyond vertex, fragment and compute.
  • Features. A required feature without a WebGPU name (wgpu-native’s) fails request_device with a wgpu::RequestDeviceError. wasi features without a wgpu bit (core-features-and-limits, texture-formats-tier1/2, texture-component-swizzle) are not reported.

Hints with no wasi counterpart and no effect on results are accepted and dropped: DeviceDescriptor::{trace, memory_hints, experimental_features}, RequestAdapterOptions::apply_limit_buckets, ShaderRuntimeChecks, PipelineCompilationOptions::zero_initialize_workgroup_memory (WebGPU always zeroes) and start/stop_graphics_debugger_capture. transition_resources is a no-op because WebGPU tracks resource state itself.

§Where the semantics differ from wgpu-core

  • Mapping copies. The boundary shares no memory: get_mapped_range copies the range into the component (get-mapped-range-get-with-copy), and a mutable view is copied back when it is dropped (get-mapped-range-set-with-copy); drop every BufferViewMut before unmap.
  • Callbacks fire when the program yields. request_adapter, request_device, pop_error_scope and get_compilation_info are wasi async calls awaited by the futures wgpu returns. map_async, on_submitted_work_done, set_device_lost_callback and on_uncaptured_error are spawned onto the program’s executor and run when it next .awaits; Device::poll cannot wait for them and returns PollStatus::QueueEmpty at once, exactly as wgpu’s web backend does.
  • Submission indices count submissions per queue; PollType::Wait cannot wait on one.
  • A frame on a lost device is handed out as good: the canvas hands out an invalid texture it cannot tell from a good one, and the loss comes through the device’s lost callback.
  • AdapterInfo reports Backend::BrowserWebGpu (the WebGPU API, not a browser) and zero vendor/device ids: the wasi info is strings, which land in name and driver_info.
  • LoadOp::DontCare clears, as on the web.
  • Queue::write_buffer_with returns None for a write that fails validation (alignment, bounds, COPY_DST), as wgpu documents, instead of raising a validation error.
  • Validation the boundary reports becomes a panic. Six calls answer with an error the wgpu signature has nowhere to put: Queue::write_buffer, Buffer::unmap, Buffer::get_mapped_range, writing a mapped range back, Device::create_query_set and set_bind_group. Each panics with the engine’s message rather than reaching an error scope, where wgpu-core would raise a validation error.

Modules§

convert
Conversions between wgpu’s vocabulary and wasi:webgpu’s.

Structs§

SharedView
A program’s view, shared by the program and the surfaces made on it: the window wgpu makes a surface for, as an HTML canvas is on the web. It is the view’s Arc with the window handle Rust’s orphan rule keeps off Arc<View>, so it dereferences to the view; every clone is the same view.
WasdkDevice
The device behind a wgpu::Device from this backend: device.as_custom::<WasdkDevice>().
WasdkInstance
The instance behind a wgpu::Instance from this backend: instance.as_custom::<WasdkInstance>().
WasdkSurface
The surface behind a wgpu::Surface on a view: surface.as_custom::<WasdkSurface>().
WasdkSurfaceOutputDetail
A frame a surface handed out: the view it is presented on.
WasdkTexture
The texture behind a wgpu::Texture from this backend: texture.as_custom::<WasdkTexture>().

Functions§

import_texture
buffer imported as a texture on device, over its memory, as a wgpu::Texture (wasdk:platform/gpu-interop): a buffer the program allocated, an image the hardware codecs decoded or a video frame’s, which the texture holds, with its frame, until it is dropped. Its size and format are the buffer’s, and its usages follow from the buffer’s usage.
instance
The wgpu instance over the engine’s WebGPU. wgpu::Instance::new on this target has no backend; this is the one to use.