diff --git a/Source/Core/VideoBackends/D3D/D3DBase.cpp b/Source/Core/VideoBackends/D3D/D3DBase.cpp index 730a722e5d..60475988ce 100644 --- a/Source/Core/VideoBackends/D3D/D3DBase.cpp +++ b/Source/Core/VideoBackends/D3D/D3DBase.cpp @@ -52,8 +52,6 @@ unsigned int xres, yres; bool bFrameInProgress = false; -#define NUM_SWAPCHAIN_BUFFERS 2 - HRESULT LoadDXGI() { if (dxgi_dll_ref++ > 0) @@ -294,13 +292,13 @@ HRESULT Create(HWND wnd) } DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {}; - swap_chain_desc.BufferCount = NUM_SWAPCHAIN_BUFFERS; + swap_chain_desc.BufferCount = 2; swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swap_chain_desc.SampleDesc.Count = 1; swap_chain_desc.SampleDesc.Quality = 0; swap_chain_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swap_chain_desc.Scaling = DXGI_SCALING_STRETCH; - swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; swap_chain_desc.Width = xres; swap_chain_desc.Height = yres; @@ -351,11 +349,20 @@ HRESULT Create(HWND wnd) { hr = factory->CreateSwapChainForHwnd(device, hWnd, &swap_chain_desc, nullptr, nullptr, &swapchain); + if (FAILED(hr)) + { + // Flip-model discard swapchains aren't supported on Windows 8, so here we fall back to + // a sequential swapchain + swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + hr = factory->CreateSwapChainForHwnd(device, hWnd, &swap_chain_desc, nullptr, nullptr, + &swapchain); + } + if (FAILED(hr)) { // Flip-model swapchains aren't supported on Windows 7, so here we fall back to a legacy // BitBlt-model swapchain - swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; + swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; hr = factory->CreateSwapChainForHwnd(device, hWnd, &swap_chain_desc, nullptr, nullptr, &swapchain); } @@ -385,6 +392,12 @@ HRESULT Create(HWND wnd) SAFE_RELEASE(factory); SAFE_RELEASE(adapter); + if (SConfig::GetInstance().bFullscreen && !g_ActiveConfig.bBorderlessFullscreen) + { + swapchain->SetFullscreenState(true, nullptr); + swapchain->ResizeBuffers(0, xres, yres, DXGI_FORMAT_R8G8B8A8_UNORM, 0); + } + ID3D11Texture2D* buf; hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf); if (FAILED(hr)) @@ -542,7 +555,7 @@ void Reset() GetClientRect(hWnd, &client); xres = client.right - client.left; yres = client.bottom - client.top; - D3D::swapchain->ResizeBuffers(NUM_SWAPCHAIN_BUFFERS, xres, yres, DXGI_FORMAT_R8G8B8A8_UNORM, 0); + D3D::swapchain->ResizeBuffers(0, xres, yres, DXGI_FORMAT_R8G8B8A8_UNORM, 0); // recreate back buffer texture ID3D11Texture2D* buf; diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 027c3611c0..df4aad0e28 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -66,6 +66,7 @@ struct GXPipelineState static u32 s_last_multisamples = 1; static bool s_last_stereo_mode = false; static bool s_last_xfb_mode = false; +static bool s_last_fullscreen_mode = false; static Television s_television; @@ -240,6 +241,7 @@ Renderer::Renderer() : ::Renderer(D3D::GetBackBufferWidth(), D3D::GetBackBufferH s_last_multisamples = g_ActiveConfig.iMultisamples; s_last_stereo_mode = g_ActiveConfig.iStereoMode > 0; s_last_xfb_mode = g_ActiveConfig.bUseRealXFB; + s_last_fullscreen_mode = D3D::GetFullscreenState(); g_framebuffer_manager = std::make_unique(m_target_width, m_target_height); SetupDeviceObjects(); @@ -838,7 +840,9 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, SetWindowSize(fbStride, fbHeight); - const bool windowResized = CheckForResize(); + const bool window_resized = CheckForResize(); + const bool fullscreen = D3D::GetFullscreenState(); + const bool fs_changed = s_last_fullscreen_mode != fullscreen; bool xfbchanged = s_last_xfb_mode != g_ActiveConfig.bUseRealXFB; @@ -856,15 +860,16 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, D3D::Present(); // Resize the back buffers NOW to avoid flickering - if (CalculateTargetSize() || xfbchanged || windowResized || + if (CalculateTargetSize() || xfbchanged || window_resized || fs_changed || s_last_multisamples != g_ActiveConfig.iMultisamples || s_last_stereo_mode != (g_ActiveConfig.iStereoMode > 0)) { s_last_xfb_mode = g_ActiveConfig.bUseRealXFB; s_last_multisamples = g_ActiveConfig.iMultisamples; + s_last_fullscreen_mode = fullscreen; PixelShaderCache::InvalidateMSAAShaders(); - if (windowResized) + if (window_resized || fs_changed) { // TODO: Aren't we still holding a reference to the back buffer right now? D3D::Reset();