Skip to content

mewbak/naga

 
 

naga

Pure Go Shader Compiler
WGSL to SPIR-V. Zero CGO.

CI codecov Go Reference Go Report Card License Go Version Zero CGO

Part of the GoGPU ecosystem

v0.4.0 — Compute shaders, atomics, barriers, unused var warnings. ~17K lines of pure Go.


Features

  • Pure Go — No CGO, no external dependencies
  • WGSL Frontend — Full lexer and parser (140+ tokens)
  • IR — Complete intermediate representation (expressions, statements, types)
  • Compute Shaders — Storage buffers, workgroup memory, @workgroup_size
  • Atomic Operations — atomicAdd, atomicSub, atomicMin, atomicMax, atomicCompareExchangeWeak
  • Barriers — workgroupBarrier, storageBarrier, textureBarrier
  • Type Inference — Automatic type resolution for all expressions, including let bindings
  • Type Deduplication — SPIR-V compliant unique type emission
  • Array Initializationarray(1, 2, 3) shorthand with inferred type and size
  • Texture Sampling — textureSample, textureLoad, textureStore, textureDimensions
  • SPIR-V Backend — Vulkan-compatible bytecode generation with correct type handling
  • Warnings — Unused variable detection with _ prefix exception
  • Validation — Type checking and semantic validation
  • CLI Toolnagac command-line compiler

Installation

go get github.com/gogpu/naga

Usage

As Library

package main

import (
    "fmt"
    "log"

    "github.com/gogpu/naga"
)

func main() {
    source := `
@vertex
fn main(@builtin(vertex_index) idx: u32) -> @builtin(position) vec4<f32> {
    return vec4<f32>(0.0, 0.0, 0.0, 1.0);
}
`
    // Simple compilation
    spirv, err := naga.Compile(source)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Generated %d bytes of SPIR-V\n", len(spirv))
}

With Options

opts := naga.CompileOptions{
    SPIRVVersion: spirv.Version1_3,
    Debug:        true,   // Include debug names
    Validate:     true,   // Enable IR validation
}
spirv, err := naga.CompileWithOptions(source, opts)

CLI Tool

# Install
go install github.com/gogpu/naga/cmd/nagac@latest

# Compile shader
nagac shader.wgsl -o shader.spv

# With debug info
nagac -debug shader.wgsl -o shader.spv

# Show version
nagac -version

Individual Stages

// Parse WGSL to AST
ast, err := naga.Parse(source)

// Lower AST to IR
module, err := naga.Lower(ast)

// Validate IR
errors, err := naga.Validate(module)

// Generate SPIR-V
spirvOpts := spirv.Options{Version: spirv.Version1_3, Debug: true}
spirvBytes, err := naga.GenerateSPIRV(module, spirvOpts)

Architecture

naga/
├── wgsl/              # WGSL frontend
│   ├── token.go       # Token types (140+)
│   ├── lexer.go       # Tokenizer
│   ├── ast.go         # AST types
│   ├── parser.go      # Recursive descent parser (~1400 LOC)
│   └── lower.go       # AST → IR converter (~1100 LOC)
├── ir/                # Intermediate representation
│   ├── ir.go          # Core types (Module, Type, Function)
│   ├── expression.go  # 33 expression types (~520 LOC)
│   ├── statement.go   # 16 statement types (~320 LOC)
│   ├── validate.go    # IR validation (~750 LOC)
│   ├── resolve.go     # Type inference (~500 LOC) ← NEW
│   └── registry.go    # Type deduplication (~100 LOC) ← NEW
├── spirv/             # SPIR-V backend
│   ├── spirv.go       # SPIR-V constants and opcodes
│   ├── writer.go      # Binary module builder (~670 LOC)
│   └── backend.go     # IR → SPIR-V translator (~1800 LOC)
├── naga.go            # Public API
└── cmd/nagac/         # CLI tool

Supported WGSL Features

