DXGI_ERROR_INVALID_CALL when creating swap chain for core window

0

I'm learning DX11 by following this tutorial on DirectXTutorials.com. I'm at the point where I have created the device and it's context and now need to create the swap chain.
However, when I call CreateSwapChainForCoreWindow(...), it leaves the swap chain as a nullptr and returns 0x887a0001. DirectX Error Lookup spits out the following for the code:

Name: DXGI_ERROR_INVALID_CALL
Description: The application has made an erroneous API call that it had enough information to avoid.
This error is intended to denote that the application should be altered to avoid the error.
Use of the debug version of the DXGI.DLL will provide run-time debug output with further information.
Severity code: Failed

How should I go about altering to code to avoid this error? I've tried following others answers in changing the format or effect for the swap chain description to no avail.

Here's the code in question, it's the last call that fails:

void Game::Initialize()
{
    // Define temporary pointers to a device and a device context
    ComPtr<ID3D11Device> dev11;
    ComPtr<ID3D11DeviceContext> devcon11;

    // Create the device and device context objects
    D3D11CreateDevice(
        nullptr,
        D3D_DRIVER_TYPE_HARDWARE,
        nullptr,
        0,
        nullptr,
        0,
        D3D11_SDK_VERSION,
        &dev11,
        nullptr,
        &devcon11
    );

    // Convert the pointers from the DirectX 11 version to the DirectX 11.1 versions
    dev11.As(&mDevice);
    devcon11.As(&mDeviceContext);

    // Obtain the DXGI factory
    // [1] Convert our ID3D11Device1 into an IDXGIDevice1
    ComPtr<IDXGIDevice1> dxgiDevice;
    mDevice.As(&dxgiDevice);

    // [2] Use the IDXGDevice1 interface to get access to the adapter
    ComPtr<IDXGIAdapter> dxgiAdapter;
    dxgiDevice->GetAdapter(&dxgiAdapter);

    // [3] Use the IDXGIAdapter interface to get access to the factory
    ComPtr<IDXGIFactory2> dxgiFactory;
    dxgiAdapter->GetParent(__uuidof(IDXGIFactory2), &dxgiFactory);

    // Set up the swap chain description
    DXGI_SWAP_CHAIN_DESC1 scd = { 0 };
    scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;  // How the swap chain should be used
    scd.BufferCount = 2;                                // A front and back buffer
    scd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;            // The most common swap chain format
    scd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;  // The recommended flip mode
    scd.SampleDesc.Count = 1;                           // Disable anti-aliasing

    HRESULT result = dxgiFactory->CreateSwapChainForCoreWindow(
        mDevice.Get(),      // Address of the device
        reinterpret_cast<IUnknown*>(CoreWindow::GetForCurrentThread()), // Address of the window
        &scd,               // Address of the swap chain description                        
        nullptr,            // Monitor selection stuff - leave null
        &mSwapChain         // Address of the new swap chain
    );
}

mDevice, mDeviceContext and mSwapChain are all members variables of the class.

I've come straight to DirectX from SDL and SFML so this is as low level as I've been. If there's enough information to avoid the problematic call, then what should I be calling instead? I see some questions where people are calling CreateDeviceAndSwapChain, is this the preferred method?

EDIT: To clarify, the project type is DirectX11 App (Universal Windows), if that makes any difference.

c++
directx
directx-11
asked on Stack Overflow Jan 30, 2017 by Alex Meuer • edited Jan 31, 2017 by Alex Meuer

2 Answers

0

Here's the problem line:

    reinterpret_cast<IUnknown*>(CoreWindow::GetForCurrentThread()), // Address of the window

A look at the stack trace at the point of failure showed that I was calling Game::Initialize from App::Initialize. Therefore, GetForCurrentThread() was returning null because the window didn't exist yet! (App::SetWindow(CoreWindow^ window) is called afterwards, and only from then on can we get the window.)
It was a painfully simple mistake.

answered on Stack Overflow Feb 8, 2017 by Alex Meuer
0

I just had the same error for the same call, but the cause in my case was that I was passing in the D3D device instead of the D3D command queue. This is different for D3D11 and D3D12. See:

https://docs.microsoft.com/en-us/windows/win32/api/dxgi1_2/nf-dxgi1_2-idxgifactory2-createswapchainforcorewindow

Parameters

pDevice

For Direct3D 11, and earlier versions of Direct3D, this is a pointer to the Direct3D device for the swap chain. For Direct3D 12 this is a pointer to a direct command queue (refer to ID3D12CommandQueue). This parameter cannot be NULL.

answered on Stack Overflow Aug 25, 2019 by Kelsie • edited Jun 20, 2020 by Community

User contributions licensed under CC BY-SA 3.0