shdrlib 0.1.3

A three-tiered Vulkan shader compilation and rendering framework built in pure Rust
Documentation
# Architecture Overview


**How shdrlib is designed and why.**

## Core Philosophy


**Progressive disclosure** - Start simple, gain complexity when needed.

Three tiers, one library. Choose your abstraction level.

## Design Goals


1. **Zero-cost abstractions** - Higher tiers compile to same code as lower tiers
2. **Memory safety** - Rust ownership prevents use-after-free (in EZ/EX)
3. **Mixing tiers** - Drop to lower tier anytime for more control
4. **Pure Rust** - No external build tools (naga for shaders)

## Not a Game Engine


shdrlib is a **rendering library**, not a full engine.

**We provide:**
- Vulkan wrapper with three abstraction levels
- Shader compilation (GLSL → SPIR-V)
- Resource management helpers

**You provide:**
- Windowing (winit, SDL, etc.)
- Input handling
- Asset loading
- Game logic

## Three-Tier System


### CORE (Tier 0)

**Philosophy:** Thin wrappers around ash/Vulkan

**Pattern:** Manual everything
```rust
let instance = Instance::new(...)?;
let device = Device::new(&instance, ...)?;
shader.destroy(&device);  // Manual cleanup
```

**Use when:** Building frameworks, need absolute control

---

### EX (Tier 1) ⭐

**Philosophy:** Ergonomic managers with type-safe IDs

**Pattern:** Explicit configuration, automatic cleanup
```rust
let runtime = RuntimeManager::new(...)?;
let shaders = ShaderManager::new(...)?;
// Automatic cleanup via Rust drop
```

**Use when:** Production apps, games

---

### EZ (Tier 2)

**Philosophy:** One-liners with smart defaults

**Pattern:** Minimal code
```rust
let renderer = EzRenderer::new()?;
let pipeline = renderer.quick_pipeline(v, f)?;
```

**Use when:** Learning, prototyping

---

## Key Patterns


### 1. Manual Destroy (CORE)


CORE objects don't hold Device references, so no automatic `Drop`:

```rust
shader.destroy(&device);  // Manual
```

**Why:** Keeps wrappers thin, no Arc overhead.

### 2. Owned Layout (CORE)


Pipeline owns PipelineLayout to guarantee correct drop order:

```rust
pub struct Pipeline {
    pipeline: vk::Pipeline,
    layout: PipelineLayout,  // Owned
}
```

### 3. Arc Sharing (EX)


Managers share Device via Arc to avoid lifetimes:

```rust
pub struct RuntimeManager {
    device: Arc<Device>,
}

pub struct ShaderManager {
    device: Arc<Device>,  // Cloned from RuntimeManager
}
```

**Why:** Ensures Device outlives all resources, no lifetime parameters.

### 4. Type-Safe IDs (EX)


Newtype wrappers prevent mixing resource types:

```rust
pub struct ShaderId(usize);
pub struct PipelineId(usize);

shaders.get_pipeline(shader_id)?;  // ❌ Compile error!
```

### 5. Wrapper Wrapping (EZ)


EZ wraps EX which uses CORE:

```rust
pub struct EzRenderer {
    runtime: RuntimeManager,   // EX tier
    shaders: ShaderManager,    // EX tier
}
```

All tiers available: `renderer.device()` → CORE access

---

## Module Structure


### CORE (12 modules)

- `instance` - Vulkan instance + debug
- `device` - Logical device + memory/queue queries
- `queue` - Command submission + presentation
- `command` - CommandPool + CommandBuffer
- `shader` - GLSL→SPIR-V + reflection
- `pipeline` - Graphics/compute pipelines
- `memory` - Buffer + Image allocation
- `descriptor` - Descriptor sets + pools
- `sync` - Fence + Semaphore
- `surface` - Platform-agnostic surface
- `swapchain` - Image acquisition + present
- `utils` - Helper functions

