输入全屏会导致内部异常

时间:2015-12-25 23:46:43

标签: directx directx-11

当我使用Alt + Enter或调用IDXGISwapChain::SetFullscreenState时,我注意到DirectX会在内部抛出一堆异常。当且仅当我配置DXGI_SWAP_CHAIN_DESC

时,我使用大于1的多重采样计数时才会出现这种情况
Exception thrown at 0x7412D8A8 in 05 - D3D11 Core App.exe: Microsoft C++ exception: _com_error at memory location 0x0018CC58.
Exception thrown at 0x7412D8A8 in 05 - D3D11 Core App.exe: Microsoft C++ exception: _com_error at memory location 0x0018D854.
Exception thrown at 0x7412D8A8 in 05 - D3D11 Core App.exe: Microsoft C++ exception: _com_error at memory location 0x0018D980.
Exception thrown at 0x7412D8A8 in 05 - D3D11 Core App.exe: Microsoft C++ exception: _com_error at memory location 0x0018EBD8.
Exception thrown at 0x7412D8A8 in 05 - D3D11 Core App.exe: Microsoft C++ exception: _com_error at memory location 0x0018ED8C.
Exception thrown at 0x7412D8A8 in 05 - D3D11 Core App.exe: Microsoft C++ exception: _com_error at memory location 0x0018CC58.
Exception thrown at 0x7412D8A8 in 05 - D3D11 Core App.exe: Microsoft C++ exception: _com_error at memory location 0x0018D854.
Exception thrown at 0x7412D8A8 in 05 - D3D11 Core App.exe: Microsoft C++ exception: _com_error at memory location 0x0018D980.
Exception thrown at 0x7412D8A8 in 05 - D3D11 Core App.exe: Microsoft C++ exception: _com_error at memory location 0x0018EBD8.
Exception thrown at 0x7412D8A8 in 05 - D3D11 Core App.exe: Microsoft C++ exception: _com_error at memory location 0x0018ED8C.

这些从未传播到我的代码,所以我假设这些消息是针对正在处理的第一次机会异常。

我的问题是:这些消息是正常的,还是表明我以非理想的方式做某事?

就上下文而言,我正在阅读Frank Luna的DirectX 11书籍。这发生在他自己的第6章Box演示的示例代码中。他的网站上的相关代码:

