Binding Macros
wgsl-rs provides declarative macros for declaring GPU bindings. Each macro emits both the WGSL binding declaration and a Rust-side static so the same code works on CPU and GPU. To auto-generate wgpu bind group layouts and buffer descriptors from these bindings, see wgpu Linkage.
Overview
| Macro | WGSL | Rust static | Access |
|---|---|---|---|
uniform! | @group(N) @binding(M) var<uniform> ... | Uniform<T> | get!(NAME) |
storage! | @group(N) @binding(M) var<storage, ...> ... | Storage<T> | get! / get_mut! |
workgroup! | var<workgroup> ... | Workgroup<T> | get! / get_mut! |
texture! | @group(N) @binding(M) var ... | hidden __NAME + pub const NAME | by value |
sampler! | @group(N) @binding(M) var ... | hidden __NAME + pub const NAME | by value |
ptr! | ptr<address_space, T> | &mut T | *p |
discard! | discard; | thread-local flag | direct call |
Declaration and Access
Binding macros are used at module scope inside a #[wgsl] module. They declare the WGSL binding and the Rust-side static simultaneously:
#![allow(unused)] fn main() { #[wgsl] pub mod shader { use wgsl_rs::std::*; uniform!(group(0), binding(0), CAMERA: Camera); pub fn view() -> Mat4f { get!(CAMERA).view } } }
get! and get_mut!
get!(VAR)reads auniform!,storage!, orworkgroup!binding. It returns a guard that derefs to the value.get!(VAR, T)reads with an explicit type, used inside generic/template entry points.get_mut!(VAR)returns a mutable guard forstorage!andworkgroup!bindings.
#![allow(unused)] fn main() { pub fn add_delta() { let mut s = get_mut!(COUNTER); s.value += 1; } }
Slab Helpers
For packed slab buffers, use the slab_copy! macro. It is bidirectional — pass the slab as the source to read from a storage buffer into a local array, or pass the slab as the destination to write from a local array into a storage buffer:
#![allow(unused)] fn main() { slab_copy!(src, src_offset, dest, dest_offset, size) }
Copies size elements from src[src_offset..] into dest[dest_offset..]. On the GPU this emits a WGSL for loop; on the CPU it is a simple element-by-element copy.
#![allow(unused)] fn main() { let mut raw = [0u32; 4]; slab_copy!(get!(SLAB), index, raw, 0, 4); slab_copy!(raw, 0, get_mut!(SLAB), index, 4); }