RenderDoc in-application API wrapper + automation helpers + an MCP server.
This project is not affiliated with RenderDoc. RenderDoc itself is developed by Baldur Karlsson: https://github.com/baldurk/renderdoc
Repository: https://github.com/Latias94/renderdog
- Provide a small, safe-ish Rust wrapper for RenderDoc's in-app capture API.
- Provide out-of-process automation that is usable by an AI agent (capture + export searchable artifacts).
- Keep the stable "replay/analysis" workflow in
qrenderdoc --pythonfor fast iteration. - Optionally experiment with a minimal Rust-friendly replay shim (
renderdog-replay, not published).
renderdog: in-app API wrapper (connect to injected RenderDoc or dynamically load it).renderdog-sys: low-level FFI bindings (pregenerated, optional bindgen regeneration).renderdog-automation: out-of-process automation helpers (renderdoccmd,qrenderdoc --pythonworkflows).renderdog-mcp: MCP server exposing automation workflows.renderdog-winit: optionalwinithelpers (key mapping + window-handle helpers).renderdog-replay: experimental replay shim (C++/cxx, not published to crates.io).
- Windows: primary target for in-app capture and automation.
- Linux (x86_64): supported; in-app loader uses
librenderdoc.so/librenderdoc.so.1by default. - macOS: RenderDoc is experimental and not officially supported for debugging;
renderdogmay compile but capture/replay can be unreliable.
- Library:
cargo add renderdog - MCP server (binary):
cargo install renderdog-mcp
You need a local RenderDoc installation that provides both:
renderdoccmd(used for injection-based capture)qrenderdoc(used for replay/analysis/export viaqrenderdoc --python)
renderdog-automation / renderdog-mcp tries to detect RenderDoc via:
RENDERDOG_RENDERDOC_DIR(preferred: points to the RenderDoc install root)- Windows default:
C:\Program Files\RenderDoc PATH(ifrenderdoccmd/qrenderdocare discoverable)
Run the example:
cargo run -p renderdog --example in_app_capture
Key points:
- Loader tries API versions from
1.6.0down to1.0.0viaRENDERDOC_GetAPI. - Windows injected connect uses
GetModuleHandleA("renderdoc.dll")and does not callLoadLibrary. - Explicit load is available via
RenderDog::load("renderdoc.dll")/RenderDocInApp::try_load_and_connect(...). - Linux optional: connect only if already loaded (RTLD_NOLOAD):
RenderDocInApp::try_connect_noload_default()orRenderDog::new_noload_first(). - Thread-safety: in-app handles are
Sendbut!Syncand notClone. For cross-thread usage, wrap inArc<Mutex<...>>to serialize calls.
RenderDoc analysis depends heavily on having stable pass markers/labels. Regardless of which workflow you choose below, make sure your renderer emits consistent GPU markers for each pass so you can search them in RenderDoc's Event Browser.
See: docs/guides/gpu-markers.md and docs/playbooks/fret-clip-mask.md.
Use this when you want a local/manual workflow (or your own automation) without an MCP client.
- In-app capture control (integrate
renderdoginto your renderer):cargo add renderdog- Typical flow:
- connect/load RenderDoc (
RenderDog::new()/RenderDocInApp::try_connect_or_load_default()) - optionally set capture path template (
set_capture_file_path_template...) - trigger capture (
trigger_captureorstart_frame_capture/end_frame_capture)
- connect/load RenderDoc (
- Out-of-process automation from CLI (no MCP):
- Capture + export:
cargo run -p renderdog-automation --example one_shot_capture_export -- <exe> [args...] - Export from existing
.rdc:cargo run -p renderdog-automation --example export_bundle_from_capture -- <capture.rdc> [out_dir] [basename] - Headless replay outputs:
cargo run -p renderdog-automation --example replay_save_outputs_png -- <capture.rdc> [event_id] [out_dir] [basename] - Note: relative paths are resolved against your current working directory.
- Capture + export:
Use this when you want an AI agent to drive capture/replay/export via tool calls.
- Run the server (stdio):
cargo run -p renderdog-mcp(orcargo install renderdog-mcpthenrenderdog-mcp) - Recommended tool entrypoints:
- One-shot capture + export bundle:
renderdoc_capture_and_export_bundle_jsonl - Export bundle from an existing
.rdc:renderdoc_export_bundle_jsonl - Find event IDs by marker/name:
renderdoc_find_events - One-shot find + save outputs:
renderdoc_find_events_and_save_outputs_png - Headless replay outputs:
renderdoc_replay_save_outputs_png
- One-shot capture + export bundle:
Minimal requests (JSON examples):
{
"tool": "renderdoc_find_events",
"args": {
"cwd": ".",
"capture_path": "captures/fret_capture.rdc",
"only_drawcalls": true,
"marker_contains": "fret composite",
"max_results": 200
}
}Notes:
max_resultsdefaults to200inrenderdog-mcp. Set it tonullto disable truncation.- Use
cwdto control how relative paths (e.g.capture_path,output_dir,output_path) are resolved for this call.
{
"tool": "renderdoc_find_events_and_save_outputs_png",
"args": {
"cwd": ".",
"capture_path": "captures/fret_capture.rdc",
"marker_contains": "fret composite",
"selection": "last",
"output_dir": "artifacts/renderdoc/exports/replay",
"basename": "fret_capture",
"include_depth": false
}
}renderdog-mcp uses the stdio transport, so any MCP client that supports stdio servers can run it.
You typically want to set RENDERDOG_RENDERDOC_DIR so the server can find renderdoccmd and qrenderdoc.
You should also set the MCP server working directory (cwd) to your project root so relative paths
in tool arguments (e.g. artifacts_dir, output_dir, thumbnail_output_path) behave as expected.
Claude Code supports managing MCP servers via CLI commands and config files.
- Add a local stdio server (default scope):
claude mcp add --transport stdio --env RENDERDOG_RENDERDOC_DIR=C:\Users\you\scoop\apps\renderdoc\current renderdog -- renderdog-mcp
- Add a user-scoped server (cross-project):
claude mcp add --transport stdio --scope user --env RENDERDOG_RENDERDOC_DIR=C:\Users\you\scoop\apps\renderdoc\current renderdog -- renderdog-mcp
- Project-scoped (team) config:
- Create/commit a
.mcp.jsonin the project root (Claude Code can also generate/update it). - Minimal example:
- Create/commit a
{
"mcpServers": {
"renderdog": {
"type": "stdio",
"command": "renderdog-mcp",
"args": [],
"cwd": ".",
"env": {
"RENDERDOG_RENDERDOC_DIR": "C:\\\\Users\\\\you\\\\scoop\\\\apps\\\\renderdoc\\\\current"
}
}
}
}Notes:
- Option ordering matters:
--transport/--env/--scopemust come before the server name, and--separates Claude flags from the server command/args. - If you are in a managed environment with
managed-mcp.json, users may be blocked from adding servers via CLI/config and must rely on the managed configuration.
Codex stores MCP server launchers in ~/.codex/config.toml (see codex mcp subcommands).
- Add via CLI:
codex mcp add renderdog --env RENDERDOG_RENDERDOC_DIR=C:\\Users\\you\\scoop\\apps\\renderdoc\\current -- renderdog-mcp
- Or configure directly in
~/.codex/config.toml:
[mcp_servers.renderdog]
command = "renderdog-mcp"
args = []
cwd = "C:\\path\\to\\your\\project"
env = { RENDERDOG_RENDERDOC_DIR = "C:\\\\Users\\\\you\\\\scoop\\\\apps\\\\renderdoc\\\\current" }Notes:
- Verify setup with
codex mcp list. - If you run Codex in WSL but want to use a Windows RenderDoc install, ensure
renderdog-mcpis launched as a Windows executable and thatRENDERDOG_RENDERDOC_DIRpoints to the Windows install root.
Gemini CLI can manage MCP servers either via commands or by editing settings.json.
- Add a local stdio server via CLI:
gemini mcp add --transport stdio -e RENDERDOG_RENDERDOC_DIR=C:\Users\you\scoop\apps\renderdoc\current renderdog renderdog-mcp
- Verify:
gemini mcp list
- Configure via
settings.json(user scope:~/.gemini/settings.json, project scope:.gemini/settings.json):
{
"mcpServers": {
"renderdog": {
"command": "renderdog-mcp",
"args": [],
"cwd": ".",
"env": {
"RENDERDOG_RENDERDOC_DIR": "C:\\\\Users\\\\you\\\\scoop\\\\apps\\\\renderdoc\\\\current"
}
}
}
}- In-app connect (injected-only, Windows):
cargo run -p renderdog --example in_app_injected_only - In-app options/overlay/output template:
cargo run -p renderdog --example in_app_options_overlay - Automation one-shot capture + export:
cargo run -p renderdog-automation --example one_shot_capture_export -- <exe> [args...] - Automation export bundle from capture:
cargo run -p renderdog-automation --example export_bundle_from_capture -- <capture.rdc> [out_dir] [basename] - Automation save pipeline outputs to PNG:
cargo run -p renderdog-automation --example replay_save_outputs_png -- <capture.rdc> [event_id] [out_dir] [basename] - Automation diagnose environment (RenderDoc paths + Vulkan layer):
cargo run -p renderdog-automation --example diagnose_environment - Winit hotkey capture (F12):
cargo run -p renderdog-winit --example winit_hotkey_capture
Run the server locally (stdio transport):
- From crates.io:
renderdog-mcp - From source:
cargo run -p renderdog-mcp
renderdog-mcp provides one-shot tools that can:
- launch a target with
renderdoccmd capture - trigger capture via target-control
- export searchable artifacts
Recommended: renderdoc_capture_and_export_bundle_jsonl (exports both actions + bindings index).
For an existing capture, use: renderdoc_export_bundle_jsonl.
Bundle tools also support optional save_thumbnail / open_capture_ui helpers.
Artifacts:
- actions tree:
.actions.jsonl+.summary.json - bindings index:
.bindings.jsonl+.bindings_summary.json(shader names + resource bindings per drawcall)
The export supports optional filters:
only_drawcalls,marker_prefixevent_id_min/event_id_maxname_contains,marker_contains(+case_sensitive)
Practical checklists for validating real-world rendering issues:
- Clip-mask mapping (fret):
docs/playbooks/fret-clip-mask.md
If you want an AI agent (or a human) to debug a renderer effectively with RenderDoc, aim for a workflow that is repeatable and searchable:
- Capture a frame (
.rdc)- In-app control: integrate
renderdogand trigger captures programmatically (or via hotkeys). - Injection-based: use
renderdog-automation/renderdog-mcp(wrapsrenderdoccmd capture).
- In-app control: integrate
- Make passes easy to find
- Emit stable GPU markers / debug labels for key passes (RenderDoc Event Browser search relies on these).
- Inspect in
qrenderdocUI, then automate exports- Use the playbooks for step-by-step validation (e.g.
docs/playbooks/fret-clip-mask.md). - Export actions/bindings to JSONL for grep-friendly queries.
- Use headless replay helpers (
qrenderdoc --python) to list textures / pick pixels / save PNGs.
- Use the playbooks for step-by-step validation (e.g.
In addition to exporting actions/bindings, renderdog-automation and renderdog-mcp provide
headless replay helpers (implemented via qrenderdoc --python) that are useful for quick sanity
checks:
- List textures in a capture
- Pick a pixel from a texture
- Save a texture to PNG
- Save current pipeline outputs (RTs + optional depth) to PNG
These are exposed as:
renderdog-automationexamples:replay_list_texturesreplay_pick_pixelreplay_save_texture_pngreplay_save_outputs_png
renderdog-mcptools:renderdoc_replay_list_texturesrenderdoc_replay_pick_pixelrenderdoc_replay_save_texture_pngrenderdoc_replay_save_outputs_png
renderdog-mcp uses tracing and honors RUST_LOG:
- Default:
info - Debug (includes detailed command failure context):
RUST_LOG=debug renderdog-mcp
If Vulkan capture doesn't work, RenderDoc's Vulkan layer registration may be missing or conflicting. You can diagnose it via:
- MCP tool:
renderdoc_vulkanlayer_diagnose - MCP tool:
renderdoc_diagnose_environment(includes env var hints andplatform/arch) - CLI:
"renderdoccmd" vulkanlayer --explain
If it needs attention, suggested fixes typically include:
"renderdoccmd" vulkanlayer --register --user"renderdoccmd" vulkanlayer --register --system(administrator)
- RenderDoc not detected: set
RENDERDOG_RENDERDOC_DIRto the RenderDoc install root. - Linux in-app load fails: ensure
librenderdoc.sois available on the loader search path (e.g. install RenderDoc system-wide, or setLD_LIBRARY_PATHappropriately). - Vulkan capture fails: use
renderdoc_diagnose_environment/renderdoc_vulkanlayer_diagnoseand follow suggested fixes.
renderdog-sys ships with pregenerated bindings by default. If you want to regenerate bindings via
bindgen, you can use the optional submodule at third-party/renderdoc and run:
RENDERDOG_SYS_REGEN_BINDINGS=1 cargo build -p renderdog-sys --features bindgen
You can also point to a specific header via RENDERDOG_SYS_HEADER=/path/to/renderdoc_app.h.
Alternatively, use the helper script (maintainers):
- Update pregenerated bindings:
python scripts/regen_bindings.py - Check without writing:
python scripts/regen_bindings.py --check
This repository is a Cargo workspace. When you add new cross-crate APIs locally (e.g. new
renderdog-automation functions used by renderdog-mcp), cargo package -p renderdog-mcp will
only pass after the corresponding renderdog-automation version is published to crates.io.
During development, use workspace builds/tests (cargo build, cargo nextest run). For packaging
checks, you can run cargo package -p <crate> --allow-dirty (but verification may still fail if it
depends on unpublished crates).
Dual-licensed under MIT OR Apache-2.0. See LICENSE-MIT and LICENSE-APACHE.