Current status (2026-06-15): historical/superseded graphics vision record. Use
STATUS.md,ARCHITECTURE.md, anddocs/COMPILER_WIND_DOWN_ASSESSMENT_2026-06-15.mdfor current compiler maturity. The current wind-down posture keeps C as the verified execution anchor, HLSL/GLSL as shader-source output, and SPIR-V/native backends as experimental research lanes.
Historical context from an earlier graphics push: BuildLang had accumulated a large Rust compiler and multiple graphics proof artifacts. Those counts and milestones are not the current release gate.
Now it needs to become the language elite graphics programmers demand - the tool Pascal Gilcher, Boris Vorontsov, and every AAA shader programmer would choose over HLSL/GLSL/C++.
The core thesis: No language lets you write math once and have it run identically on CPU and GPU, catches color space errors at compile time, and tracks floating-point precision through a rendering pipeline. BuildLang will be the first.
What we have (working):
- SPIR-V backend: 4,274 lines, generates valid SPIR-V binaries (spirv-val passes)
- Hardcoded shader generators produce valid vertex/fragment/compute shaders
- Algebraic effects system with row polymorphism (proven end-to-end)
- TypeKind::WithEffect EXISTS in the AST (not yet wired to parser/type checker)
- Higher-kinded type infrastructure with Kind::Effect and Kind::Row
- Operator overloading, generics, multi-module compilation all working
What's missing (the gaps):
- End-to-end BuildLang source → SPIR-V → runs on GPU: NOT proven
- MIR→SPIR-V has ~50% operation coverage (many ops return zero/stub)
- No Vulkan host runtime (only printf stubs)
- WithEffect type annotations: not parsed, not lowered, not checked
- No color space types, no precision tracking
- DXIL backend: does not exist
Write once, run on CPU AND GPU - identical results
The compiler catches the bugs that take days to find
Replace raw DirectX/Vulkan calls with compiler-verified constructs
Goal: A BuildLang function with #[fragment] compiles to SPIR-V, loads in Vulkan, renders pixels.
Problem: The SPIR-V backend has hardcoded shader generators that produce valid SPIR-V, but the normal AST→MIR→SPIR-V path has ~50% operation coverage. Many MIR operations fall through to a default that returns zero.
Deliverables:
- Fix MIR→SPIR-V operation coverage: implement FieldAccess, VariantField, IndexAccess, pointer stores, globals
- Make
buildc compile shader.bld --target=spirvproduce valid SPIR-V from BuildLang source - Test: compile a real fragment shader (PBR BRDF from test 75) to SPIR-V, validate with spirv-val
Key file: buildlang/compiler/src/codegen/backend/spirv.rs
- Lines 1815-1817: pointer store stubs → implement OpStore
- Lines 1911-1915: default zero fallback → implement remaining RValues
- Line 669+:
gen_function()entry point for compilation
Problem: No host code exists to actually load and execute SPIR-V shaders.
Deliverables:
- Write a minimal Vulkan host library in C (~500 lines): create instance, device, swapchain, render pass, pipeline
- Expose as C FFI functions callable from BuildLang:
vk_init(),vk_create_pipeline(spv_bytes),vk_draw(),vk_present() - Wire into the BuildLang C runtime so a compiled program can create a window and render
Key files:
- New:
buildlang/runtime/vulkan_host.c- minimal Vulkan host - Modify:
buildlang/compiler/src/codegen/runtime.rs- add vulkan FFI declarations
Deliverables:
- Write a complete BuildLang program: vertex shader + fragment shader + host code
- Compile vertex/fragment to SPIR-V, host to native via C
- Program opens a window, renders a colored triangle, outputs a screenshot
- Same BRDF math compiled to C produces identical output values
Test: 102_vulkan_triangle.bld - first BuildLang program rendering real pixels via Vulkan
Proof point: C and SPIR-V backends produce bit-identical results for PBR functions
Goal: fn tonemap(c: LinearRGB) -> sRGB - the compiler catches color space mixing errors.
Problem: TypeKind::WithEffect { ty, effects } exists in the AST but is never parsed or lowered.
Deliverables:
- Extend the parser to handle
Type with Effect1, Effect2in parameter positions - Lower WithEffect to the type system as a new TyKind variant
- Propagate through function signatures: if input is
with ColorSpace<Linear>, output is too
Key files:
buildlang/compiler/src/parser/ty.rs- parsewithafter typebuildlang/compiler/src/types/ty.rs- add TyKind::Annotated { base, annotations }buildlang/compiler/src/types/infer.rs- propagate annotations through unification
Deliverables:
- Define built-in color space effects:
ColorSpace<Linear>,ColorSpace<sRGB>,ColorSpace<ACEScg>,ColorSpace<P3> - Define conversion functions that change the color space annotation
- Compiler error when mixing:
let wrong: sRGB = my_linear_color;
Syntax:
effect ColorSpace<S> {}
type LinearRGB = vec3 with ColorSpace<Linear>;
type sRGBColor = vec3 with ColorSpace<sRGB>;
fn srgb_to_linear(c: sRGBColor) -> LinearRGB { ... }
// COMPILE ERROR: expected LinearRGB, got sRGBColor
let result = pbr_shade(my_srgb_color);
Deliverables:
#[precision(bits = 23)]on function parameters and returns- Compiler tracks precision loss through arithmetic chains
- Warning when precision drops below a threshold
This is a research-level feature - start simple with annotations, work toward full tracking.
Goal: Render passes are first-class compiler-verified constructs.
This pillar depends on Pillars 1+2 being complete. Design only - no implementation yet.
Vision:
render_graph deferred_pipeline {
pass gbuffer {
vertex: gbuffer_vertex,
fragment: gbuffer_fragment,
outputs: [albedo: RGBA8, normal: RGB16F, depth: D32F],
}
pass lighting {
compute: tiled_lighting,
inputs: [gbuffer.albedo, gbuffer.normal, gbuffer.depth],
outputs: [hdr: RGBA16F],
}
pass tonemap {
fragment: aces_tonemap,
inputs: [lighting.hdr],
outputs: [display: sRGB_RGBA8],
}
}
The compiler verifies:
- All inputs satisfied by previous pass outputs
- No circular dependencies
- Format compatibility between connected passes
- Color space correctness at each stage
- Memory layout optimization
Do first (Pillar 1A): Fix MIR→SPIR-V operation coverage
- This is the single most impactful change
- Currently ~50% of MIR operations are handled
- Most gaps are mechanical - implement the same pattern for each missing op
- Estimated: 200-300 lines of Rust additions to spirv.rs
Do second (Pillar 1B): Minimal Vulkan host
- ~500 lines of C
- Standard boilerplate (every Vulkan tutorial covers this)
- Wire as FFI functions in the BuildLang runtime
Do third (Pillar 1C): The proof
- Write the triangle demo in BuildLang
- This is the moment BuildLang becomes real for graphics programmers
Then (Pillar 2A-2C): Color space types
- Parser changes: small
- Type system changes: medium
- Precision tracking: large (research-level)
| Milestone | Metric |
|---|---|
| Pillar 1A | buildc compile shader.bld --target=spirv produces valid SPIR-V from BuildLang source |
| Pillar 1B | A C program linked with the Vulkan host lib renders a triangle using BuildLang-compiled SPIR-V |
| Pillar 1C | A pure BuildLang program (no C) opens a window and renders pixels via Vulkan |
| Pillar 2A | fn foo(c: vec3 with ColorSpace<Linear>) parses, type-checks, and compiles |
| Pillar 2B | Compiler error when passing sRGB color to function expecting Linear |
| Pillar 2C | Precision warning after 10-pass pipeline |
Pillar 1:
compiler/src/codegen/backend/spirv.rs- MIR op coverage (primary work)compiler/src/codegen/runtime.rs- Vulkan FFI declarationscompiler/src/main.rs- ensure --target=spirv works end-to-end- New:
runtime/vulkan_host.c- minimal Vulkan host
Pillar 2:
compiler/src/parser/ty.rs- parsewithannotationscompiler/src/types/ty.rs- TyKind::Annotatedcompiler/src/types/infer.rs- annotation propagationcompiler/src/types/effects.rs- color space effect definitions
| Risk | Mitigation |
|---|---|
| SPIR-V MIR coverage too complex | Focus on shader-relevant ops only (no closures, no HashMap in shaders) |
| Vulkan host code is large | Use minimal triangle-only subset, expand later |
| Color space types affect all type inference | Make annotations optional - existing code unaffected |
| Precision tracking is research-level | Start with simple annotations, defer full tracking |