Aims to auto-generate a Zig wrapper of wgpu-native with object notation and error unions.
  • Zig 97.3%
  • Nix 2.3%
  • WGSL 0.4%
Find a file
2026-05-19 06:11:08 +08:00
build improve build.zig and flake 2026-05-19 05:53:28 +08:00
src improve build.zig and flake 2026-05-19 05:53:28 +08:00
tests improve build.zig and flake 2026-05-19 05:53:28 +08:00
vendor pull wgpu-native submodule and add union_ prefix 2026-05-10 05:57:19 +08:00
.envrc init 2026-03-04 11:40:18 +08:00
.gitignore build system 2026-05-11 06:19:41 +08:00
.gitmodules build system 2026-05-11 06:19:41 +08:00
build.zig readme 2026-05-19 06:11:08 +08:00
build.zig.zon improve build.zig and flake 2026-05-19 05:53:28 +08:00
build.zig.zon.nix build system 2026-05-11 06:19:41 +08:00
build.zig.zon2json-lock init 2026-03-04 11:40:18 +08:00
flake.lock cross compiling support (tested for 64bit windows gnu) 2026-05-17 10:23:41 +08:00
flake.nix improve build.zig and flake 2026-05-19 05:53:28 +08:00
LICENSE-APACHE fixes, features, headed tests, split output.zig, license, readme, zig zon 2026-05-11 03:48:27 +08:00
LICENSE-MIT fixes, features, headed tests, split output.zig, license, readme, zig zon 2026-05-11 03:48:27 +08:00
readme.md readme 2026-05-19 06:11:08 +08:00
triples.zig all builds should work now 1.0.1 2026-05-18 02:57:51 +08:00

z-wgpu-native

Idiomatic Zig bindings for wgpu-native, auto-generated from the C headers.

This codebase DOES use LLM/AI for development.

imo llms are good for repetitive work, search, and pattern recognition, not for creating anything novel. bindings should be an "okay" use-case, but if you mind, definitely avoid using this repo unless you review and test all code yourself.

Build

Requires clang and cargo on $PATH along with linking dependencies.

zig build --help
  -Dtarget=[string]            The CPU architecture, OS, and ABI to build for
  -Dcpu=[string]               Target CPU features to add or subtract
  -Dofmt=[string]              Target object format
  -Ddynamic-linker=[string]    Path to interpreter on the target system
  -Doptimize=[enum]            Prioritize performance, safety, or binary size
  -Dtest=[bool]                Run tests.
  -Dforce-cross-tests=[bool]   Force run tests when crosscompiling regardless of emulation flags.
  -Dheaded-tests=[bool]        Run headed tests on top of default headless tests
  -Dcargo-target=[string]      Override a more reliable Cargo target triple if `triples.zig` does not translate it correctly.
  -Dc-includes=[string]        Path to any headers needed for translate-c and other steps.
  -Dwgpu=[lazy_path]           Provide a prebuilt wgpu-native library to skip the cargo and rust dependencies.
  -Dmode=[enum]
    `minimal` : Consumers can usually build from the existing src/, though it could be out-of-sync with vendor/ or codegen.
    `codegen` : Generates src/ and builds; requires git submodules to run translate-c.
    `full`    : Suitable for hermetic builds and building tests; requires cargo and rust dependencies.
     Note: You can provide a prebuilt wgpu_native library with `-Dwgpu=<path-to-file>` for tests.
           For hermetic or deterministic builds, flake.nix provides coverage for crosscompilation as well.
    Supported Values:
        minimal
        codegen
        full

Quirks

A few things work differently from raw wgpu-native:

Handle fields in descriptors use Optional{Handle}

The C headers use null pointers for optional handles. In Zig that's a ?*anyopaque, but extern structs can't hold non-pointer optionals with a guaranteed layout. So nullable handle fields use handles.Optional{Foo} instead:

// set a handle
.d = .{ .device = wgpu.handles.OptionalDevice.wrap(device) },
// leave it empty
.d = .{ .device = wgpu.handles.OptionalDevice.none() },
// read it back
const dev = surface_tex.texture.unwrap();       // panics if null
const dev = surface_tex.texture.get();          // returns ?Texture

WGPUBool is u32, not bool

C WGPUBool is u32, 1 or 0.

.alpha_to_coverage_enabled = 1, // true
.mapped_at_creation = 0,        // false

Usage

const wgpu = @import("z_wgpu_native");

// Types are under wgpu.types
const desc: wgpu.types.ShaderModuleDescriptor = .{
    .label = wgpu.types.StringView.fromSlice("my shader"),
};

// Handles are under wgpu.handles
const instance = wgpu.handles.createInstance(null);

// Callbacks are under wgpu.callbacks
const callback_info = wgpu.callbacks.requestAdapterCallback(
    Ctx, u8, &ctx, &ctx2,
    struct { fn cb(c: *Ctx, _: *u8, status: wgpu.types.RequestAdapterStatus, ...) void { ... } }.cb,
);

// Raw C bindings available under wgpu.c
const raw_device = wgpu.c.wgpuAdapterRequestDevice(@ptrCast(adapter.ptr), null, callback_info);

// Chained struct iterator
var iter = wgpu.types.chainedIterator(&first_chain);
while (iter.next()) |chain| { ... }

License

This project is dual-licensed under either:

at your option.