locum
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.
Features
- 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
- 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
Getting Started
Requirements
- 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.
Installation
Each release has two downloads for Windows (x86_64), with
SHA256SUMS:
locum-dlls-<version>-x86_64-pc-windows-msvc.zip:locum.dll,d3d11.dll,dxgi.dll,d3d12.dllandnvapi64.dll, the DLLs that go beside a gamelocum-cli-<version>-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.
Usage
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's
To 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 --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.