1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-19 05:52:11 +01:00

[d3d9] Make swapchain use new wsi abstraction

This commit is contained in:
Joshua Ashton 2022-08-14 17:36:58 +00:00 committed by Philip Rebohle
parent 654b517057
commit dac7e38f4b
2 changed files with 27 additions and 83 deletions

View File

@ -439,20 +439,14 @@ namespace dxvk {
*pRotation = D3DDISPLAYROTATION_IDENTITY; *pRotation = D3DDISPLAYROTATION_IDENTITY;
if (pMode != nullptr) { if (pMode != nullptr) {
DEVMODEW devMode = DEVMODEW(); wsi::WsiMode devMode = { };
devMode.dmSize = sizeof(devMode);
if (!GetMonitorDisplayMode(GetDefaultMonitor(), ENUM_CURRENT_SETTINGS, &devMode)) { if (!wsi::getCurrentDisplayMode(wsi::getDefaultMonitor(), &devMode)) {
Logger::err("D3D9SwapChainEx::GetDisplayModeEx: Failed to enum display settings"); Logger::err("D3D9SwapChainEx::GetDisplayModeEx: Failed to enum display settings");
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
} }
pMode->Size = sizeof(D3DDISPLAYMODEEX); *pMode = ConvertDisplayMode(devMode);
pMode->Width = devMode.dmPelsWidth;
pMode->Height = devMode.dmPelsHeight;
pMode->RefreshRate = devMode.dmDisplayFrequency;
pMode->Format = D3DFMT_X8R8G8B8;
pMode->ScanLineOrdering = D3DSCANLINEORDERING_PROGRESSIVE;
} }
return D3D_OK; return D3D_OK;
@ -487,15 +481,9 @@ namespace dxvk {
if (!changeFullscreen) { if (!changeFullscreen) {
if (FAILED(ChangeDisplayMode(pPresentParams, pFullscreenDisplayMode))) if (FAILED(ChangeDisplayMode(pPresentParams, pFullscreenDisplayMode)))
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
wsi::updateFullscreenWindow(m_monitor, m_window, true);
} }
// Move the window so that it covers the entire output
RECT rect;
GetMonitorRect(GetDefaultMonitor(), &rect);
::SetWindowPos(m_window, HWND_TOPMOST,
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE);
} }
m_presentParams = *pPresentParams; m_presentParams = *pPresentParams;
@ -634,12 +622,12 @@ namespace dxvk {
} }
if (pPresentParams->Windowed) { if (pPresentParams->Windowed) {
GetWindowClientSize(pPresentParams->hDeviceWindow, wsi::getWindowSize(pPresentParams->hDeviceWindow,
pPresentParams->BackBufferWidth ? nullptr : &pPresentParams->BackBufferWidth, pPresentParams->BackBufferWidth ? nullptr : &pPresentParams->BackBufferWidth,
pPresentParams->BackBufferHeight ? nullptr : &pPresentParams->BackBufferHeight); pPresentParams->BackBufferHeight ? nullptr : &pPresentParams->BackBufferHeight);
} }
else { else {
GetMonitorClientSize(GetDefaultMonitor(), wsi::getMonitorClientSize(wsi::getDefaultMonitor(),
pPresentParams->BackBufferWidth ? nullptr : &pPresentParams->BackBufferWidth, pPresentParams->BackBufferWidth ? nullptr : &pPresentParams->BackBufferWidth,
pPresentParams->BackBufferHeight ? nullptr : &pPresentParams->BackBufferHeight); pPresentParams->BackBufferHeight ? nullptr : &pPresentParams->BackBufferHeight);
} }
@ -1049,28 +1037,13 @@ namespace dxvk {
D3D9WindowMessageFilter filter(m_window); D3D9WindowMessageFilter filter(m_window);
// Change the window flags to remove the decoration etc. m_monitor = wsi::getDefaultMonitor();
LONG style = ::GetWindowLongW(m_window, GWL_STYLE);
LONG exstyle = ::GetWindowLongW(m_window, GWL_EXSTYLE);
m_windowState.style = style; if (!wsi::enterFullscreenMode(m_monitor, m_window, &m_windowState, true)) {
m_windowState.exstyle = exstyle; Logger::err("D3D9: EnterFullscreenMode: Failed to enter fullscreen mode");
return D3DERR_INVALIDCALL;
}
style &= ~WS_OVERLAPPEDWINDOW;
exstyle &= ~WS_EX_OVERLAPPEDWINDOW;
::SetWindowLongW(m_window, GWL_STYLE, style);
::SetWindowLongW(m_window, GWL_EXSTYLE, exstyle);
// Move the window so that it covers the entire output
RECT rect;
GetMonitorRect(GetDefaultMonitor(), &rect);
::SetWindowPos(m_window, HWND_TOPMOST,
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
SWP_FRAMECHANGED | SWP_SHOWWINDOW | SWP_NOACTIVATE);
m_monitor = GetDefaultMonitor();
return D3D_OK; return D3D_OK;
} }
@ -1086,24 +1059,11 @@ namespace dxvk {
ResetWindowProc(m_window); ResetWindowProc(m_window);
// Only restore the window style if the application hasn't if (!wsi::leaveFullscreenMode(m_window, &m_windowState)) {
// changed them. This is in line with what native D3D9 does. Logger::err("D3D9: LeaveFullscreenMode: Failed to exit fullscreen mode");
LONG curStyle = ::GetWindowLongW(m_window, GWL_STYLE) & ~WS_VISIBLE; return D3DERR_NOTAVAILABLE;
LONG curExstyle = ::GetWindowLongW(m_window, GWL_EXSTYLE) & ~WS_EX_TOPMOST;
if (curStyle == (m_windowState.style & ~(WS_VISIBLE | WS_OVERLAPPEDWINDOW))
&& curExstyle == (m_windowState.exstyle & ~(WS_EX_TOPMOST | WS_EX_OVERLAPPEDWINDOW))) {
::SetWindowLongW(m_window, GWL_STYLE, m_windowState.style);
::SetWindowLongW(m_window, GWL_EXSTYLE, m_windowState.exstyle);
} }
// Restore window position and apply the style
const RECT rect = m_windowState.rect;
::SetWindowPos(m_window, 0,
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE);
return D3D_OK; return D3D_OK;
} }
@ -1124,27 +1084,15 @@ namespace dxvk {
mode.Size = sizeof(D3DDISPLAYMODEEX); mode.Size = sizeof(D3DDISPLAYMODEEX);
} }
DEVMODEW devMode = { }; wsi::WsiMode wsiMode = ConvertDisplayMode(mode);
devMode.dmSize = sizeof(devMode);
devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
devMode.dmPelsWidth = mode.Width;
devMode.dmPelsHeight = mode.Height;
devMode.dmBitsPerPel = GetMonitorFormatBpp(EnumerateFormat(mode.Format));
if (mode.RefreshRate != 0) { HMONITOR monitor = wsi::getDefaultMonitor();
devMode.dmFields |= DM_DISPLAYFREQUENCY;
devMode.dmDisplayFrequency = mode.RefreshRate;
}
HMONITOR monitor = GetDefaultMonitor(); if (!wsi::setWindowMode(monitor, m_window, wsiMode))
if (!SetMonitorDisplayMode(monitor, &devMode))
return D3DERR_NOTAVAILABLE; return D3DERR_NOTAVAILABLE;
devMode.dmFields = DM_DISPLAYFREQUENCY; if (wsi::getCurrentDisplayMode(monitor, &wsiMode))
NotifyDisplayRefreshRate(double(wsiMode.refreshRate.numerator) / double(wsiMode.refreshRate.denominator));
if (GetMonitorDisplayMode(monitor, ENUM_CURRENT_SETTINGS, &devMode))
NotifyDisplayRefreshRate(double(devMode.dmDisplayFrequency));
else else
NotifyDisplayRefreshRate(0.0); NotifyDisplayRefreshRate(0.0);
@ -1156,7 +1104,7 @@ namespace dxvk {
if (hMonitor == nullptr) if (hMonitor == nullptr)
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
if (!RestoreMonitorDisplayMode()) if (!wsi::restoreDisplayMode())
return D3DERR_NOTAVAILABLE; return D3DERR_NOTAVAILABLE;
NotifyDisplayRefreshRate(0.0); NotifyDisplayRefreshRate(0.0);
@ -1177,7 +1125,7 @@ namespace dxvk {
if (pDestRect == nullptr) { if (pDestRect == nullptr) {
// TODO: Should we hook WM_SIZE message for this? // TODO: Should we hook WM_SIZE message for this?
UINT width, height; UINT width, height;
GetWindowClientSize(m_window, &width, &height); wsi::getWindowSize(m_window, &width, &height);
dstRect.top = 0; dstRect.top = 0;
dstRect.left = 0; dstRect.left = 0;

View File

@ -10,6 +10,9 @@
#include "../util/sync/sync_signal.h" #include "../util/sync/sync_signal.h"
#include "../wsi/wsi_window.h"
#include "../wsi/wsi_monitor.h"
#include <vector> #include <vector>
namespace dxvk { namespace dxvk {
@ -85,13 +88,6 @@ namespace dxvk {
Gamma = 1, Gamma = 1,
}; };
struct WindowState {
LONG style = 0;
LONG exstyle = 0;
RECT rect = { 0, 0, 0, 0 };
};
D3DPRESENT_PARAMETERS m_presentParams; D3DPRESENT_PARAMETERS m_presentParams;
D3DGAMMARAMP m_ramp; D3DGAMMARAMP m_ramp;
@ -126,7 +122,7 @@ namespace dxvk {
HWND m_window = nullptr; HWND m_window = nullptr;
HMONITOR m_monitor = nullptr; HMONITOR m_monitor = nullptr;
WindowState m_windowState; wsi::DxvkWindowState m_windowState;
double m_displayRefreshRate = 0.0; double m_displayRefreshRate = 0.0;