mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-12 04:54:17 +01:00
[wsi] Add SDL2 implementation
This commit is contained in:
parent
191d54e210
commit
e6fb3e1509
@ -3,9 +3,17 @@ wsi_win32_src = [
|
|||||||
'win32/wsi_window_win32.cpp',
|
'win32/wsi_window_win32.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
wsi_sdl2_src = [
|
||||||
|
'sdl2/wsi_monitor_sdl2.cpp',
|
||||||
|
'sdl2/wsi_window_sdl2.cpp',
|
||||||
|
]
|
||||||
|
|
||||||
if dxvk_wsi == 'win32'
|
if dxvk_wsi == 'win32'
|
||||||
wsi_src = wsi_win32_src
|
wsi_src = wsi_win32_src
|
||||||
wsi_deps = []
|
wsi_deps = []
|
||||||
|
elif dxvk_wsi == 'sdl2'
|
||||||
|
wsi_src = wsi_sdl2_src
|
||||||
|
wsi_deps = [ lib_sdl2 ]
|
||||||
else
|
else
|
||||||
error('Unknown wsi')
|
error('Unknown wsi')
|
||||||
endif
|
endif
|
||||||
|
147
src/wsi/sdl2/wsi_monitor_sdl2.cpp
Normal file
147
src/wsi/sdl2/wsi_monitor_sdl2.cpp
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
#include "../wsi_monitor.h"
|
||||||
|
|
||||||
|
#include "wsi/native_wsi.h"
|
||||||
|
#include "wsi_platform_sdl2.h"
|
||||||
|
|
||||||
|
#include "../../util/util_string.h"
|
||||||
|
#include "../../util/log/log.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
|
namespace dxvk::wsi {
|
||||||
|
|
||||||
|
HMONITOR getDefaultMonitor() {
|
||||||
|
return enumMonitors(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HMONITOR enumMonitors(uint32_t index) {
|
||||||
|
return isDisplayValid(int32_t(index))
|
||||||
|
? toHmonitor(index)
|
||||||
|
: nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getDisplayName(
|
||||||
|
HMONITOR hMonitor,
|
||||||
|
WCHAR (&Name)[32]) {
|
||||||
|
const int32_t displayId = fromHmonitor(hMonitor);
|
||||||
|
|
||||||
|
if (!isDisplayValid(displayId))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::wstringstream nameStream;
|
||||||
|
nameStream << LR"(\\.\DISPLAY)" << (displayId + 1);
|
||||||
|
|
||||||
|
std::wstring name = nameStream.str();
|
||||||
|
|
||||||
|
std::memset(Name, 0, sizeof(Name));
|
||||||
|
name.copy(Name, name.length(), 0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool getDesktopCoordinates(
|
||||||
|
HMONITOR hMonitor,
|
||||||
|
RECT* pRect) {
|
||||||
|
const int32_t displayId = fromHmonitor(hMonitor);
|
||||||
|
|
||||||
|
if (!isDisplayValid(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline uint32_t roundToNextPow2(uint32_t num) {
|
||||||
|
if (num-- == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
num |= num >> 1; num |= num >> 2;
|
||||||
|
num |= num >> 4; num |= num >> 8;
|
||||||
|
num |= num >> 16;
|
||||||
|
|
||||||
|
return ++num;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline 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) * 1000, 1000 };
|
||||||
|
// BPP should always be a power of two
|
||||||
|
// to match Windows behaviour of including padding.
|
||||||
|
pMode->bitsPerPixel = roundToNextPow2(SDL_BITSPERPIXEL(mode.format));
|
||||||
|
pMode->interlaced = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool getDisplayMode(
|
||||||
|
HMONITOR hMonitor,
|
||||||
|
uint32_t ModeNumber,
|
||||||
|
WsiMode* pMode) {
|
||||||
|
const int32_t displayId = fromHmonitor(hMonitor);
|
||||||
|
|
||||||
|
if (!isDisplayValid(displayId))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SDL_DisplayMode mode = { };
|
||||||
|
if (SDL_GetDisplayMode(displayId, ModeNumber, &mode) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
convertMode(mode, pMode);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool getCurrentDisplayMode(
|
||||||
|
HMONITOR hMonitor,
|
||||||
|
WsiMode* pMode) {
|
||||||
|
const int32_t displayId = fromHmonitor(hMonitor);
|
||||||
|
|
||||||
|
if (!isDisplayValid(displayId))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SDL_DisplayMode mode = { };
|
||||||
|
if (SDL_GetCurrentDisplayMode(displayId, &mode) != 0) {
|
||||||
|
Logger::err(str::format("SDL_GetCurrentDisplayMode: ", SDL_GetError()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
convertMode(mode, pMode);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool getDesktopDisplayMode(
|
||||||
|
HMONITOR hMonitor,
|
||||||
|
WsiMode* pMode) {
|
||||||
|
const int32_t displayId = fromHmonitor(hMonitor);
|
||||||
|
|
||||||
|
if (!isDisplayValid(displayId))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SDL_DisplayMode mode = { };
|
||||||
|
if (SDL_GetDesktopDisplayMode(displayId, &mode) != 0) {
|
||||||
|
Logger::err(str::format("SDL_GetCurrentDisplayMode: ", SDL_GetError()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
convertMode(mode, pMode);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
21
src/wsi/sdl2/wsi_platform_sdl2.h
Normal file
21
src/wsi/sdl2/wsi_platform_sdl2.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
#include "../wsi_monitor.h"
|
||||||
|
|
||||||
|
namespace dxvk::wsi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Impl-dependent state
|
||||||
|
*/
|
||||||
|
struct DxvkWindowState {
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool isDisplayValid(int32_t displayId) {
|
||||||
|
const int32_t displayCount = SDL_GetNumVideoDisplays();
|
||||||
|
|
||||||
|
return displayId < displayCount && displayId >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
155
src/wsi/sdl2/wsi_window_sdl2.cpp
Normal file
155
src/wsi/sdl2/wsi_window_sdl2.cpp
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
#include "../wsi_window.h"
|
||||||
|
|
||||||
|
#include "native/wsi/native_wsi.h"
|
||||||
|
#include "wsi_platform_sdl2.h"
|
||||||
|
|
||||||
|
#include "../../util/util_string.h"
|
||||||
|
#include "../../util/log/log.h"
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <SDL2/SDL_vulkan.h>
|
||||||
|
|
||||||
|
namespace dxvk::wsi {
|
||||||
|
|
||||||
|
void getWindowSize(
|
||||||
|
HWND hWindow,
|
||||||
|
uint32_t* pWidth,
|
||||||
|
uint32_t* pHeight) {
|
||||||
|
SDL_Window* window = fromHwnd(hWindow);
|
||||||
|
|
||||||
|
int32_t w, h;
|
||||||
|
SDL_GetWindowSize(window, &w, &h);
|
||||||
|
|
||||||
|
if (pWidth)
|
||||||
|
*pWidth = uint32_t(w);
|
||||||
|
|
||||||
|
if (pHeight)
|
||||||
|
*pHeight = uint32_t(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void resizeWindow(
|
||||||
|
HWND hWindow,
|
||||||
|
DxvkWindowState* pState,
|
||||||
|
uint32_t Width,
|
||||||
|
uint32_t Height) {
|
||||||
|
SDL_Window* window = fromHwnd(hWindow);
|
||||||
|
|
||||||
|
SDL_SetWindowSize(window, int32_t(Width), int32_t(Height));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool setWindowMode(
|
||||||
|
HMONITOR hMonitor,
|
||||||
|
HWND hWindow,
|
||||||
|
const WsiMode& pMode) {
|
||||||
|
const int32_t displayId = fromHmonitor(hMonitor);
|
||||||
|
SDL_Window* window = fromHwnd(hWindow);
|
||||||
|
|
||||||
|
if (!isDisplayValid(displayId))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SDL_DisplayMode wantedMode = { };
|
||||||
|
wantedMode.w = pMode.width;
|
||||||
|
wantedMode.h = pMode.height;
|
||||||
|
wantedMode.refresh_rate = pMode.refreshRate.numerator != 0
|
||||||
|
? pMode.refreshRate.numerator / pMode.refreshRate.denominator
|
||||||
|
: 0;
|
||||||
|
// TODO: Implement lookup format for bitsPerPixel here.
|
||||||
|
|
||||||
|
SDL_DisplayMode mode = { };
|
||||||
|
if (SDL_GetClosestDisplayMode(displayId, &wantedMode, &mode) == nullptr) {
|
||||||
|
Logger::err(str::format("SDL2 WSI: setWindowMode: SDL_GetClosestDisplayMode: ", SDL_GetError()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDL_SetWindowDisplayMode(window, &mode) != 0) {
|
||||||
|
Logger::err(str::format("SDL2 WSI: setWindowMode: SDL_SetWindowDisplayMode: ", SDL_GetError()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool enterFullscreenMode(
|
||||||
|
HMONITOR hMonitor,
|
||||||
|
HWND hWindow,
|
||||||
|
DxvkWindowState* pState,
|
||||||
|
bool ModeSwitch) {
|
||||||
|
const int32_t displayId = fromHmonitor(hMonitor);
|
||||||
|
SDL_Window* window = fromHwnd(hWindow);
|
||||||
|
|
||||||
|
if (!isDisplayValid(displayId))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint32_t flags = ModeSwitch
|
||||||
|
? SDL_WINDOW_FULLSCREEN
|
||||||
|
: SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||||
|
|
||||||
|
// TODO: Set this on the correct monitor.
|
||||||
|
// Docs aren't clear on this...
|
||||||
|
if (SDL_SetWindowFullscreen(window, flags) != 0) {
|
||||||
|
Logger::err(str::format("SDL2 WSI: enterFullscreenMode: SDL_SetWindowFullscreen: ", SDL_GetError()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool leaveFullscreenMode(
|
||||||
|
HWND hWindow,
|
||||||
|
DxvkWindowState* pState) {
|
||||||
|
SDL_Window* window = fromHwnd(hWindow);
|
||||||
|
|
||||||
|
if (SDL_SetWindowFullscreen(window, 0) != 0) {
|
||||||
|
Logger::err(str::format("SDL2 WSI: leaveFullscreenMode: SDL_SetWindowFullscreen: ", SDL_GetError()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool restoreDisplayMode() {
|
||||||
|
// Don't need to do anything with SDL2 here.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HMONITOR getWindowMonitor(HWND hWindow) {
|
||||||
|
SDL_Window* window = fromHwnd(hWindow);
|
||||||
|
const int32_t displayId = SDL_GetWindowDisplayIndex(window);
|
||||||
|
|
||||||
|
return toHmonitor(displayId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool isWindow(HWND hWindow) {
|
||||||
|
SDL_Window* window = fromHwnd(hWindow);
|
||||||
|
return window != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void updateFullscreenWindow(
|
||||||
|
HMONITOR hMonitor,
|
||||||
|
HWND hWindow,
|
||||||
|
bool forceTopmost) {
|
||||||
|
// Don't need to do anything with SDL2 here.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VkResult createSurface(
|
||||||
|
HWND hWindow,
|
||||||
|
const Rc<vk::InstanceFn>& vki,
|
||||||
|
VkSurfaceKHR* pSurface) {
|
||||||
|
SDL_Window* window = fromHwnd(hWindow);
|
||||||
|
|
||||||
|
return SDL_Vulkan_CreateSurface(window, vki->instance(), pSurface)
|
||||||
|
? VK_SUCCESS
|
||||||
|
: VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef DXVK_WSI_WIN32
|
#if defined(DXVK_WSI_WIN32)
|
||||||
#include "win32/wsi_platform_win32.h"
|
#include "win32/wsi_platform_win32.h"
|
||||||
|
#elif defined(DXVK_WSI_SDL2)
|
||||||
|
#include "sdl2/wsi_platform_sdl2.h"
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user