bool D3DApp::InitDirect3D()
{
    // Create the device and device context.

    UINT createDeviceFlags = 0;
#if defined(DEBUG) || defined(_DEBUG)
    createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

    D3D_FEATURE_LEVEL featureLevel;
    HRESULT hr = D3D11CreateDevice(
            0,                 // default adapter
            md3dDriverType,
            0,                 // no software device
            createDeviceFlags,
            0, 0,              // default feature level array
            D3D11_SDK_VERSION,
            &md3dDevice,
            &featureLevel,
            &md3dImmediateContext);

    if( FAILED(hr) )
    {
        MessageBox(0, L"D3D11CreateDevice Failed.", 0, 0);
        return false;
    }

    if( featureLevel != D3D_FEATURE_LEVEL_11_0 )
    {
        MessageBox(0, L"Direct3D Feature Level 11 unsupported.", 0, 0);
        return false;
    }

    // Check 4X MSAA quality support for our back buffer format.
    // All Direct3D 11 capable devices support 4X MSAA for all render
    // target formats, so we only need to check quality support.

    HR(md3dDevice->CheckMultisampleQualityLevels(
        DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality));
    assert( m4xMsaaQuality > 0 );

    // Fill out a DXGI_SWAP_CHAIN_DESC to describe our swap chain.

    DXGI_SWAP_CHAIN_DESC sd;
    sd.BufferDesc.Width  = mClientWidth;
    sd.BufferDesc.Height = mClientHeight;
    sd.BufferDesc.RefreshRate.Numerator = 60;
    sd.BufferDesc.RefreshRate.Denominator = 1;
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
    sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

    // Use 4X MSAA?
    if( mEnable4xMsaa )
    {
        sd.SampleDesc.Count   = 4;
        sd.SampleDesc.Quality = m4xMsaaQuality-1;
    }
    // No MSAA
    else
    {
        sd.SampleDesc.Count   = 1;
        sd.SampleDesc.Quality = 0;
    }

    sd.BufferUsage  = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.BufferCount  = 1;
    sd.OutputWindow = mhMainWnd;
    sd.Windowed     = true;
    sd.SwapEffect   = DXGI_SWAP_EFFECT_DISCARD;
    sd.Flags        = 0;

    // To correctly create the swap chain, we must use the IDXGIFactory that was
    // used to create the device.  If we tried to use a different IDXGIFactory instance
    // (by calling CreateDXGIFactory), we get an error: "IDXGIFactory::CreateSwapChain:
    // This function is being called with a device from a different IDXGIFactory."

    IDXGIDevice* dxgiDevice = 0;
    HR(md3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice));

    IDXGIAdapter* dxgiAdapter = 0;
    HR(dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter));

    IDXGIFactory* dxgiFactory = 0;
    HR(dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory));

    HR(dxgiFactory->CreateSwapChain(md3dDevice, &sd, &mSwapChain));

    ReleaseCOM(dxgiDevice);
    ReleaseCOM(dxgiAdapter);
    ReleaseCOM(dxgiFactory);

    // The remaining steps that need to be carried out for d3d creation
    // also need to be executed every time the window is resized.  So
    // just call the OnResize method here to avoid code duplication.

    OnResize();

    return true;
}
void D3DApp::OnResize()
{
    assert(md3dImmediateContext);
    assert(md3dDevice);
    assert(mSwapChain);

    // Release the old views, as they hold references to the buffers we
    // will be destroying.  Also release the old depth/stencil buffer.

    ReleaseCOM(mRenderTargetView);
    ReleaseCOM(mDepthStencilView);
    ReleaseCOM(mDepthStencilBuffer);


    // Resize the swap chain and recreate the render target view.

    HR(mSwapChain->ResizeBuffers(1, mClientWidth, mClientHeight, DXGI_FORMAT_R8G8B8A8_UNORM, 0));
    ID3D11Texture2D* backBuffer;
    HR(mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBuffer)));
    HR(md3dDevice->CreateRenderTargetView(backBuffer, 0, &mRenderTargetView));
    ReleaseCOM(backBuffer);

    // Create the depth/stencil buffer and view.

    D3D11_TEXTURE2D_DESC depthStencilDesc;

    depthStencilDesc.Width     = mClientWidth;
    depthStencilDesc.Height    = mClientHeight;
    depthStencilDesc.MipLevels = 1;
    depthStencilDesc.ArraySize = 1;
    depthStencilDesc.Format    = DXGI_FORMAT_D24_UNORM_S8_UINT;

    // Use 4X MSAA? --must match swap chain MSAA values.
    if( mEnable4xMsaa )
    {
        depthStencilDesc.SampleDesc.Count   = 4;
        depthStencilDesc.SampleDesc.Quality = m4xMsaaQuality-1;
    }
    // No MSAA
    else
    {
        depthStencilDesc.SampleDesc.Count   = 1;
        depthStencilDesc.SampleDesc.Quality = 0;
    }

    depthStencilDesc.Usage          = D3D11_USAGE_DEFAULT;
    depthStencilDesc.BindFlags      = D3D11_BIND_DEPTH_STENCIL;
    depthStencilDesc.CPUAccessFlags = 0;
    depthStencilDesc.MiscFlags      = 0;

    HR(md3dDevice->CreateTexture2D(&depthStencilDesc, 0, &mDepthStencilBuffer));
    HR(md3dDevice->CreateDepthStencilView(mDepthStencilBuffer, 0, &mDepthStencilView));


    // Bind the render target view and depth/stencil view to the pipeline.

    md3dImmediateContext->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilView);


    // Set the viewport transform.

    mScreenViewport.TopLeftX = 0;
    mScreenViewport.TopLeftY = 0;
    mScreenViewport.Width    = static_cast<float>(mClientWidth);
    mScreenViewport.Height   = static_cast<float>(mClientHeight);
    mScreenViewport.MinDepth = 0.0f;
    mScreenViewport.MaxDepth = 1.0f;

    md3dImmediateContext->RSSetViewports(1, &mScreenViewport);
}

1 个答案:

答案 0 :(得分:1)

这里的C ++异常是运行时内部的,不会传播出函数。除非HRESULT出现错误,否则请忽略它们。