mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-04-27 21:01:37 +00:00
Wayland support.
This commit is contained in:
parent
bacfe02d0e
commit
ddda801d47
9 changed files with 102 additions and 13 deletions
|
|
@ -272,6 +272,10 @@ if (SWA_D3D12)
|
||||||
target_compile_definitions(UnleashedRecomp PRIVATE SWA_D3D12)
|
target_compile_definitions(UnleashedRecomp PRIVATE SWA_D3D12)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
|
target_compile_definitions(UnleashedRecomp PRIVATE SDL_VULKAN_ENABLED)
|
||||||
|
endif()
|
||||||
|
|
||||||
find_package(directx-dxc REQUIRED)
|
find_package(directx-dxc REQUIRED)
|
||||||
|
|
||||||
if (SWA_D3D12)
|
if (SWA_D3D12)
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,18 @@
|
||||||
typedef struct _NSWindow NSWindow;
|
typedef struct _NSWindow NSWindow;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SDL_VULKAN_ENABLED
|
||||||
|
#include <SDL_vulkan.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace plume {
|
namespace plume {
|
||||||
#if defined(_WIN64)
|
#if defined(_WIN64)
|
||||||
// Native HWND handle to the target window.
|
// Native HWND handle to the target window.
|
||||||
typedef HWND RenderWindow;
|
typedef HWND RenderWindow;
|
||||||
#elif defined(__ANDROID__)
|
#elif defined(__ANDROID__)
|
||||||
typedef ANativeWindow* RenderWindow;
|
typedef ANativeWindow* RenderWindow;
|
||||||
|
#elif defined(SDL_VULKAN_ENABLED)
|
||||||
|
typedef SDL_Window *RenderWindow;
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
struct RenderWindow {
|
struct RenderWindow {
|
||||||
Display* display;
|
Display* display;
|
||||||
|
|
|
||||||
|
|
@ -1989,6 +1989,13 @@ namespace plume {
|
||||||
fprintf(stderr, "vkCreateWin32SurfaceKHR failed with error code 0x%X.\n", res);
|
fprintf(stderr, "vkCreateWin32SurfaceKHR failed with error code 0x%X.\n", res);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
# elif defined(SDL_VULKAN_ENABLED)
|
||||||
|
VulkanInterface *renderInterface = commandQueue->device->renderInterface;
|
||||||
|
SDL_bool sdlRes = SDL_Vulkan_CreateSurface(renderWindow, renderInterface->instance, &surface);
|
||||||
|
if (sdlRes == SDL_FALSE) {
|
||||||
|
fprintf(stderr, "SDL_Vulkan_CreateSurface failed with error %s.\n", SDL_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
# elif defined(__ANDROID__)
|
# elif defined(__ANDROID__)
|
||||||
assert(renderWindow != nullptr);
|
assert(renderWindow != nullptr);
|
||||||
VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo = {};
|
VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo = {};
|
||||||
|
|
@ -2312,6 +2319,8 @@ namespace plume {
|
||||||
GetClientRect(renderWindow, &rect);
|
GetClientRect(renderWindow, &rect);
|
||||||
dstWidth = rect.right - rect.left;
|
dstWidth = rect.right - rect.left;
|
||||||
dstHeight = rect.bottom - rect.top;
|
dstHeight = rect.bottom - rect.top;
|
||||||
|
# elif defined(SDL_VULKAN_ENABLED)
|
||||||
|
SDL_GetWindowSize(renderWindow, (int *)(&dstWidth), (int *)(&dstHeight));
|
||||||
# elif defined(__ANDROID__)
|
# elif defined(__ANDROID__)
|
||||||
dstWidth = ANativeWindow_getWidth(renderWindow);
|
dstWidth = ANativeWindow_getWidth(renderWindow);
|
||||||
dstHeight = ANativeWindow_getHeight(renderWindow);
|
dstHeight = ANativeWindow_getHeight(renderWindow);
|
||||||
|
|
@ -4073,7 +4082,11 @@ namespace plume {
|
||||||
|
|
||||||
// VulkanInterface
|
// VulkanInterface
|
||||||
|
|
||||||
|
#if SDL_VULKAN_ENABLED
|
||||||
|
VulkanInterface::VulkanInterface(RenderWindow sdlWindow) {
|
||||||
|
#else
|
||||||
VulkanInterface::VulkanInterface() {
|
VulkanInterface::VulkanInterface() {
|
||||||
|
#endif
|
||||||
VkResult res = volkInitialize();
|
VkResult res = volkInitialize();
|
||||||
if (res != VK_SUCCESS) {
|
if (res != VK_SUCCESS) {
|
||||||
fprintf(stderr, "volkInitialize failed with error code 0x%X.\n", res);
|
fprintf(stderr, "volkInitialize failed with error code 0x%X.\n", res);
|
||||||
|
|
@ -4100,11 +4113,31 @@ namespace plume {
|
||||||
std::vector<VkExtensionProperties> availableExtensions(extensionCount);
|
std::vector<VkExtensionProperties> availableExtensions(extensionCount);
|
||||||
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, availableExtensions.data());
|
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, availableExtensions.data());
|
||||||
|
|
||||||
std::unordered_set<std::string> missingRequiredExtensions = RequiredInstanceExtensions;
|
std::unordered_set<std::string> requiredExtensions = RequiredInstanceExtensions;
|
||||||
std::unordered_set<std::string> supportedOptionalExtensions;
|
std::unordered_set<std::string> supportedOptionalExtensions;
|
||||||
# if DLSS_ENABLED
|
# if DLSS_ENABLED
|
||||||
const std::unordered_set<std::string> dlssExtensions = DLSS::getRequiredInstanceExtensionsVulkan();
|
const std::unordered_set<std::string> dlssExtensions = DLSS::getRequiredInstanceExtensionsVulkan();
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# if SDL_VULKAN_ENABLED
|
||||||
|
// Push the extensions specified by SDL as required.
|
||||||
|
// SDL2 has this awkward requirement for the window to pull the extensions from.
|
||||||
|
// This can be removed when upgrading to SDL3.
|
||||||
|
if (sdlWindow != nullptr) {
|
||||||
|
uint32_t sdlVulkanExtensionCount = 0;
|
||||||
|
if (SDL_Vulkan_GetInstanceExtensions(sdlWindow, &sdlVulkanExtensionCount, nullptr)) {
|
||||||
|
std::vector<char *> sdlVulkanExtensions;
|
||||||
|
sdlVulkanExtensions.resize(sdlVulkanExtensionCount);
|
||||||
|
if (SDL_Vulkan_GetInstanceExtensions(sdlWindow, &sdlVulkanExtensionCount, (const char **)(sdlVulkanExtensions.data()))) {
|
||||||
|
for (char *sdlVulkanExtension : sdlVulkanExtensions) {
|
||||||
|
requiredExtensions.insert(sdlVulkanExtension);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
std::unordered_set<std::string> missingRequiredExtensions = requiredExtensions;
|
||||||
for (uint32_t i = 0; i < extensionCount; i++) {
|
for (uint32_t i = 0; i < extensionCount; i++) {
|
||||||
const std::string extensionName(availableExtensions[i].extensionName);
|
const std::string extensionName(availableExtensions[i].extensionName);
|
||||||
missingRequiredExtensions.erase(extensionName);
|
missingRequiredExtensions.erase(extensionName);
|
||||||
|
|
@ -4129,7 +4162,7 @@ namespace plume {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const char *> enabledExtensions;
|
std::vector<const char *> enabledExtensions;
|
||||||
for (const std::string &extension : RequiredInstanceExtensions) {
|
for (const std::string &extension : requiredExtensions) {
|
||||||
enabledExtensions.push_back(extension.c_str());
|
enabledExtensions.push_back(extension.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4192,8 +4225,15 @@ namespace plume {
|
||||||
|
|
||||||
// Global creation function.
|
// Global creation function.
|
||||||
|
|
||||||
|
#if SDL_VULKAN_ENABLED
|
||||||
|
std::unique_ptr<RenderInterface> CreateVulkanInterface(RenderWindow sdlWindow) {
|
||||||
|
std::unique_ptr<VulkanInterface> createdInterface = std::make_unique<VulkanInterface>(sdlWindow);
|
||||||
|
return createdInterface->isValid() ? std::move(createdInterface) : nullptr;
|
||||||
|
}
|
||||||
|
#else
|
||||||
std::unique_ptr<RenderInterface> CreateVulkanInterface() {
|
std::unique_ptr<RenderInterface> CreateVulkanInterface() {
|
||||||
std::unique_ptr<VulkanInterface> createdInterface = std::make_unique<VulkanInterface>();
|
std::unique_ptr<VulkanInterface> createdInterface = std::make_unique<VulkanInterface>();
|
||||||
return createdInterface->isValid() ? std::move(createdInterface) : nullptr;
|
return createdInterface->isValid() ? std::move(createdInterface) : nullptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -422,7 +422,12 @@ namespace plume {
|
||||||
VkApplicationInfo appInfo = {};
|
VkApplicationInfo appInfo = {};
|
||||||
RenderInterfaceCapabilities capabilities;
|
RenderInterfaceCapabilities capabilities;
|
||||||
|
|
||||||
|
# if SDL_VULKAN_ENABLED
|
||||||
|
VulkanInterface(RenderWindow sdlWindow);
|
||||||
|
# else
|
||||||
VulkanInterface();
|
VulkanInterface();
|
||||||
|
# endif
|
||||||
|
|
||||||
~VulkanInterface() override;
|
~VulkanInterface() override;
|
||||||
std::unique_ptr<RenderDevice> createDevice() override;
|
std::unique_ptr<RenderDevice> createDevice() override;
|
||||||
const RenderInterfaceCapabilities &getCapabilities() const override;
|
const RenderInterfaceCapabilities &getCapabilities() const override;
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,11 @@ namespace plume
|
||||||
#ifdef SWA_D3D12
|
#ifdef SWA_D3D12
|
||||||
extern std::unique_ptr<RenderInterface> CreateD3D12Interface();
|
extern std::unique_ptr<RenderInterface> CreateD3D12Interface();
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef SDL_VULKAN_ENABLED
|
||||||
|
extern std::unique_ptr<RenderInterface> CreateVulkanInterface(RenderWindow sdlWindow);
|
||||||
|
#else
|
||||||
extern std::unique_ptr<RenderInterface> CreateVulkanInterface();
|
extern std::unique_ptr<RenderInterface> CreateVulkanInterface();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
|
@ -1306,7 +1310,7 @@ static void CreateImGuiBackend()
|
||||||
|
|
||||||
static void BeginCommandList();
|
static void BeginCommandList();
|
||||||
|
|
||||||
void Video::CreateHostDevice()
|
void Video::CreateHostDevice(bool sdlVideoDefault)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < 16; i++)
|
for (uint32_t i = 0; i < 16; i++)
|
||||||
g_inputSlots[i].index = i;
|
g_inputSlots[i].index = i;
|
||||||
|
|
@ -1314,7 +1318,7 @@ void Video::CreateHostDevice()
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
|
|
||||||
GameWindow::Init();
|
GameWindow::Init(sdlVideoDefault);
|
||||||
|
|
||||||
#ifdef SWA_D3D12
|
#ifdef SWA_D3D12
|
||||||
g_vulkan = DetectWine() || Config::GraphicsAPI == EGraphicsAPI::Vulkan;
|
g_vulkan = DetectWine() || Config::GraphicsAPI == EGraphicsAPI::Vulkan;
|
||||||
|
|
@ -1322,11 +1326,16 @@ void Video::CreateHostDevice()
|
||||||
|
|
||||||
LoadEmbeddedResources();
|
LoadEmbeddedResources();
|
||||||
|
|
||||||
#ifdef SWA_D3D12
|
if (g_vulkan)
|
||||||
g_interface = g_vulkan ? CreateVulkanInterface() : CreateD3D12Interface();
|
#ifdef SDL_VULKAN_ENABLED
|
||||||
|
g_interface = CreateVulkanInterface(GameWindow::s_renderWindow);
|
||||||
#else
|
#else
|
||||||
g_interface = CreateVulkanInterface();
|
g_interface = CreateVulkanInterface();
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef SWA_D3D12
|
||||||
|
else
|
||||||
|
g_interface = CreateD3D12Interface();
|
||||||
|
#endif
|
||||||
|
|
||||||
g_device = g_interface->createDevice();
|
g_device = g_interface->createDevice();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ using namespace plume;
|
||||||
|
|
||||||
struct Video
|
struct Video
|
||||||
{
|
{
|
||||||
static void CreateHostDevice();
|
static void CreateHostDevice(bool sdlVideoDefault);
|
||||||
static void HostPresent();
|
static void HostPresent();
|
||||||
static void StartPipelinePrecompilation();
|
static void StartPipelinePrecompilation();
|
||||||
static void WaitForGPU();
|
static void WaitForGPU();
|
||||||
|
|
|
||||||
|
|
@ -145,10 +145,12 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
bool forceInstaller = false;
|
bool forceInstaller = false;
|
||||||
bool forceDLCInstaller = false;
|
bool forceDLCInstaller = false;
|
||||||
|
bool sdlVideoDefault = false;
|
||||||
for (uint32_t i = 1; i < argc; i++)
|
for (uint32_t i = 1; i < argc; i++)
|
||||||
{
|
{
|
||||||
forceInstaller = forceInstaller || (strcmp(argv[i], "--install") == 0);
|
forceInstaller = forceInstaller || (strcmp(argv[i], "--install") == 0);
|
||||||
forceDLCInstaller = forceDLCInstaller || (strcmp(argv[i], "--install-dlc") == 0);
|
forceDLCInstaller = forceDLCInstaller || (strcmp(argv[i], "--install-dlc") == 0);
|
||||||
|
sdlVideoDefault = sdlVideoDefault || (strcmp(argv[i], "--sdl-video-default") == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Config::Load();
|
Config::Load();
|
||||||
|
|
@ -159,7 +161,7 @@ int main(int argc, char *argv[])
|
||||||
bool runInstallerWizard = forceInstaller || forceDLCInstaller || !isGameInstalled;
|
bool runInstallerWizard = forceInstaller || forceDLCInstaller || !isGameInstalled;
|
||||||
if (runInstallerWizard)
|
if (runInstallerWizard)
|
||||||
{
|
{
|
||||||
Video::CreateHostDevice();
|
Video::CreateHostDevice(sdlVideoDefault);
|
||||||
|
|
||||||
if (!InstallerWizard::Run(GAME_INSTALL_DIRECTORY, isGameInstalled && forceDLCInstaller))
|
if (!InstallerWizard::Run(GAME_INSTALL_DIRECTORY, isGameInstalled && forceDLCInstaller))
|
||||||
{
|
{
|
||||||
|
|
@ -175,7 +177,7 @@ int main(int argc, char *argv[])
|
||||||
uint32_t entry = LdrLoadModule(std::u8string_view((const char8_t*)(modulePath)));
|
uint32_t entry = LdrLoadModule(std::u8string_view((const char8_t*)(modulePath)));
|
||||||
|
|
||||||
if (!runInstallerWizard)
|
if (!runInstallerWizard)
|
||||||
Video::CreateHostDevice();
|
Video::CreateHostDevice(sdlVideoDefault);
|
||||||
|
|
||||||
Video::StartPipelinePrecompilation();
|
Video::StartPipelinePrecompilation();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -147,9 +147,26 @@ int Window_OnSDLEvent(void*, SDL_Event* event)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameWindow::Init()
|
void GameWindow::Init(bool sdlVideoDefault)
|
||||||
{
|
{
|
||||||
SDL_InitSubSystem(SDL_INIT_VIDEO);
|
#ifdef __linux__
|
||||||
|
if (!sdlVideoDefault)
|
||||||
|
{
|
||||||
|
int videoRes = SDL_VideoInit("wayland");
|
||||||
|
if (videoRes != 0)
|
||||||
|
SDL_VideoInit(nullptr);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SDL_VideoInit(nullptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char* videoDriverName = SDL_GetCurrentVideoDriver();
|
||||||
|
if (videoDriverName != nullptr)
|
||||||
|
fmt::println("SDL Video Driver: {}", videoDriverName);
|
||||||
|
|
||||||
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
|
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
|
||||||
SDL_AddEventWatch(Window_OnSDLEvent, s_pWindow);
|
SDL_AddEventWatch(Window_OnSDLEvent, s_pWindow);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
@ -185,6 +202,8 @@ void GameWindow::Init()
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
s_renderWindow = info.info.win.window;
|
s_renderWindow = info.info.win.window;
|
||||||
SetDarkTitleBar(true);
|
SetDarkTitleBar(true);
|
||||||
|
#elif defined(SDL_VULKAN_ENABLED)
|
||||||
|
s_renderWindow = s_pWindow;
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
s_renderWindow = { info.info.x11.display, info.info.x11.window };
|
s_renderWindow = { info.info.x11.display, info.info.x11.window };
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,10 @@ public:
|
||||||
if (Config::Fullscreen)
|
if (Config::Fullscreen)
|
||||||
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||||
|
|
||||||
|
#ifdef SDL_VULKAN_ENABLED
|
||||||
|
flags |= SDL_WINDOW_VULKAN;
|
||||||
|
#endif
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -299,6 +303,6 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Init();
|
static void Init(bool sdlVideoDefault);
|
||||||
static void Update();
|
static void Update();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue