A frame capture and replay tool for Direct3D 11 and Direct3D 12 games on Windows. It runs as stand-in system DLLs in the game's folder and writes each captured frame to a SQLite database, which a command-line tool and a local web viewer read.
- Records every draw, dispatch, clear, copy, update and map of a frame in GPU order, with each draw's shaders, state and bindings
- Records the constant-buffer bytes each draw read, with constants named from the shaders' DXBC or DXIL reflection
- Stores each used resource's contents as the frame began and the render and depth targets at the end of each pass
- Captures up to 64 consecutive frames from one request
- Keeps resource contents in a blob store shared by all captures of a game, keyed by XXH3-128 and LZ4-compressed
- Lists, filters, exports (DDS, PNG, raw) and queries captures with
locum-cli, including plain SQL - Traces a target's output lane back to the texture channels, constants and vertex attributes it came from
- Replays a draw or a whole frame offline on the GPU or on WARP and verifies every target against the game's
- Holds a translation layer (DXVK, vkd3d-proton) to a captured frame: replays it on the system's Direct3D and through the layer, and names what only the layer draws differently or cannot do
- Changes draws with rules (skip, solid colour, replacement shader, constant), live in Direct3D 11 games or in replay
- Names textures, buffers and shader programs after the game's own files through indexes of DDS files, shaders and key lists
- Diffs two captures draw by draw
- Writes a process memory dump at capture time and searches it for the values a draw saw (Direct3D 11)
- Reads, sets and calls game values from a
table.txtto set up a scene before a capture - Browses captures in a local web viewer with timeline, draw, resource, shader and SQL pages
- Compares the output of shaders whose results depend on GPU thread order by records rather than bytes
- Windows, and a 64-bit game that uses Direct3D 11 or Direct3D 12
- Rust 1.99.0 (pinned in
rust-toolchain.toml) with the MSVC build tools; the DLL shims are linked withlib.exe - Bun for the viewer
dxcompiler.dllfor DXIL tools and DXIL replay rules: found on the DLL search path, in the Windows SDK, or atLOCUM_DXCOMPILER
Do not use locum on games with anti-cheat. Live override rules, memory dumps and the skip/max_mb capture options
are implemented for Direct3D 11 only.
Each release has two downloads for Windows (x86_64), each with
its .sha256 (and sha256.sum for both):
locum-x86_64-pc-windows-msvc.zip:locum.dll,d3d11.dll,dxgi.dll,d3d12.dllandnvapi64.dll, the DLLs that go beside a gamelocum-cli-x86_64-pc-windows-msvc.zip:locum-cli.exe(alsocargo install locum-cli)
The libraries are on crates.io (cargo add locum-capture). To build the DLLs yourself instead, run
cargo build --release in the workspace; they are written to target/release/.
| Package | What it is |
|---|---|
locum |
locum.dll: wraps the Direct3D and DXGI objects and records captures |
locum-shim-d3d11, locum-shim-dxgi, locum-shim-d3d12 |
d3d11.dll, dxgi.dll, d3d12.dll: forward every export to locum.dll |
locum-shim-nvapi64 |
nvapi64.dll: an empty NVAPI for Direct3D 12 games |
locum-capture |
The capture format, blob store, formats, reflection and rule language |
locum-d3d11 |
Direct3D 11 readback shared by capture and replay |
locum-cli |
Reads, replays and verifies captures |
viewer |
Bun and Preact web viewer for captures |
locum-smoke, locum-smoke-d3d12, xtask |
Test programs and the cargo xtask build tasks |
Copy the DLLs next to the game's executable (for Unreal games, the one under Binaries/Win64), not into a system
folder:
- Direct3D 11:
locum.dll,d3d11.dll,dxgi.dll - Direct3D 12:
locum.dll,d3d12.dll,dxgi.dll,nvapi64.dll
If the game's folder already has a file of one of these names (another tool's dxgi.dll, say), set it aside first.
Remove the DLLs again when you are done.
locum writes its log, shaders and captures to %LOCALAPPDATA%\locum (or LOCUM_DIR). With the game running, create
an empty file named capture there. locum removes the file and writes the next frame to captures\frame-<n>\.
New-Item "$env:LOCALAPPDATA\locum\capture"
locum-cli info last # what the capture holds and what it is missing
locum-cli draws last --ps 9f2c # draws that used a pixel shader
locum-cli draw last 120 # one draw: state, bindings, named constants, targets after it
locum-cli target last 120 rt0 -o rt0.png # a render target read back after its pass
locum-cli verify last # replay the frame and compare every target with the game'sTo open the capture in the viewer, which prints its address (http://127.0.0.1:5170/...):
cd viewer
bun install
bun run viewer --db "$env:LOCALAPPDATA\locum\captures\frame-<n>"Other commands:
locum-cli shader last 9f2c -d: a shader's constant buffers, bindings and disassembly (--wgslfor WGSL)locum-cli trace last 120 rt1.z: what one lane of a target is made oflocum-cli export last 812 -o tex.dds: a resource's contents as the frame beganlocum-cli replay last 120 --rule "skip ps=9f2c": a draw replayed with a rule, before and afterlocum-cli diff before after: two captures compared draw by drawlocum-cli conform last --layer C:\dxvk\x64: the frame through a translation layer's DLLs, compared with the system's replay and the game'slocum-cli --index files.db join last: what each resource was made fromlocum-cli sql last "SELECT ...": any query on the capture
locum-cli --help lists every command. settings.txt, overrides.txt, table.txt and the capture request options
are described in docs/README.md.
cargo xtask smoke runs the Direct3D 11 test programs through locum and verifies their captures on the GPU and WARP.
cargo xtask smoke --api d3d12 does the same for Direct3D 12, and bun test runs the viewer's tests.
docs/README.md is the full reference, and viewer/README.md covers the viewer.
locum is licensed under GPL-3.0-or-later. CONTRIBUTING.md describes how releases are made.