Types

  • Scalars: f32, f64, i32, u32, bool
  • Vectors: vec2<T>, vec3<T>, vec4<T>
  • Matrices: mat2x2<f32> ... mat4x4<f32>
  • Arrays: array<T, N>
  • Structs: struct { ... }
  • Atomics: atomic<u32>, atomic<i32>
  • Textures: texture_2d<f32>, texture_3d<f32>, texture_cube<f32>
  • Samplers: sampler, sampler_comparison

Shader Stages

  • @vertex — Vertex shaders with @builtin(position) output
  • @fragment — Fragment shaders with @location(N) outputs
  • @compute — Compute shaders with @workgroup_size(X, Y, Z)

Bindings

  • @builtin(position), @builtin(vertex_index), @builtin(instance_index)
  • @builtin(global_invocation_id) — Compute shader invocation ID
  • @location(N) — Vertex attributes and fragment outputs
  • @group(G) @binding(B) — Resource bindings

Address Spaces

  • var<uniform> — Uniform buffer
  • var<storage, read> — Read-only storage buffer
  • var<storage, read_write> — Read-write storage buffer
  • var<workgroup> — Workgroup shared memory

Statements

  • Variable declarations: var, let
  • Control flow: if, else, for, while, loop
  • Loop control: break, continue
  • Functions: return, discard
  • Assignment: =, +=, -=, *=, /=

Built-in Functions (50+)

  • Math: sin, cos, tan, exp, log, pow, sqrt, abs, min, max, clamp
  • Geometric: dot, cross, length, distance, normalize, reflect
  • Interpolation: mix, step, smoothstep
  • Derivatives: dpdx, dpdy, fwidth
  • Atomic: atomicAdd, atomicSub, atomicMin, atomicMax, atomicAnd, atomicOr, atomicXor, atomicExchange, atomicCompareExchangeWeak
  • Barriers: workgroupBarrier, storageBarrier, textureBarrier

Roadmap

v0.1.0 ✅

  • WGSL lexer and parser
  • Complete IR (expressions, statements, types)
  • IR validation
  • SPIR-V binary writer
  • SPIR-V backend (types, constants, functions, expressions)
  • Control flow (if, loop, break, continue)
  • Built-in math functions (GLSL.std.450)
  • Public API and CLI tool

v0.2.0 ✅

  • Type inference for all expressions
  • Type deduplication (SPIR-V compliant)
  • Correct int/float/uint opcode selection
  • SPIR-V backend with proper type handling
  • 67+ unit tests

v0.3.0 ✅

  • Type inference for let bindings
  • Array initialization syntax (array(1, 2, 3))
  • Texture sampling operations (textureSample, textureLoad, textureStore)
  • SPIR-V image operations (OpImageSample*, OpImageFetch, OpImageQuery*)
  • 124 unit tests

v0.4.0 (Current) ✅

  • Better error messages with source locations
  • Storage buffers (var<storage, read>, var<storage, read_write>)
  • Workgroup shared memory (var<workgroup>)
  • Atomic operations (atomicAdd, atomicSub, atomicCompareExchangeWeak, etc.)
  • Workgroup barriers (workgroupBarrier, storageBarrier, textureBarrier)
  • Unused variable warnings
  • 203 unit tests

v0.5.0 (Next)

  • GLSL backend output
  • Source maps for debugging
  • Optimization passes

v1.0.0 (Goal)

  • Full WGSL specification compliance
  • Production-ready stability
  • HLSL/MSL backends

References

Related Projects

Project Description Status
gogpu/gogpu Pure Go graphics framework v0.4.0
gogpu/wgpu Pure Go WebGPU types and HAL v0.5.0
gogpu/gg 2D graphics with GPU backend, scene graph, SIMD v0.9.2
go-webgpu/webgpu WebGPU FFI bindings Stable

Contributing

We welcome contributions! Areas where help is needed:

  • Additional WGSL features (ray tracing, mesh shaders)
  • Test cases from real shaders
  • GLSL backend implementation
  • Documentation improvements

License

MIT License — see LICENSE for details.


naga — Shaders in Pure Go

About

Pure Go Shader Compiler — WGSL to SPIR-V

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Go 97.8%
  • Shell 2.2%