DirectX 11 Переключение из полноэкранного режима -> проблема с оконным режимом

Я просматривал различные сайты в поисках правильного способа управления переключением.

Я думал, что взломал его, но теперь я заметил странную проблему, когда устанавливаю вершинные и пиксельные шейдеры для вызова отрисовки.

Я могу переключиться в полноэкранный режим с помощью alt-enter, и все в порядке, вернуться обратно, либо оставить пустое окно, либо отобразить правильно, но никогда не продолжать отображать какие-либо обновления.

То есть он в основном отображает один кадр, и любой ввод регистрируется, но не отображается на экране, пока вы не переключитесь на полноэкранный режим.

Ясно, что я, вероятно, что-то упустил с swapchain или devicecontext, поскольку я заметил, что использование Flush() заставит его работать, однако я понимаю, что это явно не решение.

Фрагмент функции рендеринга

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

Функция изменения размера, которая получает переданную высоту/ширину из случая WM_SIZE

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

Настройка цепочки обмена с этим

    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;

Я тестировал это с помощью D3D11_CREATE_DEVICE_DEBUG, никаких ошибок/предупреждений/утечек, любые комментарии или ввод приветствуются.


person wookey    schedule 17.02.2011    source источник
comment
Из любопытства я добавил флаг D3D10_CREATE_DEVICE_SINGLETHREADED, а также флаг отладки, и это, похоже, решило проблему. Я предполагаю, что мне нужно проверить, чтобы убедиться, что другой поток не активен при обмене?   -  person wookey    schedule 18.02.2011
comment
Хорошо, я думаю, что это только ошибка nvidia, друзья тестировали разные карты ati, и проблема никогда не возникала. Это было проверено на двух nvidia gtx 460, и возникла та же проблема. Я подозреваю, что другие карты nvidia ведут себя так же. Если у вас есть один из последних SDK DirectX, вы можете проверить эту странную проблему на себе, используя пример из руководства 7. Нажмите Alt-Enter, нажмите Alt-Enter, чтобы переключиться обратно в оконный режим, и окно станет либо пустым, либо статичным — без обновления. В примере будет предупреждение о том, что resizeBuffers не используются, но мой код использует их. (тот же эффект)   -  person wookey    schedule 03.03.2011
comment
Хорошо, протестировано на nvidia 570 gtx, и проблема также появляется, поэтому я думаю, что это, скорее всего, проблема только nvidia.   -  person wookey    schedule 24.03.2011


Ответы (2)


Последние драйверы nvidia решили эту проблему (драйверы 275.33) для протестированных gtx460 и gtx570.

Очевидно, что есть объяснение программного обеспечения и ответ на эту проблему, но теперь он работает, и это то, что я хотел.

Любой, кто читает это в будущем и наткнется на другое исправление, пожалуйста, дайте мне знать.

person wookey    schedule 13.06.2011

После переноса с D3D10 на 11 я столкнулся с теми же проблемами с моим приложением. При переключении из полноэкранного режима в оконный все пусто. Установка последних дисков GeForce решила проблему (без каких-либо изменений кода).

person Menno    schedule 20.12.2011