shdrlib 0.1.2

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


Quick reference for shdrlib's three-tier API.

> **Full API docs:** Run `cargo doc --open`

---

## CORE Tier


**Thin Vulkan wrappers. Manual lifetime management required.**

### Instance & Device


```rust
// Instance
let instance = Instance::new(&InstanceCreateInfo { /* ... */ })?;
instance.handle() -> &ash::Instance
instance.enumerate_physical_devices() -> Result<Vec<vk::PhysicalDevice>>

// Device
let device = Device::new(&instance, physical_device, &DeviceCreateInfo { /* ... */ })?;
device.handle() -> &ash::Device
device.find_memory_type(type_filter, properties) -> Option<u32>
device.find_queue_family(flags) -> Option<u32>
device.wait_idle() -> Result<()>
```

### Shaders & Pipelines


```rust
// Shader
let shader = Shader::from_glsl(&device, source, ShaderStage::Vertex)?;
let shader = Shader::from_spirv(&device, spirv, ShaderStage::Fragment)?;
shader.handle() -> vk::ShaderModule
shader.destroy(&device)

// Pipeline
let pipeline = PipelineBuilder::new()
    .vertex_shader(module, "main")
    .fragment_shader(module, "main")
    .color_attachment_formats(vec![Format::R8G8B8A8_UNORM])
    .build_graphics(&device, layout)?;
pipeline.handle() -> vk::Pipeline
pipeline.destroy(&device)
```

### Buffers & Images


```rust
// Buffer
let buffer = Buffer::new(&device, size, usage, memory_properties)?;
buffer.handle() -> vk::Buffer
buffer.map<T>(&device) -> Result<*mut T>
buffer.unmap(&device)
buffer.destroy(&device)

// Image
let image = Image::new(&device, extent, format, usage, memory_properties)?;
image.handle() -> vk::Image
image.view() -> vk::ImageView
image.destroy(&device)
```

### Commands


```rust
// CommandPool
let pool = CommandPool::new(&device, family_index, flags)?;
pool.allocate_primary(&device) -> Result<CommandBuffer>
pool.reset(&device, flags) -> Result<()>
pool.destroy(&device)

// CommandBuffer
cmd.begin(&device, flags)?;
cmd.bind_pipeline(&device, bind_point, pipeline);
cmd.bind_vertex_buffers(&device, first_binding, buffers, offsets);
cmd.draw(&device, vertex_count, instance_count, first_vertex, first_instance);
cmd.begin_rendering(&device, &rendering_info);
cmd.end_rendering(&device);
cmd.end(&device)?;
```

### Sync & Queues


```rust
// Fence & Semaphore
let fence = Fence::new(&device, signaled)?;
let semaphore = Semaphore::new(&device)?;
fence.wait(&device, timeout)?;
fence.reset(&device)?;

// Queue
let queue = Queue::get(&device, family_index, queue_index);
queue.submit(&device, command_buffers, wait_semaphores, signal_semaphores, fence)?;
queue.present(&device, swapchains, image_indices, wait_semaphores)?;
```

---

## EX Tier


**Ergonomic managers with type-safe resource tracking.**

### RuntimeManager


```rust
let mut runtime = RuntimeManager::new(RuntimeConfig::default())?;
runtime.device() -> Arc<Device>
runtime.queue() -> &Queue
runtime.command_pool() -> &CommandPool

// Frame management
let frame = runtime.begin_frame()?;
frame.command_buffer -> CommandBuffer
frame.frame_index -> usize

runtime.end_frame(&SubmitInfo::default())?;
runtime.wait_idle()?;
```

### ShaderManager


```rust
let mut shaders = ShaderManager::new(device)?;

// Add shaders (returns type-safe ShaderId)
let vert_id = shaders.add_shader(glsl, ShaderStage::Vertex, "vert")?;
let frag_id = shaders.add_shader(glsl, ShaderStage::Fragment, "frag")?;

// Build pipelines (returns type-safe PipelineId)
let pipeline_id = shaders.build_pipeline(
    PipelineBuilder::new()
        .vertex_shader(module, "main")
        .fragment_shader(module, "main")
        .color_attachment_formats(vec![Format::R8G8B8A8_UNORM]),
    "my_pipeline"
)?;

// Getters
shaders.get_shader(shader_id) -> Result<&Shader>
shaders.get_pipeline(pipeline_id) -> Result<&Pipeline>
```

### Buffer Helpers


```rust
use shdrlib::ex::helpers::*;

// One-liners
let vbuf = create_vertex_buffer(&device, &vertices)?;
let ibuf = create_index_buffer(&device, &indices)?;
let ubuf = create_uniform_buffer::<CameraData>(&device)?;
let sbuf = create_storage_buffer(&device, size)?;

// Data upload
write_buffer(&device, &buffer, &data)?;
copy_buffer(&device, &pool, &queue, &src, &dst, size)?;
```

### Image Helpers


```rust
use shdrlib::ex::helpers::*;

// One-liners
let rt = create_render_target(&device, width, height, format)?;
let ds = create_depth_stencil(&device, width, height, format)?;
let tex = create_texture(&device, width, height, format)?;
let img = create_storage_image(&device, width, height, format)?;

// Layout transitions
transition_image_layout(&device, &pool, &queue, image, old_layout, new_layout)?;
```

