在 DirectX12 下无法全屏
Can't go fullscreen under DirectX12
我有一个使用 DirectX12 的应用程序。我想在我的应用程序中支持全屏模式。
然而,每次我调用 IDXGISwapChain::SetFullscreenState() 时,我都会得到这个错误:
DXGI ERROR: IDXGISwapChain::GetContainingOutput: The swapchain's adapter
does not control the output on which the swapchain's window resides.
IDXGISwapChain::SetFullscreenState() 返回的错误代码是
0x887a0004
我的电脑有两个 GPU:
英特尔(R) 高清显卡 630 和
英伟达 GeForce GTX 1060
后者是发生错误时用于创建d3d12设备的适配器。
如果适配器是前者,则不会出现错误。
用于创建 IDXGISwapChain3 的代码流是
//variables used in the code example
ID3D12Device *pDevice;
IDXGIFactory4 *pDXGIFactory;
IDXGIAdapter *pAdapter;
ID3D12CommandQueue *pCommandQueue;
IDXGISwapChain1 *pTempSwapchain;
IDXGISwapChain3 *pSwapchain;
//the code flow
CreateDXGIFactory2();
pDXGIFactory->EnumAdapter();
D3D12CreateDevice(pAdapter, ...);
pD3DDevice->CreateCommandQueue();
pDXGIFactory->CreateSwapChainForHwnd(pCommandQueue, ..., &pTempSwapchain);
pTempSwapchain->QueryInterface(IID_PPV_ARGS(&pSwapChain));
IDXGISwapChain::SetFullscreenState() 应该会成功,但失败了。
我找到了解决办法。使用 IDXGIFactory6::EnumAdapterByGpuPreference() 方法而不是 IDXGIFactory::EnumAdapter() 方法然后错误将消失。
请注意,问题是 DXGI 调试层的一个怪癖和 "hybrid graphics" 解决方案的实施方式的特定组合,具体取决于您当时使用的设备。
这里最好的选择是只抑制错误:
#if defined(_DEBUG)
// Enable the debug layer (requires the Graphics Tools "optional feature").
//
// NOTE: Enabling the debug layer after device creation will invalidate the active device.
{
ComPtr<ID3D12Debug> debugController;
if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(debugController.GetAddressOf()))))
{
debugController->EnableDebugLayer();
}
else
{
OutputDebugStringA("WARNING: Direct3D Debug Device is not available\n");
}
ComPtr<IDXGIInfoQueue> dxgiInfoQueue;
if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(dxgiInfoQueue.GetAddressOf()))))
{
dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, true);
dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, true);
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 = _countof(hide);
filter.DenyList.pIDList = hide;
dxgiInfoQueue->AddStorageFilterEntries(DXGI_DEBUG_DXGI, &filter);
}
}
#endif
I use this in all my templates on GitHub.
我有一个使用 DirectX12 的应用程序。我想在我的应用程序中支持全屏模式。 然而,每次我调用 IDXGISwapChain::SetFullscreenState() 时,我都会得到这个错误:
DXGI ERROR: IDXGISwapChain::GetContainingOutput: The swapchain's adapter does not control the output on which the swapchain's window resides.
IDXGISwapChain::SetFullscreenState() 返回的错误代码是
0x887a0004
我的电脑有两个 GPU:
英特尔(R) 高清显卡 630 和
英伟达 GeForce GTX 1060
后者是发生错误时用于创建d3d12设备的适配器。 如果适配器是前者,则不会出现错误。
用于创建 IDXGISwapChain3 的代码流是
//variables used in the code example
ID3D12Device *pDevice;
IDXGIFactory4 *pDXGIFactory;
IDXGIAdapter *pAdapter;
ID3D12CommandQueue *pCommandQueue;
IDXGISwapChain1 *pTempSwapchain;
IDXGISwapChain3 *pSwapchain;
//the code flow
CreateDXGIFactory2();
pDXGIFactory->EnumAdapter();
D3D12CreateDevice(pAdapter, ...);
pD3DDevice->CreateCommandQueue();
pDXGIFactory->CreateSwapChainForHwnd(pCommandQueue, ..., &pTempSwapchain);
pTempSwapchain->QueryInterface(IID_PPV_ARGS(&pSwapChain));
IDXGISwapChain::SetFullscreenState() 应该会成功,但失败了。
我找到了解决办法。使用 IDXGIFactory6::EnumAdapterByGpuPreference() 方法而不是 IDXGIFactory::EnumAdapter() 方法然后错误将消失。
请注意,问题是 DXGI 调试层的一个怪癖和 "hybrid graphics" 解决方案的实施方式的特定组合,具体取决于您当时使用的设备。
这里最好的选择是只抑制错误:
#if defined(_DEBUG)
// Enable the debug layer (requires the Graphics Tools "optional feature").
//
// NOTE: Enabling the debug layer after device creation will invalidate the active device.
{
ComPtr<ID3D12Debug> debugController;
if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(debugController.GetAddressOf()))))
{
debugController->EnableDebugLayer();
}
else
{
OutputDebugStringA("WARNING: Direct3D Debug Device is not available\n");
}
ComPtr<IDXGIInfoQueue> dxgiInfoQueue;
if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(dxgiInfoQueue.GetAddressOf()))))
{
dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, true);
dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, true);
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 = _countof(hide);
filter.DenyList.pIDList = hide;
dxgiInfoQueue->AddStorageFilterEntries(DXGI_DEBUG_DXGI, &filter);
}
}
#endif
I use this in all my templates on GitHub.