mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-04-28 05:11:37 +00:00
Wayland support. (#55)
This commit is contained in:
parent
bacfe02d0e
commit
68343a574c
9 changed files with 102 additions and 13 deletions
|
|
@ -272,6 +272,10 @@ if (SWA_D3D12)
|
|||
target_compile_definitions(UnleashedRecomp PRIVATE SWA_D3D12)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
target_compile_definitions(UnleashedRecomp PRIVATE SDL_VULKAN_ENABLED)
|
||||
endif()
|
||||
|
||||
find_package(directx-dxc REQUIRED)
|
||||
|
||||
if (SWA_D3D12)
|
||||
|
|
|
|||
|
|
@ -29,12 +29,18 @@
|
|||
typedef struct _NSWindow NSWindow;
|
||||
#endif
|
||||
|
||||
#ifdef SDL_VULKAN_ENABLED
|
||||
#include <SDL_vulkan.h>
|
||||
#endif
|
||||
|
||||
namespace plume {
|
||||
#if defined(_WIN64)
|
||||
// Native HWND handle to the target window.
|
||||
typedef HWND RenderWindow;
|
||||
#elif defined(__ANDROID__)
|
||||
typedef ANativeWindow* RenderWindow;
|
||||
#elif defined(SDL_VULKAN_ENABLED)
|
||||
typedef SDL_Window *RenderWindow;
|
||||
#elif defined(__linux__)
|
||||
struct RenderWindow {
|
||||
Display* display;
|
||||
|
|
|
|||
|
|
@ -1989,6 +1989,13 @@ namespace plume {
|
|||
fprintf(stderr, "vkCreateWin32SurfaceKHR failed with error code 0x%X.\n", res);
|
||||
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__)
|
||||
assert(renderWindow != nullptr);
|
||||
VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo = {};
|
||||
|
|
@ -2312,6 +2319,8 @@ namespace plume {
|
|||
GetClientRect(renderWindow, &rect);
|
||||
dstWidth = rect.right - rect.left;
|
||||
dstHeight = rect.bottom - rect.top;
|
||||
# elif defined(SDL_VULKAN_ENABLED)
|
||||
SDL_GetWindowSize(renderWindow, (int *)(&dstWidth), (int *)(&dstHeight));
|
||||
# elif defined(__ANDROID__)
|
||||
dstWidth = ANativeWindow_getWidth(renderWindow);
|
||||
dstHeight = ANativeWindow_getHeight(renderWindow);
|
||||
|
|
@ -4073,7 +4082,11 @@ namespace plume {
|
|||
|
||||
// VulkanInterface
|
||||
|
||||
#if SDL_VULKAN_ENABLED
|
||||
VulkanInterface::VulkanInterface(RenderWindow sdlWindow) {
|
||||
#else
|
||||
VulkanInterface::VulkanInterface() {
|
||||
#endif
|
||||
VkResult res = volkInitialize();
|
||||
if (res != VK_SUCCESS) {
|
||||
fprintf(stderr, "volkInitialize failed with error code 0x%X.\n", res);
|
||||
|
|
@ -4100,11 +4113,31 @@ namespace plume {
|
|||
std::vector<VkExtensionProperties> availableExtensions(extensionCount);
|
||||
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;
|
||||
# if DLSS_ENABLED
|
||||
const std::unordered_set<std::string> dlssExtensions = DLSS::getRequiredInstanceExtensionsVulkan();
|
||||
# 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++) {
|
||||
const std::string extensionName(availableExtensions[i].extensionName);
|
||||
missingRequiredExtensions.erase(extensionName);
|
||||
|
|
@ -4129,7 +4162,7 @@ namespace plume {
|
|||
}
|
||||
|
||||
std::vector<const char *> enabledExtensions;
|
||||
for (const std::string &extension : RequiredInstanceExtensions) {
|
||||
for (const std::string &extension : requiredExtensions) {
|
||||
enabledExtensions.push_back(extension.c_str());
|
||||
}
|
||||
|
||||
|
|
@ -4192,8 +4225,15 @@ namespace plume {
|
|||
|
||||
// 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<VulkanInterface> createdInterface = std::make_unique<VulkanInterface>();
|
||||
return createdInterface->isValid() ? std::move(createdInterface) : nullptr;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
|
|
|||
|
|
@ -422,7 +422,12 @@ namespace plume {
|
|||
VkApplicationInfo appInfo = {};
|
||||
RenderInterfaceCapabilities capabilities;
|
||||
|
||||
# if SDL_VULKAN_ENABLED
|
||||
VulkanInterface(RenderWindow sdlWindow);
|
||||
# else
|
||||
VulkanInterface();
|
||||
# endif
|
||||
|
||||
~VulkanInterface() override;
|
||||
std::unique_ptr<RenderDevice> createDevice() override;
|
||||
const RenderInterfaceCapabilities &getCapabilities() const override;
|
||||
|
|
|
|||
|
|
@ -83,7 +83,11 @@ namespace plume
|
|||
#ifdef SWA_D3D12
|
||||
extern std::unique_ptr<RenderInterface> CreateD3D12Interface();
|
||||
#endif
|
||||
#ifdef SDL_VULKAN_ENABLED
|
||||
extern std::unique_ptr<RenderInterface> CreateVulkanInterface(RenderWindow sdlWindow);
|
||||
#else
|
||||
extern std::unique_ptr<RenderInterface> CreateVulkanInterface();
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
|
@ -1306,7 +1310,7 @@ static void CreateImGuiBackend()
|
|||
|
||||
static void BeginCommandList();
|
||||
|
||||
void Video::CreateHostDevice()
|
||||
void Video::CreateHostDevice(bool sdlVideoDefault)
|
||||
{
|
||||
for (uint32_t i = 0; i < 16; i++)
|
||||
g_inputSlots[i].index = i;
|
||||
|
|
@ -1314,7 +1318,7 @@ void Video::CreateHostDevice()
|
|||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
|
||||
GameWindow::Init();
|
||||
GameWindow::Init(sdlVideoDefault);
|
||||
|
||||
#ifdef SWA_D3D12
|
||||
g_vulkan = DetectWine() || Config::GraphicsAPI == EGraphicsAPI::Vulkan;
|
||||
|
|
@ -1322,10 +1326,15 @@ void Video::CreateHostDevice()
|
|||
|
||||
LoadEmbeddedResources();
|
||||
|
||||
#ifdef SWA_D3D12
|
||||
g_interface = g_vulkan ? CreateVulkanInterface() : CreateD3D12Interface();
|
||||
if (g_vulkan)
|
||||
#ifdef SDL_VULKAN_ENABLED
|
||||
g_interface = CreateVulkanInterface(GameWindow::s_renderWindow);
|
||||
#else
|
||||
g_interface = CreateVulkanInterface();
|
||||
g_interface = CreateVulkanInterface();
|
||||
#endif
|
||||
#ifdef SWA_D3D12
|
||||
else
|
||||
g_interface = CreateD3D12Interface();
|
||||
#endif
|
||||
|
||||
g_device = g_interface->createDevice();
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ using namespace plume;
|
|||
|
||||
struct Video
|
||||
{
|
||||
static void CreateHostDevice();
|
||||
static void CreateHostDevice(bool sdlVideoDefault);
|
||||
static void HostPresent();
|
||||
static void StartPipelinePrecompilation();
|
||||
static void WaitForGPU();
|
||||
|
|
|
|||
|
|
@ -145,10 +145,12 @@ int main(int argc, char *argv[])
|
|||
|
||||
bool forceInstaller = false;
|
||||
bool forceDLCInstaller = false;
|
||||
bool sdlVideoDefault = false;
|
||||
for (uint32_t i = 1; i < argc; i++)
|
||||
{
|
||||
forceInstaller = forceInstaller || (strcmp(argv[i], "--install") == 0);
|
||||
forceDLCInstaller = forceDLCInstaller || (strcmp(argv[i], "--install-dlc") == 0);
|
||||
sdlVideoDefault = sdlVideoDefault || (strcmp(argv[i], "--sdl-video-default") == 0);
|
||||
}
|
||||
|
||||
Config::Load();
|
||||
|
|
@ -159,7 +161,7 @@ int main(int argc, char *argv[])
|
|||
bool runInstallerWizard = forceInstaller || forceDLCInstaller || !isGameInstalled;
|
||||
if (runInstallerWizard)
|
||||
{
|
||||
Video::CreateHostDevice();
|
||||
Video::CreateHostDevice(sdlVideoDefault);
|
||||
|
||||
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)));
|
||||
|
||||
if (!runInstallerWizard)
|
||||
Video::CreateHostDevice();
|
||||
Video::CreateHostDevice(sdlVideoDefault);
|
||||
|
||||
Video::StartPipelinePrecompilation();
|
||||
|
||||
|
|
|
|||
|
|
@ -147,9 +147,26 @@ int Window_OnSDLEvent(void*, SDL_Event* event)
|
|||
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_AddEventWatch(Window_OnSDLEvent, s_pWindow);
|
||||
#ifdef _WIN32
|
||||
|
|
@ -185,6 +202,8 @@ void GameWindow::Init()
|
|||
#if defined(_WIN32)
|
||||
s_renderWindow = info.info.win.window;
|
||||
SetDarkTitleBar(true);
|
||||
#elif defined(SDL_VULKAN_ENABLED)
|
||||
s_renderWindow = s_pWindow;
|
||||
#elif defined(__linux__)
|
||||
s_renderWindow = { info.info.x11.display, info.info.x11.window };
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -199,6 +199,10 @@ public:
|
|||
if (Config::Fullscreen)
|
||||
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
|
||||
#ifdef SDL_VULKAN_ENABLED
|
||||
flags |= SDL_WINDOW_VULKAN;
|
||||
#endif
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
|
@ -299,6 +303,6 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
static void Init();
|
||||
static void Init(bool sdlVideoDefault);
|
||||
static void Update();
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue