gpu-allocator

A pure-Rust sub-allocation library for managing GPU memory across Vulkan, DirectX 12, and Metal.

Library
Cargo
v0.28.0
493stars
MIT OR Apache-2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
64/100Good
Development Activity56
Maintenance40
Community72
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
77/100Good
Architecture82
Code Quality72
Innovation78
Learning Curve75

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
  • MemoryLocation hints (GpuOnly, CpuToGpu, GpuToCpu, Unknown) that map allocation requests to the right heap or memory type per backend
  • Configurable AllocationSizes for tuning initial and maximum shared memory block sizes independently per memory type
  • An optional visualizer feature (egui-based) for inspecting live allocations, memory blocks, and leak sources at runtime
  • no_std support via the hashbrown feature flag for use outside a standard-library environment

Common Use Cases

  • Custom Vulkan renderer memory management - engine authors building a Vulkan renderer allocate AllocationCreateDesc buffers/images from a shared Allocator instead of calling vkAllocateMemory per resource
  • DirectX 12 resource placement - Windows game/engine code creates placed resources on GPU heaps managed by the D3D12 allocator, avoiding a per-resource CreateCommittedResource call
  • 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_traces and the visualizer feature to trace which call sites allocated memory that was never freed
  • Streaming/upload buffer management - applications request CpuToGpu allocations for per-frame constant buffers and vertex streaming, with predictable memory-block growth via AllocationSizes

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.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search