我目前正在将一个渲染引擎从OpenGL移植到Direct3D11
它在我的开发机器上运行得很好,但现在已经将它发布给了几个beta测试人员,两个测试人员报告了一个调整窗口大小的问题(一个崩溃,另一个UI冻结)。因为它在我的机器上工作,并且我在代码中看不到任何错误,我希望有更多Direct3D经验的人能够发现我做错了什么。
下面的代码是当窗口调整大小时发生的相关代码( m_stencilview等是指向Com对象的智能指针,D3D_CHECK是用于检查结果的宏包装)
m_stencilview.Clear();
m_stencil.Clear();
m_rendertargetview.Clear();
ctx.OMSetRenderTargets(0, 0, 0);
D3D_CHECK(m_swpchain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0));
ComPtr <ID3D11Texture2D> framebuffer;
D3D_CHECK(m_swpchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&framebuffer));
D3D_CHECK(engine.m_device->CreateRenderTargetView(framebuffer, 0, &m_rendertargetview));发布于 2021-06-08 11:08:10
请注意,一个关键问题是:
ctx.OMSetRenderTargets(0, 0, 0);这根本不会清除设置的渲染目标。您需要实际传递一个nullptr数组来让它清除绑定:
ID3D11RenderTargetView* nullViews [] = { nullptr };
ctx.OMSetRenderTargets(1, nullViews, nullptr);如果你使用的是“多个渲染目标”,那么你必须传递多个nullptr,这就是为什么数组在这里简单易用的原因。
此外,您需要在运行时检查来自ResizeBuffers的HRESULT。目前,你只是认为它总是会成功,但事实并非如此。
特别是,您需要检查ResizeBuffers和Present的返回值DXGI_ERROR_DEVICE_REMOVED或DXGI_ERROR_DEVICE_RESET。
在运行时出现这种情况的最常见原因是在应用程序运行时在后台更新设备驱动程序。如果驱动程序崩溃并重新启动,或者如果GPU硬件挂起并超时,也会发生这种情况。
您有两个基本选择:
(a)消息框中出现致命错误,如“您必须立即重新启动此应用程序”。这很差劲,但至少发生了什么事情是很清楚的。
(b)更好的应对方法是基本上像Direct3D 9应用程序对“丢失的设备”所做的那样:销毁所有Direct3D对象并重新创建它们。
通过在Direct3D应用程序运行时从开发人员命令提示符(以管理员身份打开)运行dxcap -forcetdr,可以使用最新的Visual Studio发行版
测试此行为。
请参阅GitHub了解完整的游戏循环,以及对“丢失设备”的处理。
https://stackoverflow.com/questions/67880045
复制相似问题