Concepts
GPU backends #
Knots draws through one of two GPU backends: WebGPU or Vulkan. The UI code is the same for both. This page explains the differences and how to select a backend.
Summary #
| WebGPU | Vulkan | |
|---|---|---|
| Default on | macOS, browser | Linux, Windows |
| Native implementation | wgpu-native, linked statically | Knots code, written in Zig on the Vulkan API |
| Browser implementation | The WebGPU API of the browser, through a JavaScript bridge | Not available |
| Shaders | WGSL | Zig, compiled to SPIR-V at build time |
| Driver API under it | Metal, Vulkan, or Direct3D 12, chosen by wgpu | Vulkan; MoltenVK on macOS |
| Runtime files | None. The library is in the executable. | The system Vulkan loader |
| Prebuilt targets | macOS ARM64, Linux x86-64, Windows x86-64 | All targets that Zig and the window backend support |
Select a backend #
Pass the gpu_backend option to the Knots dependency:
const knots = b.dependency("knots", .{
.target = target,
.optimize = optimize,
.gpu_backend = .vulkan, // or .webgpu
});
To select it from the command line, forward a build option:
const Knots = @import("knots");
const gpu_backend = b.option(Knots.GPUBackend, "gpu_backend", "GPU backend");
const knots = b.dependency("knots", .{
.target = target,
.optimize = optimize,
.gpu_backend = gpu_backend orelse defaultBackend(target.result),
});
defaultBackend is your own function. Return .webgpu for
macOS and WebAssembly, and .vulkan for the other targets. If you do not
set gpu_backend, Knots uses these defaults.
zig build run -Dgpu_backend=webgpu
Knots compiles only one backend into an executable. There is no runtime switch. Browser builds always use WebGPU.
The WebGPU backend #
On native targets, the backend calls wgpu-native. The build downloads a prebuilt static library for the target, so the executable does not need other files. wgpu selects the best API on the machine: Metal on macOS, and Vulkan or Direct3D 12 on Windows and Linux.
In the browser, the backend calls navigator.gpu through
js-bridge.js. The browser must support WebGPU. If it does not, startup fails
with the error WebGPU adapter unavailable.
Use WebGPU when:
- You ship to macOS. It uses Metal directly and needs no MoltenVK.
- You want one executable file without a dependency on the system loader.
- You write custom
GPUCanvasshaders that must also run in the browser.
The Vulkan backend #
The Vulkan backend is part of Knots. It uses
vulkan-zig bindings and loads the
Vulkan library when the app starts: libvulkan.so.1 on Linux,
vulkan-1.dll on Windows, and libvulkan.1.dylib on macOS. On
macOS, Knots looks first in the Frameworks directory of the app bundle.
The backend has these features:
- Shaders are written in Zig and compiled to SPIR-V by the Zig compiler.
- A pooled memory allocator, with uploads that wait until the next frame.
- Descriptor sets that are allocated for one frame at a time.
Use Vulkan when:
- You target Linux or Windows and want the smallest executable.
- You target an architecture that has no prebuilt wgpu-native library, for example Linux ARM64.
- You embed Knots in a renderer that already uses Vulkan. The build exports the shader sources: see Embedding.
Driver requirements #
- Vulkan: a driver with Vulkan 1.3 support, including dynamic rendering. Knots does not use a device that does not have these. On macOS, install the Vulkan SDK, or put MoltenVK and the loader in the app bundle.
- WebGPU native: a driver for Metal, Direct3D 12, or Vulkan.
-
WebGPU browser: a browser with WebGPU enabled, on a secure origin
(
httpsorlocalhost).
Custom shaders #
GPUCanvas gives your code a render pass of the active backend. Your shader
must match the backend: WGSL for WebGPU and SPIR-V for Vulkan. To support both, compile
each shader for each backend and select one at build time. The
playground
does this. It embeds gpu_shader.wgsl for WebGPU, and compiles Zig shaders
to SPIR-V for Vulkan.