Can't go fullscreen under DirectX12

1

I have an app which uses DirectX12. I wanted to support fullscreen mode in my app. However, each time I called IDXGISwapChain::SetFullscreenState(), I got this error:

DXGI ERROR: IDXGISwapChain::GetContainingOutput: The swapchain's adapter does not control the output on which the swapchain's window resides.

The error code returned by IDXGISwapChain::SetFullscreenState() was

0x887a0004

My computer has two GPU:

Intel(R) HD Graphics 630 and

NVIDIA GeForce GTX 1060

the latter was the adapter used to create d3d12 device when the error occurred. And if the adapter was the former, there would be no error.

The code flow used to create a IDXGISwapChain3 was

//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));

The IDXGISwapChain::SetFullscreenState() should succeed, but it failed.

c++
directx-12
dxgi
asked on Stack Overflow Jul 8, 2019 by Guanyuming He • edited Jul 10, 2019 by Guanyuming He

2 Answers

2

Note that the problem is a specific combination of a quirk of the DXGI debug layer and the way that the "hybrid graphics" solutions are implemented depending on which device you are using at the time.

The best option here is to just suppress the error:

#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.

answered on Stack Overflow Jul 22, 2019 by Chuck Walbourn
1

I have found a solution. Use IDXGIFactory6::EnumAdapterByGpuPreference() method instead of IDXGIFactory::EnumAdapter() method then the error will disappear.

answered on Stack Overflow Jul 11, 2019 by Guanyuming He

User contributions licensed under CC BY-SA 3.0