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

DirectX 12 application is crashing in Windows 11

我对基于几个 DirectX 工具包示例构建的 DirectX 12 桌面 x64 应用程序有了很大的了解,但现在还支持自定义着色器,用于定向和全向阴影、动态反射、硬件实例化粒子效果系统,FBX模型骨骼动画,以及景深post-处理.

在万圣节,Windows更新将我的系统(英特尔酷睿 i7[第 8 代]/GeForce GTX1050)升级到 Windows11。当我 运行 我的项目时,我收到了一个以下形式的诡异惊喜 'Source Not Available' window:

停止调试后,应用程序在 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 进入 windowed 模式,应用程序仍会崩溃。

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

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

是否有任何其他开发人员在 Windows 11 上遇到过 DirectX 12 的稳定性 and/or 性能问题?还是我应该坐等未来的 Windows 更新来稳定新的 OS?

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

Debug Layer 在处理 'hybrid graphics' 系统(即同时配备 Intel 集成 GPU 和独立 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);

解决方法包含在 October 2021 release of my Direct3D Game template VSIX. See this commit

The D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_WRONGSWAPCHAINBUFFERREFERENCE error can trigger during "lost device" handling on hybrid-graphics systems. This issue was introduced in Windows 10 (18363). It should be fixed now, so in theory you can remove that suppression for Windows 11. Added suppression in this commit.

The "IDXGISwapChain::GetContainingOutput" DXGI warning was introduced in Windows 10 (17134). Added suppression in this commit.