Mach v0.3 has been released! For all the details check out the announcement

GPU memory management

Reference counting

GPU objects like gpu.Texture, gpu.Buffer, or any other object which has a .reference, .release and .destroy method - use reference counting.

As Zig developers, we have no qualms with explicit memory management, but GPU memory is perhaps one of the best use-cases for reference counting. GPU objects are reference-counted handles CPU-side, much like a file handle, but often hold references to eachother - while the actual memory lives on the GPU.

Guidance

Use .reference() and .release() to release memory of objects. When the reference count reaches zero, .destroy() will be called automatically for you.

Use-after-free is possible (e.g. passing a texture whose reference count has reached 0 into an API.)

In the browser, .reference() and .release() are managed by the JavaScript garbage collector - and as a result, an additional .destroy() option is provided which lets you explicitly request an object be freed, so you can get GPU memory back without being at the mercy of the JS garbage collector. Whenever the reference count reaches zero, .destroy() is automatically called for you.

Memory alignment

GPUs and underlying graphics APIs have unique memory alignment requirements:

  • Uniforms: 16-byte alignment
  • Buffer uploads: any alignment
  • Buffer uploads with an offset: 256-byte alignment
  • WGSL accesses of e.g. buffer struct fields: any alignment
  • Buffer downloads (calls to getMappedRange(T, ...)) return pointers from the underlying GPU API, generally it is required that @alignOf(T) == 16. See also hexops/mach#847 and webgpu-headers#180.