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

Tim*_*man 4 directx graphics qt driver directx-11

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

在大多数情况下,这非常有效。正如我期望的那样,DirectX 11渲染呈现给我的自定义小部件。问题是图形驱动程序随机挂起并使我的程序崩溃。我之所以说“随机”,是因为我一直在使用相同的数据文件进行测试,并且在特定的时间或以特定的滚动速度(滚动速度越快,每帧GPU所做的工作越多)。

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

D3D11:卸下设备。

D3D11错误:ID3D11Device :: RemoveDevice:出于以下原因触发了设备移除(DXGI_ERROR_DEVICE_HUNG:设备花费了不合理的时间来执行其命令,或者硬件崩溃/挂起。因此,TDR(超时检测和恢复)机制已触发。当发生挂起时,当前的设备上下文正在执行命令。应用程序可能需要重新生成和回退,以减少对显示硬件的积极使用。[执行错误#378:DEVICE_REMOVAL_PROCESS_AT_FAULT]

我发现,只需注释掉IDXGISwapChain1 :: Present调用,应用程序便会以极快的速度运行文件。在图形方面,它仍然将数据推送到GPU并进行绘制以渲染目标,但它从未显示在我的窗口中。

我希望获得有关导致驱动程序挂起的原因的帮助。我的着色器非常简单-基本上只是使用投影矩阵定位我的顶点。考虑到我在上一段中描述的内容,即使不调用Present时,着色器仍应在顶点和像素之间移动,是吗?

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

我还怀疑笔记本电脑中的驱动程序错误,因此我尝试在功能更强大的台式机上运行该应用程序,该台式机定期运行另一个DirectX 11应用程序(非Qt)而不会出现故障(值得一提的是,该其他应用程序在滚动显示,以及使用复杂得多的着色器)。但是我的QT应用程序也将驱动程序挂在该PC上。

谁知道我可以更详细地说明导致驱动程序挂起的原因的任何方法?

预先感谢您提供的任何帮助。

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

Tim*_*man 5

经过今天的测试,这似乎是一个线程问题。我今天跑了好几次,没有图形崩溃。因此,必须解决我的问题,除非我今天对自己的测试很幸运(或者不幸的是,如果这在一两天内再次显示出丑陋的面孔)。

我知道即时设备上下文不是线程安全的。但是,我没有使用延迟的上下文,而是使用关键部分来同步线程并协调设备上下文的使用。我没有意识到的是,当另一个线程正在使用设备上下文时,调用IDXGISwapChain1 :: Present是不安全的。是有道理的,但是由于它不是直接从设备上下文本身调用的,因此我忽略了它。我从字面上将我的Present()调用移到了我的关键节块中,但此后没有崩溃。