BGFX 渲染引擎中着色器代码的调试方法

在实时渲染的图形开发中,着色器代码(Shader)越来越复杂,于是单纯的靠经验和不断试错的开发和调试方法早已不能满足实际需求。使用调试工具进行调试,成为开发中重要的方法。

Bgfx 是一款跨平台、抽象封装了众多主流图形 API 的优秀渲染引擎。作为示例,本文在 Windows 平台上演示使用 Microsoft Visual Studio* 和 RenderDoc 对 bgfx 中的 DX11 着色器代码进行调试。

准备工作

  1. 克隆 bfgx 源代码
    git clone git://github.com/bkaradzic/bx.git
    git clone git://github.com/bkaradzic/bimg.git
    git clone git://github.com/bkaradzic/bgfx.git
  2. 使用 GENie 生成 Visual Studio 项目文件,其中包含示例和工具
    cd bgfx
    ..\bx\tools\bin\windows\genie.exe --with-tools --with-examples vs2017
    	

我们可以通过 --help 命令行参数得到更多项目生成的信息。

在生成的 bgfx/.build/projects/vs2017 目录下用 Microsoft Visual Studio* 2017 打开  bgfx.sln,如图1所示我们看到示例和工具的项目都已经在我们的 Visual Studio 解决方案里面了。

Examples and tools in Visual Studio project file
图1. 在Visual Studio中部分显示的示例和工具项目

我们使用 example-37-gpudrivenrendering 项目作为本文的示例项目,我们的调试将围绕这个项目展开。另一个项目是 shaderc ,它是 bgfx 的 Shader 编译器,负责将 bgfx 规格的 Shader 源码编译成目标 API 运行时需要的二进制。

接下去我们在 Visual Studio 里面构建项目。构建完成后,在 bgfx/.build/win64_vs2017/bin 目录下我们可以找到所有已经编译好的示例程序以及 shaderc.exe ,如果选择的是 Debug 模式,生成的应用程序名字中将会带 Debug 后缀。

Highlighted applications from list of files
图2. 两个构建出的应用程序(蓝色高亮),用于配合本文。由于是调试版,带“Debug”后缀

测试“example-37-gpudrivenrendering”示例程序

我们并不能直接双击启动目标示例程序,因为我们需要将程序启动目录指定到 bgfx/examples/runtime 目录下。该目录包含了应用需要加载的资源文件。更简单的方式是在 Visual Studio 里面调试,因为在项目设置里面已经设置了调试时的工作目录(图3所示)。

Debugging configuration properties
图3. 项目属性->调试,examples\runtime目录已经预先设置好了

一切顺利的话,我们将会看到如下画面。

Example of running project
图4. Example-37-gpudrivenrenderingDebug运行中

重新编译 DX11 Shader

默认情况下,我们用到的 bgfx 的 DX11 Shader 文件位于 bgfx/examples/runtime/shaders/dx11 目录下,但这些后缀为 .bin 的 Shader 文件并不带调试信息,而且已经优化过,对于我们的调试不友好。我们需要重新编译这些 DX11 Shader,让 Shader 带上调试信息并且禁用优化,这样可以在调试工具里面看到更多有用的信息。我们将用 cs_gdr_downscale_hi_z 这个 Shader 来作为例子进行调试。

  1. 设置当前目录为 bgfx/src 。
    之所以要把当前工作目录设置为“src”目录是因为 Shader 编译时引用的公用 Shader 源文件也在这个目录下,如果没有这一步,shaderc 将会找不到这些公用 Shader 文件。

    cd bgfx/src
  2. 我们使用如下命令对需要调试的 Shader 进行编译。
..\.build\win64_vs2017\bin\shadercDebug.exe -f ..\examples\37-gpudrivenrendering\cs_gdr_downscale_hi_z.sc -o ..\examples\runtime\shaders\dx11\cs_gdr_downscale_hi_z.bin --type c -p cs_5_0 --platform windows --debug -O 0

其中:

  • 是 bgfx 的 Shader 编译器,由于示例中使用的是 Debug 版本,故带 Debug 后缀。
  •  cs_gdr_downscale_hi_z.sc 是我们测试用的 Compute Shader 的源码。
  •  cs_gdr_downscale_hi_z.bin 是编译后二进制。
  •  --type c 表示将目标编译成 Compute Shader。
  •  -p cs_5_0 表示用 Compute Shader Profile 5.0 生成 Shader。
  •  --platform windows 表示 Windows 平台。
  •  --debug -O 0 表示调试模式并且禁止优化。

