RenderDoc 功能测试与验证指南:从 ad-hoc 手测到自动化测试套件
2026/9/24 4:51:16 网站建设 项目流程
  • 开发工具
  • 调试器
  • 图形学
  • GPU

【免费下载链接】renderdoc

RenderDoc is a stand-alone graphics debugging tool.

项目地址:https://gitcode.com/gh_mirrors/re/renderdoc
点击查看免费下载

本指南面向 RenderDoc 的贡献者与二次开发者,系统说明在为 RenderDoc 提交功能或修改时应当如何测试与验证。文章以官方贡献文档 docs/CONTRIBUTING/Testing.md 为骨架,结合仓库中真实的自动化测试基础设施(util/test 目录下的测试框架、demo 程序与 190+ 条测试用例),讲解测试现状、测试思路、自动化测试的运行方式,以及如何新增一条测试。

一、官方文档对测试的定位:当前仍是"ad-hoc"验证为主

官方 Testing.md 明确说明了当前测试策略的现状:

目前,任何特性和变更的测试基本是即兴(ad-hoc)的。我一直在开发一套正式的测试套件,用于同时测试 API 捕获/重放支持以及分析功能。

翻译成实操要点就是两条:

  1. 改动后务必回归验证:在提交修改之前,围绕你改动所涉及的区域做针对性测试("test any changes you make around the area that you've tested")。例如你改了 Vulkan 驱动的捕获逻辑,就应该跑一遍 Vulkan 相关的 demo 和捕获流程。
  2. PR 阶段听从维护者建议:如果维护者对测试有特别建议,通常会在 Pull Request 中直接提出,按建议补测即可。

这条文档撰写于测试套件尚未成型的阶段,属于"过渡期指引"。但从当前仓库的目录结构看,文档中提到的"proper test suite"已经落地为 util/test 目录下的一套完整、可运行的自动化测试体系。因此,今天的贡献者实际上拥有两条测试路径:轻量的针对性手测(ad-hoc)与完整的自动化测试套件(util/test/run_tests.py)。

二、理解测试套件的整体架构

自动化测试体系位于仓库根目录下的 util/test,主要由四部分组成:

组成部分路径职责
测试入口util/test/run_tests.py命令行入口,解析参数、调度测试、汇总结果
测试框架util/test/rdtestPython 测试框架:用例基类、日志、图像比较、远端服务等
demo 程序util/test/demos一组自包含的小型 API 使用示例,按图形 API 分目录(D3D11、D3D12、GL、Vulkan)
测试用例util/test/tests190+ 条 Python 测试用例,与 demo 一一对应

从源码结构看,整套系统的工作流是:

  1. demo 负责制造可复现的图形场景(如绘制一个简单三角形、创建各类纹理、触发特定的资源生命周期场景),并在运行时被 RenderDoc 注入捕获;
  2. 测试用例负责回放分析:打开捕获文件,通过renderdocPython 模块(rd)驱动重放,校验管线状态、着色器输出、像素拾取值、网格数据等是否符合预期;
  3. 测试框架负责调度与报告:每个用例在独立子进程中执行(防止崩溃拖垮整轮测试),失败时把 RenderDoc 日志、截图差异等产物写入 artifacts 目录。

2.1 用例基类:rdtest.TestCase

