gpu-allocator
A pure-Rust sub-allocation library for managing GPU memory across Vulkan, DirectX 12, and Metal.
Repository Health
Technical Analysis
gpu-allocator is a sub-allocation library written entirely in Rust that manages GPU memory for graphics and compute applications targeting Vulkan, DirectX 12, and Metal. Rather than requesting a fresh memory allocation from the driver for every buffer or texture — an operation with real overhead and hard OS/driver limits on the number of live allocations — it carves large memory blocks into smaller sub-allocations with a free-list allocator, and falls back to dedicated blocks when a request doesn’t fit the shared pool.
It exposes a backend-specific Allocator type per graphics API behind Cargo feature flags (vulkan, d3d12, metal), each following the calling conventions of its respective ash/windows-rs/objc2 bindings, so engine code can request GPU memory with a MemoryLocation hint (device-only, upload, or readback) and get back an object owning the offset, size, and backing handle. It ships an optional visualizer feature built on egui for inspecting live memory blocks and leak sources, and supports no_std builds via the hashbrown feature for constrained targets.
What You Get
- Backend-specific allocators for Vulkan (via ash), DirectX 12 (via windows-rs), and Metal (via objc2), each behind its own Cargo feature flag
- A free-list sub-allocator that packs many buffer/texture allocations into shared memory blocks, plus a dedicated-block path for oversized allocations
MemoryLocationhints (GpuOnly,CpuToGpu,GpuToCpu,Unknown) that map allocation requests to the right heap or memory type per backend- Configurable
AllocationSizesfor tuning initial and maximum shared memory block sizes independently per memory type - An optional
visualizerfeature (egui-based) for inspecting live allocations, memory blocks, and leak sources at runtime no_stdsupport via thehashbrownfeature flag for use outside a standard-library environment
Common Use Cases
- Custom Vulkan renderer memory management - engine authors building a Vulkan renderer allocate
AllocationCreateDescbuffers/images from a sharedAllocatorinstead of callingvkAllocateMemoryper resource - DirectX 12 resource placement - Windows game/engine code creates placed resources on GPU heaps managed by the D3D12 allocator, avoiding a per-resource
CreateCommittedResourcecall - Metal buffer and texture allocation on Apple platforms - macOS/iOS graphics code obtains GPU-visible buffers and heaps through the Metal backend, using objc2 bindings
- Debugging GPU memory leaks in a game engine - teams enable
store_stack_tracesand thevisualizerfeature to trace which call sites allocated memory that was never freed - Streaming/upload buffer management - applications request
CpuToGpuallocations for per-frame constant buffers and vertex streaming, with predictable memory-block growth viaAllocationSizes
Under The Hood
Architecture
The crate is organized around a small SubAllocator trait (src/allocator/mod.rs) implemented by two concrete strategies: FreeListAllocator (src/allocator/free_list_allocator/mod.rs), a best-fit, doubly-linked-list-based allocator that sub-divides a shared memory block across many buffer/texture allocations while tracking Vulkan-style linear/non-linear granularity conflicts, and DedicatedBlockAllocator for oversized allocations that get their own memory block. Each graphics backend (src/vulkan/mod.rs, src/d3d12/mod.rs, src/metal/mod.rs) wraps these sub-allocators in a public Allocator type that owns per-memory-type collections of blocks, exposes allocate/free/generate_report, and defers to the backend’s native API (ash for Vulkan, windows-rs for D3D12, objc2-metal for Metal) only at the block-creation boundary. This clean split — one platform-agnostic sub-allocation core, three thin backend adapters — means the core algorithm never needs backend-specific changes, and a new backend only has to implement memory-block creation/destruction.
Tech Stack
Pure Rust, edition = "2021", MSRV 1.71 (1.81 for no_std+hashbrown). Core dependencies are minimal: log for tracing, thiserror for typed errors, and presser for safely writing to mapped memory. Backend bindings are optional and feature-gated: ash (Vulkan), windows-rs (D3D12, Windows-only target), and objc2/objc2-metal/objc2-foundation (Metal, Apple-only target). The optional visualizer feature pulls in egui/egui_extras for a debug UI, and hashbrown substitutes for std::collections in no_std builds. No async runtime, no build-script code generation — it’s a straightforward, dependency-light library crate.
Code Quality
There are no dedicated #[test] unit tests in src/; correctness is instead exercised through extensive no_run doctests embedded in src/lib.rs covering all three backends, plus CI-run doc tests and MSRV checks across multiple feature-flag combinations (std, hashbrown, visualizer) on Linux, Windows, and macOS runners. CI additionally enforces cargo fmt --check and cargo clippy -D warnings across the same feature matrix, and the crate itself opts into strict lint gates (#![deny(clippy::unimplemented, clippy::unwrap_used, clippy::ok_expect)], with the free-list allocator further denying unsafe_code). Error handling is typed via a small thiserror-based AllocationError enum rather than panics. The absence of a conventional test suite is a real gap for an allocator whose correctness (fragmentation, granularity conflicts, leak tracking) is subtle, though the doctest/CI coverage across three platforms partially offsets it.
What Makes It Unique
Most memory sub-allocators are backend-specific (a Vulkan-only VMA-style allocator, or a D3D12-only one); gpu-allocator instead implements one sub-allocation algorithm and exposes it uniformly across Vulkan, DirectX 12, and Metal behind Cargo feature flags, letting cross-platform engines share allocation logic and tuning (via AllocationSizes) instead of maintaining three separate allocators. It also supports no_std operation via hashbrown, which is uncommon for GPU-facing allocators and useful for constrained or embedded graphics targets, and ships an integrated egui-based visualizer for live leak/fragmentation debugging rather than requiring external tooling.