### EX (3 managers + helpers)

- `runtime_manager` - Vulkan lifecycle + frame sync
- `shader_manager` - Shader/pipeline tracking
- `pipeline_builder` - Fluent pipeline config
- `helpers/` - Buffer, image, descriptor utilities

### EZ (1 all-in-one)

- `ez::EzRenderer` - Unified rendering interface

---

## Safety Model


### CORE Tier

**Manual lifetime management required.**

```rust
let shader = Shader::from_glsl(&device, ...)?;
// ... use shader ...
shader.destroy(&device);  // YOU must call this
```

**UB possible if:**
- Wrong drop order (Pipeline before Device)
- Use-after-free (using shader after destroy)
- Device dropped while resources alive

**Mitigation:** Validation layers catch most errors

---

### EX Tier

**Rust ownership prevents UB.**

```rust
let mut shaders = ShaderManager::new(device)?;
let id = shaders.add_shader(...)?;
// ShaderManager owns shaders, correct drop order guaranteed
```

**Safe because:**
- Arc\<Device\> ensures device outlives resources
- Managers own resources
- Rust enforces correct drop order

---

### EZ Tier

**Foolproof APIs.**

```rust
let mut renderer = EzRenderer::new()?;
// Everything managed, hard to misuse
```

---

## Performance


### Zero-Cost Abstractions


All tiers compile to identical machine code:

```rust
// EZ tier
frame.draw(3, 1, 0, 0);

// Compiles to same code as CORE tier
unsafe { device.cmd_draw(cmd, 3, 1, 0, 0); }
```

**Verified via:**
- Benchmarks (see `benches/`)
- Assembly inspection (`cargo asm`)
- Profiling (RenderDoc, perf)

### Inline Everywhere


```rust
#[inline]

pub fn draw(&self, vertex_count: u32, ...) {
    unsafe { self.device.cmd_draw(self.cmd, vertex_count, ...); }
}
```

Optimizer eliminates wrapper overhead.

---

## Shader Compilation


**Uses naga (pure Rust):**

```rust
GLSL → naga → SPIR-V → spirv-reflect → Descriptors
```

**Benefits:**
- No external tools (glslang, shaderc)
- Cross-platform
- Fast compile times

**Limitation:** Naga's GLSL support is less complete than glslang. Complex shaders may not compile.

---

## Error Handling


### Error Hierarchy


```
EzError wraps
  ├─ RuntimeError wraps
  │   └─ DeviceError / ShaderError / etc.
  └─ ShaderManagerError wraps
      └─ ShaderError / PipelineError
```

**Pattern:** Higher tiers add context:

```rust
// CORE
ShaderError::CompilationFailed("syntax error at line 10")

// EX
ShaderManagerError::ShaderCompilationFailed {
    name: "my_shader",
    source: ShaderError::CompilationFailed(...)
}
```

---

## Testing


**48 CORE tests + 25 EX tests + 3 EZ demos = 76 total**

**Strategy:**
- CORE: Test each module independently
- EX: Test manager lifecycles
- EZ: Full integration demos

**No mocking:** Real Vulkan objects tested with validation layers.

---

## Dependencies


- **ash** 0.38 - Vulkan bindings
- **naga** 22 - Shader compilation
- **spirv-reflect** 0.2 - Reflection
- **thiserror** 1.0 - Error handling

**All pure Rust, no C/C++ dependencies.**

---

## Future Architecture


**Planned:**
- Render graph system (higher than EZ)
- Multi-threaded command recording
- Ray tracing support (CORE → EX → EZ)
- HLSL/WGSL shader support

**Not planned:**
- GUI systems
- Physics engines
- Asset management
- Scene graphs

**shdrlib focuses on rendering only.**

---

## See Also


- [Three-Tier Design]three-tier-design.md - Deep dive into tier philosophy
- [Zero-Cost Abstractions]zero-cost-abstractions.md - Performance details