所有测试用例继承自 util/test/rdtest/testcase.py 中的TestCase基类。核心设计是两种互补的写法:

  • 实现get_capture()+check_capture():前者负责运行 demo 并产生捕获文件,后者负责对捕获内容做断言。默认的run()方法会依次调用两者(见 testcase.py#L745-L762);
  • 直接实现run():完全自定义流程,适合需要自己打开多个捕获文件的复杂用例。

基类内置了大量断言工具,例如:

  • check_triangle():在输出缓冲区多个位置拾取像素,验证前景/背景颜色是否符合预期(testcase.py#L633-L666);
  • check_pixel_value():像素拾取值比较,支持按纹理格式自动放宽 epsilon(8-bit 纹理用1/255、16-bit 用1/16384);
  • check_mesh_data()/check_task_data():把重放得到的 VS 输出网格数据与参考数据逐顶点、逐属性比对;
  • debug_vertex()/debug_pixel()/debug_thread():分别对顶点、像素、计算线程执行着色器调试,并把单步跟踪状态与预期逐指令比对。

以最简单的用例 Vulkan/VK_Simple_Triangle.py 为例,可以看到一个典型用例的完整形态:声明demos_test_name指向同名 demo,在check_capture()中取最后一个 action、把事件定位到该 action、用check_triangle()验证三角形渲染结果,再通过get_postvs()拿到顶点着色器输出,与预期的gl_PositionvertOut等参考值做精确比对。

2.2 demo 程序:测试的"素材工厂"

demo 程序是测试能否成立的前提——绝大多数测试依赖它生成捕获文件。它位于 util/test/demos,按 API 组织:d3d11/d3d12/gl/vk/各有一个*_test.cpp入口和大量按场景拆分的 demo(如vk_draw_zoo.cppd3d12_rtas_zoo.cppgl_texture_zoo.cpp等)。

按 util/test/README.md 的说明,demos 的构建方式如下:

  • Windows:直接打开 util/test/demos.sln 编译,无外部依赖;
  • Linux / Apple
cmake -Bbuild -Hdemos make -C build

Linux 需要libX11libxcblibX11-xcb(构建支持 GL 的 RenderDoc 本来就需要这些)。

需要特别注意一个"软依赖":如果 demos 没有链接 shaderc,运行时会调用外部的glslc把着色器编译为 SPIR-V,找不到glslc时部分测试会被自动禁用;目前只有 Windows 支持链接 shaderc(在$VULKAN_SDK环境变量指向的目录下自动查找)。

三、针对性手测:贡献者日常的回归验证方式

在提交修改前,官方文档要求你围绕改动区域做验证。结合仓库结构,可以给出具体的操作建议:

  • 改了捕获/注入逻辑:用 renderdoccmd 或 qrenderdoc 对本地自有的测试程序做捕获,重点验证目标 API 下的帧捕获、资源枚举是否正常;
  • 改了重放或分析逻辑:运行相关 API 的测试用例(见下节自动化测试),或直接打开已有捕获文件在 qrenderdoc 中人工检查管线状态、纹理查看器、网格查看器、着色器调试等面板;
  • 改了 shader 分析:重点跑 shader debug 类用例(Shader_Debug_ZooShader_ISAShader_Editing),以及Pixel_HistoryMesh_Zoo等分析类用例;
  • 测试用例自身的维护:如果你修改的功能已有对应测试,务必保证该测试仍然通过;如果测试用例本身不适用,在 PR 中说明理由。

同时建议遵守 README 中的告诫:不要制造"uber-demo",尽量让每个 demo 只做一件简单的事,这样测试失败时可以快速定位到具体特性。

四、运行自动化测试套件

4.1 前置条件

按 util/test/README.md 的说明:

  • 使用与构建 RenderDoc 时相同的 Python 版本(Windows 仓库自带 python 3.6 左右);
  • Windows 上 Python 的位数必须与 RenderDoc 构建一致(64 位构建对应 64 位 Python);
  • Linux/Apple 需要把demos_x64所在目录加入PATH,或用--demos-binary显式指定路径;
  • 先按上文构建好 demos 程序。

4.2 常用参数

运行run_tests.py的常用参数如下(详见 run_tests.py 参数解析部分):

参数作用
--renderdoc <path>指定 renderdoc 库路径,会修改 OS 库搜索路径(Windows 下同时加入 DLL 搜索目录)
--pyrenderdoc <path>指定renderdocPython 模块路径(如 Windows 下的x64/Development/pymodules
-l/--list仅列出可用测试并退出
-t/--test_include <regexp>只运行名称匹配该正则的测试,默认.*(全部运行)
-x/--test_exclude <regexp>排除名称匹配该正则的测试
-j/--parallel <N>用 N 个进程并行运行测试(01表示串行)
--test-timeout <秒>单个测试无输出时的超时时间,默认 90 秒
--data <path>参考数据目录,默认脚本旁的data/
--artifacts <path>输出产物目录,默认artifacts/(运行前会被清空)
--temp <path>临时工作目录,默认tmp/(运行前会被清空)
--data-extra <path>额外参考数据目录(大型捕获,不入库),默认data_extra/
--demos-binary <path>指定已构建的 demos 二进制路径
--demos-timeout <秒>期望 demos 运行完成的超时时间
--adb-device <设备>在指定的 ADB 设备上运行测试(此时--demos-binary应为 demo 的 APK)
--debugger调试模式:测试在当前进程内运行,异常不被框架捕获,便于断点调试

注意:README 与源码都明确提示,tmp/artifacts/目录在运行开始时会被整体清空(runner.py 中的清理逻辑),不要在其中存放任何重要数据。

一个典型的 Linux 运行示例:

python3 util/test/run_tests.py \ --renderdoc /path/to/librenderdoc.so \ --pyrenderdoc /path/to/pymodules \ --demos-binary /path/to/demos_x64 \ -t "VK_Simple_Triangle|GL_Simple_Triangle" \ -j 4

Windows 示例(对应 README 中的用法):

python run_tests.py --renderdoc path\to\renderdoc\x64\Development ^ --pyrenderdoc path\to\renderdoc\x64\Development\pymodules

4.3 结果解读

运行结束后,artifacts/目录中会生成自包含的结果日志output.log.html:它本质是纯文本日志,但内嵌了 JavaScript 与样式(testresults.csstestresults.js),用浏览器打开即可获得可读性良好的报告;所有依赖及图像对比产物都放在同一目录下,因此整个 artifacts 目录可以独立带走查看。

从 runner.py 的实现可以看到几处值得了解的行为:

  • 进程隔离:每个测试默认在独立子进程中运行(--internal_run_test内部参数),这样测试崩溃不会拖垮整轮运行(runner.py#L65-L79);
  • 自动处理 Vulkan layer 注册:如果检测到 Vulkan layer 未注册,会尝试自动注册,Windows 下必要时通过 UAC 提权(runner.py#L289-L329);
  • 跳过机制:测试会先调用check_support(),demo 未编译进二进制、平台不支持等情况会被标记为 skip 并记录原因,而不是失败(runner.py#L359-L380);
  • 汇总输出:结束时打印通过/失败/跳过统计,若存在失败用例则以退出码 1 结束(runner.py#L461-L479)。

五、如何新增一条测试

5.1 编写 demo(如果功能需要新的捕获场景)

在 util/test/demos 对应 API 目录下新建或复制一个现有 demo(例如复制vk_template.cpp),只实现一个简单的场景。若需要主程序注册该 demo,请参考main.cpp与同目录其他*_test.cpp的注册方式。

5.2 编写测试用例

在 util/test/tests 对应 API 目录下新建同名 Python 用例,复制现有用例并修改校验逻辑。README 的建议是:

demos 项目中包含辅助库,最好的起步方式就是复制一个现有测试再按需修改;避免 uber-demo,尽量只做一件简单的事。测试用例通常与 demo 一一对应,同样可以复制现有用例并加入自己的检查。

用例骨架(以VK_Simple_Triangle为模板):

import renderdoc as rd import rdtest class VK_My_Feature(rdtest.TestCase): demos_test_name = 'VK_My_Feature' # 对应 demos 中的测试名 demos_frame_cap = 5 # 捕获帧数上限 demos_frame_count = 1 # 要捕获的帧数 def check_capture(self): # 打开捕获后,用 self.controller 驱动重放并断言 # 例如 self.check_triangle(...)、self.check_pixel_value(...) pass

5.3 新增参考图像(仅当需要图像比对时)

README 给出了新增参考图像的明确流程:

  1. 首次不带参考图像运行,框架会输出将要用于比对的图像;
  2. pngcrush处理该图像(确保保留 RGBA 输出),以减小仓库体积;
  3. 放入参考数据目录供后续比对。

需要图像比对的典型场景如check_final_backbuffer():它把最后一个 action 的 backbuffer 保存为 PNG,与参考图逐像素比对(testcase.py#L830-L847)。

5.4 运行与验证

-t正则只跑你的新用例(如-t "VK_My_Feature"),确认通过后,再跑一次该 API 目录下的相关用例(如-t "VK_"),确认没有破坏既有功能。

六、测试套件覆盖的能力范围

当前仓库的测试体系已具备相当完整的覆盖面,可作为贡献者判断"改动应跑到哪些测试"的参考:

  • 四套图形 API:D3D11、D3D12、OpenGL、Vulkan,各自拥有独立测试目录(util/test/tests/D3D11、D3D12、GL、Vulkan);
  • 捕获/重放基础能力:空捕获(Empty_Capture)、泄漏检查(Leak_Check)、资源生命周期(Resource_Lifetimes)、帧 0 校验(Frame0)等;
  • 分析功能:像素历史(Pixel_History)、网格数据(Mesh_Zoo)、纹理/缓冲区(Texture_ZooBuffer_Truncation)、丢弃操作(Discard_Zoo)、覆盖层(Overlay_Test)等;
  • 着色器调试Shader_Debug_ZooShader_ISAShader_EditingShader_Linkage_Zoo等,配合debug_vertex/debug_pixel做指令级单步比对;
  • 较新的图形特性:D3D12 的 Mesh Shader、VRS、光线追踪资源(RTAS),Vulkan 的 Dynamic Rendering、Descriptor Buffer、Ray Query 等。

七、小结:贡献者的测试清单

综合官方文档与仓库现状,提交修改前建议按以下清单自检:

  1. 手测改动区域:围绕你修改的代码路径做一次真实捕获与重放验证;
  2. 跑相关自动化用例:用-t正则选中与你改动相关的测试目录(如D3D12_GL_VK_GL_Shader_Debug等),确保没有回归;
  3. 新功能配套测试:涉及新功能时按第五章流程补充 demo 与用例,参考图像用 pngcrush 压缩后入库;
  4. 关注 PR 反馈:维护者对测试若有额外要求会在 PR 中提出,按建议补充即可。

通过"针对性手测 + 自动化测试套件"的组合,即使是变更范围横跨多个图形 API 的功能,也能在提交前获得足够可信的验证结果。

  • 开发工具
  • 调试器
  • 图形学
  • GPU

【免费下载链接】renderdoc

RenderDoc is a stand-alone graphics debugging tool.

项目地址:https://gitcode.com/gh_mirrors/re/renderdoc
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询