从 DirectX12 调试层获取有用信息

Sky*_*ine 2 visual-c++ directx-12

我正在 Visual Studio Community 2019 中开发我的第一个 DirectX 12 C++ 应用程序,但无法从 Visual Studio 输出窗口中的调试日志输出中获取有用信息。

我的问题是我试图通过调用CreateSwapChain创建交换链,但对此函数的调用失败并出现 HRESULT,并产生以下错误消息:

应用程序进行了无效的调用。调用的参数或某些对象的状态不正确。启用 D3D 调试层以便通过调试消息查看详细信息。

除此之外,我还可以在“输出”窗口中看到 Visual Studio 的标准调试输出。它显示加载了哪些 .dll 文件以及引发了异常。我不相信任何输出来自 DirectX。

为了启用调试层,我尝试以下代码,从WinMain函数的第一行开始:

#if defined(DEBUG) || defined(_DEBUG)
Microsoft::WRL::ComPtr<ID3D12Debug> debugController;
ThrowIfFailed(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)));
debugController->EnableDebugLayer();
#endif
Run Code Online (Sandbox Code Playgroud)

此外,我运行 dxcpl.exe 打开 DirectX 控制面板,将可执行文件添加到范围列表中,然后为 Direct3D/DXGI 调试层选项选择“应用程序控制”单选按钮。

我通过选择“调试”->“开始调试”再次执行代码,在 Visual Studio 输出窗口中,我现在可以看到从“D3D12”报告的信息消息,例如:

