# 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