https://github.com/gogpu/wgpu
Pure Go WebGPU Implementation
https://github.com/gogpu/wgpu
directx12 go golang gpu graphics metal pure-go vulkan webgpu
Last synced: about 1 month ago
JSON representation
Pure Go WebGPU Implementation
- Host: GitHub
- URL: https://github.com/gogpu/wgpu
- Owner: gogpu
- License: mit
- Created: 2025-12-05T15:25:10.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2026-04-21T06:08:09.000Z (2 months ago)
- Last Synced: 2026-04-21T08:03:07.978Z (2 months ago)
- Topics: directx12, go, golang, gpu, graphics, metal, pure-go, vulkan, webgpu
- Language: Go
- Size: 2.09 MB
- Stars: 80
- Watchers: 1
- Forks: 8
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Codeowners: .github/CODEOWNERS
- Security: SECURITY.md
- Roadmap: ROADMAP.md
Awesome Lists containing this project
- awesome-go-with-stars - gogpu/wgpu - 05-01 | (Game Development / Search and Analytic Databases)
- awesome-go - gogpu/wgpu - Pure Go WebGPU implementation with Vulkan, DX12, and Metal backends, zero CGO (part of [GoGPU](https://github.com/gogpu) ecosystem). (Game Development / Search and Analytic Databases)
- fucking-awesome-go - gogpu/wgpu - Pure Go WebGPU implementation with Vulkan, DX12, and Metal backends, zero CGO (part of [GoGPU](https://github.com/gogpu) ecosystem). (Game Development / Search and Analytic Databases)
README
wgpu
Pure Go WebGPU Implementation
No Rust. No CGO. Just Go.
Part of the GoGPU ecosystem
---
## Overview
**wgpu** is a complete WebGPU implementation written entirely in Go. It provides direct GPU access through multiple hardware abstraction layer (HAL) backends without requiring Rust, CGO, or any external dependencies.
### Key Features
| Category | Capabilities |
|----------|--------------|
| **Backends** | Vulkan, Metal, DirectX 12, OpenGL ES, Software, **Browser WebGPU** |
| **Platforms** | Windows, Linux, macOS, iOS, **Browser (WASM)** |
| **API** | WebGPU-compliant (W3C specification) |
| **Shaders** | WGSL via gogpu/naga compiler (SPIR-V, HLSL, MSL, GLSL, DXIL) |
| **Compute** | Full compute shader support, GPU→CPU readback |
| **Present** | Damage-aware presentation — compositor dirty rects (first WebGPU implementation) |
| **Debug** | Leak detection, error scopes, validation layers, DRED diagnostics (DX12), structured logging (`log/slog`) |
| **Build** | Zero CGO, simple `go build` |
---
## Installation
```bash
go get github.com/gogpu/wgpu
```
**Requirements:** Go 1.25+
**Build:**
```bash
CGO_ENABLED=0 go build
```
> **Note:** wgpu uses Pure Go FFI via [goffi](https://github.com/go-webgpu/goffi). Both `CGO_ENABLED=0` (default, zero C compiler dependency) and `CGO_ENABLED=1` (for race detector or coexistence with CGO libraries) are supported.
**Browser (WASM):**
```bash
GOOS=js GOARCH=wasm go build -o app.wasm .
```
> Browser backend uses `syscall/js` → `navigator.gpu` directly, bypassing core/hal. Same public API, same user code — just a different build target. Zero external dependencies.
---
## Quick Start
```go
package main
import (
"fmt"
"github.com/gogpu/wgpu"
_ "github.com/gogpu/wgpu/hal/allbackends" // Auto-register platform backends
)
func main() {
// Create instance
instance, _ := wgpu.CreateInstance(nil)
defer instance.Release()
// Request high-performance GPU
adapter, _ := instance.RequestAdapter(&wgpu.RequestAdapterOptions{
PowerPreference: wgpu.PowerPreferenceHighPerformance,
})
defer adapter.Release()
// Get adapter info
info := adapter.Info()
fmt.Printf("GPU: %s (%s)\n", info.Name, info.Backend)
// Create device
device, _ := adapter.RequestDevice(nil)
defer device.Release()
// Create a GPU buffer
buffer, _ := device.CreateBuffer(&wgpu.BufferDescriptor{
Label: "My Buffer",
Size: 1024,
Usage: wgpu.BufferUsageStorage | wgpu.BufferUsageCopyDst,
})
defer buffer.Release()
// Write data to buffer
if err := device.Queue().WriteBuffer(buffer, 0, []byte{1, 2, 3, 4}); err != nil {
panic(err)
}
}
```
### Compute Shaders
```go
// Create shader module from WGSL
shader, _ := device.CreateShaderModule(&wgpu.ShaderModuleDescriptor{
Label: "Compute Shader",
WGSL: wgslSource,
})
defer shader.Release()
// Create compute pipeline
pipeline, _ := device.CreateComputePipeline(&wgpu.ComputePipelineDescriptor{
Label: "Compute Pipeline",
Layout: pipelineLayout,
Module: shader,
EntryPoint: "main",
})
defer pipeline.Release()
// Record and submit commands
encoder, _ := device.CreateCommandEncoder(nil)
pass, _ := encoder.BeginComputePass(nil)
pass.SetPipeline(pipeline)
pass.SetBindGroup(0, bindGroup, nil)
pass.Dispatch(64, 1, 1)
pass.End()
cmdBuffer, _ := encoder.Finish()
_, _ = device.Queue().Submit(cmdBuffer) // returns (submissionIndex, error)
```
### Buffer Mapping (GPU → CPU readback)
WebGPU-spec-compliant dual-layer API. Primary path is blocking + `context.Context`
(idiomatic Go, zero allocation); escape hatch `MapAsync` + `Device.Poll` is for
game loops that cannot afford to block.
```go
// Primary: blocking, idiomatic, zero-alloc.
// Map blocks until the GPU finishes writing the buffer (or ctx cancels).
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := stagingBuf.Map(ctx, wgpu.MapModeRead, 0, size); err != nil {
log.Fatal(err)
}
defer stagingBuf.Unmap()
rng, _ := stagingBuf.MappedRange(0, size)
data := rng.Bytes() // []byte view, zero copy, valid until Unmap
process(data)
```
```go
// Escape hatch: async, non-blocking, for render loops.
pending, _ := stagingBuf.MapAsync(wgpu.MapModeRead, 0, size)
// Continue rendering; auto-polled on next Queue.Submit.
renderFrame()
if ready, _ := pending.Status(); ready {
rng, _ := stagingBuf.MappedRange(0, size)
process(rng.Bytes())
stagingBuf.Unmap()
}
```
Safety guarantees: UAF protection via generation counters on `MappedRange`,
`ErrBufferDestroyed` on destroy-during-pending, `ErrMapCancelled` on unmap-during-pending,
`ErrMapRangeOverlap` for overlapping `MappedRange` calls, `MAP_ALIGNMENT = 8`
validation, thread-safe concurrent `Device.Poll`.
See [ADR-BUFFER-MAPPING-API](docs/dev/research/ADR-BUFFER-MAPPING-API.md) for the
full design rationale and comparison with Rust wgpu.
**Guides:** [Getting Started](docs/COMPUTE-SHADERS.md) | [Backend Differences](docs/COMPUTE-BACKENDS.md)
Features: WGSL compute shaders, storage/uniform buffers, indirect dispatch, GPU timestamp queries (Vulkan, DX12), WebGPU-compliant `Buffer.Map` / `MapAsync` GPU→CPU readback with `context.Context` integration.
---
## Architecture
```
wgpu/
├── *.go # Public API (import "github.com/gogpu/wgpu")
├── core/ # Validation, state tracking, deferred resource destruction
├── hal/ # Hardware Abstraction Layer
│ ├── allbackends/ # Platform-specific backend auto-registration
│ ├── noop/ # No-op backend (testing)
│ ├── software/ # CPU software rasterizer (~14K LOC)
│ ├── gles/ # OpenGL ES 3.0+ (~12K LOC)
│ ├── vulkan/ # Vulkan 1.3 (~42K LOC)
│ ├── metal/ # Metal (~7K LOC)
│ └── dx12/ # DirectX 12 (~17K LOC)
├── examples/
│ ├── compute-copy/ # GPU buffer copy with compute shader
│ └── compute-sum/ # Parallel reduction on GPU
└── cmd/
├── vk-gen/ # Vulkan bindings generator
└── ... # Backend integration tests
```
### Public API
The root package (`import "github.com/gogpu/wgpu"`) provides a safe, ergonomic API aligned with the W3C WebGPU specification. It wraps `core/` and `hal/` into user-friendly types:
```
User Application
↓ import "github.com/gogpu/wgpu"
Root Package (public API)
↓ wraps
core/ (validation) + hal/ (backend interfaces)
↓
vulkan/ | metal/ | dx12/ | gles/ | software/
```
### HAL Backend Integration
Backends auto-register via blank imports:
```go
import _ "github.com/gogpu/wgpu/hal/allbackends"
// Platform-specific backends auto-registered:
// - Windows: Vulkan, DX12, GLES, Software
// - Linux: Vulkan, GLES, Software
// - macOS: Metal, Software
```
---
## Backend Details
### Platform Support
| Backend | Windows | Linux | macOS | iOS | Notes |
|---------|:-------:|:-----:|:-----:|:---:|-------|
| **Vulkan** | Yes | Yes | Yes | - | MoltenVK on macOS |
| **Metal** | - | - | Yes | Yes | Native Apple GPU |
| **DX12** | Yes | - | - | - | Windows 10+ |
| **GLES** | Yes | Yes | - | - | OpenGL ES 3.0+ |
| **Software** | Yes | Yes | Yes | Yes | CPU fallback |
**Architectures:** amd64, arm64 (including Windows ARM64 / Snapdragon X)
### Vulkan Backend
Full Vulkan 1.3 implementation with:
- Auto-generated bindings from official `vk.xml`
- Buddy allocator for GPU memory (O(log n), minimal fragmentation)
- Dynamic rendering (VK_KHR_dynamic_rendering)
- Classic render pass fallback for Intel compatibility
- wgpu-style swapchain synchronization
- MSAA render pass with automatic resolve
- Complete resource management (Buffer, Texture, Pipeline, BindGroup)
- Surface creation: Win32, X11, Wayland, Metal (MoltenVK)
- Debug messenger for validation layer error capture (`VK_EXT_debug_utils`)
- Structured diagnostic logging via `log/slog`
### Metal Backend
Native Apple GPU access via:
- Pure Go Objective-C bridge (goffi)
- Metal API via runtime message dispatch
- CAMetalLayer integration for surface presentation
- MSL shader compilation via naga
### DirectX 12 Backend
Windows GPU access via:
- Pure Go COM bindings (syscall, no CGO)
- DXGI integration for swapchain and adapters
- Flip model with VRR support
- Descriptor heap management with fence-based deferred destruction
- Encoder pool with allocator recycling (Rust wgpu-core pattern)
- In-memory shader cache (SHA-256 keyed, LRU eviction, works for both paths)
- DRED diagnostics (auto-breadcrumbs + page fault tracking on TDR)
- **Dual shader compilation:** HLSL→FXC (default, SM 5.1) or **DXIL direct** via naga (`GOGPU_DX12_DXIL=1`, SM 6.0+, zero external dependencies — first Pure Go DXIL generator)
- StagingBelt ring-buffer allocator for zero-allocation GPU data transfer
### OpenGL ES Backend
Cross-platform GPU access via OpenGL ES 3.0+:
- Pure Go EGL/GL bindings (goffi)
- Full rendering pipeline: VAO, FBO, MSAA, blend, stencil, depth
- WGSL shader compilation (WGSL → GLSL via naga)
- Combined texture-sampler binding via SamplerBindMap (Rust wgpu pattern)
- Text rendering with proper texture completeness handling
- CopyTextureToBuffer readback for GPU → CPU data transfer
- Platform detection: X11, Wayland, Surfaceless (headless CI)
- Works with Mesa llvmpipe for software-only environments
### Software Backend
Full-featured CPU rasterizer for headless and windowed rendering. Always compiled — no build tags or GPU hardware required.
```go
// Software backend auto-registers via init().
// No explicit import needed when using hal/allbackends.
// For standalone usage:
import _ "github.com/gogpu/wgpu/hal/software"
// Use cases:
// - CI/CD testing without GPU
// - Server-side image generation
// - Reference implementation
// - Fallback when GPU unavailable
// - Embedded systems without GPU
```
**Rasterization Features:**
- Edge function triangle rasterization (Pineda algorithm)
- Perspective-correct interpolation
- Depth buffer (8 compare functions)
- Stencil buffer (8 operations)
- Blending (13 factors, 5 operations)
- 6-plane frustum clipping (Sutherland-Hodgman)
- 8x8 tile-based parallel rendering
- **SPIR-V interpreter** — executes vertex/fragment/compute shaders on CPU. Designed for shader debugging, CI/CD testing, and GPU-less environments — **not for production rendering** (interpreted, ~100× slower than JIT software renderers like SwiftShader). See [ADR](docs/dev/research/ADR-SPIRV-JIT-VS-INTERPRETER.md).
**Debug & Testing:**
- Render pass instrumentation: `hal.Logger().Debug()` events + `RenderPassStats` for CI e2e assertions
- `GetFramebuffer()` pixel readback for headless test verification
- Damage-aware partial blit with pixel-level test coverage
**Windowed Presentation:**
- **Windows:** DWM-safe `CreateDIBSection` + `BitBlt` (SDL3/Qt6 pattern), zero-copy into GDI bitmap
- **Linux X11:** `XPutImage` via goffi (Skia pattern), BGRA = X11 ZPixmap native format
- **macOS:** CGImage + `setContents:` (CALayer) or Metal `nextDrawable` + `replaceRegion` (CAMetalLayer). Contributor: @k-chimi
---
## Environment Variables
| Variable | Values | Description |
|----------|--------|-------------|
| `GOGPU_DX12_DXIL` | `1` | Enable DXIL direct compilation on DX12 (experimental). Bypasses HLSL→FXC, generates DXIL bytecode directly from naga IR. SM 6.0+, zero external dependencies. Default: off (uses HLSL→FXC). |
| `GOGPU_DX12_DXIL_OVERRIDE_VS` | file path | Replace vertex shader DXIL with contents of the given file. For debugging only. |
| `GOGPU_DX12_DXIL_OVERRIDE_PS` | file path | Replace pixel shader DXIL with contents of the given file. For debugging only. |
> **Note:** Backend selection (`GOGPU_GRAPHICS_API`) is handled by `gogpu` (the app framework), not by `wgpu` directly. See [gogpu documentation](https://github.com/gogpu/gogpu) for `GOGPU_GRAPHICS_API=vulkan|dx12|metal|gles|software`.
---
## Ecosystem
**wgpu** is the foundation of the [GoGPU](https://github.com/gogpu) ecosystem.
| Project | Description |
|---------|-------------|
| [gogpu/gogpu](https://github.com/gogpu/gogpu) | GPU framework with windowing and input |
| **gogpu/wgpu** | **Pure Go WebGPU (this repo)** |
| [gogpu/naga](https://github.com/gogpu/naga) | Shader compiler (WGSL to SPIR-V, HLSL, MSL, GLSL, DXIL) |
| [gogpu/gg](https://github.com/gogpu/gg) | 2D graphics library with GPU SDF acceleration |
| [gogpu/ui](https://github.com/gogpu/ui) | GUI toolkit: 22+ widgets, 4 themes |
| [gogpu/gputypes](https://github.com/gogpu/gputypes) | Shared WebGPU type definitions |
| [go-webgpu/goffi](https://github.com/go-webgpu/goffi) | Pure Go FFI library |
---
## Documentation
- **[Compute Shaders Guide](docs/COMPUTE-SHADERS.md)** — Getting started with compute
- **[Compute Backend Differences](docs/COMPUTE-BACKENDS.md)** — Per-backend capabilities
- **[ARCHITECTURE.md](docs/ARCHITECTURE.md)** — System architecture
- **[ROADMAP.md](ROADMAP.md)** — Development milestones
- **[CHANGELOG.md](CHANGELOG.md)** — Release notes
- **[CONTRIBUTING.md](CONTRIBUTING.md)** — Contribution guidelines
- **[pkg.go.dev](https://pkg.go.dev/github.com/gogpu/wgpu)** — API reference
---
## References
- [WebGPU Specification](https://www.w3.org/TR/webgpu/) — W3C standard
- [wgpu (Rust)](https://github.com/gfx-rs/wgpu) — Reference implementation
- [Dawn (C++)](https://dawn.googlesource.com/dawn) — Google's implementation
- [Architecture Deep-Dive (Chinese)](https://chenxutan.com/d/1987.html) — Performance benchmarks, Snatchable pattern analysis, zero-alloc hot paths
---
## Contributing
Contributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
**Priority areas:**
- Cross-platform testing
- Performance benchmarks
- Documentation improvements
- Bug reports and fixes
---
## License
MIT License — see [LICENSE](LICENSE) for details.
---
wgpu — WebGPU in Pure Go