mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 22:29:39 -06:00
Merge pull request #506 from Armada651/d3dfullscreen
D3D: Add exclusive fullscreen support.
This commit is contained in:
@ -264,20 +264,28 @@ HRESULT Create(HWND wnd)
|
||||
swap_chain_desc.OutputWindow = wnd;
|
||||
swap_chain_desc.SampleDesc.Count = 1;
|
||||
swap_chain_desc.SampleDesc.Quality = 0;
|
||||
swap_chain_desc.Windowed = TRUE;
|
||||
swap_chain_desc.Windowed = !g_ActiveConfig.bFullscreen;
|
||||
|
||||
DXGI_OUTPUT_DESC out_desc;
|
||||
memset(&out_desc, 0, sizeof(out_desc));
|
||||
output->GetDesc(&out_desc);
|
||||
|
||||
DXGI_MODE_DESC mode_desc;
|
||||
memset(&mode_desc, 0, sizeof(mode_desc));
|
||||
mode_desc.Width = xres;
|
||||
mode_desc.Height = yres;
|
||||
mode_desc.Width = out_desc.DesktopCoordinates.right - out_desc.DesktopCoordinates.left;
|
||||
mode_desc.Height = out_desc.DesktopCoordinates.bottom - out_desc.DesktopCoordinates.top;
|
||||
mode_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
mode_desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
||||
hr = output->FindClosestMatchingMode(&mode_desc, &swap_chain_desc.BufferDesc, nullptr);
|
||||
if (FAILED(hr)) MessageBox(wnd, _T("Failed to find a supported video mode"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
|
||||
|
||||
// forcing buffer resolution to xres and yres.. TODO: The new video mode might not actually be supported!
|
||||
swap_chain_desc.BufferDesc.Width = xres;
|
||||
swap_chain_desc.BufferDesc.Height = yres;
|
||||
if (swap_chain_desc.Windowed)
|
||||
{
|
||||
// forcing buffer resolution to xres and yres..
|
||||
// this is not a problem as long as we're in windowed mode
|
||||
swap_chain_desc.BufferDesc.Width = xres;
|
||||
swap_chain_desc.BufferDesc.Height = yres;
|
||||
}
|
||||
|
||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||
// Creating debug devices can sometimes fail if the user doesn't have the correct
|
||||
@ -308,6 +316,13 @@ HRESULT Create(HWND wnd)
|
||||
SAFE_RELEASE(swapchain);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// prevent DXGI from responding to Alt+Enter, unfortunately DXGI_MWA_NO_ALT_ENTER
|
||||
// does not work so we disable all monitoring of window messages. However this
|
||||
// may make it more difficult for DXGI to handle display mode changes.
|
||||
hr = factory->MakeWindowAssociation(wnd, DXGI_MWA_NO_WINDOW_CHANGES);
|
||||
if (FAILED(hr)) MessageBox(wnd, _T("Failed to associate the window"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
|
||||
|
||||
SetDebugObjectName((ID3D11DeviceChild*)context, "device context");
|
||||
SAFE_RELEASE(factory);
|
||||
SAFE_RELEASE(output);
|
||||
@ -342,6 +357,9 @@ HRESULT Create(HWND wnd)
|
||||
|
||||
void Close()
|
||||
{
|
||||
// we can't release the swapchain while in fullscreen.
|
||||
swapchain->SetFullscreenState(false, nullptr);
|
||||
|
||||
// release all bound resources
|
||||
context->ClearState();
|
||||
SAFE_RELEASE(backbuf);
|
||||
@ -474,6 +492,24 @@ void Present()
|
||||
swapchain->Present((UINT)g_ActiveConfig.IsVSync(), 0);
|
||||
}
|
||||
|
||||
HRESULT SetFullscreenState(bool enable_fullscreen)
|
||||
{
|
||||
return swapchain->SetFullscreenState(enable_fullscreen, nullptr);
|
||||
}
|
||||
|
||||
HRESULT GetFullscreenState(bool* fullscreen_state)
|
||||
{
|
||||
if (fullscreen_state == nullptr)
|
||||
{
|
||||
return E_POINTER;
|
||||
}
|
||||
|
||||
BOOL state;
|
||||
HRESULT hr = swapchain->GetFullscreenState(&state, nullptr);
|
||||
*fullscreen_state = !!state;
|
||||
return hr;
|
||||
}
|
||||
|
||||
} // namespace D3D
|
||||
|
||||
} // namespace DX11
|
||||
|
@ -58,6 +58,9 @@ bool BGRATexturesSupported();
|
||||
|
||||
unsigned int GetMaxTextureSize();
|
||||
|
||||
HRESULT SetFullscreenState(bool enable_fullscreen);
|
||||
HRESULT GetFullscreenState(bool* fullscreen_state);
|
||||
|
||||
// Ihis function will assign a name to the given resource.
|
||||
// The DirectX debug layer will make it easier to identify resources that way,
|
||||
// e.g. when listing up all resources who have unreleased references.
|
||||
|
@ -42,6 +42,8 @@ static u32 s_LastAA = 0;
|
||||
|
||||
static Television s_television;
|
||||
|
||||
static bool s_last_fullscreen_mode = false;
|
||||
|
||||
ID3D11Buffer* access_efb_cbuf = nullptr;
|
||||
ID3D11BlendState* clearblendstates[4] = {nullptr};
|
||||
ID3D11DepthStencilState* cleardepthstates[3] = {nullptr};
|
||||
@ -936,6 +938,22 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl
|
||||
SetWindowSize(fbWidth, fbHeight);
|
||||
|
||||
const bool windowResized = CheckForResize();
|
||||
const bool fullscreen = g_ActiveConfig.ExclusiveFullscreenEnabled() &&
|
||||
!SConfig::GetInstance().m_LocalCoreStartupParameter.bRenderToMain;
|
||||
|
||||
bool fullscreen_changed = s_last_fullscreen_mode != fullscreen;
|
||||
|
||||
bool fullscreen_state;
|
||||
if (SUCCEEDED(D3D::GetFullscreenState(&fullscreen_state)))
|
||||
{
|
||||
if (fullscreen_state != fullscreen && Host_RendererHasFocus())
|
||||
{
|
||||
// The current fullscreen state does not match the configuration,
|
||||
// this may happen when the renderer frame loses focus. When the
|
||||
// render frame is in focus again we can re-apply the configuration.
|
||||
fullscreen_changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool xfbchanged = false;
|
||||
|
||||
@ -951,17 +969,31 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl
|
||||
// Flip/present backbuffer to frontbuffer here
|
||||
D3D::Present();
|
||||
|
||||
// resize the back buffers NOW to avoid flickering
|
||||
// Resize the back buffers NOW to avoid flickering
|
||||
if (xfbchanged ||
|
||||
windowResized ||
|
||||
fullscreen_changed ||
|
||||
s_LastEFBScale != g_ActiveConfig.iEFBScale ||
|
||||
s_LastAA != g_ActiveConfig.iMultisampleMode)
|
||||
{
|
||||
s_LastAA = g_ActiveConfig.iMultisampleMode;
|
||||
PixelShaderCache::InvalidateMSAAShaders();
|
||||
|
||||
if (windowResized)
|
||||
if (windowResized || fullscreen_changed)
|
||||
{
|
||||
// Apply fullscreen state
|
||||
if (fullscreen_changed)
|
||||
{
|
||||
s_last_fullscreen_mode = fullscreen;
|
||||
D3D::SetFullscreenState(fullscreen);
|
||||
|
||||
// Notify the host that it is safe to exit fullscreen
|
||||
if (!fullscreen)
|
||||
{
|
||||
Host_RequestFullscreen(false);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Aren't we still holding a reference to the back buffer right now?
|
||||
D3D::Reset();
|
||||
SAFE_RELEASE(s_screenshot_texture);
|
||||
|
@ -84,7 +84,7 @@ void InitBackendInfo()
|
||||
g_Config.backend_info.APIType = API_D3D;
|
||||
g_Config.backend_info.bUseRGBATextures = true; // the GX formats barely match any D3D11 formats
|
||||
g_Config.backend_info.bUseMinimalMipCount = true;
|
||||
g_Config.backend_info.bSupports3DVision = false;
|
||||
g_Config.backend_info.bSupportsExclusiveFullscreen = true;
|
||||
g_Config.backend_info.bSupportsDualSourceBlend = true;
|
||||
g_Config.backend_info.bSupportsPrimitiveRestart = true;
|
||||
g_Config.backend_info.bSupportsOversizedViewports = false;
|
||||
|
Reference in New Issue
Block a user