如何确定DirectX 11驱动程序挂起的原因

时间:2013-08-01 21:32:38

标签: qt graphics directx driver directx-11

我正在开发一个QT应用程序,我已将DirectX 11集成到自定义小部件中。应用程序呈现滚动显示 - 从文件读取的数据的图形表示。用户可以加快和降低滚动速度。

在大多数情况下,这很有效。就像我期望的那样,DirectX 11渲染呈现给我的自定义小部件。问题是图形驱动程序随机挂起并崩溃我的程序。我说“随机”,因为我一直在使用相同的数据文件进行测试,它似乎永远不会在文件中的同一点崩溃,在特定的时间后,或以特定的滚动速度(滚动速度越快,每帧GPU完成的工作量越多。)

当应用程序挂起时,我的屏幕会冻结片刻,变黑,然后返回来自NVidia的一条消息,它已从驱动程序崩溃中恢复过来。 Visual Studio中的调试输出包含以下内容:

  

D3D11:删除设备。

     

D3D11错误:ID3D11Device :: RemoveDevice:   由于以下原因,已触发设备删除   (DXGI_ERROR_DEVICE_HUNG:该设备采取了不合理的数量   执行命令的时间,或硬件崩溃/挂起的时间。作为一个   结果,TDR(超时检测和恢复)机制一直如此   触发。当前的Device Context正在执行命令   挂起了。应用程序可能希望重新生成并回退到   不太积极地使用显示硬件)。 [执行错误#378:   DEVICE_REMOVAL_PROCESS_AT_FAULT]

我发现通过简单地注释掉IDXGISwapChain1 :: Present调用,应用程序将以极快的速度运行该文件。在图形方面,它仍然将数据推送到GPU并绘制以渲染目标,它永远不会显示在我的窗口中。

我所希望的是帮助了解导致驱动程序挂起的事物类型的想法。我的着色器非常简单 - 基本上只是使用投影矩阵定位顶点。考虑到我在上一段中描述的内容,即使没有调用Present,着色器仍然应该通过顶点和像素,是吗?是的?

我怀疑这可能是Qt的兼容性问题 - 我知道Qt没有正式支持DirectX。所以我尝试使用CreateWindowEx创建一个单独的窗口,并将其用于我的交换链而不是自定义Qt小部件。它渲染到那个窗口,但也像以前一样挂起了驱动程序。

我也怀疑我的笔记本电脑中存在驱动程序错误,因此我尝试在更强大的桌面PC上运行该应用程序,该计算机定期运行另一个DirectX 11应用程序(非Qt)而没有任何障碍(值得一提的是,此其他应用程序呈现类似滚动显示中的数据,使用更复杂的着色器)。但我的QT应用程序也将该驱动程序挂起在该PC上。

任何人都知道我可以更详细地了解导致驱动程序挂起的原因吗?

提前感谢您提供任何帮助。

更新时间:2013-08-01 17:16 CST 我目前正在调查可能是线程同步问题,这可能是罪魁祸首。如果我自己解决这个问题,明天早上会继续发布。

1 个答案:

答案 0 :(得分:3)

经过今天的一些测试后,它似乎是一个线程问题。我今天跑了几次没有图形崩溃。所以我的问题必须得到解决,除非我今天的测试很幸运(或者不幸的是,相反 - 如果这在一两天内再次显示出丑陋的面孔)。

我知道立即设备上下文不是线程安全的。但是,我使用关键部分来同步我的线程并协调设备上下文的使用,而不是使用延迟上下文。我没有意识到,当另一个线程正在使用设备上下文时,调用IDXGISwapChain1 :: Present是不安全的。有道理,但由于它不是直接从设备上下文本身调用,我忽略了它。我确实把我的Present()调用了几行放到了我的关键部分块中,并且从那以后它没有让我崩溃。