DirectX 11 Switching from fullscreen -> windowed problem

5k views Asked by At

I've been trawling various sites looking for the correct way to manage switching.

I thought I had cracked it but I've noticed a bizarre issue now that I am setting vertex and pixel shaders for a draw call.

I can swap to full screen using alt-enter and everything is fine, swapping back with either leave a blank window or render correctly but never continue to render any updates.

I.e it'll basically render one frame and any input is registered but not visible on screen till you swap to full screen.

Its clear I'm probably missing something with the swapchain or devicecontext as I noticed using Flush() it would force it to work however I realize that clearly isn't the solution.

Render function snippet

    cube_.setToContext(context);
    context->VSSetConstantBuffers( 0, 1, &cb_NeverChanges_ );
    context->VSSetConstantBuffers( 1, 1, &cb_ResizeChanges_ );
    context->VSSetConstantBuffers( 2, 1, &cb_FrameChanges_ );

    context->PSSetConstantBuffers( 0, 1, &cb_NeverChanges_ );
    context->PSSetConstantBuffers( 1, 1, &cb_ResizeChanges_ );
    context->PSSetConstantBuffers( 2, 1, &cb_FrameChanges_ );

    context->VSSetShader( vertexShader_, nullptr, 0 );
    context->PSSetShader( pixelShader_, nullptr, 0 );
    context->Draw(cube_.getVertexTotal(), 0);

    dx_.getSwapChain()->Present(0,0);

Resize function which gets passed height/width from WM_SIZE case

if(FAILED(swapChain_->GetFullscreenState(&fullScreen, nullptr)))
        OutputDebugStringA("Failed to get fullscreen state.\n");

    swapChain_->GetDesc(&swapChainDesc);
    swapChainDesc.Windowed = !fullScreen;
    swapChainDesc.Flags = 0;
    if(fullScreen)
        swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
    //Release renderTarget, depth stencil, depth stencil view, etc

    depthStencilView_->Release();
    depthStencil_->Release();
    renderTarget_->Release();

    if(FAILED(swapChain_->ResizeBuffers(swapChainDesc.BufferCount,width,height, swapChainDesc.BufferDesc.Format ,swapChainDesc.Flags)))
    {
        MessageBox( NULL, "Failed to resize buffers.", "Error", MB_OK );
        return false;
    }

    //recreate everything that was released
    if(!createRenderTarget())   
        return false;
    if(!createDepthStencils(width,height))
        return false;


    context_->OMSetRenderTargets( 1, &renderTarget_, depthStencilView_);
    D3D11_VIEWPORT vp;  //Should be a member of dx!
    vp.Width = (float)width;
    vp.Height = (float)height;
    vp.MinDepth = 0.0f;
    vp.MaxDepth = 1.0f;
    vp.TopLeftX = 0;
    vp.TopLeftY = 0;
    context_->RSSetViewports( 1, &vp );

Swap Chain setup with this

    DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory( &swapChainDesc, sizeof( swapChainDesc ) );
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferDesc.Width = width;
swapChainDesc.BufferDesc.Height = height; 
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; //auto =0, originally 60
swapChainDesc.BufferDesc.RefreshRate.Denominator = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow = hWnd;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.Windowed = TRUE;

I've been testing this with D3D11_CREATE_DEVICE_DEBUG and no errors/warnings/leaks, any comments or input welcome.

2

There are 2 answers

0
wookey On BEST ANSWER

The latest nvidia drivers have resolved this issue (drivers 275.33) for the gtx460 and gtx570 tested on.

There obviously is a software explanation and answer to this problem but its working now and that is what I wanted.

Anyone reading this in the future and stumble upon the other fix please let me know.

0
Menno On

After porting from D3D10 to 11 my I ran into the same issues with my app. Everything blank when switching from fullscreen to windowed mode. Installing the latest GeForce drives resolved the issue (without any code changes).