Scriptable CLI for RenderDoc captures — built for terminal workflows, CI pipelines, and AI agents
SaferSkills independently audited rdc-cli (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
rdc-cli is a Unix-friendly command-line interface for RenderDoc GPU captures. It provides a daemon-backed architecture using JSON-RPC over TCP, a virtual filesystem (VFS) path namespace for navigating capture internals, and composable commands designed for shell pipelines, scripting, and CI assertions.
Install: pip install rdc-cli (requires a local RenderDoc build with Python bindings). Check setup: rdc doctor.
Follow this session lifecycle for any capture analysis task:
rdc open path/to/capture.rdcrdc open capture.rdc --proxy host:portrdc open --connect host:port --token TOKENrdc open capture.rdc --android [--serial SERIAL]rdc info, rdc stats, rdc eventsrdc ls /, rdc ls /textures, rdc cat /draws/0/pipeline/summaryrdc shaders, rdc pipeline, rdc resources, rdc bindingsrdc debug pixel EID X Y, rdc debug vertex EID VTXID, rdc debug thread EID GX GY GZrdc texture ID -o out.png, rdc rt EID, rdc buffer ID -o buf.bin, rdc cbuffer EID --stage ps --binding 0, rdc logrdc closedefault (or value of $RDC_SESSION).rdc --session myname open capture.rdc.rdc status.rdc goto EID.All list/table commands default to TSV (tab-separated values) with a header row, suitable for cut, awk, and sort.
| Flag | Format | Use Case |
|---|---|---|
| (default) | TSV with header | Human reading, shell pipelines |
--no-header | TSV without header | Piping to awk/cut without stripping |
--json | JSON array | Structured processing with jq |
--jsonl | Newline-delimited JSON | Streaming processing, large datasets |
-q / --quiet | Minimal (single column) | Extracting IDs for loops |
Example -- get all draw call EIDs as a plain list:
rdc draws -qExample -- JSON pipeline with jq:
rdc events --json | jq '.[] | select(.type == "DrawIndexed")'rdc passes outputs 6 columns: NAME, DRAWS, DISPATCHES, TRIANGLES, BEGIN_EID, END_EID.
rdc passes # TSV table
rdc passes --json # includes load_ops/store_ops per pass
rdc passes --deps --table # per-pass READS/WRITES/LOAD/STORErdc pass <name> shows enriched attachments: resource name, format, dimensions, and load/store ops.
rdc pass GBuffer
rdc pass GBuffer --json
rdc pass 0 # by 0-based indexrdc unused-targets finds render targets written but never consumed by visible output. Columns: ID, NAME, WRITTEN_BY, WAVE.
rdc unused-targets # TSV
rdc unused-targets --json # structured
rdc unused-targets -q # one resource ID per line (for scripting)rdc stats outputs three sections: Per-Pass Breakdown, Top Draws by Triangle Count, and Largest Resources.
rdc stats # all three sections
rdc stats --json # includes largest_resources arrayGL/GLES/D3D11 captures without native BeginPass/EndPass markers get synthetic pass inference automatically — no extra flags needed.
rdc draws
rdc draws --pass "GBuffer" --jsonrdc debug pixel 1024 512 384 # EID first, then X Y
rdc debug pixel 1024 512 384 --json # structured output
rdc debug pixel 1024 512 384 --trace # full step-by-step tracerdc search "main" # regex search over shader disassembly
rdc search "Sample" --stage ps -C 2
rdc shaders --name "GBuffer*"rdc rt EID -o output.png
rdc rt EID --depth -o depth.png # export the raw depth attachment
rdc texture ID -o tex.png # export a texture by resource ID (PNG)rdc cbuffer EID --stage ps --binding 0 # decode to JSON
rdc cbuffer EID --stage vs --binding 0 --raw -o cbuffer.binrdc ls /
rdc ls /textures -l
rdc tree /draws/42/pipeline --depth 2 # pipeline state lives under /draws/<eid>/pipeline/
rdc cat /draws/42/pipeline/summary
rdc cat /events/42rdc goto EID
rdc pipeline --json
rdc bindings --jsonrdc goto 100 && rdc pipeline --json > before.json
rdc goto 200 && rdc pipeline --json > after.json
diff before.json after.jsonrdc-cli provides assertion commands that exit non-zero on failure, designed for automated testing pipelines:
| Command | Purpose |
|---|---|
rdc assert-pixel EID X Y --expect "R G B A" | Assert pixel RGBA (4 space-separated floats) at EID/coordinates |
rdc assert-clean | Assert no validation errors in capture |
rdc assert-count <what> --expect N [--op CHOICE] | Assert a capture metric (e.g. draws) satisfies a comparison |
rdc assert-state EID KEY-PATH --expect VALUE | Assert pipeline state value at EID matches expected |
rdc assert-image EXPECTED ACTUAL [--threshold FLOAT] | Compare two image files pixel-by-pixel |
Example CI script:
#!/bin/bash
set -e
rdc open test_capture.rdc
rdc assert-clean
rdc assert-count draws --expect 10 --op ge
rdc assert-pixel 1024 256 256 --expect "1.0 0.0 0.0 1.0"
rdc closeModify and replay shaders without recompiling the application:
rdc shader-encodings # list available encodings
rdc shader EID ps --source > s.frag # extract shader source
# ... edit s.frag ...
rdc shader-build s.frag --stage ps # compile; prints the built shader ID
rdc shader-replace EID ps --with <ID> # hot-swap built shader ID into capture
rdc shader-restore EID ps # revert single shader (STAGE required)
rdc shader-restore-all # revert all modificationsrdc-cli wraps renderdoccmd remoteserver to support PC-to-PC remote captures.
rdc serve [--port PORT] [--allow-ips CIDR] [--no-exec] [--daemon] — launch remoteserver on the target machinerdc remote connect <host:port> — save remote connection staterdc remote list — enumerate capturable apps on the remoterdc remote capture <app> -o frame.rdc [--args ...] [--frame N] [--keep-remote] — inject, capture, and transfer back. --keep-remote skips the transfer and prints the remote path; replay it with rdc open <path> --proxy host:port. (The CLI's own next: hint currently still references the deprecated --remote alias for --proxy.)rdc open frame.rdc --proxy host:port — remote-backed replay (daemon local, GPU remote)remote_state.py persists the last connected host so subsequent rdc remote list can omit --url.
Split mode decouples CLI and daemon — run the daemon where the GPU is and connect from a machine that doesn't need the renderdoc module. Useful when the analyst's laptop is macOS/Windows and the GPU is on a Linux server.
rdc open capture.rdc --listen [ADDR[:PORT]]host: ADDR, port: PORT, token: TOKEN, connect with: rdc open --connect ADDR:PORT --token TOKENrdc open --connect HOST:PORT --token TOKENSSH tunnel tip (use the port from --listen, or rdc serve's default 39920): ssh -L 39920:localhost:39920 user@server, then connect to localhost:39920.
Every normal command (rdc draws, rdc rt, ...) works transparently in Split mode. Binary exports use file_read RPC with raw binary frames — no base64 overhead.
rdc setup-renderdoc --android (upstream) or --android --arm (ARM PS fork for Mali). rdc android setup does not push the APK itself.rdc android setup [--serial SERIAL] — starts remoteserver on the device via RenderDoc's Device Protocol API (StartRemoteServer), sets adb forward, saves remote state.rdc android capture <activity> [--serial SERIAL] [--timeout N] [--port PORT] [-o out.rdc] — GPU debug layers based capture (works around EMUI/Mali injection limitations).rdc android stop [--serial SERIAL] — stops the remoteserver and cleans state.rdc open frame.rdc --android [--serial SERIAL] — this is the only form that rewrites the saved adb://SERIAL to the forwarded localhost:PORT. Passing --proxy adb://SERIAL directly bypasses the rewrite and is known to crash the daemon (see session.py:_resolve_android_url).Hardware matrix: Adreno is the happy path; Mali may need the ARM Performance Studio fork (see rdc setup-renderdoc --android --arm).
Always run rdc doctor first. It reports status for renderdoc module, renderdoccmd, adb, Android APK, and platform-specific toolchains. Only the missing-renderdoc-module case emits a dedicated build-hint block; other checks surface inline hints in the detail column, so read each failing line rather than relying on a uniform next-step list.
Common failure categories (conceptual, not literal error strings — map from the text the tool actually emits):
rdc serve is running on the target.rdc setup-renderdoc or rdc setup-renderdoc --android to align.rdc doctor and check the platform-specific detail.--proxy or --android remote replay.rdc doctor warns when more than one VK_LAYER_RENDERDOC_Capture Vulkan layer is registered (a system-installed RenderDoc plus the rdc-managed one create a split-brain). The loader then picks one non-deterministically and capture can silently time out; unregister the extra manifest so only one remains.rdc open; use rdc status to inspect.For long operations (large capture transfers, remote replay init), the CLI has limited progress feedback — this is a known UX gap, not a hang. Wait up to the --timeout value before concluding failure.
For the complete list of all commands with their arguments, options, types, and defaults, see references/commands-quick-ref.md.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.