...
D3D12 INFO: Create ID3D12CommandAllocator: Addr=0x0C3CBD78, ExtRef=1, IntRef=0 [ STATE_CREATION          INFO #558: CREATE_COMMANDALLOCATOR]
D3D12 INFO: Create ID3D12GraphicsCommandList: Addr=0x0C42EA78, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #560: CREATE_COMMANDLIST12]
D3D12 INFO: Create ID3D12GraphicsCommandList: Addr=0x0C479C68, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #560: CREATE_COMMANDLIST12]
Exception thrown at 0x7705B5B2 in D3DX12.exe: Microsoft C++ exception: _com_error at memory location 0x003ADDC8.
Exception thrown at 0x7705B5B2 in D3DX12.exe: Microsoft C++ exception: _com_error at memory location 0x003ADDC8.
Exception thrown at 0x7705B5B2 in D3DX12.exe: Microsoft C++ exception: D3DAppException at memory location 0x003AE670.
D3D12 INFO: Destroy ID3D12GraphicsCommandList: Name="unnamed", Addr=0x0C479C68 [ STATE_CREATION INFO #586: DESTROY_COMMANDLIST12]
D3D12 INFO: Destroy ID3D12GraphicsCommandList: Name="unnamed", Addr=0x0C42EA78 [ STATE_CREATION INFO #586: DESTROY_COMMANDLIST12]
D3D12 INFO: Destroy ID3D12CommandAllocator: Name="unnamed", Addr=0x0C3CBD78 [ STATE_CREATION INFO #584: DESTROY_COMMANDALLOCATOR]
...
Run Code Online (Sandbox Code Playgroud)

请注意,一系列异常消息之前的最后一条信息消息用于创建命令列表。命令列表是我在创建交换链之前立即创建的。我怀疑我传递给交换链的窗口存在问题,但我的怀疑并不是真正重要的。我相信 DirectX 12 应该准确地告诉我问题是什么(即“错误:您的窗口句柄对于 <在此处插入具体原因> 无效”),因为我相信这就是调试层的目的以及它告诉我启用的原因它。我相信我已经根据上面的代码启用了调试层,但是,我没有收到比启用它之前更多的有用信息。

因此,这里真正的问题是,为什么只有 DirectX 12 INFO 日志,而没有错误、警告或任何其他类型的消息来指示创建交换链的调用失败的原因?

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

Sky*_*ine 7

我花了几个小时进行搜索,但我找到了没有收到 DirectX 12 应用程序错误日志的原因。

我使用以下命令创建了 DXGI Factory:

ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(&factory)));
Run Code Online (Sandbox Code Playgroud)

这将为 DXGI 版本 1.1 创建一个 DXGI 工厂。相反,函数 CreateDXGIFactory2 的第一个参数接受一个用于调试的标志:

ThrowIfFailed(CreateDXGIFactory2(DXGI_CREATE_FACTORY_DEBUG, IID_PPV_ARGS(&factory)));
Run Code Online (Sandbox Code Playgroud)

现在使用它会显示错误日志:

D3D12 INFO: Create ID3D12CommandAllocator: Addr=0x0D6D1D18, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #558: CREATE_COMMANDALLOCATOR]
D3D12 INFO: Create ID3D12GraphicsCommandList: Addr=0x0D7358C8, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #560: CREATE_COMMANDLIST12]
D3D12 INFO: Create ID3D12GraphicsCommandList: Addr=0x0D777D40, ExtRef=1, IntRef=0 [ STATE_CREATION INFO #560: CREATE_COMMANDLIST12]
DXGI ERROR: IDXGIFactory::CreateSwapChain: Flip model swapchains (DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL and DXGI_SWAP_EFFECT_FLIP_DISCARD) do not support multisampling. DXGI_SWAP_CHAIN_DESC{ SwapChainType = ..._HWND, BufferDesc = DXGI_MODE_DESC1{Width = 1920, Height = 1080, RefreshRate = DXGI_RATIONAL{ Numerator = 144, Denominator = 1 }, Format = R8G8B8A8_UNORM, ScanlineOrdering = ..._UNSPECIFIED, Scaling = ..._UNSPECIFIED, Stereo = FALSE }, SampleDesc = DXGI_SAMPLE_DESC{ Count = 4, Quality = 1 }, BufferUsage = 0x20, BufferCount = 2, OutputWindow = 0x001C0808, Scaling = ..._STRETCH, Windowed = TRUE, SwapEffect = ..._FLIP_DISCARD, AlphaMode = ..._IGNORE, Flags = 0x2 } [ MISCELLANEOUS ERROR #102: ]
Exception thrown at 0x7705B5B2 in D3DX12.exe: Microsoft C++ exception: _com_error at memory location 0x012FDD00.
DXGI ERROR: IDXGIFactory::CreateSwapChain: Flip model swapchains (DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL and DXGI_SWAP_EFFECT_FLIP_DISCARD) do not support multisampling. DXGI_SWAP_CHAIN_DESC{ SwapChainType = ..._HWND, BufferDesc = DXGI_MODE_DESC1{Width = 1920, Height = 1080, RefreshRate = DXGI_RATIONAL{ Numerator = 144, Denominator = 1 }, Format = R8G8B8A8_UNORM, ScanlineOrdering = ..._UNSPECIFIED, Scaling = ..._UNSPECIFIED, Stereo = FALSE }, SampleDesc = DXGI_SAMPLE_DESC{ Count = 4, Quality = 1 }, BufferUsage = 0x20, BufferCount = 2, OutputWindow = 0x001C0808, Scaling = ..._STRETCH, Windowed = TRUE, SwapEffect = ..._FLIP_DISCARD, AlphaMode = ..._IGNORE, Flags = 0x2 } [ MISCELLANEOUS ERROR #102: ]
Exception thrown at 0x7705B5B2 in D3DX12.exe: Microsoft C++ exception: _com_error at memory location 0x012FDD00.
Exception thrown at 0x7705B5B2 in D3DX12.exe: Microsoft C++ exception: D3DAppException at memory location 0x012FE5A8.
D3D12 INFO: Destroy ID3D12GraphicsCommandList: Name="unnamed", Addr=0x0D777D40 [ STATE_CREATION INFO #586: DESTROY_COMMANDLIST12]
D3D12 INFO: Destroy ID3D12GraphicsCommandList: Name="unnamed", Addr=0x0D7358C8 [ STATE_CREATION INFO #586: DESTROY_COMMANDLIST12]
D3D12 INFO: Destroy ID3D12CommandAllocator: Name="unnamed", Addr=0x0D6D1D18 [ STATE_CREATION INFO #584: DESTROY_COMMANDALLOCATOR]
Run Code Online (Sandbox Code Playgroud)

我不确定 DXGI API 的历史,但我希望这可以帮助其他人解决这个问题,因为这让我很头疼。我目前正在阅读 Frank Luna 的 DirectX 12 3D 游戏编程简介。他让您启用调试层,但我在他的示例中没有看到此标志的任何设置。我克隆了他的示例项目目录,试图在他的应用程序中引发错误,结果发现没有报告错误日志。只有一个消息对话框会出现,给出与我之前发布的相同的 HRESULT 错误(这也表明应该启用调试层)。

谢谢。