mirror of
https://github.com/PCSX2/pcsx2.git
synced 2026-01-31 01:15:24 +01:00
GS/DX: Fix exclusive fullscreen potentially using wrong resolution
This commit is contained in:
committed by
lightningterror
parent
44ba9e283e
commit
82e5f80f11
@@ -123,17 +123,18 @@ std::vector<GSAdapterInfo> D3D::GetAdapterInfo(IDXGIFactory5* factory)
|
||||
return adapters;
|
||||
}
|
||||
|
||||
bool D3D::GetRequestedExclusiveFullscreenModeDesc(IDXGIFactory5* factory, const RECT& window_rect, u32 width,
|
||||
bool D3D::GetRequestedExclusiveFullscreenModeDesc(IDXGIFactory5* factory, HWND window_hwnd, u32 width,
|
||||
u32 height, float refresh_rate, DXGI_FORMAT format, DXGI_MODE_DESC* fullscreen_mode, IDXGIOutput** output)
|
||||
{
|
||||
// We need to find which monitor the window is located on.
|
||||
const GSVector4i client_rc_vec = GSVector4i::load<false>(&window_rect);
|
||||
// DXGI seems to use the nearest monitor if the window is out of bounds.
|
||||
const auto* monitor = MonitorFromWindow(window_hwnd, MONITOR_DEFAULTTONEAREST);
|
||||
|
||||
// The window might be on a different adapter to which we are rendering.. so we have to enumerate them all.
|
||||
// The monitor might be on a different adapter to which we are rendering.. so we have to enumerate them all.
|
||||
HRESULT hr;
|
||||
wil::com_ptr_nothrow<IDXGIOutput> first_output, intersecting_output;
|
||||
wil::com_ptr_nothrow<IDXGIOutput> first_output, monitor_output;
|
||||
|
||||
for (u32 adapter_index = 0; !intersecting_output; adapter_index++)
|
||||
for (u32 adapter_index = 0; !monitor_output; adapter_index++)
|
||||
{
|
||||
wil::com_ptr_nothrow<IDXGIAdapter1> adapter;
|
||||
hr = factory->EnumAdapters1(adapter_index, adapter.put());
|
||||
@@ -152,10 +153,9 @@ bool D3D::GetRequestedExclusiveFullscreenModeDesc(IDXGIFactory5* factory, const
|
||||
else if (FAILED(hr) || FAILED(this_output->GetDesc(&output_desc)))
|
||||
continue;
|
||||
|
||||
const GSVector4i output_rc = GSVector4i::load<false>(&output_desc.DesktopCoordinates);
|
||||
if (!client_rc_vec.rintersect(output_rc).rempty())
|
||||
if (output_desc.Monitor == monitor)
|
||||
{
|
||||
intersecting_output = std::move(this_output);
|
||||
monitor_output = std::move(this_output);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ bool D3D::GetRequestedExclusiveFullscreenModeDesc(IDXGIFactory5* factory, const
|
||||
}
|
||||
}
|
||||
|
||||
if (!intersecting_output)
|
||||
if (!monitor_output)
|
||||
{
|
||||
if (!first_output)
|
||||
{
|
||||
@@ -174,7 +174,7 @@ bool D3D::GetRequestedExclusiveFullscreenModeDesc(IDXGIFactory5* factory, const
|
||||
}
|
||||
|
||||
Console.Warning("No DXGI output found for window, using first.");
|
||||
intersecting_output = std::move(first_output);
|
||||
monitor_output = std::move(first_output);
|
||||
}
|
||||
|
||||
DXGI_MODE_DESC request_mode = {};
|
||||
@@ -184,15 +184,15 @@ bool D3D::GetRequestedExclusiveFullscreenModeDesc(IDXGIFactory5* factory, const
|
||||
request_mode.RefreshRate.Numerator = static_cast<UINT>(std::floor(refresh_rate * 1000.0f));
|
||||
request_mode.RefreshRate.Denominator = 1000u;
|
||||
|
||||
if (FAILED(hr = intersecting_output->FindClosestMatchingMode(&request_mode, fullscreen_mode, nullptr)) ||
|
||||
if (FAILED(hr = monitor_output->FindClosestMatchingMode(&request_mode, fullscreen_mode, nullptr)) ||
|
||||
request_mode.Format != format)
|
||||
{
|
||||
ERROR_LOG("Failed to find closest matching mode, hr={:08X}", static_cast<unsigned>(hr));
|
||||
return false;
|
||||
}
|
||||
|
||||
*output = intersecting_output.get();
|
||||
intersecting_output->AddRef();
|
||||
*output = monitor_output.get();
|
||||
monitor_output->AddRef();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace D3D
|
||||
std::vector<GSAdapterInfo> GetAdapterInfo(IDXGIFactory5* factory);
|
||||
|
||||
// returns the fullscreen mode to use for the specified dimensions
|
||||
bool GetRequestedExclusiveFullscreenModeDesc(IDXGIFactory5* factory, const RECT& window_rect, u32 width, u32 height,
|
||||
bool GetRequestedExclusiveFullscreenModeDesc(IDXGIFactory5* factory, HWND window_hwnd, u32 width, u32 height,
|
||||
float refresh_rate, DXGI_FORMAT format, DXGI_MODE_DESC* fullscreen_mode, IDXGIOutput** output);
|
||||
|
||||
// get an adapter based on name
|
||||
|
||||
@@ -659,7 +659,7 @@ bool GSDevice11::CreateSwapChain()
|
||||
float fullscreen_refresh_rate;
|
||||
m_is_exclusive_fullscreen =
|
||||
GetRequestedExclusiveFullscreenMode(&fullscreen_width, &fullscreen_height, &fullscreen_refresh_rate) &&
|
||||
D3D::GetRequestedExclusiveFullscreenModeDesc(m_dxgi_factory.get(), client_rc, fullscreen_width,
|
||||
D3D::GetRequestedExclusiveFullscreenModeDesc(m_dxgi_factory.get(), window_hwnd, fullscreen_width,
|
||||
fullscreen_height, fullscreen_refresh_rate, swap_chain_format, &fullscreen_mode,
|
||||
fullscreen_output.put());
|
||||
|
||||
|
||||
@@ -822,7 +822,7 @@ bool GSDevice12::CreateSwapChain()
|
||||
float fullscreen_refresh_rate;
|
||||
m_is_exclusive_fullscreen =
|
||||
GetRequestedExclusiveFullscreenMode(&fullscreen_width, &fullscreen_height, &fullscreen_refresh_rate) &&
|
||||
D3D::GetRequestedExclusiveFullscreenModeDesc(m_dxgi_factory.get(), client_rc, fullscreen_width,
|
||||
D3D::GetRequestedExclusiveFullscreenModeDesc(m_dxgi_factory.get(), window_hwnd, fullscreen_width,
|
||||
fullscreen_height, fullscreen_refresh_rate, swap_chain_format, &fullscreen_mode,
|
||||
fullscreen_output.put());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user