Linux: Add CMake find module for wayland + make wayland optional (#572)

This commit is contained in:
SSimco 2022-12-15 07:44:14 +00:00 committed by GitHub
parent aea9f5b966
commit fcab8f8f1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 64 additions and 16 deletions

View File

@ -70,6 +70,10 @@ if (APPLE)
enable_language(OBJC OBJCXX) enable_language(OBJC OBJCXX)
endif() endif()
if (UNIX AND NOT APPLE)
option(ENABLE_WAYLAND "Build with Wayland support" ON)
endif()
option(ENABLE_OPENGL "Enables the OpenGL backend" ON) option(ENABLE_OPENGL "Enables the OpenGL backend" ON)
option(ENABLE_VULKAN "Enables the Vulkan backend" ON) option(ENABLE_VULKAN "Enables the Vulkan backend" ON)
option(ENABLE_DISCORD_RPC "Enables the Discord Rich Presence feature" ON) option(ENABLE_DISCORD_RPC "Enables the Discord Rich Presence feature" ON)
@ -114,6 +118,10 @@ endif()
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)
find_package(X11 REQUIRED) find_package(X11 REQUIRED)
if (ENABLE_WAYLAND)
find_package(Wayland REQUIRED)
add_compile_definitions(HAS_WAYLAND)
endif()
find_package(GTK3 REQUIRED) find_package(GTK3 REQUIRED)
endif() endif()

14
cmake/FindWayland.cmake Normal file
View File

@ -0,0 +1,14 @@
find_package(PkgConfig)
pkg_search_module(WAYLAND_CLIENT IMPORTED_TARGET wayland-client)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Wayland
REQUIRED_VARS
WAYLAND_CLIENT_LIBRARIES
VERSION_VAR WAYLAND_CLIENT_VERSION
)
if (Wayland_FOUND)
add_library(Wayland::client ALIAS PkgConfig::WAYLAND_CLIENT)
endif()

View File

@ -27,8 +27,10 @@ elseif(UNIX)
add_compile_definitions( add_compile_definitions(
VK_USE_PLATFORM_XLIB_KHR # legacy. Do we need to support XLIB surfaces? VK_USE_PLATFORM_XLIB_KHR # legacy. Do we need to support XLIB surfaces?
VK_USE_PLATFORM_XCB_KHR VK_USE_PLATFORM_XCB_KHR
VK_USE_PLATFORM_WAYLAND_KHR
) )
if (ENABLE_WAYLAND)
add_compile_definitions(VK_USE_PLATFORM_WAYLAND_KHR)
endif()
endif() endif()
add_compile_options(-maes) add_compile_options(-maes)
# warnings # warnings

View File

@ -502,6 +502,11 @@ target_link_libraries(CemuCafe PRIVATE
zstd::zstd zstd::zstd
) )
if (ENABLE_WAYLAND)
# PUBLIC because wayland-client.h is included in VulkanAPI.h
target_link_libraries(CemuCafe PUBLIC Wayland::client)
endif()
if (ENABLE_WXWIDGETS) if (ENABLE_WXWIDGETS)
target_link_libraries(CemuCafe PRIVATE wx::base wx::core) target_link_libraries(CemuCafe PRIVATE wx::base wx::core)
endif() endif()

View File

@ -129,8 +129,10 @@ VKFUNC_DEVICE(vkCmdBindPipeline);
#if BOOST_OS_LINUX #if BOOST_OS_LINUX
VKFUNC_INSTANCE(vkCreateXlibSurfaceKHR); VKFUNC_INSTANCE(vkCreateXlibSurfaceKHR);
VKFUNC_INSTANCE(vkCreateXcbSurfaceKHR); VKFUNC_INSTANCE(vkCreateXcbSurfaceKHR);
#ifdef HAS_WAYLAND
VKFUNC_INSTANCE(vkCreateWaylandSurfaceKHR); VKFUNC_INSTANCE(vkCreateWaylandSurfaceKHR);
#endif #endif
#endif
#if BOOST_OS_WINDOWS #if BOOST_OS_WINDOWS
VKFUNC_INSTANCE(vkCreateWin32SurfaceKHR); VKFUNC_INSTANCE(vkCreateWin32SurfaceKHR);

View File

@ -110,8 +110,10 @@ std::vector<VulkanRenderer::DeviceInfo> VulkanRenderer::GetDevices()
auto backend = gui_getWindowInfo().window_main.backend; auto backend = gui_getWindowInfo().window_main.backend;
if(backend == WindowHandleInfo::Backend::X11) if(backend == WindowHandleInfo::Backend::X11)
requiredExtensions.emplace_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); requiredExtensions.emplace_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
#ifdef HAS_WAYLAND
else if (backend == WindowHandleInfo::Backend::WAYLAND) else if (backend == WindowHandleInfo::Backend::WAYLAND)
requiredExtensions.emplace_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); requiredExtensions.emplace_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
#endif
#elif BOOST_OS_MACOS #elif BOOST_OS_MACOS
requiredExtensions.emplace_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME); requiredExtensions.emplace_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME);
#endif #endif
@ -1156,8 +1158,10 @@ std::vector<const char*> VulkanRenderer::CheckInstanceExtensionSupport(FeatureCo
auto backend = gui_getWindowInfo().window_main.backend; auto backend = gui_getWindowInfo().window_main.backend;
if(backend == WindowHandleInfo::Backend::X11) if(backend == WindowHandleInfo::Backend::X11)
requiredInstanceExtensions.emplace_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); requiredInstanceExtensions.emplace_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
#if HAS_WAYLAND
else if (backend == WindowHandleInfo::Backend::WAYLAND) else if (backend == WindowHandleInfo::Backend::WAYLAND)
requiredInstanceExtensions.emplace_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); requiredInstanceExtensions.emplace_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
#endif
#elif BOOST_OS_MACOS #elif BOOST_OS_MACOS
requiredInstanceExtensions.emplace_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME); requiredInstanceExtensions.emplace_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME);
#endif #endif
@ -1275,7 +1279,7 @@ VkSurfaceKHR VulkanRenderer::CreateXcbSurface(VkInstance instance, xcb_connectio
return result; return result;
} }
#ifdef HAS_WAYLAND
VkSurfaceKHR VulkanRenderer::CreateWaylandSurface(VkInstance instance, wl_display* display, wl_surface* surface) VkSurfaceKHR VulkanRenderer::CreateWaylandSurface(VkInstance instance, wl_display* display, wl_surface* surface)
{ {
VkWaylandSurfaceCreateInfoKHR sci{}; VkWaylandSurfaceCreateInfoKHR sci{};
@ -1294,7 +1298,8 @@ VkSurfaceKHR VulkanRenderer::CreateWaylandSurface(VkInstance instance, wl_displa
return result; return result;
} }
#endif #endif // HAS_WAYLAND
#endif // BOOST_OS_LINUX
VkSurfaceKHR VulkanRenderer::CreateFramebufferSurface(VkInstance instance, struct WindowHandleInfo& windowInfo) VkSurfaceKHR VulkanRenderer::CreateFramebufferSurface(VkInstance instance, struct WindowHandleInfo& windowInfo)
{ {
@ -1303,8 +1308,10 @@ VkSurfaceKHR VulkanRenderer::CreateFramebufferSurface(VkInstance instance, struc
#elif BOOST_OS_LINUX #elif BOOST_OS_LINUX
if(windowInfo.backend == WindowHandleInfo::Backend::X11) if(windowInfo.backend == WindowHandleInfo::Backend::X11)
return CreateXlibSurface(instance, windowInfo.xlib_display, windowInfo.xlib_window); return CreateXlibSurface(instance, windowInfo.xlib_display, windowInfo.xlib_window);
#ifdef HAS_WAYLAND
if(windowInfo.backend == WindowHandleInfo::Backend::WAYLAND) if(windowInfo.backend == WindowHandleInfo::Backend::WAYLAND)
return CreateWaylandSurface(instance, windowInfo.display, windowInfo.surface); return CreateWaylandSurface(instance, windowInfo.display, windowInfo.surface);
#endif
return {}; return {};
#elif BOOST_OS_MACOS #elif BOOST_OS_MACOS
return CreateCocoaSurface(instance, windowInfo.handle); return CreateCocoaSurface(instance, windowInfo.handle);

View File

@ -201,8 +201,10 @@ public:
#if BOOST_OS_LINUX #if BOOST_OS_LINUX
static VkSurfaceKHR CreateXlibSurface(VkInstance instance, Display* dpy, Window window); static VkSurfaceKHR CreateXlibSurface(VkInstance instance, Display* dpy, Window window);
static VkSurfaceKHR CreateXcbSurface(VkInstance instance, xcb_connection_t* connection, xcb_window_t window); static VkSurfaceKHR CreateXcbSurface(VkInstance instance, xcb_connection_t* connection, xcb_window_t window);
#ifdef HAS_WAYLAND
static VkSurfaceKHR CreateWaylandSurface(VkInstance instance, wl_display* display, wl_surface* surface); static VkSurfaceKHR CreateWaylandSurface(VkInstance instance, wl_display* display, wl_surface* surface);
#endif #endif
#endif
static VkSurfaceKHR CreateFramebufferSurface(VkInstance instance, struct WindowHandleInfo& windowInfo); static VkSurfaceKHR CreateFramebufferSurface(VkInstance instance, struct WindowHandleInfo& windowInfo);

View File

@ -150,6 +150,9 @@ target_link_libraries(CemuGui PRIVATE
if(ENABLE_WXWIDGETS AND UNIX AND NOT APPLE) if(ENABLE_WXWIDGETS AND UNIX AND NOT APPLE)
# PUBLIC because gdk/gdkkeysyms.h is included in guiWrapper.h # PUBLIC because gdk/gdkkeysyms.h is included in guiWrapper.h
target_link_libraries(CemuGui PUBLIC GTK3::gtk) target_link_libraries(CemuGui PUBLIC GTK3::gtk)
if (ENABLE_WAYLAND)
target_link_libraries(CemuGui PRIVATE Wayland::client)
endif()
endif() endif()
if(ENABLE_CUBEB) if(ENABLE_CUBEB)

View File

@ -2,6 +2,10 @@
#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h" #include "Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h"
#include "gui/guiWrapper.h" #include "gui/guiWrapper.h"
#if BOOST_OS_LINUX && HAS_WAYLAND
#include "gui/helpers/wxWayland.h"
#endif
#include <wx/msgdlg.h> #include <wx/msgdlg.h>
VulkanCanvas::VulkanCanvas(wxWindow* parent, const wxSize& size, bool is_main_window) VulkanCanvas::VulkanCanvas(wxWindow* parent, const wxSize& size, bool is_main_window)
@ -14,7 +18,7 @@ VulkanCanvas::VulkanCanvas(wxWindow* parent, const wxSize& size, bool is_main_wi
{ {
WindowHandleInfo& canvasMain = gui_getWindowInfo().canvas_main; WindowHandleInfo& canvasMain = gui_getWindowInfo().canvas_main;
gui_initHandleContextFromWxWidgetsWindow(canvasMain, this); gui_initHandleContextFromWxWidgetsWindow(canvasMain, this);
#if BOOST_OS_LINUX #if BOOST_OS_LINUX && HAS_WAYLAND
if(canvasMain.backend == WindowHandleInfo::Backend::WAYLAND) if(canvasMain.backend == WindowHandleInfo::Backend::WAYLAND)
{ {
m_subsurface = std::make_unique<wxWlSubsurface>(this); m_subsurface = std::make_unique<wxWlSubsurface>(this);
@ -65,7 +69,7 @@ void VulkanCanvas::OnPaint(wxPaintEvent& event)
void VulkanCanvas::OnResize(wxSizeEvent& event) void VulkanCanvas::OnResize(wxSizeEvent& event)
{ {
#if BOOST_OS_LINUX #if BOOST_OS_LINUX && HAS_WAYLAND
if(m_subsurface) if(m_subsurface)
{ {
int32_t x,y; int32_t x,y;

View File

@ -6,14 +6,11 @@
#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h" #include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h"
#include <set> #include <set>
#if BOOST_OS_LINUX
#include "gui/helpers/wxWayland.h"
#endif
class VulkanCanvas : public IRenderCanvas, public wxWindow class VulkanCanvas : public IRenderCanvas, public wxWindow
{ {
#if BOOST_OS_LINUX #if BOOST_OS_LINUX && HAS_WAYLAND
std::unique_ptr<wxWlSubsurface> m_subsurface; std::unique_ptr<class wxWlSubsurface> m_subsurface;
#endif #endif
public: public:
VulkanCanvas(wxWindow* parent, const wxSize& size, bool is_main_window); VulkanCanvas(wxWindow* parent, const wxSize& size, bool is_main_window);

View File

@ -3,8 +3,10 @@
#include <gdk/gdk.h> #include <gdk/gdk.h>
#include <gdk/gdkwindow.h> #include <gdk/gdkwindow.h>
#include <gdk/gdkx.h> #include <gdk/gdkx.h>
#ifdef HAS_WAYLAND
#include <gdk/gdkwayland.h> #include <gdk/gdkwayland.h>
#endif #endif
#endif
#include "gui/wxgui.h" #include "gui/wxgui.h"
#include "gui/guiWrapper.h" #include "gui/guiWrapper.h"
@ -219,16 +221,18 @@ void gui_initHandleContextFromWxWidgetsWindow(WindowHandleInfo& handleInfoOut, c
cemuLog_log(LogType::Force, "Unable to get xlib display"); cemuLog_log(LogType::Force, "Unable to get xlib display");
} }
} }
else if(GDK_IS_WAYLAND_WINDOW(gdkWindow)) else
#ifdef HAS_WAYLAND
if(GDK_IS_WAYLAND_WINDOW(gdkWindow))
{ {
handleInfoOut.backend = WindowHandleInfo::Backend::WAYLAND; handleInfoOut.backend = WindowHandleInfo::Backend::WAYLAND;
handleInfoOut.surface = gdk_wayland_window_get_wl_surface(gdkWindow); handleInfoOut.surface = gdk_wayland_window_get_wl_surface(gdkWindow);
handleInfoOut.display = gdk_wayland_display_get_wl_display(gdkDisplay); handleInfoOut.display = gdk_wayland_display_get_wl_display(gdkDisplay);
} }
else else
#endif
{ {
cemuLog_log(LogType::Force, "Unsuported GTK backend"); cemuLog_log(LogType::Force, "Unsuported GTK backend");
} }
#else #else
handleInfoOut.handle = wxw->GetHandle(); handleInfoOut.handle = wxw->GetHandle();

View File

@ -5,7 +5,6 @@
#if BOOST_OS_LINUX #if BOOST_OS_LINUX
#include "xcb/xproto.h" #include "xcb/xproto.h"
#include <gdk/gdkkeysyms.h> #include <gdk/gdkkeysyms.h>
#include <wayland-client.h>
#endif #endif
#if BOOST_OS_MACOS #if BOOST_OS_MACOS
@ -29,9 +28,10 @@ struct WindowHandleInfo
// XCB (not used by GTK so we cant retrieve these without making our own window) // XCB (not used by GTK so we cant retrieve these without making our own window)
//xcb_connection_t* xcb_con{}; //xcb_connection_t* xcb_con{};
//xcb_window_t xcb_window{}; //xcb_window_t xcb_window{};
// Wayland #ifdef HAS_WAYLAND
wl_display* display; struct wl_display* display;
wl_surface* surface; struct wl_surface* surface;
#endif // HAS_WAYLAND
#else #else
void* handle; void* handle;
#endif #endif