首页 文章

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

提问于
浏览
3

我正在开发一个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小部件 . 它渲染到那个窗口,但也像以前一样挂起了驱动程序 .

我也怀疑我的笔记本电脑中存在驱动程序错误,所以我尝试在更强大的桌面PC上运行该应用程序,该计算机经常运行另一个DirectX 11应用程序(非Qt)而没有任何障碍(值得一提的是,这个其他应用程序在滚动显示,使用更复杂的着色器) . 但我的QT应用程序也挂起了该PC上的驱动程序 .

任何人都知道我可以获得更详细的描述导致驱动程序挂起的方法吗?

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

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

1 回答

  • 3

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

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

相关问题