mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 19:54:19 +01:00
[native] Dynamically load SDL2/GLFW at runtime.
Removing these link-time dependencies is important for making a single binary that is compatible with either backend, regardless of whether or not each one is currently available to the program.
This commit is contained in:
parent
0f7c1f753a
commit
10b83d184b
@ -1,9 +1,37 @@
|
||||
#include "wsi_platform_glfw.h"
|
||||
#include "../../util/util_error.h"
|
||||
#include "../../util/util_string.h"
|
||||
#include "../../util/util_win32_compat.h"
|
||||
|
||||
namespace dxvk::wsi {
|
||||
|
||||
GlfwWsiDriver::GlfwWsiDriver() {
|
||||
libglfw = LoadLibraryA( // FIXME: Get soname as string from meson
|
||||
#if defined(_WIN32)
|
||||
"glfw.dll"
|
||||
#elif defined(__APPLE__)
|
||||
"libglfw.3.dylib"
|
||||
#else
|
||||
"libglfw.so.3"
|
||||
#endif
|
||||
);
|
||||
if (libglfw == nullptr)
|
||||
throw DxvkError("GLFW WSI: Failed to load GLFW DLL.");
|
||||
|
||||
#define GLFW_PROC(ret, name, params) \
|
||||
name = reinterpret_cast<pfn_##name>(GetProcAddress(libglfw, #name)); \
|
||||
if (name == nullptr) { \
|
||||
FreeLibrary(libglfw); \
|
||||
libglfw = nullptr; \
|
||||
throw DxvkError("GLFW WSI: Failed to load " #name "."); \
|
||||
}
|
||||
#include "wsi_platform_glfw_funcs.h"
|
||||
}
|
||||
|
||||
GlfwWsiDriver::~GlfwWsiDriver() {
|
||||
FreeLibrary(libglfw);
|
||||
}
|
||||
|
||||
std::vector<const char *> GlfwWsiDriver::getInstanceExtensions() {
|
||||
if (!glfwVulkanSupported())
|
||||
throw DxvkError(str::format("GLFW WSI: Vulkan is not supported in any capacity!"));
|
||||
|
@ -8,7 +8,24 @@
|
||||
namespace dxvk::wsi {
|
||||
|
||||
class GlfwWsiDriver : public WsiDriver {
|
||||
private:
|
||||
HMODULE libglfw;
|
||||
#define GLFW_PROC(ret, name, params) \
|
||||
typedef ret (*pfn_##name) params; \
|
||||
pfn_##name name;
|
||||
#include "wsi_platform_glfw_funcs.h"
|
||||
|
||||
inline bool isDisplayValid(int32_t displayId) {
|
||||
int32_t displayCount = 0;
|
||||
glfwGetMonitors(&displayCount);
|
||||
|
||||
return displayId < displayCount && displayId >= 0;
|
||||
}
|
||||
|
||||
public:
|
||||
GlfwWsiDriver();
|
||||
~GlfwWsiDriver();
|
||||
|
||||
// Platform
|
||||
virtual std::vector<const char *> getInstanceExtensions();
|
||||
|
||||
@ -89,12 +106,5 @@ namespace dxvk::wsi {
|
||||
VkInstance instance,
|
||||
VkSurfaceKHR* pSurface);
|
||||
};
|
||||
|
||||
inline bool isDisplayValid(int32_t displayId) {
|
||||
int32_t displayCount = 0;
|
||||
glfwGetMonitors(&displayCount);
|
||||
|
||||
return displayId < displayCount && displayId >= 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
12
src/wsi/glfw/wsi_platform_glfw_funcs.h
Normal file
12
src/wsi/glfw/wsi_platform_glfw_funcs.h
Normal file
@ -0,0 +1,12 @@
|
||||
GLFW_PROC(VkResult, glfwCreateWindowSurface, (VkInstance, GLFWwindow*, const VkAllocationCallbacks*, VkSurfaceKHR*))
|
||||
GLFW_PROC(GLFWmonitor**, glfwGetMonitors, (int*))
|
||||
GLFW_PROC(void, glfwGetMonitorWorkarea, (GLFWmonitor*, int*, int*, int*, int*))
|
||||
GLFW_PROC(GLFWmonitor*, glfwGetPrimaryMonitor, (void))
|
||||
GLFW_PROC(const char**, glfwGetRequiredInstanceExtensions, (uint32_t*))
|
||||
GLFW_PROC(const GLFWvidmode*, glfwGetVideoMode, (GLFWmonitor*))
|
||||
GLFW_PROC(const GLFWvidmode*, glfwGetVideoModes, (GLFWmonitor*, int*))
|
||||
GLFW_PROC(void, glfwGetWindowSize, (GLFWwindow*, int*, int*))
|
||||
GLFW_PROC(void, glfwSetWindowMonitor, (GLFWwindow*, GLFWmonitor*, int, int, int, int, int))
|
||||
GLFW_PROC(void, glfwSetWindowSize, (GLFWwindow*, int, int))
|
||||
GLFW_PROC(int, glfwVulkanSupported, (void))
|
||||
#undef GLFW_PROC
|
@ -23,16 +23,14 @@ wsi_glfw_src = [
|
||||
|
||||
if dxvk_wsi == 'win32'
|
||||
wsi_src = wsi_common_src + wsi_win32_src
|
||||
wsi_deps = [ dep_displayinfo ]
|
||||
elif dxvk_wsi == 'sdl2'
|
||||
wsi_src = wsi_common_src + wsi_sdl2_src
|
||||
wsi_deps = [ dep_displayinfo, lib_sdl2 ]
|
||||
elif dxvk_wsi == 'glfw'
|
||||
wsi_src = wsi_common_src + wsi_glfw_src
|
||||
wsi_deps = [ dep_displayinfo, lib_glfw ]
|
||||
else
|
||||
error('Unknown wsi')
|
||||
endif
|
||||
wsi_deps = [ dep_displayinfo ]
|
||||
|
||||
wsi_lib = static_library('wsi', wsi_src,
|
||||
dependencies : wsi_deps,
|
||||
|
@ -1,11 +1,39 @@
|
||||
#include "wsi_platform_sdl2.h"
|
||||
#include "../../util/util_error.h"
|
||||
#include "../../util/util_string.h"
|
||||
#include "../../util/util_win32_compat.h"
|
||||
|
||||
#include <SDL2/SDL_vulkan.h>
|
||||
|
||||
namespace dxvk::wsi {
|
||||
|
||||
Sdl2WsiDriver::Sdl2WsiDriver() {
|
||||
libsdl = LoadLibraryA( // FIXME: Get soname as string from meson
|
||||
#if defined(_WIN32)
|
||||
"SDL2.dll"
|
||||
#elif defined(__APPLE__)
|
||||
"libSDL2-2.0.0.dylib"
|
||||
#else
|
||||
"libSDL2-2.0.so.0"
|
||||
#endif
|
||||
);
|
||||
if (libsdl == nullptr)
|
||||
throw DxvkError("SDL2 WSI: Failed to load SDL2 DLL.");
|
||||
|
||||
#define SDL_PROC(ret, name, params) \
|
||||
name = reinterpret_cast<pfn_##name>(GetProcAddress(libsdl, #name)); \
|
||||
if (name == nullptr) { \
|
||||
FreeLibrary(libsdl); \
|
||||
libsdl = nullptr; \
|
||||
throw DxvkError("SDL2 WSI: Failed to load " #name "."); \
|
||||
}
|
||||
#include "wsi_platform_sdl2_funcs.h"
|
||||
}
|
||||
|
||||
Sdl2WsiDriver::~Sdl2WsiDriver() {
|
||||
FreeLibrary(libsdl);
|
||||
}
|
||||
|
||||
std::vector<const char *> Sdl2WsiDriver::getInstanceExtensions() {
|
||||
SDL_Vulkan_LoadLibrary(nullptr);
|
||||
|
||||
|
@ -7,7 +7,23 @@
|
||||
namespace dxvk::wsi {
|
||||
|
||||
class Sdl2WsiDriver : public WsiDriver {
|
||||
private:
|
||||
HMODULE libsdl;
|
||||
#define SDL_PROC(ret, name, params) \
|
||||
typedef ret (SDLCALL *pfn_##name) params; \
|
||||
pfn_##name name;
|
||||
#include "wsi_platform_sdl2_funcs.h"
|
||||
|
||||
inline bool isDisplayValid(int32_t displayId) {
|
||||
const int32_t displayCount = SDL_GetNumVideoDisplays();
|
||||
|
||||
return displayId < displayCount && displayId >= 0;
|
||||
}
|
||||
|
||||
public:
|
||||
Sdl2WsiDriver();
|
||||
~Sdl2WsiDriver();
|
||||
|
||||
// Platform
|
||||
virtual std::vector<const char *> getInstanceExtensions();
|
||||
|
||||
@ -88,11 +104,5 @@ namespace dxvk::wsi {
|
||||
VkInstance instance,
|
||||
VkSurfaceKHR* pSurface);
|
||||
};
|
||||
|
||||
inline bool isDisplayValid(int32_t displayId) {
|
||||
const int32_t displayCount = SDL_GetNumVideoDisplays();
|
||||
|
||||
return displayId < displayCount && displayId >= 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
16
src/wsi/sdl2/wsi_platform_sdl2_funcs.h
Normal file
16
src/wsi/sdl2/wsi_platform_sdl2_funcs.h
Normal file
@ -0,0 +1,16 @@
|
||||
SDL_PROC(SDL_DisplayMode*, SDL_GetClosestDisplayMode, (int, const SDL_DisplayMode*, SDL_DisplayMode*))
|
||||
SDL_PROC(int, SDL_GetCurrentDisplayMode, (int, SDL_DisplayMode*))
|
||||
SDL_PROC(int, SDL_GetDesktopDisplayMode, (int, SDL_DisplayMode*))
|
||||
SDL_PROC(int, SDL_GetDisplayBounds, (int, SDL_Rect*))
|
||||
SDL_PROC(int, SDL_GetDisplayMode, (int, int, SDL_DisplayMode*))
|
||||
SDL_PROC(const char*, SDL_GetError, (void))
|
||||
SDL_PROC(int, SDL_GetNumVideoDisplays, (void))
|
||||
SDL_PROC(int, SDL_GetWindowDisplayIndex, (SDL_Window*))
|
||||
SDL_PROC(int, SDL_SetWindowDisplayMode, (SDL_Window*, const SDL_DisplayMode*))
|
||||
SDL_PROC(int, SDL_SetWindowFullscreen, (SDL_Window*, Uint32))
|
||||
SDL_PROC(void, SDL_GetWindowSize, (SDL_Window*, int*, int*))
|
||||
SDL_PROC(void, SDL_SetWindowSize, (SDL_Window*, int, int))
|
||||
SDL_PROC(SDL_bool, SDL_Vulkan_CreateSurface, (SDL_Window*, VkInstance, VkSurfaceKHR*))
|
||||
SDL_PROC(SDL_bool, SDL_Vulkan_GetInstanceExtensions, (SDL_Window*, unsigned int*, const char**))
|
||||
SDL_PROC(int, SDL_Vulkan_LoadLibrary, (const char*))
|
||||
#undef SDL_PROC
|
Loading…
x
Reference in New Issue
Block a user