mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 14: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
|
endif
|
||||||
|
|
||||||
dxvk_wsi = 'win32'
|
|
||||||
dxvk_name_prefix = ''
|
dxvk_name_prefix = ''
|
||||||
compiler_args += ['-DDXVK_WSI_WIN32']
|
compiler_args += ['-DDXVK_WSI_WIN32']
|
||||||
else
|
else
|
||||||
@ -128,15 +127,17 @@ else
|
|||||||
'./include/native/directx'
|
'./include/native/directx'
|
||||||
]
|
]
|
||||||
|
|
||||||
dxvk_wsi = get_option('dxvk_native_wsi')
|
lib_sdl2 = cpp.find_library('SDL2', required: false)
|
||||||
|
lib_glfw = cpp.find_library('glfw', required: false)
|
||||||
if dxvk_wsi == 'sdl2'
|
if lib_sdl2.found()
|
||||||
lib_sdl2 = cpp.find_library('SDL2')
|
|
||||||
compiler_args += ['-DDXVK_WSI_SDL2']
|
compiler_args += ['-DDXVK_WSI_SDL2']
|
||||||
elif dxvk_wsi == 'glfw'
|
endif
|
||||||
lib_glfw = cpp.find_library('glfw')
|
if lib_glfw.found()
|
||||||
compiler_args += ['-DDXVK_WSI_GLFW']
|
compiler_args += ['-DDXVK_WSI_GLFW']
|
||||||
endif
|
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_'
|
dxvk_name_prefix = 'libdxvk_'
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#if defined(DXVK_WSI_GLFW)
|
||||||
|
|
||||||
#include "../wsi_monitor.h"
|
#include "../wsi_monitor.h"
|
||||||
|
|
||||||
#include "wsi/native_wsi.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 "wsi_platform_glfw.h"
|
||||||
#include "../../util/util_error.h"
|
#include "../../util/util_error.h"
|
||||||
#include "../../util/util_string.h"
|
#include "../../util/util_string.h"
|
||||||
@ -50,8 +52,20 @@ namespace dxvk::wsi {
|
|||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
WsiDriver* platformCreateWsiDriver() {
|
static bool createGlfwWsiDriver(WsiDriver **driver) {
|
||||||
return new GlfwWsiDriver();
|
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 "../wsi_window.h"
|
||||||
|
|
||||||
#include "native/wsi/native_wsi.h"
|
#include "native/wsi/native_glfw.h"
|
||||||
#include "wsi_platform_glfw.h"
|
#include "wsi_platform_glfw.h"
|
||||||
|
|
||||||
#include "../../util/util_string.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_edid.cpp',
|
||||||
'wsi_platform.cpp',
|
'wsi_platform.cpp',
|
||||||
]
|
|
||||||
|
|
||||||
wsi_win32_src = [
|
|
||||||
'win32/wsi_monitor_win32.cpp',
|
'win32/wsi_monitor_win32.cpp',
|
||||||
'win32/wsi_platform_win32.cpp',
|
'win32/wsi_platform_win32.cpp',
|
||||||
'win32/wsi_window_win32.cpp',
|
'win32/wsi_window_win32.cpp',
|
||||||
]
|
|
||||||
|
|
||||||
wsi_sdl2_src = [
|
|
||||||
'sdl2/wsi_monitor_sdl2.cpp',
|
'sdl2/wsi_monitor_sdl2.cpp',
|
||||||
'sdl2/wsi_platform_sdl2.cpp',
|
'sdl2/wsi_platform_sdl2.cpp',
|
||||||
'sdl2/wsi_window_sdl2.cpp',
|
'sdl2/wsi_window_sdl2.cpp',
|
||||||
]
|
|
||||||
|
|
||||||
wsi_glfw_src = [
|
|
||||||
'glfw/wsi_monitor_glfw.cpp',
|
'glfw/wsi_monitor_glfw.cpp',
|
||||||
'glfw/wsi_platform_glfw.cpp',
|
'glfw/wsi_platform_glfw.cpp',
|
||||||
'glfw/wsi_window_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_deps = [ dep_displayinfo ]
|
||||||
|
|
||||||
wsi_lib = static_library('wsi', wsi_src,
|
wsi_lib = static_library('wsi', wsi_src,
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#if defined(DXVK_WSI_SDL2)
|
||||||
|
|
||||||
#include "../wsi_monitor.h"
|
#include "../wsi_monitor.h"
|
||||||
|
|
||||||
#include "wsi/native_wsi.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 "wsi_platform_sdl2.h"
|
||||||
#include "../../util/util_error.h"
|
#include "../../util/util_error.h"
|
||||||
#include "../../util/util_string.h"
|
#include "../../util/util_string.h"
|
||||||
@ -48,8 +50,20 @@ namespace dxvk::wsi {
|
|||||||
return extensionNames;
|
return extensionNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
WsiDriver* platformCreateWsiDriver() {
|
static bool createSdl2WsiDriver(WsiDriver **driver) {
|
||||||
return new Sdl2WsiDriver();
|
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 "../wsi_window.h"
|
||||||
|
|
||||||
#include "native/wsi/native_wsi.h"
|
#include "native/wsi/native_sdl2.h"
|
||||||
#include "wsi_platform_sdl2.h"
|
#include "wsi_platform_sdl2.h"
|
||||||
|
|
||||||
#include "../../util/util_string.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 "wsi_platform_win32.h"
|
||||||
|
|
||||||
#include "../../util/util_string.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"
|
#include "wsi_platform_win32.h"
|
||||||
|
|
||||||
namespace dxvk::wsi {
|
namespace dxvk::wsi {
|
||||||
@ -6,8 +8,16 @@ namespace dxvk::wsi {
|
|||||||
return { VK_KHR_WIN32_SURFACE_EXTENSION_NAME };
|
return { VK_KHR_WIN32_SURFACE_EXTENSION_NAME };
|
||||||
}
|
}
|
||||||
|
|
||||||
WsiDriver* platformCreateWsiDriver() {
|
static bool createWin32WsiDriver(WsiDriver **driver) {
|
||||||
return new Win32WsiDriver();
|
*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 "wsi_platform_win32.h"
|
||||||
|
|
||||||
#include "../../util/util_string.h"
|
#include "../../util/util_string.h"
|
||||||
@ -169,14 +171,14 @@ namespace dxvk::wsi {
|
|||||||
[[maybe_unused]]
|
[[maybe_unused]]
|
||||||
bool modeSwitch) {
|
bool modeSwitch) {
|
||||||
// Find a display mode that matches what we need
|
// 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.
|
// Change the window flags to remove the decoration etc.
|
||||||
LONG style = ::GetWindowLongW(hWindow, GWL_STYLE);
|
LONG style = ::GetWindowLongW(hWindow, GWL_STYLE);
|
||||||
LONG exstyle = ::GetWindowLongW(hWindow, GWL_EXSTYLE);
|
LONG exstyle = ::GetWindowLongW(hWindow, GWL_EXSTYLE);
|
||||||
|
|
||||||
pState->style = style;
|
pState->win.style = style;
|
||||||
pState->exstyle = exstyle;
|
pState->win.exstyle = exstyle;
|
||||||
|
|
||||||
style &= ~WS_OVERLAPPEDWINDOW;
|
style &= ~WS_OVERLAPPEDWINDOW;
|
||||||
exstyle &= ~WS_EX_OVERLAPPEDWINDOW;
|
exstyle &= ~WS_EX_OVERLAPPEDWINDOW;
|
||||||
@ -204,20 +206,20 @@ namespace dxvk::wsi {
|
|||||||
LONG curStyle = ::GetWindowLongW(hWindow, GWL_STYLE) & ~WS_VISIBLE;
|
LONG curStyle = ::GetWindowLongW(hWindow, GWL_STYLE) & ~WS_VISIBLE;
|
||||||
LONG curExstyle = ::GetWindowLongW(hWindow, GWL_EXSTYLE) & ~WS_EX_TOPMOST;
|
LONG curExstyle = ::GetWindowLongW(hWindow, GWL_EXSTYLE) & ~WS_EX_TOPMOST;
|
||||||
|
|
||||||
if (curStyle == (pState->style & ~(WS_VISIBLE | WS_OVERLAPPEDWINDOW))
|
if (curStyle == (pState->win.style & ~(WS_VISIBLE | WS_OVERLAPPEDWINDOW))
|
||||||
&& curExstyle == (pState->exstyle & ~(WS_EX_TOPMOST | WS_EX_OVERLAPPEDWINDOW))) {
|
&& curExstyle == (pState->win.exstyle & ~(WS_EX_TOPMOST | WS_EX_OVERLAPPEDWINDOW))) {
|
||||||
::SetWindowLongW(hWindow, GWL_STYLE, pState->style);
|
::SetWindowLongW(hWindow, GWL_STYLE, pState->win.style);
|
||||||
::SetWindowLongW(hWindow, GWL_EXSTYLE, pState->exstyle);
|
::SetWindowLongW(hWindow, GWL_EXSTYLE, pState->win.exstyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore window position and apply the style
|
// Restore window position and apply the style
|
||||||
UINT flags = SWP_FRAMECHANGED | SWP_NOACTIVATE;
|
UINT flags = SWP_FRAMECHANGED | SWP_NOACTIVATE;
|
||||||
const RECT rect = pState->rect;
|
const RECT rect = pState->win.rect;
|
||||||
|
|
||||||
if (!restoreCoordinates)
|
if (!restoreCoordinates)
|
||||||
flags |= SWP_NOSIZE | SWP_NOMOVE;
|
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);
|
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, flags);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -295,3 +297,5 @@ namespace dxvk::wsi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -1,18 +1,49 @@
|
|||||||
#include "wsi_platform.h"
|
#include "wsi_platform.h"
|
||||||
#include "wsi_monitor.h"
|
#include "wsi_monitor.h"
|
||||||
#include "wsi_window.h"
|
#include "wsi_window.h"
|
||||||
|
#include "../util/util_env.h"
|
||||||
#include "../util/util_error.h"
|
#include "../util/util_error.h"
|
||||||
|
|
||||||
namespace dxvk::wsi {
|
namespace dxvk::wsi {
|
||||||
static WsiDriver* s_driver = nullptr;
|
static WsiDriver* s_driver = nullptr;
|
||||||
static int s_refcount = 0;
|
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() {
|
void init() {
|
||||||
if (s_refcount++ > 0)
|
if (s_refcount++ > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
s_driver = platformCreateWsiDriver();
|
std::string hint = dxvk::env::getEnvVar("DXVK_WSIDRIVER");
|
||||||
if (s_driver == nullptr)
|
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.");
|
throw DxvkError("Failed to initialize WSI.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,9 +92,23 @@ namespace dxvk::wsi {
|
|||||||
VkSurfaceKHR* pSurface) = 0;
|
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 init();
|
||||||
void quit();
|
void quit();
|
||||||
std::vector<const char *> getInstanceExtensions();
|
std::vector<const char *> getInstanceExtensions();
|
||||||
WsiDriver* platformCreateWsiDriver();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,18 @@ namespace dxvk::wsi {
|
|||||||
* \brief Impl-dependent state
|
* \brief Impl-dependent state
|
||||||
*/
|
*/
|
||||||
struct DxvkWindowState {
|
struct DxvkWindowState {
|
||||||
#ifdef DXVK_WSI_WIN32
|
#if defined(DXVK_WSI_WIN32)
|
||||||
LONG style = 0;
|
struct {
|
||||||
LONG exstyle = 0;
|
LONG style = 0;
|
||||||
RECT rect = { 0, 0, 0, 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
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user