前一段时间我一直认为Shader是无法断点调试的,后来在知乎无聊逛帖子,发现好几年前就能 用诸如Pix For Window,Renderdoc,NSight等等工具来调试Shader.这里有一个各种调试Shader或者图形性能工具的链接,是英伟达(中国)张静前辈收集的:http://vinjn.github.io/2013/07/07/graphics-debugging-tools-overview.html
这里呢,Pix For Window为微软前几年在D3D SDK里的一个调试Shader的工具,然而已经被改进为Visual Studio Graphics Debugger,这里我用一个例子教大家怎么使用Visual Studio Graphics Debugger。
首先呢,这是我下面要使用的demo,源代码链接如下:http://download.csdn.net/detail/qq_29523119/9710595
首先,再次强调下,我用的VS2015,我修改了编译VertexShader的代码和编译PixelShader的代码:
//第二,编译VertexShader代码,并创建VertexShader,注意D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION
result = D3DX11CompileFromFile(VSFileName, NULL, NULL, "VS", "vs_5_0", D3DCOMPILE_ENABLE_STRICTNESS| D3DCOMPILE_DEBUG| D3DCOMPILE_SKIP_OPTIMIZATION, 0, NULL, &VertexShaderBuffer, &errorMessage, NULL);
if (FAILED(result))
{
//存在错误信息
if (errorMessage)
{
OutputShaderErrorMessage(errorMessage, hwnd, VSFileName);
}
//不存在错误信息,也就是没有找到Shader文件
else
{
MessageBox(hwnd, L"can not find VS file", L"error", MB_OK);
}
//第三,编译PixelShader,并创建PixelShader,注意D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION
result = D3DX11CompileFromFile(PSFileName, NULL, NULL, "PS", "ps_5_0", D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION, 0, NULL, &PixelShaderBuffer, &errorMessage, NULL);
if (FAILED(result))
{
//存在错误信息
if (errorMessage)
{
OutputShaderErrorMessage(errorMessage, hwnd, PSFileName);
}
//不存在错误信息,也就是没有找到Shader文件
else
{
MessageBox(hwnd, L"can not find PS file", L"error", MB_OK);
}
}
这里编译VS和PS文件的函数D3DX11CompileFromFile的第六个参数都是 D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION,这里千万不能忘记 D3DCOMPILE_DEBUG,否则后面调试Shader时会跳出如下面图的错误:
当然也不要忘记D3DCOMPILE_SKIP_OPTIMIZATION,这可以防止某些数据被自动优化而无法查看。
这里我用的是VS2015中文版:启用Visual Studio Graphics Debugger的方法:调试(D)->图形->启用诊断(Alt+F5),
按操作得到下面的图:
我们针对当前运行的程序,点击捕捉帧来捕捉图形程序运行在某一帧的画面,可以捕捉大量的帧数,如下面图所示:
然后鼠标双击某一帧进入那一帧画面的具体调试流程,在这个图形分析器里,可以选取这一帧画面的某个特定的像素进行分析,也可以进行D3D11的各种状态的设置情况,如下图所示,
然后我们点击VertexShader调试按钮或者PixelShader调试按钮,也就是上面图红圈的部分,这里得注意的是如果你不在编译Shader代码时指定D3DCOMPILE_DEBUG,那么你将失败,所以再次强调,注意指定D3DCOMPILE_DEBUG,最后得到下面图:
这样,Shader的断点调试效果出来了,这里我调试的是VertexShader,但PixelShader跟VertexShader调试的操作是一样的。
ComputeShader的Debug具体参考这篇博客:Directx11入门教程四十八之小议ComputeShader
如何用VS GraphicsDebugger 调试UnityShader请参考:VS2017下用Graphics Debugger调试UnityShader
具体进一步使用的参考MSDN的开发文档:https://msdn.microsoft.com/en-us/library/hh708964.aspx