### Descriptor Helpers


```rust
use shdrlib::ex::helpers::*;

// Layout builder
let layout = DescriptorLayoutBuilder::new()
    .uniform_buffer(0, ShaderStageFlags::VERTEX)
    .combined_image_sampler(1, ShaderStageFlags::FRAGMENT)
    .build(&device)?;

// Pool builder
let pool = DescriptorPoolBuilder::simple_material(10).build(&device)?;

// Writer
DescriptorWriter::new(&device)
    .write_buffer(set, 0, buffer, offset, range, DescriptorType::UNIFORM_BUFFER)
    .write_image(set, 1, view, layout, DescriptorType::COMBINED_IMAGE_SAMPLER)
    .update();
```

---

## EZ Tier


**One-liner APIs with smart defaults.**

### EzRenderer


```rust
// Setup
let mut renderer = EzRenderer::new()?;
let renderer = EzRenderer::with_config(EzConfig { /* ... */ })?;

// Pipelines
let graphics = renderer.quick_pipeline(vertex_glsl, fragment_glsl)?;
let compute = renderer.quick_compute(compute_glsl)?;

// Buffers
let vbuf = renderer.create_vertex_buffer(&vertices)?;
let ibuf = renderer.create_index_buffer(&indices)?;
let ubuf = renderer.create_uniform_buffer::<T>()?;
let sbuf = renderer.create_storage_buffer(size)?;

// Images
let rt = renderer.create_render_target(width, height)?;
let ds = renderer.create_depth_stencil(width, height)?;
let tex = renderer.create_texture(width, height)?;

// Data
renderer.write_buffer(&buffer, &data)?;

// Rendering
renderer.render_frame(|frame| {
    frame.bind_pipeline(pipeline)?;
    frame.set_viewport(x, y, width, height);
    frame.set_scissor(x, y, width, height);
    frame.draw(vertex_count, instance_count, first_vertex, first_instance);
    Ok(())
})?;

// Access lower tiers
renderer.runtime() -> &RuntimeManager
renderer.shader_manager() -> &ShaderManager
renderer.device() -> Arc<Device>
```

### EzFrame


```rust
// In render_frame callback
renderer.render_frame(|frame| {
    // Binding
    frame.bind_pipeline(pipeline_id)?;
    frame.bind_vertex_buffers(first, buffers, offsets);
    frame.bind_index_buffer(buffer, offset, index_type);
    frame.bind_descriptor_sets(pipeline_id, first_set, sets, offsets)?;

    // Dynamic state
    frame.set_viewport(x, y, width, height);
    frame.set_scissor(x, y, width, height);

    // Drawing
    frame.draw(vertex_count, instance_count, first_vertex, first_instance);
    frame.draw_indexed(index_count, instance_count, first_index, vertex_offset, first_instance);
    frame.dispatch(x, y, z);

    // Rendering control
    frame.begin_rendering(width, height, format);
    frame.end_rendering();

    // Low-level access
    frame.command_buffer() -> vk::CommandBuffer
    frame.device() -> &Arc<Device>

    Ok(())
})
```

---

## Common Patterns


### CORE: Manual Everything


```rust
let instance = Instance::new(&InstanceCreateInfo::default())?;
let device = Device::new(&instance, physical_device, &DeviceCreateInfo::default())?;
let shader = Shader::from_glsl(&device, glsl, ShaderStage::Vertex)?;

// YOU manage drop order!
shader.destroy(&device);
device.wait_idle()?;
// device drops automatically
```

### EX: Managed Resources


```rust
let mut runtime = RuntimeManager::new(RuntimeConfig::default())?;
let mut shaders = ShaderManager::new(runtime.device())?;
let pipeline_id = shaders.build_pipeline(/* ... */)?;

// Drop order guaranteed by Rust
// No manual cleanup needed
```

### EZ: One-Liners


```rust
let mut renderer = EzRenderer::new()?;
let pipeline = renderer.quick_pipeline(vert, frag)?;

renderer.render_frame(|frame| {
    frame.bind_pipeline(pipeline)?;
    frame.draw(3, 1, 0, 0);
    Ok(())
})?;

// Everything auto-managed
```

---

## Error Types


**CORE:**
- `InstanceError`, `DeviceError`, `ShaderError`, `PipelineError`
- `MemoryError`, `CommandPoolError`, `CommandBufferError`
- `QueueError`, `FenceError`, `SemaphoreError`

**EX:**
- `RuntimeError` - Wraps CORE errors with context
- `ShaderManagerError` - Shader/pipeline management errors

**EZ:**
- `EzError` - Wraps all lower-tier errors

---

## Constants


```rust
// Timeouts
FENCE_TIMEOUT: u64 = 1_000_000_000  // 1 second
NO_TIMEOUT: u64 = u64::MAX

// API version
VULKAN_API_VERSION: u32 = vk::API_VERSION_1_3
```

---

## See Also


- **Full API:** `cargo doc --open`
- **Examples:** `demos/` directory
- **Guides:** `docs/guides/`