Skip to content

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 GPUCanvas shaders 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 (https or localhost).

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.