用 Microsoft Visual Studio* 进行 Shader 调试

在打开的 bgfx 项目中,我们选择 Debug>Graphics>Start Graphics Debugging(图5所示),用图形调试模式启动 example-37-gpudrivenrendering 示例程序。

Debug tab options
图5. 在Debug菜单中,选择Graphics,然后选择Start Graphics Debugging(或者直接按Alt + F5)启动示例程序

在 diagsession 视图中(图6),我们点击任何一个 Capture Frame 按钮或者在游戏窗口中点击键盘上的 Print Screen 键,即可捕捉到一个图形帧。

How to capture frames
图 6. 点击Capture Frame(用红色圈出)或者键盘上的Print Screen键,来收集一个图形帧

关闭渲染窗口或者点击 Stop Collection 按钮停止收集。双击缩略图打开我们捕捉到的那一帧的,我们可以看到在“Graphics Analyzer”中打开的一帧。

Graphic analyzer panels options
图7. 图形分析器(Graphics Analyzer)中的Event List,Call Stack,Pipeline Stages以及其他面板

我们可以看到不同的面板,最重要的包括 Event ListCall StackPipeline StagesObject Table 等等。我们在 Event List 里面选中一个 Compute Shader 相关的 Dispatch 接口事件,在展开的子列表中选择 CS Shader 。由于我们是调试模式下编译的,此时在打开的源代码面板中就会展现目标 Shader 的源代码。

接下去,我们点击目标 Shader 底下的绿色调试箭头(在图7中用红色圈出),就可以开始对这个 Shader 进行调试。 我们可以像平时在 Visual Studio 调试程序那样对 Shader 进行调试。我们可以 Step Into (F11)Step Over (F10)Step Out (Shift + F11),还可以查看变量的值。

使用 RenderDoc 进行 Shader 调试

RenderDoc 是一款开源的强大图形开发和调试工具。我们从 https://renderdoc.org/ 下载 RenderDoc 最新版本,安装后待用。

Launch gpudrivenrenderingDebug.exe in RenderDoc as shown in the Figure 8. Be sure to set Working Directory to the examples/runtime directory. Click Launch to run the gpudrivenrendering program.在 RenderDoc 中启动 gpudrivenrenderingDebug.exe 如图所示,需要注意的是,我们必须将 Working Directory 设置到 examples/runtime 目录下。点击 Launch 即可启动 gpudrivenrendering 程序。

RenderDco Interface
图8. 分别设置可执行文件路径和工作目录后使用RenderDoc启动example-37-gpudrivenrenderingDebug.exe

将鼠标放在运行的 gpudrivenrendering 窗口中,点击 F11,我们将抓取到一个图形帧。双击新生成的这一帧的预览图,我们可以打开这一帧。

Example of a captured frame
图9. 抓取到的一个图形帧显示在 Captures Collected: 区域中

在打开的一帧中,我们按图10 A中所示的 1,2,3 步聚依次点击,即可进入 Compute Shader 调试模式。我们可以查看反汇编(图10 B)或者 HLSL(图10 C),还可以查看变量、寄存器、常量和资源等。到此,我们就可以进行调试了。

steps to enter computer shader
图10 A. 按1,2,3的步骤依次点击,进入Compute Shader的调试模式

Check for disassembly, tab
图10 B. 查看和调试汇编

Debug tab options
图10 C. 查看和调试HLSL源码

请注意 RenderDoc 对Compute Shader 的调试支持是实验性质的,文档中有这样的语句:

“This feature is highly experimental and is provided with no guarantees yet! It may work on simple shaders which is why it is available.”

结论

由于硬件平台和图形 API 的多样性,我们需要使用不同的工具和方法,针对具体情况采用不同的开发和调试方法。本文从一个实际的渲染引擎入手,详细介绍了使用在 Windows 平台上使用 Visual Studio 和 RenderDoc 调试 Shader 的方法,对其它平台和图形 API 也有一定的参考价值。

参考资料

BGFX项目地址

如何构建BGFX

BGFX的shaderc编译器

微软 Visual Studio* Graphics Diagnostics

如何使用RenderDoc调试Shader

有关编译器优化的更完整信息,请参阅优化通知