# renderdoc_parser Direct-call Python interface for RenderDoc capture analysis. No MCP protocol required — import and call functions directly. **Requires Python 3.6** (the `renderdoc.pyd` extension module is compiled for Python 3.6). ## Quick Start ```python import sys sys.path.insert(0, "engine/tools") from renderdoc_parser import open_capture, get_capture_info, get_frame_overview open_capture("frame.rdc") print(get_capture_info()) print(get_frame_overview()) ``` ## Requirements - Python 3.6 - `renderdoc.pyd` and `renderdoc.dll` in `engine/third_party/renderdoc/` - Supported APIs: D3D12, D3D11, Vulkan, OpenGL ES, OpenGL, Metal ## API Reference ### Session (4 functions) | Function | Description | |----------|-------------| | `open_capture(filepath)` | Open a `.rdc` capture file. Returns API type, action/resource counts. | | `close_capture()` | Close the current capture and free resources. | | `get_capture_info()` | Capture metadata: API, resolution, texture/buffer counts, GPU quirks. | | `get_frame_overview()` | Frame stats: draw calls, clears, dispatches, memory usage, render targets. | ### Event Navigation (5 functions) | Function | Description | |----------|-------------| | `list_actions(max_depth=2, filter_flags=None, filter=None, event_type=None)` | Draw call/action tree. `max_depth` limits recursion. `filter_flags` accepts `["Drawcall", "Clear", "Dispatch"]`. `event_type` shorthand: `"draw"`, `"dispatch"`, `"clear"`. | | `get_action(event_id)` | Get a single ActionDescription by event ID. | | `set_event(event_id)` | Navigate to a specific event. | | `search_actions(name_pattern=None, flags=None)` | Search actions by name substring or ActionFlags. | | `find_draws(filter=None)` | Find all draw calls, optionally filtered by name substring. | ### Pipeline State (4 functions) | Function | Description | |----------|-------------| | `get_pipeline_state(event_id)` | Full pipeline state at an event (shaders, blend, rasterizer, depth-stencil, etc.). | | `get_shader_bindings(event_id, stage=None)` | Shader resource bindings. `stage` accepts `"vertex"`, `"pixel"`, `"compute"`, etc. | | `get_vertex_inputs(event_id)` | Vertex input layout (format, semantic, register). | | `get_draw_call_state(event_id)` | Summary of the draw call at an event (indices, instances, topology, outputs). | ### Resources (4 functions) | Function | Description | |----------|-------------| | `list_textures()` | All textures with dimensions, format, mip levels, memory estimate. | | `list_buffers()` | All buffers with length and creation flags. | | `list_resources()` | All resources (textures + buffers) unified. | | `get_resource_usage(resource_id)` | Which events use a given resource and how. | ### Data Reading (8 functions) | Function | Description | |----------|-------------| | `save_texture(resource_id, path, fmt=None)` | Save a texture to file. `fmt` accepts `"png"`, `"jpg"`, `"bmp"`, `"tga"`, `"hdr"`, `"exr"`, `"dds"`. | | `get_buffer_data(resource_id)` | Raw bytes of a buffer. | | `pick_pixel(x, y, event_id=None)` | RGBA value at a pixel. Defaults to current event if `event_id` is `None`. | | `get_texture_stats(resource_id)` | Min/max/avg values for a texture. | | `read_texture_pixels(resource_id, x, y, w, h)` | Pixel region as a 2D list of RGBA values. | | `export_draw_textures(event_id, path)` | Save all render targets at a draw call to image files. | | `save_render_target(resource_id, path)` | Save a specific render target to file. | | `export_mesh(event_id, vertex_buffer=None, index_buffer=None)` | Export mesh data (positions, normals, UVs, indices) as a structured dict. | ### Shader Analysis (3 functions) | Function | Description | |----------|-------------| | `disassemble_shader(event_id, stage=None, target=None)` | Disassembled shader code. `stage` is required. | | `get_shader_reflection(event_id, stage=None)` | Shader reflection: inputs, outputs, cbuffers, textures, samplers. | | `get_cbuffer_contents(event_id, stage, slot)` | Contents of a constant buffer slot for a given stage. | ### Advanced (6 functions) | Function | Description | |----------|-------------| | `pixel_history(x, y)` | All events that wrote to or modified a pixel, with before/after values. | | `get_post_vs_data(event_id, stage="vertex")` | Post-vertex-shader data (positions, clip positions, cull distances). | | `diff_draw_calls(event_id1, event_id2)` | Diff two draw calls: state differences and likely causes. | | `analyze_render_passes(event_id)` | Render pass grouping: which draw calls contribute to which render targets. | | `sample_pixel_region(x, y, w, h, event_id=None)` | Sample all pixels in a region. Returns NaN/Inf/negative/bright pixel counts. | | `debug_shader_at_pixel(x, y, event_id=None)` | Step-by-step shader debug at a pixel. | ### Performance (4 functions) | Function | Description | |----------|-------------| | `get_pass_timing(granularity="pass", top_n=20)` | GPU timing per pass or per draw call. | | `analyze_overdraw(sample_count=64)` | Overdraw heatmap data: which pixels are shaded how many times. | | `analyze_bandwidth()` | Estimated memory bandwidth: texture reads, render target writes, buffer traffic. | | `analyze_state_changes(track=None)` | Track state changes between draw calls. `track` accepts `["blend", "depth", "stencil", "rasterizer", "shader", "vertex", "index", "viewport"]`. | ### Diagnostics (4 functions) | Function | Description | |----------|-------------| | `diagnose_negative_values(event_id)` | Detect render targets receiving negative values — undefined behavior on many GPUs. | | `diagnose_precision_issues(event_id)` | Detect potential half-float precision issues in shaders. | | `diagnose_reflection_mismatch(event_id)` | Detect shader resource counts/types that differ from pipeline state. | | `diagnose_mobile_risks(event_id)` | Mobile GPU-specific risks based on detected driver (Adreno, Mali, PowerVR, Apple). | ## Return Format All functions return a Python `dict`. On error, all functions return: ```python {"error": "human-readable message", "code": "ERROR_CODE"} ``` Successful calls return a non-empty `dict` with function-specific data. ## File Structure ``` engine/tools/renderdoc_parser/ ├── __init__.py # Re-exports all 42 functions at package level ├── session.py # RenderDoc session singleton ├── util.py # load_renderdoc(), serialization helpers, enum maps ├── test.rdc # Sample capture for testing └── tools/ ├── __init__.py # Re-exports all functions by module ├── session_tools.py # open_capture, close_capture, get_capture_info, get_frame_overview ├── event_tools.py # list_actions, get_action, set_event, search_actions, find_draws ├── pipeline_tools.py # get_pipeline_state, get_shader_bindings, get_vertex_inputs, get_draw_call_state ├── resource_tools.py # list_textures, list_buffers, list_resources, get_resource_usage ├── data_tools.py # save_texture, get_buffer_data, pick_pixel, get_texture_stats, ... ├── shader_tools.py # disassemble_shader, get_shader_reflection, get_cbuffer_contents ├── advanced_tools.py # pixel_history, get_post_vs_data, diff_draw_calls, ... ├── performance_tools.py # get_pass_timing, analyze_overdraw, analyze_bandwidth, analyze_state_changes └── diagnostic_tools.py # diagnose_negative_values, diagnose_precision_issues, ... ``` ## GPU Quirks `get_capture_info()` automatically detects the GPU/driver and returns known quirks: - **Adreno**: mediump precision issues, R11G11B10_FLOAT signed behavior, textureLod bugs - **Mali**: R11G11B10_FLOAT undefined negative writes, discard early-Z interactions, mediump accumulation - **PowerVR**: tile-based deferred rendering considerations, sampler binding limits - **Apple GPU**: tile memory bandwidth, float16 performance recommendations - **OpenGL ES**: precision qualifier correctness, extension compatibility