naga

package module
v0.8.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 4, 2026 License: MIT Imports: 4 Imported by: 0

README

naga

Pure Go Shader Compiler
WGSL to SPIR-V, MSL, GLSL, and HLSL. Zero CGO.

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

Part of the GoGPU ecosystem


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
  • MSL Backend — Metal Shading Language output for macOS/iOS
  • GLSL Backend — OpenGL Shading Language for OpenGL 3.3+, ES 3.0+
  • HLSL Backend — High-Level Shading Language for DirectX 11/12
  • 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

Multiple Backends

// Parse and lower WGSL to IR (shared across all backends)
ast, _ := naga.Parse(source)
module, _ := naga.Lower(ast)

// Generate SPIR-V (Vulkan)
spirvBytes, _ := naga.GenerateSPIRV(module, spirv.Options{})

// Generate MSL (Metal)
mslCode, _, _ := msl.Compile(module, msl.DefaultOptions())

// Generate GLSL (OpenGL)
glslCode, _, _ := glsl.Compile(module, glsl.DefaultOptions())

// Generate HLSL (DirectX)
hlslCode, _, _ := hlsl.Compile(module, hlsl.DefaultOptions())

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)
│   └── registry.go    # Type deduplication (~100 LOC)
├── 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)
├── msl/               # MSL backend (Metal)
│   ├── backend.go     # Public API, Options, Compile()
│   ├── writer.go      # MSL code writer
│   ├── types.go       # Type generation (~400 LOC)
│   ├── expressions.go # Expression codegen (~600 LOC)
│   ├── statements.go  # Statement codegen (~350 LOC)
│   ├── functions.go   # Entry points and functions (~500 LOC)
│   └── keywords.go    # MSL/C++ reserved words
├── glsl/              # GLSL backend (OpenGL)
│   ├── backend.go     # Public API
│   ├── writer.go      # GLSL code writer
│   ├── types.go       # Type generation
│   ├── expressions.go # Expression codegen
│   ├── statements.go  # Statement codegen
│   └── keywords.go    # Reserved word escaping
├── hlsl/              # HLSL backend (DirectX)
│   ├── backend.go     # Public API, Options, Compile()
│   ├── writer.go      # HLSL code writer (~400 LOC)
│   ├── types.go       # Type generation (~500 LOC)
│   ├── expressions.go # Expression codegen (~1100 LOC)
│   ├── statements.go  # Statement codegen (~600 LOC)
│   ├── storage.go     # Buffer/atomic operations (~500 LOC)
│   ├── functions.go   # Entry points with semantics (~500 LOC)
│   └── keywords.go    # HLSL reserved words
├── 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

Status

Current Version: See CHANGELOG.md for release history.

Backend Status Target Platform
SPIR-V ✅ Stable Vulkan
MSL ✅ Stable Metal (macOS/iOS)
GLSL ✅ Stable OpenGL 3.3+, ES 3.0+
HLSL ✅ Stable DirectX 11/12

See ROADMAP.md for detailed development plans.

References

Project Description Purpose
gogpu/gogpu Graphics framework GPU abstraction, windowing, input
gogpu/wgpu Pure Go WebGPU Vulkan, Metal, GLES, Software backends
gogpu/gg 2D graphics Canvas API, scene graph, GPU text
gogpu/ui GUI toolkit Widgets, layouts, themes (planned)
go-webgpu/webgpu FFI bindings wgpu-native integration

Note: Always use the latest versions. Check each repository for current releases.

Contributing

We welcome contributions! Areas where help is needed:

  • Additional WGSL features
  • Test cases from real shaders
  • Backend optimizations
  • Documentation improvements

License

MIT License — see LICENSE for details.


naga — Shaders in Pure Go

Documentation

Overview

Package naga provides a Pure Go shader compiler.

naga compiles WGSL (WebGPU Shading Language) source code to multiple output formats:

  • SPIR-V — Binary format for Vulkan
  • MSL — Metal Shading Language for macOS/iOS
  • GLSL — OpenGL Shading Language for OpenGL 3.3+, ES 3.0+

The package provides a simple, high-level API for shader compilation as well as lower-level access to individual compilation stages.

