DirectX 12 应用程序在 Windows 11 中崩溃

Posted

技术标签:

【中文标题】DirectX 12 应用程序在 Windows 11 中崩溃【英文标题】:DirectX 12 application is crashing in Windows 11 【发布时间】:2021-12-16 16:12:37 【问题描述】:

我非常喜欢基于几个 DirectX 工具包示例构建的 DirectX 12 桌面 x64 应用程序,但现在还支持用于定向和全向阴影、动态反射、硬件实例化粒子效果系统、FBX 的自定义着色器模型骨骼动画和景深后处理。

在万圣节,Windows 更新将我的系统(英特尔酷睿 i7[第 8 代]/GeForce GTX1050)升级到了 Windows 11。当我运行我的项目时,我收到了以下“源不可用”窗口形式的令人毛骨悚然的惊喜:

停止调试后,应用程序在 DeviceResources.cpp 中的 Present() 调用处崩溃并生成以下错误:

D3D12 ERROR: ID3D12CommandQueue::Present: Resource state (0x800: D3D12_RESOURCE_STATE_COPY_SOURCE) (promoted from COMMON state) of resource (0x0000011BD5330080:'Render target 0') (subresource: 0) must be in COMMON state when transitioning to use in a different Command List type, because resource state on previous Command List type : D3D12_COMMAND_LIST_TYPE_COPY, is actually incompatible and different from that on the next Command List type : D3D12_COMMAND_LIST_TYPE_DIRECT. [ RESOURCE_MANIPULATION ERROR #990: RESOURCE_BARRIER_MISMATCHING_COMMAND_LIST_TYPE]
D3D12: **BREAK** enabled for the previous message, which was: [ ERROR RESOURCE_MANIPULATION #990: RESOURCE_BARRIER_MISMATCHING_COMMAND_LIST_TYPE ]
Exception thrown at 0x00007FFA0F6A466C (KernelBase.dll) in DXTK12 Game.exe: 0x0000087A (parameters: 0x0000000000000001, 0x00000014297FC640, 0x00000014297FE420).
Unhandled exception at 0x00007FFA0F6A466C (KernelBase.dll) in DXTK12 Game.exe: 0x0000087A (parameters: 0x0000000000000001, 0x00000014297FC640, 0x00000014297FE420).

这在 Windows 10 中从未发生过,而且这种崩溃是不稳定的。我的游戏配置为以无边框全屏模式启动,有时会在崩溃前运行几秒钟。如果我有时间 Alt+Enter 进入窗口模式,应用程序仍然会崩溃。

我已更新我的 Nvidia 驱动程序并将项目指向最新的 Windows 11 SDK 版本 (10.0.22000.0),但问题仍然存在。

经过一番谷歌搜索后,有证据表明存在与 Windows 11 上不稳定的 DXGI/WDM 行为有关的已知问题,该问题由在模拟全屏(即无边框窗口)模式下运行游戏的用户报告。崩溃后我也遇到了 Alt+Tab 窗口切换行为错误,但这似乎已通过图形驱动程序更新修复。

是否有其他开发人员在 Windows 11 上遇到过 DirectX 12 的稳定性和/或性能问题?还是我应该坐等未来的 Windows 更新来稳定新操作系统?

【问题讨论】:

【参考方案1】:

这是 DXGI 调试层与带有 Windows 11 的 DX12 调试层交互中的一个错误。有一个简单的解决方法是抑制 D3D12_MESSAGE_ID_RESOURCE_BARRIER_MISMATCHING_COMMAND_LIST_TYPE。该错误本身将在未来的 Windows 更新中修复。

在处理“混合图形”系统(即同时配备英特尔集成和独立 GPU 的笔记本电脑)时,调试层总是有一些怪癖,因此我在与它相关的 DeviceResources 实现中有一些抑制:

DXGI_INFO_QUEUE_MESSAGE_ID hide[] =

    80 /* IDXGISwapChain::GetContainingOutput: The swapchain's adapter does not control the output on which the swapchain's window resides. */,
;
DXGI_INFO_QUEUE_FILTER filter = ;
filter.DenyList.NumIDs = static_cast<UINT>(std::size(hide));
filter.DenyList.pIDList = hide;
dxgiInfoQueue->AddStorageFilterEntries(DXGI_DEBUG_DXGI, &filter);
D3D12_MESSAGE_ID hide[] =

    D3D12_MESSAGE_ID_MAP_INVALID_NULLRANGE,
    D3D12_MESSAGE_ID_UNMAP_INVALID_NULLRANGE,
    // Workarounds for debug layer issues on hybrid-graphics systems
    D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_WRONGSWAPCHAINBUFFERREFERENCE,
    D3D12_MESSAGE_ID_RESOURCE_BARRIER_MISMATCHING_COMMAND_LIST_TYPE,
;
D3D12_INFO_QUEUE_FILTER filter = ;
filter.DenyList.NumIDs = static_cast<UINT>(std::size(hide));
filter.DenyList.pIDList = hide;
d3dInfoQueue->AddStorageFilterEntries(&filter);

解决方法包含在我的 Direct3D 游戏模板 VSIX 的 October 2021 版本中。见this commit

D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_WRONGSWAPCHAINBUFFERREFERENCE 错误可能会在混合图形系统上的“丢失设备”处理期间触发。此问题是在 Windows 10 (18363) 中引入的。它现在应该已修复,因此理论上您可以删除 Windows 11 的抑制。在 this commit 中添加了抑制。

Windows 10 (17134) 中引入了“IDXGISwapChain::GetContainingOutput”DXGI 警告。在this commit 中添加了抑制。

【讨论】:

谢谢@ChuckWalbourn。我可以报告,在将 D3D12_MESSAGE_ID_RESOURCE_BARRIER_MISMATCHING_COMMAND_LIST_TYPE 添加到 D3D12_MESSAGE_ID 枚举列表后,我的游戏在 Windows 11 中完美运行。再次感谢您在 DirectXTK 上所做的工作,这对于 DirectX 12 来说是无价的。 IMO 的最佳功能是 GraphicsResource 内存分配器助手,它取代了为“运行中”常量缓冲区数据(根据“原始”DirectX 12 编程中的要求)设置循环帧资源缓冲区的麻烦,以及其他好处,例如管理GPU 围栏也适合您。我赞成你的回答。

以上是关于DirectX 12 应用程序在 Windows 11 中崩溃的主要内容,如果未能解决你的问题,请参考以下文章

DirectX 官方文档

DirectX11 With Windows SDK--30 计算着色器:图像模糊索贝尔算子

微软工程师详细介绍了Windows 11原生DX12视频编码API

检查是不是支持 DirectX 或 OpenGL

它是 Winapi 的 WIC(Windows 映像组件)和 DirectX 部分吗? [关闭]

带有 Directx 11 的 WPF