mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-19 05:52:11 +01:00
[wsi] Refactor platform system to support multiple WSI implementations
This commit is contained in:
parent
10b83d184b
commit
d5d236a1e2
15
meson.build
15
meson.build
@ -115,7 +115,6 @@ if platform == 'windows'
|
||||
)
|
||||
endif
|
||||
|
||||
dxvk_wsi = 'win32'
|
||||
dxvk_name_prefix = ''
|
||||
compiler_args += ['-DDXVK_WSI_WIN32']
|
||||
else
|
||||
@ -128,15 +127,17 @@ else
|
||||
'./include/native/directx'
|
||||
]
|
||||
|
||||
dxvk_wsi = get_option('dxvk_native_wsi')
|
||||
|
||||
if dxvk_wsi == 'sdl2'
|
||||
lib_sdl2 = cpp.find_library('SDL2')
|
||||
lib_sdl2 = cpp.find_library('SDL2', required: false)
|
||||
lib_glfw = cpp.find_library('glfw', required: false)
|
||||
if lib_sdl2.found()
|
||||
compiler_args += ['-DDXVK_WSI_SDL2']
|
||||
elif dxvk_wsi == 'glfw'
|
||||
lib_glfw = cpp.find_library('glfw')
|
||||
endif
|
||||
if lib_glfw.found()
|
||||
compiler_args += ['-DDXVK_WSI_GLFW']
|
||||
endif
|
||||
if (not lib_sdl2.found() and not lib_glfw.found())
|
||||
error('SDL2 or GLFW are required to build dxvk-native')
|
||||
endif
|
||||
|
||||
dxvk_name_prefix = 'libdxvk_'
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
#if defined(DXVK_WSI_GLFW)
|
||||
|
||||
#include "../wsi_monitor.h"
|
||||
|
||||
#include "wsi/native_wsi.h"
|
||||
@ -165,3 +167,5 @@ namespace dxvk::wsi {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,3 +1,5 @@
|
||||
#if defined(DXVK_WSI_GLFW)
|
||||
|
||||
#include "wsi_platform_glfw.h"
|
||||
#include "../../util/util_error.h"
|
||||
#include "../../util/util_string.h"
|
||||
@ -50,8 +52,20 @@ namespace dxvk::wsi {
|
||||
return names;
|
||||
}
|
||||
|
||||
WsiDriver* platformCreateWsiDriver() {
|
||||
return new GlfwWsiDriver();
|
||||
static bool createGlfwWsiDriver(WsiDriver **driver) {
|
||||
try {
|
||||
*driver = new GlfwWsiDriver();
|
||||
} catch (const DxvkError& e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
WsiBootstrap GlfwWSI = {
|
||||
"GLFW",
|
||||
createGlfwWsiDriver
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,8 @@
|
||||
#if defined(DXVK_WSI_GLFW)
|
||||
|
||||
#include "../wsi_window.h"
|
||||
|
||||
#include "native/wsi/native_wsi.h"
|
||||
#include "native/wsi/native_glfw.h"
|
||||
#include "wsi_platform_glfw.h"
|
||||
|
||||
#include "../../util/util_string.h"
|
||||
@ -142,3 +144,5 @@ namespace dxvk::wsi {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,35 +1,17 @@
|
||||
wsi_common_src = [
|
||||
wsi_src = [
|
||||
'wsi_edid.cpp',
|
||||
'wsi_platform.cpp',
|
||||
]
|
||||
|
||||
wsi_win32_src = [
|
||||
'win32/wsi_monitor_win32.cpp',
|
||||
'win32/wsi_platform_win32.cpp',
|
||||
'win32/wsi_window_win32.cpp',
|
||||
]
|
||||
|
||||
wsi_sdl2_src = [
|
||||
'sdl2/wsi_monitor_sdl2.cpp',
|
||||
'sdl2/wsi_platform_sdl2.cpp',
|
||||
'sdl2/wsi_window_sdl2.cpp',
|
||||
]
|
||||
|
||||
wsi_glfw_src = [
|
||||
'glfw/wsi_monitor_glfw.cpp',
|
||||
'glfw/wsi_platform_glfw.cpp',
|
||||
'glfw/wsi_window_glfw.cpp',
|
||||
]
|
||||
|
||||
if dxvk_wsi == 'win32'
|
||||
wsi_src = wsi_common_src + wsi_win32_src
|
||||
elif dxvk_wsi == 'sdl2'
|
||||
wsi_src = wsi_common_src + wsi_sdl2_src
|
||||
elif dxvk_wsi == 'glfw'
|
||||
wsi_src = wsi_common_src + wsi_glfw_src
|
||||
else
|
||||
error('Unknown wsi')
|
||||
endif
|
||||
wsi_deps = [ dep_displayinfo ]
|
||||
|
||||
wsi_lib = static_library('wsi', wsi_src,
|
||||
|
@ -1,3 +1,5 @@
|
||||
#if defined(DXVK_WSI_SDL2)
|
||||
|
||||
#include "../wsi_monitor.h"
|
||||
|
||||
#include "wsi/native_wsi.h"
|
||||
@ -154,3 +156,5 @@ namespace dxvk::wsi {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,3 +1,5 @@
|
||||
#if defined(DXVK_WSI_SDL2)
|
||||
|
||||
#include "wsi_platform_sdl2.h"
|
||||
#include "../../util/util_error.h"
|
||||
#include "../../util/util_string.h"
|
||||
@ -48,8 +50,20 @@ namespace dxvk::wsi {
|
||||
return extensionNames;
|
||||
}
|
||||
|
||||
WsiDriver* platformCreateWsiDriver() {
|
||||
return new Sdl2WsiDriver();
|
||||
static bool createSdl2WsiDriver(WsiDriver **driver) {
|
||||
try {
|
||||
*driver = new Sdl2WsiDriver();
|
||||
} catch (const DxvkError& e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
WsiBootstrap Sdl2WSI = {
|
||||
"SDL2",
|
||||
createSdl2WsiDriver
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,8 @@
|
||||
#if defined(DXVK_WSI_SDL2)
|
||||
|
||||
#include "../wsi_window.h"
|
||||
|
||||
#include "native/wsi/native_wsi.h"
|
||||
#include "native/wsi/native_sdl2.h"
|
||||
#include "wsi_platform_sdl2.h"
|
||||
|
||||
#include "../../util/util_string.h"
|
||||
@ -155,3 +157,5 @@ namespace dxvk::wsi {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,3 +1,5 @@
|
||||
#if defined(DXVK_WSI_WIN32)
|
||||
|
||||
#include "wsi_platform_win32.h"
|
||||
|
||||
#include "../../util/util_string.h"
|
||||
@ -370,3 +372,5 @@ namespace dxvk::wsi {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,3 +1,5 @@
|
||||
#if defined(DXVK_WSI_WIN32)
|
||||
|
||||
#include "wsi_platform_win32.h"
|
||||
|
||||
namespace dxvk::wsi {
|
||||
@ -6,8 +8,16 @@ namespace dxvk::wsi {
|
||||
return { VK_KHR_WIN32_SURFACE_EXTENSION_NAME };
|
||||
}
|
||||
|
||||
WsiDriver* platformCreateWsiDriver() {
|
||||
return new Win32WsiDriver();
|
||||
static bool createWin32WsiDriver(WsiDriver **driver) {
|
||||
*driver = new Win32WsiDriver();
|
||||
return true;
|
||||
}
|
||||
|
||||
WsiBootstrap Win32WSI = {
|
||||
"Win32",
|
||||
createWin32WsiDriver
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,3 +1,5 @@
|
||||
#if defined(DXVK_WSI_WIN32)
|
||||
|
||||
#include "wsi_platform_win32.h"
|
||||
|
||||
#include "../../util/util_string.h"
|
||||
@ -169,14 +171,14 @@ namespace dxvk::wsi {
|
||||
[[maybe_unused]]
|
||||
bool modeSwitch) {
|
||||
// Find a display mode that matches what we need
|
||||
::GetWindowRect(hWindow, &pState->rect);
|
||||
::GetWindowRect(hWindow, &pState->win.rect);
|
||||
|
||||
// Change the window flags to remove the decoration etc.
|
||||
LONG style = ::GetWindowLongW(hWindow, GWL_STYLE);
|
||||
LONG exstyle = ::GetWindowLongW(hWindow, GWL_EXSTYLE);
|
||||
|
||||
pState->style = style;
|
||||
pState->exstyle = exstyle;
|
||||
pState->win.style = style;
|
||||
pState->win.exstyle = exstyle;
|
||||
|
||||
style &= ~WS_OVERLAPPEDWINDOW;
|
||||
exstyle &= ~WS_EX_OVERLAPPEDWINDOW;
|
||||
@ -204,20 +206,20 @@ namespace dxvk::wsi {
|
||||
LONG curStyle = ::GetWindowLongW(hWindow, GWL_STYLE) & ~WS_VISIBLE;
|
||||
LONG curExstyle = ::GetWindowLongW(hWindow, GWL_EXSTYLE) & ~WS_EX_TOPMOST;
|
||||
|
||||
if (curStyle == (pState->style & ~(WS_VISIBLE | WS_OVERLAPPEDWINDOW))
|
||||
&& curExstyle == (pState->exstyle & ~(WS_EX_TOPMOST | WS_EX_OVERLAPPEDWINDOW))) {
|
||||
::SetWindowLongW(hWindow, GWL_STYLE, pState->style);
|
||||
::SetWindowLongW(hWindow, GWL_EXSTYLE, pState->exstyle);
|
||||
if (curStyle == (pState->win.style & ~(WS_VISIBLE | WS_OVERLAPPEDWINDOW))
|
||||
&& curExstyle == (pState->win.exstyle & ~(WS_EX_TOPMOST | WS_EX_OVERLAPPEDWINDOW))) {
|
||||
::SetWindowLongW(hWindow, GWL_STYLE, pState->win.style);
|
||||
::SetWindowLongW(hWindow, GWL_EXSTYLE, pState->win.exstyle);
|
||||
}
|
||||
|
||||
// Restore window position and apply the style
|
||||
UINT flags = SWP_FRAMECHANGED | SWP_NOACTIVATE;
|
||||
const RECT rect = pState->rect;
|
||||
const RECT rect = pState->win.rect;
|
||||
|
||||
if (!restoreCoordinates)
|
||||
flags |= SWP_NOSIZE | SWP_NOMOVE;
|
||||
|
||||
::SetWindowPos(hWindow, (pState->exstyle & WS_EX_TOPMOST) ? HWND_TOPMOST : HWND_NOTOPMOST,
|
||||
::SetWindowPos(hWindow, (pState->win.exstyle & WS_EX_TOPMOST) ? HWND_TOPMOST : HWND_NOTOPMOST,
|
||||
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, flags);
|
||||
|
||||
return true;
|
||||
@ -295,3 +297,5 @@ namespace dxvk::wsi {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,18 +1,49 @@
|
||||
#include "wsi_platform.h"
|
||||
#include "wsi_monitor.h"
|
||||
#include "wsi_window.h"
|
||||
#include "../util/util_env.h"
|
||||
#include "../util/util_error.h"
|
||||
|
||||
namespace dxvk::wsi {
|
||||
static WsiDriver* s_driver = nullptr;
|
||||
static int s_refcount = 0;
|
||||
|
||||
static const WsiBootstrap *wsiBootstrap[] = {
|
||||
#if defined(DXVK_WSI_WIN32)
|
||||
&Win32WSI,
|
||||
#endif
|
||||
#if defined(DXVK_WSI_SDL2)
|
||||
&Sdl2WSI,
|
||||
#endif
|
||||
#if defined(DXVK_WSI_GLFW)
|
||||
&GlfwWSI,
|
||||
#endif
|
||||
};
|
||||
|
||||
void init() {
|
||||
if (s_refcount++ > 0)
|
||||
return;
|
||||
|
||||
s_driver = platformCreateWsiDriver();
|
||||
if (s_driver == nullptr)
|
||||
std::string hint = dxvk::env::getEnvVar("DXVK_WSIDRIVER");
|
||||
if (hint == "") {
|
||||
// At least for Windows, it is reasonable to fall back to a default;
|
||||
// for other platforms however we _need_ to know which WSI to use!
|
||||
#if defined(DXVK_WSI_WIN32)
|
||||
hint = "Win32";
|
||||
#else
|
||||
throw DxvkError("DXVK_WSIDRIVER environment variable unset");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
for (const WsiBootstrap *b : wsiBootstrap) {
|
||||
if (hint == b->name && b->createDriver(&s_driver)) {
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!success)
|
||||
throw DxvkError("Failed to initialize WSI.");
|
||||
}
|
||||
|
||||
|
@ -92,9 +92,23 @@ namespace dxvk::wsi {
|
||||
VkSurfaceKHR* pSurface) = 0;
|
||||
};
|
||||
|
||||
struct WsiBootstrap {
|
||||
const std::string name;
|
||||
bool (*createDriver)(WsiDriver **driver);
|
||||
};
|
||||
|
||||
#if defined(DXVK_WSI_WIN32)
|
||||
extern WsiBootstrap Win32WSI;
|
||||
#endif
|
||||
#if defined(DXVK_WSI_SDL2)
|
||||
extern WsiBootstrap Sdl2WSI;
|
||||
#endif
|
||||
#if defined(DXVK_WSI_GLFW)
|
||||
extern WsiBootstrap GlfwWSI;
|
||||
#endif
|
||||
|
||||
void init();
|
||||
void quit();
|
||||
std::vector<const char *> getInstanceExtensions();
|
||||
WsiDriver* platformCreateWsiDriver();
|
||||
|
||||
}
|
||||
|
@ -12,10 +12,18 @@ namespace dxvk::wsi {
|
||||
* \brief Impl-dependent state
|
||||
*/
|
||||
struct DxvkWindowState {
|
||||
#ifdef DXVK_WSI_WIN32
|
||||
LONG style = 0;
|
||||
LONG exstyle = 0;
|
||||
RECT rect = { 0, 0, 0, 0 };
|
||||
#if defined(DXVK_WSI_WIN32)
|
||||
struct {
|
||||
LONG style = 0;
|
||||
LONG exstyle = 0;
|
||||
RECT rect = { 0, 0, 0, 0 };
|
||||
} win;
|
||||
#endif
|
||||
#if defined(DXVK_WSI_SDL2)
|
||||
// Nothing to store
|
||||
#endif
|
||||
#if defined(DXVK_WSI_GLFW)
|
||||
// Nothing to store
|
||||
#endif
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user