为核心窗口创建交换链时的DXGI_ERROR_INVALID_CALL

时间:2017-01-30 19:27:55

标签: c++ directx directx-11

我正在DirectXTutorials.com上关注this tutorial学习DX11。我正处于创建设备及其上下文的位置,现在需要创建交换链 但是,当我调用CreateSwapChainForCoreWindow(...)时,它会将交换链保留为nullptr并返回0x887a0001。 DirectX Error Lookup为代码吐出以下内容:

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

我应该如何改变代码以避免此错误?我尝试在更改交换链描述的格式或效果时遵循其他答案,但无济于事。

这是有问题的代码,它是最后一次失败的调用:

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

mDevicemDeviceContextmSwapChain都是该类的成员变量。

我直接从SDL和SFML直接使用DirectX,所以这和我一直很低。如果有足够的信息来避免有问题的电话,那么我该怎么称呼呢?我看到人们打电话CreateDeviceAndSwapChain的一些问题,这是首选方法吗?

编辑: 为了澄清,项目类型为DirectX11 App (Universal Windows),如果这有任何区别。

2 个答案:

答案 0 :(得分:0)

问题在于:

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

查看失败点处的堆栈跟踪显示我正在从Game::Initialize调用App::Initialize。因此,GetForCurrentThread()返回null,因为窗口尚未存在! (App::SetWindow(CoreWindow^ window)之后被调用,只有从那时起我们才能得到窗口。)
这是一个非常痛苦的错误。

答案 1 :(得分:0)

对于同一调用,我只是遇到了相同的错误,但在我的情况下,原因是我传入了D3D设备而不是D3D命令队列。对于D3D11和D3D12,这是不同的。参见:

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

  

参数

     

pDevice

     

对于Direct3D 11和早期版本的Direct3D,这是指向交换链的Direct3D设备的指针。对于Direct3D 12,这是指向直接命令队列的指针(请参阅ID3D12CommandQueue)。此参数不能为NULL。