mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-21 22:54:16 +01:00
native: Add SDL3 WSI
Co-authored-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
This commit is contained in:
parent
0259f55285
commit
469025d234
@ -186,7 +186,7 @@ This is primarily useful for game and application ports to either avoid having t
|
|||||||
DXVK Native replaces certain Windows-isms with a platform and framework-agnostic replacement, for example, `HWND`s can become `SDL_Window*`s, etc.
|
DXVK Native replaces certain Windows-isms with a platform and framework-agnostic replacement, for example, `HWND`s can become `SDL_Window*`s, etc.
|
||||||
All it takes to do that is to add another WSI backend.
|
All it takes to do that is to add another WSI backend.
|
||||||
|
|
||||||
**Note:** DXVK Native requires a backend to be explicitly set via the `DXVK_WSI_DRIVER` environment variable. The current built-in options are `SDL2` and `GLFW`.
|
**Note:** DXVK Native requires a backend to be explicitly set via the `DXVK_WSI_DRIVER` environment variable. The current built-in options are `SDL3`, `SDL2`, and `GLFW`.
|
||||||
|
|
||||||
DXVK Native comes with a slim set of Windows header definitions required for D3D9/11 and the MinGW headers for D3D9/11.
|
DXVK Native comes with a slim set of Windows header definitions required for D3D9/11 and the MinGW headers for D3D9/11.
|
||||||
In most cases, it will end up being plug and play with your renderer, but there may be certain teething issues such as:
|
In most cases, it will end up being plug and play with your renderer, but there may be certain teething issues such as:
|
||||||
|
@ -13,6 +13,7 @@ install_subdir(
|
|||||||
|
|
||||||
install_headers(
|
install_headers(
|
||||||
'wsi/native_wsi.h',
|
'wsi/native_wsi.h',
|
||||||
|
'wsi/native_sdl3.h',
|
||||||
'wsi/native_sdl2.h',
|
'wsi/native_sdl2.h',
|
||||||
'wsi/native_glfw.h',
|
'wsi/native_glfw.h',
|
||||||
subdir: 'dxvk/wsi',
|
subdir: 'dxvk/wsi',
|
||||||
|
25
include/native/wsi/native_sdl3.h
Normal file
25
include/native/wsi/native_sdl3.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
namespace dxvk::wsi {
|
||||||
|
|
||||||
|
inline SDL_Window* fromHwnd(HWND hWindow) {
|
||||||
|
return reinterpret_cast<SDL_Window*>(hWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline HWND toHwnd(SDL_Window* pWindow) {
|
||||||
|
return reinterpret_cast<HWND>(pWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Offset so null HMONITORs go to -1
|
||||||
|
inline SDL_DisplayID fromHmonitor(HMONITOR hMonitor) {
|
||||||
|
return SDL_DisplayID(reinterpret_cast<uintptr_t>(hMonitor));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Offset so -1 display id goes to 0 == NULL
|
||||||
|
inline HMONITOR toHmonitor(SDL_DisplayID display) {
|
||||||
|
return reinterpret_cast<HMONITOR>(uintptr_t(display));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#ifdef DXVK_WSI_WIN32
|
#ifdef DXVK_WSI_WIN32
|
||||||
#error You shouldnt be using this code path.
|
#error You shouldnt be using this code path.
|
||||||
|
#elif DXVK_WSI_SDL3
|
||||||
|
#include "wsi/native_sdl3.h"
|
||||||
#elif DXVK_WSI_SDL2
|
#elif DXVK_WSI_SDL2
|
||||||
#include "wsi/native_sdl2.h"
|
#include "wsi/native_sdl2.h"
|
||||||
#elif DXVK_WSI_GLFW
|
#elif DXVK_WSI_GLFW
|
||||||
|
@ -148,16 +148,20 @@ else
|
|||||||
'./include/native/directx'
|
'./include/native/directx'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
lib_sdl3 = dependency('SDL3', required: false)
|
||||||
lib_sdl2 = dependency('SDL2', required: false)
|
lib_sdl2 = dependency('SDL2', required: false)
|
||||||
lib_glfw = dependency('glfw', required: false)
|
lib_glfw = dependency('glfw', required: false)
|
||||||
|
if lib_sdl3.found()
|
||||||
|
compiler_args += ['-DDXVK_WSI_SDL3']
|
||||||
|
endif
|
||||||
if lib_sdl2.found()
|
if lib_sdl2.found()
|
||||||
compiler_args += ['-DDXVK_WSI_SDL2']
|
compiler_args += ['-DDXVK_WSI_SDL2']
|
||||||
endif
|
endif
|
||||||
if lib_glfw.found()
|
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())
|
if (not lib_sdl3.found() and not lib_sdl2.found() and not lib_glfw.found())
|
||||||
error('SDL2 or GLFW are required to build dxvk-native')
|
error('SDL3, SDL2, or GLFW are required to build dxvk-native')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
dxvk_name_prefix = 'dxvk_'
|
dxvk_name_prefix = 'dxvk_'
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "../wsi_monitor.h"
|
#include "../wsi_monitor.h"
|
||||||
|
|
||||||
#include "wsi/native_wsi.h"
|
#include "wsi/native_glfw.h"
|
||||||
#include "wsi_platform_glfw.h"
|
#include "wsi_platform_glfw.h"
|
||||||
|
|
||||||
#include "../../util/util_string.h"
|
#include "../../util/util_string.h"
|
||||||
|
@ -4,6 +4,9 @@ wsi_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',
|
||||||
|
'sdl3/wsi_monitor_sdl3.cpp',
|
||||||
|
'sdl3/wsi_platform_sdl3.cpp',
|
||||||
|
'sdl3/wsi_window_sdl3.cpp',
|
||||||
'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',
|
||||||
@ -16,6 +19,7 @@ wsi_deps = [ dep_displayinfo ]
|
|||||||
|
|
||||||
if platform != 'windows'
|
if platform != 'windows'
|
||||||
wsi_deps += [
|
wsi_deps += [
|
||||||
|
lib_sdl3.partial_dependency(compile_args: true, includes: true),
|
||||||
lib_sdl2.partial_dependency(compile_args: true, includes: true),
|
lib_sdl2.partial_dependency(compile_args: true, includes: true),
|
||||||
lib_glfw.partial_dependency(compile_args: true, includes: true),
|
lib_glfw.partial_dependency(compile_args: true, includes: true),
|
||||||
]
|
]
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "../wsi_monitor.h"
|
#include "../wsi_monitor.h"
|
||||||
|
|
||||||
#include "wsi/native_wsi.h"
|
#include "wsi/native_sdl2.h"
|
||||||
#include "wsi_platform_sdl2.h"
|
#include "wsi_platform_sdl2.h"
|
||||||
|
|
||||||
#include "../../util/util_string.h"
|
#include "../../util/util_string.h"
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "../../util/util_string.h"
|
#include "../../util/util_string.h"
|
||||||
#include "../../util/util_win32_compat.h"
|
#include "../../util/util_win32_compat.h"
|
||||||
|
|
||||||
#include <SDL2/SDL_vulkan.h>
|
#include <SDL_vulkan.h>
|
||||||
|
|
||||||
namespace dxvk::wsi {
|
namespace dxvk::wsi {
|
||||||
|
|
||||||
|
157
src/wsi/sdl3/wsi_monitor_sdl3.cpp
Normal file
157
src/wsi/sdl3/wsi_monitor_sdl3.cpp
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
#if defined(DXVK_WSI_SDL3)
|
||||||
|
|
||||||
|
#include "../wsi_monitor.h"
|
||||||
|
|
||||||
|
#include "wsi/native_sdl3.h"
|
||||||
|
#include "wsi_platform_sdl3.h"
|
||||||
|
|
||||||
|
#include "../../util/util_string.h"
|
||||||
|
#include "../../util/log/log.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
|
namespace dxvk::wsi {
|
||||||
|
|
||||||
|
HMONITOR Sdl3WsiDriver::getDefaultMonitor() {
|
||||||
|
return enumMonitors(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HMONITOR Sdl3WsiDriver::enumMonitors(uint32_t index) {
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
SDL_DisplayID* displays = SDL_GetDisplays(&count);
|
||||||
|
|
||||||
|
HMONITOR result = displays && int(index) < count
|
||||||
|
? toHmonitor(displays[index])
|
||||||
|
: nullptr;
|
||||||
|
|
||||||
|
SDL_free(displays);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HMONITOR Sdl3WsiDriver::enumMonitors(const LUID *adapterLUID[], uint32_t numLUIDs, uint32_t index) {
|
||||||
|
return enumMonitors(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Sdl3WsiDriver::getDisplayName(
|
||||||
|
HMONITOR hMonitor,
|
||||||
|
WCHAR (&Name)[32]) {
|
||||||
|
SDL_DisplayID displayId = fromHmonitor(hMonitor);
|
||||||
|
|
||||||
|
if (!displayId)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::wstringstream nameStream;
|
||||||
|
nameStream << LR"(\\.\DISPLAY)" << displayId;
|
||||||
|
|
||||||
|
std::wstring name = nameStream.str();
|
||||||
|
|
||||||
|
std::memset(Name, 0, sizeof(Name));
|
||||||
|
name.copy(Name, name.length(), 0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Sdl3WsiDriver::getDesktopCoordinates(
|
||||||
|
HMONITOR hMonitor,
|
||||||
|
RECT* pRect) {
|
||||||
|
SDL_DisplayID displayId = fromHmonitor(hMonitor);
|
||||||
|
|
||||||
|
if (!displayId)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SDL_Rect rect = { };
|
||||||
|
SDL_GetDisplayBounds(displayId, &rect);
|
||||||
|
|
||||||
|
pRect->left = rect.x;
|
||||||
|
pRect->top = rect.y;
|
||||||
|
pRect->right = rect.x + rect.w;
|
||||||
|
pRect->bottom = rect.y + rect.h;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Sdl3WsiDriver::getDisplayMode(
|
||||||
|
HMONITOR hMonitor,
|
||||||
|
uint32_t ModeNumber,
|
||||||
|
WsiMode* pMode) {
|
||||||
|
SDL_DisplayID displayId = fromHmonitor(hMonitor);
|
||||||
|
|
||||||
|
if (!displayId)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
auto* modes = SDL_GetFullscreenDisplayModes(displayId, &count);
|
||||||
|
|
||||||
|
if (!modes) {
|
||||||
|
Logger::err(str::format("SDL_GetFullscreenDisplayModes: ", SDL_GetError()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (int(ModeNumber) >= count) {
|
||||||
|
SDL_free(modes);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
convertMode(*modes[ModeNumber], pMode);
|
||||||
|
|
||||||
|
SDL_free(modes);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Sdl3WsiDriver::getCurrentDisplayMode(
|
||||||
|
HMONITOR hMonitor,
|
||||||
|
WsiMode* pMode) {
|
||||||
|
SDL_DisplayID displayId = fromHmonitor(hMonitor);
|
||||||
|
|
||||||
|
if (!displayId)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto* mode = SDL_GetCurrentDisplayMode(displayId);
|
||||||
|
|
||||||
|
if (!mode) {
|
||||||
|
Logger::err(str::format("SDL_GetCurrentDisplayMode: ", SDL_GetError()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
convertMode(*mode, pMode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Sdl3WsiDriver::getDesktopDisplayMode(
|
||||||
|
HMONITOR hMonitor,
|
||||||
|
WsiMode* pMode) {
|
||||||
|
SDL_DisplayID displayId = fromHmonitor(hMonitor);
|
||||||
|
|
||||||
|
if (!displayId)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto* mode = SDL_GetDesktopDisplayMode(displayId);
|
||||||
|
|
||||||
|
if (!mode) {
|
||||||
|
Logger::err(str::format("SDL_GetDesktopDisplayMode: ", SDL_GetError()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
convertMode(*mode, pMode);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<uint8_t> Sdl3WsiDriver::getMonitorEdid(HMONITOR hMonitor) {
|
||||||
|
Logger::err("getMonitorEdid not implemented on this platform.");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
78
src/wsi/sdl3/wsi_platform_sdl3.cpp
Normal file
78
src/wsi/sdl3/wsi_platform_sdl3.cpp
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#if defined(DXVK_WSI_SDL3)
|
||||||
|
|
||||||
|
#include "wsi_platform_sdl3.h"
|
||||||
|
#include "../../util/util_error.h"
|
||||||
|
#include "../../util/util_string.h"
|
||||||
|
#include "../../util/util_win32_compat.h"
|
||||||
|
|
||||||
|
#include <SDL3/SDL_vulkan.h>
|
||||||
|
|
||||||
|
namespace dxvk::wsi {
|
||||||
|
|
||||||
|
Sdl3WsiDriver::Sdl3WsiDriver() {
|
||||||
|
libsdl = LoadLibraryA( // FIXME: Get soname as string from meson
|
||||||
|
#if defined(_WIN32)
|
||||||
|
"SDL3.dll"
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
"libSDL3.0.dylib"
|
||||||
|
#else
|
||||||
|
"libSDL3.so.0"
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
if (libsdl == nullptr)
|
||||||
|
throw DxvkError("SDL3 WSI: Failed to load SDL3 DLL.");
|
||||||
|
|
||||||
|
#define SDL_PROC(ret, name, params) \
|
||||||
|
name = reinterpret_cast<pfn_##name>(GetProcAddress(libsdl, #name)); \
|
||||||
|
if (name == nullptr) { \
|
||||||
|
FreeLibrary(libsdl); \
|
||||||
|
libsdl = nullptr; \
|
||||||
|
throw DxvkError("SDL3 WSI: Failed to load " #name "."); \
|
||||||
|
}
|
||||||
|
#include "wsi_platform_sdl3_funcs.h"
|
||||||
|
|
||||||
|
if (!SDL_InitSubSystem(SDL_INIT_VIDEO))
|
||||||
|
throw DxvkError("SDL3 WSI: Failed to initialize video subsystem."); \
|
||||||
|
}
|
||||||
|
|
||||||
|
Sdl3WsiDriver::~Sdl3WsiDriver() {
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||||
|
FreeLibrary(libsdl);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<const char *> Sdl3WsiDriver::getInstanceExtensions() {
|
||||||
|
if (!SDL_Vulkan_LoadLibrary(nullptr))
|
||||||
|
throw DxvkError(str::format("SDL3 WSI: Failed to load Vulkan library: ", SDL_GetError()));
|
||||||
|
|
||||||
|
uint32_t extensionCount = 0;
|
||||||
|
auto extensions = SDL_Vulkan_GetInstanceExtensions(&extensionCount);
|
||||||
|
|
||||||
|
if (!extensions)
|
||||||
|
throw DxvkError(str::format("SDL3 WSI: Failed to get instance extensions: ", SDL_GetError()));
|
||||||
|
|
||||||
|
std::vector<const char*> result(extensionCount);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < extensionCount; i++)
|
||||||
|
result[i] = extensions[i];
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool createSdl3WsiDriver(WsiDriver **driver) {
|
||||||
|
try {
|
||||||
|
*driver = new Sdl3WsiDriver();
|
||||||
|
} catch (const DxvkError& e) {
|
||||||
|
Logger::err(str::format(e.message()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
WsiBootstrap Sdl3WSI = {
|
||||||
|
"SDL3",
|
||||||
|
createSdl3WsiDriver
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
120
src/wsi/sdl3/wsi_platform_sdl3.h
Normal file
120
src/wsi/sdl3/wsi_platform_sdl3.h
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include "../wsi_platform.h"
|
||||||
|
|
||||||
|
#include "../util/util_bit.h"
|
||||||
|
|
||||||
|
namespace dxvk::wsi {
|
||||||
|
|
||||||
|
class Sdl3WsiDriver : public WsiDriver {
|
||||||
|
private:
|
||||||
|
HMODULE libsdl;
|
||||||
|
#define SDL_PROC(ret, name, params) \
|
||||||
|
typedef ret (SDLCALL *pfn_##name) params; \
|
||||||
|
pfn_##name name;
|
||||||
|
#include "wsi_platform_sdl3_funcs.h"
|
||||||
|
|
||||||
|
static void convertMode(const SDL_DisplayMode& mode, WsiMode* pMode) {
|
||||||
|
pMode->width = uint32_t(mode.w);
|
||||||
|
pMode->height = uint32_t(mode.h);
|
||||||
|
pMode->refreshRate = WsiRational {
|
||||||
|
uint32_t(mode.refresh_rate_numerator),
|
||||||
|
uint32_t(mode.refresh_rate_denominator) };
|
||||||
|
// BPP should always be a power of two
|
||||||
|
// to match Windows behaviour of including padding.
|
||||||
|
pMode->bitsPerPixel = (uint32_t(-1) >> bit::lzcnt(uint32_t(SDL_BITSPERPIXEL(mode.format) - 1u))) + 1u;
|
||||||
|
pMode->interlaced = false;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
Sdl3WsiDriver();
|
||||||
|
~Sdl3WsiDriver();
|
||||||
|
|
||||||
|
// Platform
|
||||||
|
virtual std::vector<const char *> 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,
|
||||||
|
DxvkWindowState* pState,
|
||||||
|
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 bool isMinimized(HWND hWindow);
|
||||||
|
|
||||||
|
virtual bool isOccluded(HWND hWindow);
|
||||||
|
|
||||||
|
virtual void updateFullscreenWindow(
|
||||||
|
HMONITOR hMonitor,
|
||||||
|
HWND hWindow,
|
||||||
|
bool forceTopmost);
|
||||||
|
|
||||||
|
virtual VkResult createSurface(
|
||||||
|
HWND hWindow,
|
||||||
|
PFN_vkGetInstanceProcAddr pfnVkGetInstanceProcAddr,
|
||||||
|
VkInstance instance,
|
||||||
|
VkSurfaceKHR* pSurface);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
22
src/wsi/sdl3/wsi_platform_sdl3_funcs.h
Normal file
22
src/wsi/sdl3/wsi_platform_sdl3_funcs.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
SDL_PROC(const char*, SDL_GetError, (void))
|
||||||
|
SDL_PROC(SDL_DisplayID*, SDL_GetDisplays, (int*))
|
||||||
|
SDL_PROC(bool, SDL_GetDisplayBounds, (SDL_DisplayID, SDL_Rect*))
|
||||||
|
SDL_PROC(bool, SDL_GetDisplayUsableBounds, (SDL_DisplayID, SDL_Rect*))
|
||||||
|
SDL_PROC(SDL_DisplayMode*, SDL_GetCurrentDisplayMode, (SDL_DisplayID))
|
||||||
|
SDL_PROC(SDL_DisplayMode*, SDL_GetDesktopDisplayMode, (SDL_DisplayID))
|
||||||
|
SDL_PROC(SDL_DisplayMode**, SDL_GetFullscreenDisplayModes, (SDL_DisplayID, int*))
|
||||||
|
SDL_PROC(bool, SDL_GetClosestFullscreenDisplayMode, (SDL_DisplayID, int, int, float, bool, SDL_DisplayMode*))
|
||||||
|
SDL_PROC(SDL_DisplayID, SDL_GetDisplayForWindow, (SDL_Window*))
|
||||||
|
SDL_PROC(SDL_WindowFlags, SDL_GetWindowFlags, (SDL_Window *))
|
||||||
|
SDL_PROC(bool, SDL_GetWindowSize, (SDL_Window*, int*, int*))
|
||||||
|
SDL_PROC(bool, SDL_SetWindowSize, (SDL_Window*, int, int))
|
||||||
|
SDL_PROC(bool, SDL_SetWindowPosition, (SDL_Window*, int, int))
|
||||||
|
SDL_PROC(bool, SDL_SetWindowFullscreen, (SDL_Window*, bool))
|
||||||
|
SDL_PROC(bool, SDL_SetWindowFullscreenMode, (SDL_Window*, const SDL_DisplayMode*))
|
||||||
|
SDL_PROC(char const* const*, SDL_Vulkan_GetInstanceExtensions, (Uint32*))
|
||||||
|
SDL_PROC(bool, SDL_Vulkan_CreateSurface, (SDL_Window*, VkInstance, const VkAllocationCallbacks*, VkSurfaceKHR*))
|
||||||
|
SDL_PROC(bool, SDL_Vulkan_LoadLibrary, (const char*))
|
||||||
|
SDL_PROC(void, SDL_free, (void*))
|
||||||
|
SDL_PROC(bool, SDL_InitSubSystem, (SDL_InitFlags))
|
||||||
|
SDL_PROC(void, SDL_QuitSubSystem, (SDL_InitFlags))
|
||||||
|
#undef SDL_PROC
|
177
src/wsi/sdl3/wsi_window_sdl3.cpp
Normal file
177
src/wsi/sdl3/wsi_window_sdl3.cpp
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
#if defined(DXVK_WSI_SDL3)
|
||||||
|
|
||||||
|
#include "../wsi_window.h"
|
||||||
|
|
||||||
|
#include "native/wsi/native_sdl3.h"
|
||||||
|
#include "wsi_platform_sdl3.h"
|
||||||
|
|
||||||
|
#include "../../util/util_string.h"
|
||||||
|
#include "../../util/log/log.h"
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <SDL3/SDL_vulkan.h>
|
||||||
|
|
||||||
|
namespace dxvk::wsi {
|
||||||
|
|
||||||
|
void Sdl3WsiDriver::getWindowSize(
|
||||||
|
HWND hWindow,
|
||||||
|
uint32_t* pWidth,
|
||||||
|
uint32_t* pHeight) {
|
||||||
|
SDL_Window* window = fromHwnd(hWindow);
|
||||||
|
|
||||||
|
int w = 0;
|
||||||
|
int h = 0;
|
||||||
|
|
||||||
|
if (!SDL_GetWindowSize(window, &w, &h))
|
||||||
|
Logger::err(str::format("SDL3 WSI: SDL_GetWindowSize: ", SDL_GetError()));
|
||||||
|
|
||||||
|
if (pWidth)
|
||||||
|
*pWidth = uint32_t(w);
|
||||||
|
|
||||||
|
if (pHeight)
|
||||||
|
*pHeight = uint32_t(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Sdl3WsiDriver::resizeWindow(
|
||||||
|
HWND hWindow,
|
||||||
|
DxvkWindowState* pState,
|
||||||
|
uint32_t Width,
|
||||||
|
uint32_t Height) {
|
||||||
|
SDL_Window* window = fromHwnd(hWindow);
|
||||||
|
|
||||||
|
if (!SDL_SetWindowSize(window, int32_t(Width), int32_t(Height)))
|
||||||
|
Logger::err(str::format("SDL3 WSI: SDL_SetWindowSize: ", SDL_GetError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Sdl3WsiDriver::setWindowMode(
|
||||||
|
HMONITOR hMonitor,
|
||||||
|
HWND hWindow,
|
||||||
|
DxvkWindowState* pState,
|
||||||
|
const WsiMode& pMode) {
|
||||||
|
SDL_DisplayID displayId = fromHmonitor(hMonitor);
|
||||||
|
|
||||||
|
if (!displayId)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
pState->sdl3.fullscreenMode = pMode;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool Sdl3WsiDriver::enterFullscreenMode(
|
||||||
|
HMONITOR hMonitor,
|
||||||
|
HWND hWindow,
|
||||||
|
DxvkWindowState* pState,
|
||||||
|
bool ModeSwitch) {
|
||||||
|
SDL_DisplayID displayId = fromHmonitor(hMonitor);
|
||||||
|
SDL_Window* window = fromHwnd(hWindow);
|
||||||
|
|
||||||
|
if (!displayId)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SDL_Rect bounds = { };
|
||||||
|
|
||||||
|
if (!SDL_GetDisplayUsableBounds(displayId, &bounds)) {
|
||||||
|
Logger::err(str::format("SDL3 WSI: enterFullscreenMode: SDL_GetDisplayUsableBounds: ", SDL_GetError()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SDL_SetWindowPosition(window, bounds.x, bounds.y)) {
|
||||||
|
Logger::err(str::format("SDL3 WSI: enterFullscreenMode: SDL_SetWindowPosition: ", SDL_GetError()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_DisplayMode closestMode = { };
|
||||||
|
|
||||||
|
if (ModeSwitch) {
|
||||||
|
const auto& mode = pState->sdl3.fullscreenMode;
|
||||||
|
|
||||||
|
if (!SDL_GetClosestFullscreenDisplayMode(displayId, mode.width, mode.height,
|
||||||
|
float(mode.refreshRate.numerator) / float(mode.refreshRate.denominator), true, &closestMode)) {
|
||||||
|
Logger::err(str::format("SDL3 WSI: enterFullscreenMode: SDL_GetClosestFullscreenDisplayMode: ", SDL_GetError()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SDL_SetWindowFullscreenMode(window, ModeSwitch ? &closestMode : nullptr)) {
|
||||||
|
Logger::err(str::format("SDL3 WSI: enterFullscreenMode: SDL_SetWindowFullscreenMode: ", SDL_GetError()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SDL_SetWindowFullscreen(window, true)) {
|
||||||
|
Logger::err(str::format("SDL3 WSI: enterFullscreenMode: SDL_SetWindowFullscreen: ", SDL_GetError()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Sdl3WsiDriver::leaveFullscreenMode(
|
||||||
|
HWND hWindow,
|
||||||
|
DxvkWindowState* pState,
|
||||||
|
bool restoreCoordinates) {
|
||||||
|
SDL_Window* window = fromHwnd(hWindow);
|
||||||
|
|
||||||
|
if (!SDL_SetWindowFullscreen(window, false)) {
|
||||||
|
Logger::err(str::format("SDL3 WSI: leaveFullscreenMode: SDL_SetWindowFullscreen: ", SDL_GetError()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Sdl3WsiDriver::restoreDisplayMode() {
|
||||||
|
// Don't need to do anything with SDL3 here.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HMONITOR Sdl3WsiDriver::getWindowMonitor(HWND hWindow) {
|
||||||
|
return toHmonitor(SDL_GetDisplayForWindow(fromHwnd(hWindow)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Sdl3WsiDriver::isWindow(HWND hWindow) {
|
||||||
|
SDL_Window* window = fromHwnd(hWindow);
|
||||||
|
return window != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Sdl3WsiDriver::isMinimized(HWND hWindow) {
|
||||||
|
SDL_Window* window = fromHwnd(hWindow);
|
||||||
|
return (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Sdl3WsiDriver::isOccluded(HWND hWindow) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Sdl3WsiDriver::updateFullscreenWindow(
|
||||||
|
HMONITOR hMonitor,
|
||||||
|
HWND hWindow,
|
||||||
|
bool forceTopmost) {
|
||||||
|
// Don't need to do anything with SDL3 here.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VkResult Sdl3WsiDriver::createSurface(
|
||||||
|
HWND hWindow,
|
||||||
|
PFN_vkGetInstanceProcAddr pfnVkGetInstanceProcAddr,
|
||||||
|
VkInstance instance,
|
||||||
|
VkSurfaceKHR* pSurface) {
|
||||||
|
SDL_Window* window = fromHwnd(hWindow);
|
||||||
|
|
||||||
|
return SDL_Vulkan_CreateSurface(window, instance, nullptr, pSurface)
|
||||||
|
? VK_SUCCESS : VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -12,6 +12,9 @@ namespace dxvk::wsi {
|
|||||||
#if defined(DXVK_WSI_WIN32)
|
#if defined(DXVK_WSI_WIN32)
|
||||||
&Win32WSI,
|
&Win32WSI,
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(DXVK_WSI_SDL3)
|
||||||
|
&Sdl3WSI,
|
||||||
|
#endif
|
||||||
#if defined(DXVK_WSI_SDL2)
|
#if defined(DXVK_WSI_SDL2)
|
||||||
&Sdl2WSI,
|
&Sdl2WSI,
|
||||||
#endif
|
#endif
|
||||||
|
@ -105,6 +105,9 @@ namespace dxvk::wsi {
|
|||||||
#if defined(DXVK_WSI_WIN32)
|
#if defined(DXVK_WSI_WIN32)
|
||||||
extern WsiBootstrap Win32WSI;
|
extern WsiBootstrap Win32WSI;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(DXVK_WSI_SDL3)
|
||||||
|
extern WsiBootstrap Sdl3WSI;
|
||||||
|
#endif
|
||||||
#if defined(DXVK_WSI_SDL2)
|
#if defined(DXVK_WSI_SDL2)
|
||||||
extern WsiBootstrap Sdl2WSI;
|
extern WsiBootstrap Sdl2WSI;
|
||||||
#endif
|
#endif
|
||||||
|
@ -19,6 +19,11 @@ namespace dxvk::wsi {
|
|||||||
RECT rect = { 0, 0, 0, 0 };
|
RECT rect = { 0, 0, 0, 0 };
|
||||||
} win;
|
} win;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(DXVK_WSI_SDL3)
|
||||||
|
struct {
|
||||||
|
WsiMode fullscreenMode = { };
|
||||||
|
} sdl3;
|
||||||
|
#endif
|
||||||
#if defined(DXVK_WSI_SDL2)
|
#if defined(DXVK_WSI_SDL2)
|
||||||
// Nothing to store
|
// Nothing to store
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user