Example usage (SPIR-V):

source := `
@vertex
fn main(@builtin(vertex_index) idx: u32) -> @builtin(position) vec4<f32> {
    return vec4<f32>(0.0, 0.0, 0.0, 1.0);
}
`
spirv, err := naga.Compile(source)
if err != nil {
    log.Fatal(err)
}

For MSL output, use the msl package:

module, _ := naga.Lower(ast)
mslCode, info, err := msl.Compile(module, msl.DefaultOptions())

For GLSL output, use the glsl package:

module, _ := naga.Lower(ast)
glslCode, info, err := glsl.Compile(module, glsl.DefaultOptions())

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Compile

func Compile(source string) ([]byte, error)

Compile compiles WGSL source code to SPIR-V binary using default options.

This is the simplest way to compile a shader. For more control, use CompileWithOptions or the individual Parse/Lower/Generate functions.

func CompileWithOptions

func CompileWithOptions(source string, opts CompileOptions) ([]byte, error)

CompileWithOptions compiles WGSL source code to SPIR-V binary with custom options.

The compilation pipeline is:

  1. Parse WGSL source to AST
  2. Lower AST to IR (intermediate representation)
  3. Validate IR (if enabled)
  4. Generate SPIR-V binary

func GenerateSPIRV

func GenerateSPIRV(module *ir.Module, opts spirv.Options) ([]byte, error)

GenerateSPIRV generates SPIR-V binary from IR module.

This is the final stage of compilation. The output is a binary blob that can be directly consumed by Vulkan or other SPIR-V consumers.

func Lower

func Lower(ast *wgsl.Module) (*ir.Module, error)

Lower converts WGSL AST to IR (Intermediate Representation).

The IR is a lower-level representation that includes type information, resolved identifiers, and a simpler structure suitable for code generation.

func LowerWithSource added in v0.4.0

func LowerWithSource(ast *wgsl.Module, source string) (*ir.Module, error)

LowerWithSource converts WGSL AST to IR, keeping source for error messages.

When source is provided, errors will include line:column information and can show source context using ErrorList.FormatAll().

func Parse

func Parse(source string) (*wgsl.Module, error)

Parse parses WGSL source code to AST (Abstract Syntax Tree).

This is the first stage of compilation. The AST represents the syntactic structure of the shader but does not include semantic information like types.

func Validate

func Validate(module *ir.Module) ([]ir.ValidationError, error)

Validate validates an IR module for correctness.

Validation checks include:

  • Type consistency
  • Reference validity (all handles point to valid objects)
  • Control flow validity (structured control flow rules)
  • Binding uniqueness (no duplicate @group/@binding)

Returns a slice of validation errors. If the slice is empty, validation passed.

Types

type CompileOptions

type CompileOptions struct {
	// SPIRVVersion is the target SPIR-V version (default: 1.3)
	SPIRVVersion spirv.Version

	// Debug enables debug info in output (OpName, OpLine, etc.)
	Debug bool

	// Validate enables IR validation before code generation
	Validate bool
}

CompileOptions configures shader compilation.

func DefaultOptions

func DefaultOptions() CompileOptions

DefaultOptions returns sensible default options.

Directories

Path Synopsis
cmd
nagac command
Command nagac is the naga shader compiler CLI.
Command nagac is the naga shader compiler CLI.
Package glsl provides a GLSL (OpenGL Shading Language) backend for naga.
Package glsl provides a GLSL (OpenGL Shading Language) backend for naga.
Package hlsl provides HLSL (High-Level Shading Language) code generation from the naga intermediate representation.
Package hlsl provides HLSL (High-Level Shading Language) code generation from the naga intermediate representation.
Package ir defines the intermediate representation for naga.
Package ir defines the intermediate representation for naga.
Package msl implements Metal Shading Language (MSL) code generation for naga.
Package msl implements Metal Shading Language (MSL) code generation for naga.
Package spirv provides SPIR-V code generation from naga IR.
Package spirv provides SPIR-V code generation from naga IR.
Package wgsl provides WGSL (WebGPU Shading Language) parsing.
Package wgsl provides WGSL (WebGPU Shading Language) parsing.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL