4

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

在大多数情况下,这工作得很好。正如我所期望的那样,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 小部件。它渲染到那个窗口,但也像以前一样挂起驱动程序。

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

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

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

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

4

1 回答 1

5

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

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

于 2013-08-02T19:27:24.460 回答