- 开发工具
- 调试器
- 图形学
- GPU
【免费下载链接】renderdoc
RenderDoc is a stand-alone graphics debugging tool.
本文基于 RenderDoc 官方 Python 示例 "Launching an application",讲解如何通过pyrenderdoc/qrenderdoc脚本接口驱动 UI 的捕获对话框(Capture Dialog),自动完成"选择可执行文件 → 设置命令行与捕获选项 → 启动程序 → 接管捕获连接"这一完整流程。读完本文,你将掌握用 Python 脚本把反复点击的捕获操作固化成可复用的自动化工作流(例如 CI 冒烟测试或日常回归测试)的完整方案,并能结合源码理解每个设置项背后的真实含义。
示例背景:把"点击式"捕获流程变成脚本
在 RenderDoc 的 Python 脚本窗口中,官方提供了名为"Launching an application"的示例(对应源码 exe_launching.py)。它演示的核心思想是:UI 中 捕获对话框 的所有交互能力,几乎都可以通过脚本接口以编程方式完成——包括弹出对话框、设置可执行文件路径与命令行、修改捕获选项、启动捕获,以及在程序运行期间通过捕获连接(Capture Connection)窗口管理捕获结果。
这套能力非常适合自动化工作流与测试场景:你可以把"配置参数 → 启动 → 抓帧 → 检查结果"固化成脚本,避免每次手动点击,也让测试流程可重复、可追溯。
示例脚本开头先做两件准备工作:
import renderdoc import qrenderdocrenderdoc提供与 UI 无关的核心 API(例如CaptureOptions等数据结构);qrenderdoc提供 UI 集成相关的接口(对话框、窗口、DialogButton枚举等)。
另外脚本中有一段TYPE_CHECKING的写法,用于在 VS Code 中编辑示例时获得自动补全提示(让编辑器知道全局对象pyrenderdoc的类型是qrenderdoc.CaptureContext()),运行时并无实际作用。
配置捕获:弹出捕获对话框并设置启动参数
打开捕获对话框
首先让捕获对话框显示出来,并拿到它的句柄:
pyrenderdoc.ShowCaptureDialog() dialog = pyrenderdoc.GetCaptureDialog()这两个接口的底层实现可以在 PythonInvokers.cpp 中找到:GetCaptureDialog()通过ICaptureContext::GetCaptureDialog把 C++ 侧的真实对话框包装成 Python 对象,ShowCaptureDialog()则直接调用ICaptureContext::ShowCaptureDialog。也就是说,脚本拿到的dialog与用户点击 UI 时看到的是同一个对话框,后续所有Set*操作都会真实作用在 UI 上。
让用户选择可执行文件
拿到对话框句柄后,可以通过辅助函数直接设置可执行文件路径、命令行和工作目录等常见属性。示例中先弹出系统文件选择框让用户挑选可执行文件:
exe = pyrenderdoc.Extensions().OpenFileName("Find an executable", "", "*.exe") dialog.SetExecutableFilename(exe)OpenFileName(caption, dir, filter)是扩展管理器提供的方法(对应 PythonInvokers.cpp 中的IExtensionManager::OpenFileName)。示例里设置的过滤条件*.exe只在 Windows 上相关,你可以根据需要改为其他平台的可执行文件扩展名(如 Linux 下不设置过滤,或使用具体二进制名)。
设置命令行参数
dialog.SetCommandLine("--cool-level very")示例中的--cool-level very是演示用的虚构参数,实际使用时应替换为目标程序真实支持的命令行参数。在 UI 上对应的入口位于捕获对话框的 Program 区域——它同时支持设置工作目录与命令行参数:
- 工作目录留空时,默认使用可执行文件所在目录;
- 可执行路径与工作目录旁的
...按钮用于浏览文件系统,在远程上下文(remote context)下会切换为浏览远程文件系统; - 环境变量行旁的
...按钮可打开编辑器,支持对变量执行Set(覆盖/新建)、Prepend Value/Append Value(前插/追加,可自选:、;、平台风格或不分隔符)等操作,可用于设置DISPLAY等运行环境。
这些细节的完整说明见 捕获对话框文档。
读取并修改完整设置集合
对于更细粒度的功能(例如各种捕获选项),可以一次性取出整个设置集合:
settings = dialog.Settings() # 也可以在这里设置命令行,效果与上面的 SetCommandLine() 完全相同 print(settings.commandLine) # 把用户可能改动过的配置重置为默认值 settings.options = renderdoc.CaptureOptions() # 开启调用栈捕获 settings.options.captureCallstacks = True dialog.SetSettings(settings)settings对象同时承载"启动配置"(可执行文件、命令行、工作目录、环境变量)与"捕获选项"两部分。renderdoc.CaptureOptions()是捕获选项的完整容器,其结构定义在 capture_options.h 中——构造函数会先memset清零,再逐个设置默认值,因此"重置为默认"非常可靠。
结合 capture_options.h 的源码,CaptureOptions支持的全部字段及默认值如下:
| 字段 | 默认值 | 作用 |
|---|---|---|
allowVSync | True | 允许应用自行启用/禁用垂直同步;False时强制关闭 VSync |
allowFullscreen | True | 允许应用切换独占全屏;False时 RenderDoc 会将全屏请求改写为等价窗口模式 |
apiValidation | False | 启用 API 内建调试功能(D3D debug layer、ARB_debug_output、Vulkan validation)并写入捕获 |
captureCallstacks | False | 在每个 API 调用处记录用户代码调用栈,回放时可解析定位调用来源(详见 如何捕获调用栈) |
captureCallstacksOnlyActions | False | 仅在 action 调用上记录调用栈,降低 CPU/文件体积开销;仅在captureCallstacks开启时有效 |
delayForDebugger | 0 | 启动进程后延迟的秒数,便于在早期初始化代码执行前挂接传统调试器 |
verifyBufferAccess | False | 为Map()返回的指针添加边界标记并在Unmap()时校验,越界写入会弹窗提示;目前仅 D3D11 与 OpenGL 支持 |
hookIntoChildren | False | 钩取目标进程创建的子进程并同样注入 RenderDoc(Linux 上子进程始终会被钩取) |
refAllResources | False | 默认只保存帧内被引用/绑定的资源;开启后把捕获时所有存活资源全部写入捕获文件 |
captureAllCmdLists | False | 预抓取所有命令列表(仅 D3D11,可能有显著性能开销) |
debugOutputMute | True | 静默应用的调试输出 |
softMemoryLimit | 0 | 捕获内存软上限 |
对于示例聚焦的调用栈捕获,captureCallstacks = True会要求驱动在捕获帧内每个 API 调用点记录一次用户代码调用栈;若只关心绘制/计算等 action 调用,可再叠加captureCallstacksOnlyActions = True来降低开销。
启动捕获:二次确认后调用 Launch
配置完成后,示例先与用户做一次二次确认(这一步是可选的,仅为了让流程更友好):
opts = [qrenderdoc.DialogButton.Yes, qrenderdoc.DialogButton.No] go = pyrenderdoc.Extensions().QuestionDialog("Ready to Launch?", opts, "Final Check") if go == qrenderdoc.DialogButton.Yes: conn = dialog.Launch()QuestionDialog(text, options, title)对应 PythonInvokers.cpp 中的IExtensionManager::QuestionDialog,返回用户点击的按钮枚举值;dialog.Launch()返回一个CaptureConnection句柄——程序成功启动后,UI 中会出现一个"捕获连接"窗口,该句柄即指向这个窗口,包含活动连接的全部信息与已产生的捕获。
顺带一提,UI 上的捕获对话框还支持把整套设置保存为.cap设置文件(对应Save Settings按钮):该文件可被手动加载、可从File → Recent Captures菜单访问,甚至能与 RenderDoc 建立文件关联——勾选Auto start后,双击.cap文件会立即按其中的设置触发一次捕获。这与脚本自动化是互补的两条路径。
捕获连接:管理运行中的程序与捕获
Launch()返回的conn是 CaptureConnection 类型的句柄。需要注意一个重要约束:捕获连接窗口是临时的——如果程序在未产生任何捕获的情况下退出,窗口会自动关闭,此时持有的句柄将失效。文档给出的两种应对方式是:
- 调用
conn.RegisterClosedCallback(...)注册一个在连接自行关闭时触发的回调; - 或调用
conn.PreventAutoClose()禁止连接自动关闭,保证句柄始终有效。
实际上 exe_launching.py 的源码在Launch()后紧接着调用了conn.PreventAutoClose(),确保 5 秒后的延迟回调执行时连接仍然有效——这是.rst文档与最终脚本源码的一处细微差异,实战中推荐以脚本源码为准。
随后示例注册一个回调,在 5 秒后打印连接状态:
def connected_cb(): print(f"Connected to {conn.Target()} running APIs: {', '.join(conn.GetAPIs())}") numcaps = len(conn.GetCaptures()) if numcaps == 0: print("No captures have been made!") else: print(f"{numcaps} captures have been made!") # 等待一小段时间,然后调用回调打印连接状态 pyrenderdoc.DelayedCallback(5000, connected_cb)这里用到的接口含义:
conn.Target():返回被连接的目标程序标识(通常是可执行文件名);conn.GetAPIs():返回该程序已初始化的图形 API 列表(例如Vulkan、D3D11等);conn.GetCaptures():返回本次连接期间已产生的捕获列表;pyrenderdoc.DelayedCallback(毫秒, 回调):延迟执行回调,对应 PythonInvokers.cpp 中的DelayedCallback实现。
捕获连接窗口本身还提供更丰富的管理能力(详见 捕获连接窗口文档):可以带延迟触发任意帧数的捕获、按帧号排队捕获、以缩略图浏览所有捕获、保存/删除捕获,以及双击打开捕获进行分析。在脚本中,你同样可以通过conn句柄调用对应方法完成这些操作——对连接句柄做更深层的捕获控制与打开捕获属于该示例之外的话题,这里不再展开。
完整示例脚本与运行方式
将上述片段组合起来,就是完整的示例脚本 exe_launching.py:
# these imports are not strictly necessary, but are convenient import renderdoc import qrenderdoc # this is here to give autocomplete when editing the example # in VS Code where it doesn't know about this global from typing import TYPE_CHECKING if TYPE_CHECKING: pyrenderdoc = qrenderdoc.CaptureContext() pyrenderdoc.ShowCaptureDialog() dialog = pyrenderdoc.GetCaptureDialog() exe = pyrenderdoc.Extensions().OpenFileName("Find an executable", "", "*.exe") dialog.SetExecutableFilename(exe) dialog.SetCommandLine("--cool-level very") settings = dialog.Settings() # we could also set the command line here, this is identical to SetCommandLine() above print(settings.commandLine) # reset anything the user has changed to default settings.options = renderdoc.CaptureOptions() # enable callstack capture settings.options.captureCallstacks = True dialog.SetSettings(settings) opts = [qrenderdoc.DialogButton.Yes, qrenderdoc.DialogButton.No] go = pyrenderdoc.Extensions().QuestionDialog("Ready to Launch?", opts, "Final Check") if go == qrenderdoc.DialogButton.Yes: conn = dialog.Launch() # don't allow the connection to close itself so we can expect that it will be valid # when the delayed callback below is called conn.PreventAutoClose() def connected_cb(): print(f"Connected to {conn.Target()} running APIs: {', '.join(conn.GetAPIs())}") numcaps = len(conn.GetCaptures()) if numcaps == 0: print("No captures have been made!") else: print(f"{numcaps} captures have been made!") # wait a little bit, then call our callback to print the connection status pyrenderdoc.DelayedCallback(5000, connected_cb)运行方式:在 RenderDoc 的 Python 脚本窗口中选择示例 "Launching an application" 直接执行(脚本源码同时托管在仓库 exe_launching.py)。执行后会依次弹出文件选择框与确认对话框,确认后程序启动,5 秒后控制台打印目标程序、已初始化的图形 API 以及捕获数量。
进阶方向与参考资料
- 想把调用栈捕获的收益最大化,可阅读 如何捕获调用栈,了解回放时如何解析调用栈定位 API 调用来源;
- 想了解捕获连接窗口的完整交互(触发捕获、排队帧号捕获、保存/删除/打开捕获),见 捕获连接窗口文档;
- 需要远程机器上的捕获与回放时,可结合 网络捕获与回放 使用——脚本中的
OpenFileName在远程上下文中会自动切换为远程文件浏览; CaptureDialog、CaptureConnection等类的方法与成员完整定义,统一收录在 qrenderdoc Windows API 参考;- 更高层的 Python API 使用指南与 UI 扩展编写方法,参见 Python API 索引 与 UI 扩展指南。
- 开发工具
- 调试器
- 图形学
- GPU
【免费下载链接】renderdoc
RenderDoc is a stand-alone graphics debugging tool.
相关推荐
告别手动启动!Keyviz图形化配置自动启动全指南
告别手动启动!Keyviz图形化配置自动启动全指南 Keyviz是一款免费开源的实时可视化工具,能够展示您的键盘输入和鼠标操作。本文将详细介绍如何通过图形化界面
桌面应用交互助手革命性多文化头像生成器Multiavatar:12亿独特头像的终极指南
革命性多文化头像生成器Multiavatar:12亿独特头像的终极指南 Multiavatar是一款革命性的多文化头像生成器,能够为用户创建超过120亿种独特的
UI库/组件pyenv自动化配置:使用脚本一键配置Python环境
pyenv自动化配置:使用脚本一键配置Python环境 痛点直击:Python环境配置的3大困境 开发Python项目时,你是否曾遇到过这些问题? 系统Pyth
开发工具CLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考