From 0f7c1f753ad25c0d992c08ba888a70e6aa74814f Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Fri, 8 Dec 2023 00:45:46 -0500 Subject: [PATCH] [wsi] Refactor the WSI backends to be implementations of a WsiDriver interface. Rather than directly calling functions, the API now calls shared functions that call into a WsiDriver instance, which is allocated and implemented by the backend. Functionally this should be the same, it just has the extra allocation for the function table. This prepares the WSI library for supporting multiple implementations in a single binary. --- src/wsi/glfw/wsi_monitor_glfw.cpp | 18 ++-- src/wsi/glfw/wsi_platform_glfw.cpp | 6 +- src/wsi/glfw/wsi_platform_glfw.h | 89 ++++++++++++++++-- src/wsi/glfw/wsi_window_glfw.cpp | 22 ++--- src/wsi/sdl2/wsi_monitor_sdl2.cpp | 18 ++-- src/wsi/sdl2/wsi_platform_sdl2.cpp | 6 +- src/wsi/sdl2/wsi_platform_sdl2.h | 89 ++++++++++++++++-- src/wsi/sdl2/wsi_window_sdl2.cpp | 20 ++-- src/wsi/win32/wsi_monitor_win32.cpp | 20 ++-- src/wsi/win32/wsi_platform_win32.cpp | 6 +- src/wsi/win32/wsi_platform_win32.h | 92 ++++++++++++++++-- src/wsi/win32/wsi_window_win32.cpp | 23 +++-- src/wsi/wsi_platform.cpp | 135 +++++++++++++++++++++++++++ src/wsi/wsi_platform.h | 95 +++++++++++++++++-- src/wsi/wsi_window.h | 12 ++- 15 files changed, 559 insertions(+), 92 deletions(-) diff --git a/src/wsi/glfw/wsi_monitor_glfw.cpp b/src/wsi/glfw/wsi_monitor_glfw.cpp index e450f83c..00abc89a 100644 --- a/src/wsi/glfw/wsi_monitor_glfw.cpp +++ b/src/wsi/glfw/wsi_monitor_glfw.cpp @@ -11,22 +11,22 @@ namespace dxvk::wsi { - HMONITOR getDefaultMonitor() { + HMONITOR GlfwWsiDriver::getDefaultMonitor() { return enumMonitors(0); } - HMONITOR enumMonitors(uint32_t index) { + HMONITOR GlfwWsiDriver::enumMonitors(uint32_t index) { return isDisplayValid(int32_t(index)) ? toHmonitor(index) : nullptr; } - HMONITOR enumMonitors(const LUID *adapterLUID[], uint32_t numLUIDs, uint32_t index) { + HMONITOR GlfwWsiDriver::enumMonitors(const LUID *adapterLUID[], uint32_t numLUIDs, uint32_t index) { return enumMonitors(index); } - bool getDisplayName( + bool GlfwWsiDriver::getDisplayName( HMONITOR hMonitor, WCHAR (&Name)[32]) { const int32_t displayId = fromHmonitor(hMonitor); @@ -46,7 +46,7 @@ namespace dxvk::wsi { } - bool getDesktopCoordinates( + bool GlfwWsiDriver::getDesktopCoordinates( HMONITOR hMonitor, RECT* pRect) { const int32_t displayId = fromHmonitor(hMonitor); @@ -97,7 +97,7 @@ namespace dxvk::wsi { } - bool getDisplayMode( + bool GlfwWsiDriver::getDisplayMode( HMONITOR hMonitor, uint32_t ModeNumber, WsiMode* pMode) { @@ -121,7 +121,7 @@ namespace dxvk::wsi { } - bool getCurrentDisplayMode( + bool GlfwWsiDriver::getCurrentDisplayMode( HMONITOR hMonitor, WsiMode* pMode) { const int32_t displayId = fromHmonitor(hMonitor); @@ -141,7 +141,7 @@ namespace dxvk::wsi { } - bool getDesktopDisplayMode( + bool GlfwWsiDriver::getDesktopDisplayMode( HMONITOR hMonitor, WsiMode* pMode) { const int32_t displayId = fromHmonitor(hMonitor); @@ -159,7 +159,7 @@ namespace dxvk::wsi { return true; } - std::vector getMonitorEdid(HMONITOR hMonitor) { + std::vector GlfwWsiDriver::getMonitorEdid(HMONITOR hMonitor) { Logger::err("getMonitorEdid not implemented on this platform."); return {}; } diff --git a/src/wsi/glfw/wsi_platform_glfw.cpp b/src/wsi/glfw/wsi_platform_glfw.cpp index d180f597..fb711aeb 100644 --- a/src/wsi/glfw/wsi_platform_glfw.cpp +++ b/src/wsi/glfw/wsi_platform_glfw.cpp @@ -4,7 +4,7 @@ namespace dxvk::wsi { - std::vector getInstanceExtensions() { + std::vector GlfwWsiDriver::getInstanceExtensions() { if (!glfwVulkanSupported()) throw DxvkError(str::format("GLFW WSI: Vulkan is not supported in any capacity!")); @@ -22,4 +22,8 @@ namespace dxvk::wsi { return names; } + WsiDriver* platformCreateWsiDriver() { + return new GlfwWsiDriver(); + } + } diff --git a/src/wsi/glfw/wsi_platform_glfw.h b/src/wsi/glfw/wsi_platform_glfw.h index 25753494..83b95c5e 100644 --- a/src/wsi/glfw/wsi_platform_glfw.h +++ b/src/wsi/glfw/wsi_platform_glfw.h @@ -3,14 +3,91 @@ #include "../../vulkan/vulkan_loader.h" #include -#include "../wsi_monitor.h" +#include "../wsi_platform.h" namespace dxvk::wsi { - /** - * \brief Impl-dependent state - */ - struct DxvkWindowState { + class GlfwWsiDriver : public WsiDriver { + public: + // Platform + virtual std::vector getInstanceExtensions(); + + // Monitor + virtual HMONITOR getDefaultMonitor(); + + virtual HMONITOR enumMonitors(uint32_t index); + + virtual HMONITOR enumMonitors(const LUID *adapterLUID[], uint32_t numLUIDs, uint32_t index); + + virtual bool getDisplayName( + HMONITOR hMonitor, + WCHAR (&Name)[32]); + + virtual bool getDesktopCoordinates( + HMONITOR hMonitor, + RECT* pRect); + + virtual bool getDisplayMode( + HMONITOR hMonitor, + uint32_t modeNumber, + WsiMode* pMode); + + virtual bool getCurrentDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode); + + virtual bool getDesktopDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode); + + virtual WsiEdidData getMonitorEdid(HMONITOR hMonitor); + + // Window + + virtual void getWindowSize( + HWND hWindow, + uint32_t* pWidth, + uint32_t* pWeight); + + virtual void resizeWindow( + HWND hWindow, + DxvkWindowState* pState, + uint32_t width, + uint32_t weight); + + virtual bool setWindowMode( + HMONITOR hMonitor, + HWND hWindow, + const WsiMode& mode); + + virtual bool enterFullscreenMode( + HMONITOR hMonitor, + HWND hWindow, + DxvkWindowState* pState, + [[maybe_unused]] + bool modeSwitch); + + virtual bool leaveFullscreenMode( + HWND hWindow, + DxvkWindowState* pState, + bool restoreCoordinates); + + virtual bool restoreDisplayMode(); + + virtual HMONITOR getWindowMonitor(HWND hWindow); + + virtual bool isWindow(HWND hWindow); + + virtual void updateFullscreenWindow( + HMONITOR hMonitor, + HWND hWindow, + bool forceTopmost); + + virtual VkResult createSurface( + HWND hWindow, + PFN_vkGetInstanceProcAddr pfnVkGetInstanceProcAddr, + VkInstance instance, + VkSurfaceKHR* pSurface); }; inline bool isDisplayValid(int32_t displayId) { @@ -20,4 +97,4 @@ namespace dxvk::wsi { return displayId < displayCount && displayId >= 0; } -} \ No newline at end of file +} diff --git a/src/wsi/glfw/wsi_window_glfw.cpp b/src/wsi/glfw/wsi_window_glfw.cpp index 70031250..b23a7923 100644 --- a/src/wsi/glfw/wsi_window_glfw.cpp +++ b/src/wsi/glfw/wsi_window_glfw.cpp @@ -12,7 +12,7 @@ namespace dxvk::wsi { - void getWindowSize( + void GlfwWsiDriver::getWindowSize( HWND hWindow, uint32_t* pWidth, uint32_t* pHeight) { @@ -29,7 +29,7 @@ namespace dxvk::wsi { } - void resizeWindow( + void GlfwWsiDriver::resizeWindow( HWND hWindow, DxvkWindowState* pState, uint32_t Width, @@ -40,7 +40,7 @@ namespace dxvk::wsi { } - bool setWindowMode( + bool GlfwWsiDriver::setWindowMode( HMONITOR hMonitor, HWND hWindow, const WsiMode& pMode) { @@ -67,7 +67,7 @@ namespace dxvk::wsi { return true; } - bool enterFullscreenMode( + bool GlfwWsiDriver::enterFullscreenMode( HMONITOR hMonitor, HWND hWindow, DxvkWindowState* pState, @@ -89,7 +89,7 @@ namespace dxvk::wsi { } - bool leaveFullscreenMode( + bool GlfwWsiDriver::leaveFullscreenMode( HWND hWindow, DxvkWindowState* pState, bool restoreCoordinates) { @@ -103,13 +103,13 @@ namespace dxvk::wsi { } - bool restoreDisplayMode() { + bool GlfwWsiDriver::restoreDisplayMode() { // Don't need to do anything with GLFW here. return true; } - HMONITOR getWindowMonitor(HWND hWindow) { + HMONITOR GlfwWsiDriver::getWindowMonitor(HWND hWindow) { // TODO: implement this with glfwGetWindowMonitor // (or maybe not? glfwGetWindowMonitor only seems to reference *fullscreen* windows) // GLFWwindow* window = fromHwnd(hWindow); @@ -119,19 +119,19 @@ namespace dxvk::wsi { } - bool isWindow(HWND hWindow) { + bool GlfwWsiDriver::isWindow(HWND hWindow) { GLFWwindow* window = fromHwnd(hWindow); return window != nullptr; } - void updateFullscreenWindow( + void GlfwWsiDriver::updateFullscreenWindow( HMONITOR hMonitor, HWND hWindow, bool forceTopmost) { // Don't need to do anything with GLFW here. } - VkResult createSurface( + VkResult GlfwWsiDriver::createSurface( HWND hWindow, PFN_vkGetInstanceProcAddr pfnVkGetInstanceProcAddr, VkInstance instance, @@ -141,4 +141,4 @@ namespace dxvk::wsi { return glfwCreateWindowSurface(instance, window, nullptr, pSurface); } -} \ No newline at end of file +} diff --git a/src/wsi/sdl2/wsi_monitor_sdl2.cpp b/src/wsi/sdl2/wsi_monitor_sdl2.cpp index f0de7cd6..5903ef68 100644 --- a/src/wsi/sdl2/wsi_monitor_sdl2.cpp +++ b/src/wsi/sdl2/wsi_monitor_sdl2.cpp @@ -12,22 +12,22 @@ namespace dxvk::wsi { - HMONITOR getDefaultMonitor() { + HMONITOR Sdl2WsiDriver::getDefaultMonitor() { return enumMonitors(0); } - HMONITOR enumMonitors(uint32_t index) { + HMONITOR Sdl2WsiDriver::enumMonitors(uint32_t index) { return isDisplayValid(int32_t(index)) ? toHmonitor(index) : nullptr; } - HMONITOR enumMonitors(const LUID *adapterLUID[], uint32_t numLUIDs, uint32_t index) { + HMONITOR Sdl2WsiDriver::enumMonitors(const LUID *adapterLUID[], uint32_t numLUIDs, uint32_t index) { return enumMonitors(index); } - bool getDisplayName( + bool Sdl2WsiDriver::getDisplayName( HMONITOR hMonitor, WCHAR (&Name)[32]) { const int32_t displayId = fromHmonitor(hMonitor); @@ -47,7 +47,7 @@ namespace dxvk::wsi { } - bool getDesktopCoordinates( + bool Sdl2WsiDriver::getDesktopCoordinates( HMONITOR hMonitor, RECT* pRect) { const int32_t displayId = fromHmonitor(hMonitor); @@ -90,7 +90,7 @@ namespace dxvk::wsi { } - bool getDisplayMode( + bool Sdl2WsiDriver::getDisplayMode( HMONITOR hMonitor, uint32_t ModeNumber, WsiMode* pMode) { @@ -109,7 +109,7 @@ namespace dxvk::wsi { } - bool getCurrentDisplayMode( + bool Sdl2WsiDriver::getCurrentDisplayMode( HMONITOR hMonitor, WsiMode* pMode) { const int32_t displayId = fromHmonitor(hMonitor); @@ -129,7 +129,7 @@ namespace dxvk::wsi { } - bool getDesktopDisplayMode( + bool Sdl2WsiDriver::getDesktopDisplayMode( HMONITOR hMonitor, WsiMode* pMode) { const int32_t displayId = fromHmonitor(hMonitor); @@ -148,7 +148,7 @@ namespace dxvk::wsi { return true; } - std::vector getMonitorEdid(HMONITOR hMonitor) { + std::vector Sdl2WsiDriver::getMonitorEdid(HMONITOR hMonitor) { Logger::err("getMonitorEdid not implemented on this platform."); return {}; } diff --git a/src/wsi/sdl2/wsi_platform_sdl2.cpp b/src/wsi/sdl2/wsi_platform_sdl2.cpp index cc8ac22b..96ecb076 100644 --- a/src/wsi/sdl2/wsi_platform_sdl2.cpp +++ b/src/wsi/sdl2/wsi_platform_sdl2.cpp @@ -6,7 +6,7 @@ namespace dxvk::wsi { - std::vector getInstanceExtensions() { + std::vector Sdl2WsiDriver::getInstanceExtensions() { SDL_Vulkan_LoadLibrary(nullptr); uint32_t extensionCount = 0; @@ -20,4 +20,8 @@ namespace dxvk::wsi { return extensionNames; } + WsiDriver* platformCreateWsiDriver() { + return new Sdl2WsiDriver(); + } + } diff --git a/src/wsi/sdl2/wsi_platform_sdl2.h b/src/wsi/sdl2/wsi_platform_sdl2.h index 411fe8f6..845725ab 100644 --- a/src/wsi/sdl2/wsi_platform_sdl2.h +++ b/src/wsi/sdl2/wsi_platform_sdl2.h @@ -2,14 +2,91 @@ #include -#include "../wsi_monitor.h" +#include "../wsi_platform.h" namespace dxvk::wsi { - /** - * \brief Impl-dependent state - */ - struct DxvkWindowState { + class Sdl2WsiDriver : public WsiDriver { + public: + // Platform + virtual std::vector getInstanceExtensions(); + + // Monitor + virtual HMONITOR getDefaultMonitor(); + + virtual HMONITOR enumMonitors(uint32_t index); + + virtual HMONITOR enumMonitors(const LUID *adapterLUID[], uint32_t numLUIDs, uint32_t index); + + virtual bool getDisplayName( + HMONITOR hMonitor, + WCHAR (&Name)[32]); + + virtual bool getDesktopCoordinates( + HMONITOR hMonitor, + RECT* pRect); + + virtual bool getDisplayMode( + HMONITOR hMonitor, + uint32_t modeNumber, + WsiMode* pMode); + + virtual bool getCurrentDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode); + + virtual bool getDesktopDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode); + + virtual WsiEdidData getMonitorEdid(HMONITOR hMonitor); + + // Window + + virtual void getWindowSize( + HWND hWindow, + uint32_t* pWidth, + uint32_t* pWeight); + + virtual void resizeWindow( + HWND hWindow, + DxvkWindowState* pState, + uint32_t width, + uint32_t weight); + + virtual bool setWindowMode( + HMONITOR hMonitor, + HWND hWindow, + const WsiMode& mode); + + virtual bool enterFullscreenMode( + HMONITOR hMonitor, + HWND hWindow, + DxvkWindowState* pState, + [[maybe_unused]] + bool modeSwitch); + + virtual bool leaveFullscreenMode( + HWND hWindow, + DxvkWindowState* pState, + bool restoreCoordinates); + + virtual bool restoreDisplayMode(); + + virtual HMONITOR getWindowMonitor(HWND hWindow); + + virtual bool isWindow(HWND hWindow); + + virtual void updateFullscreenWindow( + HMONITOR hMonitor, + HWND hWindow, + bool forceTopmost); + + virtual VkResult createSurface( + HWND hWindow, + PFN_vkGetInstanceProcAddr pfnVkGetInstanceProcAddr, + VkInstance instance, + VkSurfaceKHR* pSurface); }; inline bool isDisplayValid(int32_t displayId) { @@ -18,4 +95,4 @@ namespace dxvk::wsi { return displayId < displayCount && displayId >= 0; } -} \ No newline at end of file +} diff --git a/src/wsi/sdl2/wsi_window_sdl2.cpp b/src/wsi/sdl2/wsi_window_sdl2.cpp index 1280b6c1..5622e876 100644 --- a/src/wsi/sdl2/wsi_window_sdl2.cpp +++ b/src/wsi/sdl2/wsi_window_sdl2.cpp @@ -11,7 +11,7 @@ namespace dxvk::wsi { - void getWindowSize( + void Sdl2WsiDriver::getWindowSize( HWND hWindow, uint32_t* pWidth, uint32_t* pHeight) { @@ -28,7 +28,7 @@ namespace dxvk::wsi { } - void resizeWindow( + void Sdl2WsiDriver::resizeWindow( HWND hWindow, DxvkWindowState* pState, uint32_t Width, @@ -39,7 +39,7 @@ namespace dxvk::wsi { } - bool setWindowMode( + bool Sdl2WsiDriver::setWindowMode( HMONITOR hMonitor, HWND hWindow, const WsiMode& pMode) { @@ -73,7 +73,7 @@ namespace dxvk::wsi { - bool enterFullscreenMode( + bool Sdl2WsiDriver::enterFullscreenMode( HMONITOR hMonitor, HWND hWindow, DxvkWindowState* pState, @@ -99,7 +99,7 @@ namespace dxvk::wsi { } - bool leaveFullscreenMode( + bool Sdl2WsiDriver::leaveFullscreenMode( HWND hWindow, DxvkWindowState* pState, bool restoreCoordinates) { @@ -114,13 +114,13 @@ namespace dxvk::wsi { } - bool restoreDisplayMode() { + bool Sdl2WsiDriver::restoreDisplayMode() { // Don't need to do anything with SDL2 here. return true; } - HMONITOR getWindowMonitor(HWND hWindow) { + HMONITOR Sdl2WsiDriver::getWindowMonitor(HWND hWindow) { SDL_Window* window = fromHwnd(hWindow); const int32_t displayId = SDL_GetWindowDisplayIndex(window); @@ -128,13 +128,13 @@ namespace dxvk::wsi { } - bool isWindow(HWND hWindow) { + bool Sdl2WsiDriver::isWindow(HWND hWindow) { SDL_Window* window = fromHwnd(hWindow); return window != nullptr; } - void updateFullscreenWindow( + void Sdl2WsiDriver::updateFullscreenWindow( HMONITOR hMonitor, HWND hWindow, bool forceTopmost) { @@ -142,7 +142,7 @@ namespace dxvk::wsi { } - VkResult createSurface( + VkResult Sdl2WsiDriver::createSurface( HWND hWindow, PFN_vkGetInstanceProcAddr pfnVkGetInstanceProcAddr, VkInstance instance, diff --git a/src/wsi/win32/wsi_monitor_win32.cpp b/src/wsi/win32/wsi_monitor_win32.cpp index ae4a0ff3..b37e0902 100644 --- a/src/wsi/win32/wsi_monitor_win32.cpp +++ b/src/wsi/win32/wsi_monitor_win32.cpp @@ -1,4 +1,4 @@ -#include "../wsi_monitor.h" +#include "wsi_platform_win32.h" #include "../../util/util_string.h" #include "../../util/log/log.h" @@ -13,7 +13,7 @@ namespace dxvk::wsi { - HMONITOR getDefaultMonitor() { + HMONITOR Win32WsiDriver::getDefaultMonitor() { return ::MonitorFromPoint({ 0, 0 }, MONITOR_DEFAULTTOPRIMARY); } @@ -45,7 +45,7 @@ namespace dxvk::wsi { return FALSE; } - HMONITOR enumMonitors(uint32_t index) { + HMONITOR Win32WsiDriver::enumMonitors(uint32_t index) { MonitorEnumInfo info; info.iMonitorId = index; info.oMonitor = nullptr; @@ -58,7 +58,7 @@ namespace dxvk::wsi { return info.oMonitor; } - HMONITOR enumMonitors(const LUID *adapterLUID[], uint32_t numLUIDs, uint32_t index) { + HMONITOR Win32WsiDriver::enumMonitors(const LUID *adapterLUID[], uint32_t numLUIDs, uint32_t index) { if (!numLUIDs) return enumMonitors(index); @@ -132,7 +132,7 @@ namespace dxvk::wsi { } - bool getDisplayName( + bool Win32WsiDriver::getDisplayName( HMONITOR hMonitor, WCHAR (&Name)[32]) { // Query monitor info to get the device name @@ -150,7 +150,7 @@ namespace dxvk::wsi { } - bool getDesktopCoordinates( + bool Win32WsiDriver::getDesktopCoordinates( HMONITOR hMonitor, RECT* pRect) { ::MONITORINFOEXW monInfo; @@ -200,7 +200,7 @@ namespace dxvk::wsi { } - bool getDisplayMode( + bool Win32WsiDriver::getDisplayMode( HMONITOR hMonitor, uint32_t modeNumber, WsiMode* pMode) { @@ -208,14 +208,14 @@ namespace dxvk::wsi { } - bool getCurrentDisplayMode( + bool Win32WsiDriver::getCurrentDisplayMode( HMONITOR hMonitor, WsiMode* pMode) { return retrieveDisplayMode(hMonitor, ENUM_CURRENT_SETTINGS, pMode); } - bool getDesktopDisplayMode( + bool Win32WsiDriver::getDesktopDisplayMode( HMONITOR hMonitor, WsiMode* pMode) { return retrieveDisplayMode(hMonitor, ENUM_REGISTRY_SETTINGS, pMode); @@ -308,7 +308,7 @@ namespace dxvk::wsi { wchar_t extraChars[MAX_DEVICE_ID_LEN]; }; - WsiEdidData getMonitorEdid(HMONITOR hMonitor) { + WsiEdidData Win32WsiDriver::getMonitorEdid(HMONITOR hMonitor) { static constexpr GUID GUID_DEVINTERFACE_MONITOR = { 0xe6f07b5f, 0xee97, 0x4a90, 0xb0, 0x76, 0x33, 0xf5, 0x7b, 0xf4, 0xea, 0xa7 }; static auto pfnSetupDiGetClassDevsW = reinterpret_cast (::GetProcAddress(::GetModuleHandleW(L"setupapi.dll"), "SetupDiGetClassDevsW")); static auto pfnSetupDiEnumDeviceInterfaces = reinterpret_cast (::GetProcAddress(::GetModuleHandleW(L"setupapi.dll"), "SetupDiEnumDeviceInterfaces")); diff --git a/src/wsi/win32/wsi_platform_win32.cpp b/src/wsi/win32/wsi_platform_win32.cpp index 8b16de56..ab27869a 100644 --- a/src/wsi/win32/wsi_platform_win32.cpp +++ b/src/wsi/win32/wsi_platform_win32.cpp @@ -2,8 +2,12 @@ namespace dxvk::wsi { - std::vector getInstanceExtensions() { + std::vector Win32WsiDriver::getInstanceExtensions() { return { VK_KHR_WIN32_SURFACE_EXTENSION_NAME }; } + WsiDriver* platformCreateWsiDriver() { + return new Win32WsiDriver(); + } + } diff --git a/src/wsi/win32/wsi_platform_win32.h b/src/wsi/win32/wsi_platform_win32.h index d382f20a..1364baf1 100644 --- a/src/wsi/win32/wsi_platform_win32.h +++ b/src/wsi/win32/wsi_platform_win32.h @@ -2,15 +2,91 @@ #include +#include "../wsi_platform.h" + namespace dxvk::wsi { - /** - * \brief Impl-dependent state - */ - struct DxvkWindowState { - LONG style = 0; - LONG exstyle = 0; - RECT rect = { 0, 0, 0, 0 }; + class Win32WsiDriver : public WsiDriver { + public: + // Platform + virtual std::vector getInstanceExtensions(); + + // Monitor + virtual HMONITOR getDefaultMonitor(); + + virtual HMONITOR enumMonitors(uint32_t index); + + virtual HMONITOR enumMonitors(const LUID *adapterLUID[], uint32_t numLUIDs, uint32_t index); + + virtual bool getDisplayName( + HMONITOR hMonitor, + WCHAR (&Name)[32]); + + virtual bool getDesktopCoordinates( + HMONITOR hMonitor, + RECT* pRect); + + virtual bool getDisplayMode( + HMONITOR hMonitor, + uint32_t modeNumber, + WsiMode* pMode); + + virtual bool getCurrentDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode); + + virtual bool getDesktopDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode); + + virtual WsiEdidData getMonitorEdid(HMONITOR hMonitor); + + // Window + + virtual void getWindowSize( + HWND hWindow, + uint32_t* pWidth, + uint32_t* pWeight); + + virtual void resizeWindow( + HWND hWindow, + DxvkWindowState* pState, + uint32_t width, + uint32_t weight); + + virtual bool setWindowMode( + HMONITOR hMonitor, + HWND hWindow, + const WsiMode& mode); + + virtual bool enterFullscreenMode( + HMONITOR hMonitor, + HWND hWindow, + DxvkWindowState* pState, + [[maybe_unused]] + bool modeSwitch); + + virtual bool leaveFullscreenMode( + HWND hWindow, + DxvkWindowState* pState, + bool restoreCoordinates); + + virtual bool restoreDisplayMode(); + + virtual HMONITOR getWindowMonitor(HWND hWindow); + + virtual bool isWindow(HWND hWindow); + + virtual void updateFullscreenWindow( + HMONITOR hMonitor, + HWND hWindow, + bool forceTopmost); + + virtual VkResult createSurface( + HWND hWindow, + PFN_vkGetInstanceProcAddr pfnVkGetInstanceProcAddr, + VkInstance instance, + VkSurfaceKHR* pSurface); }; -} \ No newline at end of file +} diff --git a/src/wsi/win32/wsi_window_win32.cpp b/src/wsi/win32/wsi_window_win32.cpp index 597d7478..cf446980 100644 --- a/src/wsi/win32/wsi_window_win32.cpp +++ b/src/wsi/win32/wsi_window_win32.cpp @@ -1,5 +1,4 @@ -#include "../wsi_window.h" -#include "../wsi_monitor.h" +#include "wsi_platform_win32.h" #include "../../util/util_string.h" #include "../../util/log/log.h" @@ -94,7 +93,7 @@ namespace dxvk::wsi { } - void getWindowSize( + void Win32WsiDriver::getWindowSize( HWND hWindow, uint32_t* pWidth, uint32_t* pHeight) { @@ -109,7 +108,7 @@ namespace dxvk::wsi { } - void resizeWindow( + void Win32WsiDriver::resizeWindow( HWND hWindow, DxvkWindowState* pState, uint32_t width, @@ -130,7 +129,7 @@ namespace dxvk::wsi { } - bool setWindowMode( + bool Win32WsiDriver::setWindowMode( HMONITOR hMonitor, HWND hWindow, const WsiMode& mode) { @@ -163,7 +162,7 @@ namespace dxvk::wsi { } - bool enterFullscreenMode( + bool Win32WsiDriver::enterFullscreenMode( HMONITOR hMonitor, HWND hWindow, DxvkWindowState* pState, @@ -196,7 +195,7 @@ namespace dxvk::wsi { } - bool leaveFullscreenMode( + bool Win32WsiDriver::leaveFullscreenMode( HWND hWindow, DxvkWindowState* pState, bool restoreCoordinates) { @@ -225,7 +224,7 @@ namespace dxvk::wsi { } - bool restoreDisplayMode() { + bool Win32WsiDriver::restoreDisplayMode() { bool success = true; bool result = ::EnumDisplayMonitors(nullptr, nullptr, &restoreDisplayModeCallback, @@ -235,7 +234,7 @@ namespace dxvk::wsi { } - HMONITOR getWindowMonitor(HWND hWindow) { + HMONITOR Win32WsiDriver::getWindowMonitor(HWND hWindow) { RECT windowRect = { 0, 0, 0, 0 }; ::GetWindowRect(hWindow, &windowRect); @@ -248,12 +247,12 @@ namespace dxvk::wsi { } - bool isWindow(HWND hWindow) { + bool Win32WsiDriver::isWindow(HWND hWindow) { return ::IsWindow(hWindow); } - void updateFullscreenWindow( + void Win32WsiDriver::updateFullscreenWindow( HMONITOR hMonitor, HWND hWindow, bool forceTopmost) { @@ -274,7 +273,7 @@ namespace dxvk::wsi { } - VkResult createSurface( + VkResult Win32WsiDriver::createSurface( HWND hWindow, PFN_vkGetInstanceProcAddr pfnVkGetInstanceProcAddr, VkInstance instance, diff --git a/src/wsi/wsi_platform.cpp b/src/wsi/wsi_platform.cpp index 56cd6c45..f4802025 100644 --- a/src/wsi/wsi_platform.cpp +++ b/src/wsi/wsi_platform.cpp @@ -1,11 +1,146 @@ #include "wsi_platform.h" +#include "wsi_monitor.h" +#include "wsi_window.h" +#include "../util/util_error.h" namespace dxvk::wsi { + static WsiDriver* s_driver = nullptr; + static int s_refcount = 0; void init() { + if (s_refcount++ > 0) + return; + + s_driver = platformCreateWsiDriver(); + if (s_driver == nullptr) + throw DxvkError("Failed to initialize WSI."); } void quit() { + if (s_refcount == 0) + return; + + s_refcount--; + if (s_refcount == 0) { + delete s_driver; + s_driver = nullptr; + } + } + + std::vector getInstanceExtensions() { + return s_driver->getInstanceExtensions(); + } + + void getWindowSize( + HWND hWindow, + uint32_t* pWidth, + uint32_t* pHeight) { + s_driver->getWindowSize(hWindow, pWidth, pHeight); + } + + void resizeWindow( + HWND hWindow, + DxvkWindowState* pState, + uint32_t width, + uint32_t height) { + s_driver->resizeWindow(hWindow, pState, width, height); + } + + bool setWindowMode( + HMONITOR hMonitor, + HWND hWindow, + const WsiMode& mode) { + return s_driver->setWindowMode(hMonitor, hWindow, mode); + } + + bool enterFullscreenMode( + HMONITOR hMonitor, + HWND hWindow, + DxvkWindowState* pState, + [[maybe_unused]] + bool modeSwitch) { + return s_driver->enterFullscreenMode(hMonitor, hWindow, pState, modeSwitch); + } + + bool leaveFullscreenMode( + HWND hWindow, + DxvkWindowState* pState, + bool restoreCoordinates) { + return s_driver->leaveFullscreenMode(hWindow, pState, restoreCoordinates); + } + + bool restoreDisplayMode() { + return s_driver->restoreDisplayMode(); + } + + HMONITOR getWindowMonitor(HWND hWindow) { + return s_driver->getWindowMonitor(hWindow); + } + + bool isWindow(HWND hWindow) { + return s_driver->isWindow(hWindow); + } + + void updateFullscreenWindow( + HMONITOR hMonitor, + HWND hWindow, + bool forceTopmost) { + s_driver->updateFullscreenWindow(hMonitor, hWindow, forceTopmost); + } + + VkResult createSurface( + HWND hWindow, + PFN_vkGetInstanceProcAddr pfnVkGetInstanceProcAddr, + VkInstance instance, + VkSurfaceKHR* pSurface) { + return s_driver->createSurface(hWindow, pfnVkGetInstanceProcAddr, instance, pSurface); + } + + HMONITOR getDefaultMonitor() { + return s_driver->getDefaultMonitor(); + } + + HMONITOR enumMonitors(uint32_t index) { + return s_driver->enumMonitors(index); + } + + HMONITOR enumMonitors(const LUID *adapterLUID[], uint32_t numLUIDs, uint32_t index) { + return s_driver->enumMonitors(adapterLUID, numLUIDs, index); + } + + bool getDisplayName( + HMONITOR hMonitor, + WCHAR (&Name)[32]) { + return s_driver->getDisplayName(hMonitor, Name); + } + + bool getDesktopCoordinates( + HMONITOR hMonitor, + RECT* pRect) { + return s_driver->getDesktopCoordinates(hMonitor, pRect); + } + + bool getDisplayMode( + HMONITOR hMonitor, + uint32_t modeNumber, + WsiMode* pMode) { + return s_driver->getDisplayMode(hMonitor, modeNumber, pMode); + } + + bool getCurrentDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode) { + return s_driver->getCurrentDisplayMode(hMonitor, pMode); + } + + bool getDesktopDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode) { + return s_driver->getDesktopDisplayMode(hMonitor, pMode); + } + + WsiEdidData getMonitorEdid(HMONITOR hMonitor) { + return s_driver->getMonitorEdid(hMonitor); } } diff --git a/src/wsi/wsi_platform.h b/src/wsi/wsi_platform.h index 7ccecc27..f8373fe5 100644 --- a/src/wsi/wsi_platform.h +++ b/src/wsi/wsi_platform.h @@ -1,19 +1,100 @@ #pragma once -#if defined(DXVK_WSI_WIN32) -#include "win32/wsi_platform_win32.h" -#elif defined(DXVK_WSI_SDL2) -#include "sdl2/wsi_platform_sdl2.h" -#elif defined(DXVK_WSI_GLFW) -#include "glfw/wsi_platform_glfw.h" -#endif +#include "wsi_window.h" #include namespace dxvk::wsi { + class WsiDriver { + public: + virtual ~WsiDriver() { + } + + // Platform + virtual std::vector getInstanceExtensions() = 0; + + // Monitor + virtual HMONITOR getDefaultMonitor() = 0; + + virtual HMONITOR enumMonitors(uint32_t index) = 0; + + virtual HMONITOR enumMonitors(const LUID *adapterLUID[], uint32_t numLUIDs, uint32_t index) = 0; + + virtual bool getDisplayName( + HMONITOR hMonitor, + WCHAR (&Name)[32]) = 0; + + virtual bool getDesktopCoordinates( + HMONITOR hMonitor, + RECT* pRect) = 0; + + virtual bool getDisplayMode( + HMONITOR hMonitor, + uint32_t modeNumber, + WsiMode* pMode) = 0; + + virtual bool getCurrentDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode) = 0; + + virtual bool getDesktopDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode) = 0; + + virtual WsiEdidData getMonitorEdid(HMONITOR hMonitor) = 0; + + // Window + + virtual void getWindowSize( + HWND hWindow, + uint32_t* pWidth, + uint32_t* pWeight) = 0; + + virtual void resizeWindow( + HWND hWindow, + DxvkWindowState* pState, + uint32_t width, + uint32_t weight) = 0; + + virtual bool setWindowMode( + HMONITOR hMonitor, + HWND hWindow, + const WsiMode& mode) = 0; + + virtual bool enterFullscreenMode( + HMONITOR hMonitor, + HWND hWindow, + DxvkWindowState* pState, + [[maybe_unused]] + bool modeSwitch) = 0; + + virtual bool leaveFullscreenMode( + HWND hWindow, + DxvkWindowState* pState, + bool restoreCoordinates) = 0; + + virtual bool restoreDisplayMode() = 0; + + virtual HMONITOR getWindowMonitor(HWND hWindow) = 0; + + virtual bool isWindow(HWND hWindow) = 0; + + virtual void updateFullscreenWindow( + HMONITOR hMonitor, + HWND hWindow, + bool forceTopmost) = 0; + + virtual VkResult createSurface( + HWND hWindow, + PFN_vkGetInstanceProcAddr pfnVkGetInstanceProcAddr, + VkInstance instance, + VkSurfaceKHR* pSurface) = 0; + }; + void init(); void quit(); std::vector getInstanceExtensions(); + WsiDriver* platformCreateWsiDriver(); } diff --git a/src/wsi/wsi_window.h b/src/wsi/wsi_window.h index e0587a0f..68c6db9c 100644 --- a/src/wsi/wsi_window.h +++ b/src/wsi/wsi_window.h @@ -3,12 +3,22 @@ #include #include "wsi_monitor.h" -#include "wsi_platform.h" #include "../vulkan/vulkan_loader.h" 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 }; +#endif + }; + /** * \brief The size of the window *