diff --git a/rpcs3/CMakeLists.txt b/rpcs3/CMakeLists.txt index 0c2bb89498..dbd66a75bc 100644 --- a/rpcs3/CMakeLists.txt +++ b/rpcs3/CMakeLists.txt @@ -81,9 +81,15 @@ if (WIN32) endif() if(UNIX AND NOT APPLE) - find_package(X11 REQUIRED) - target_include_directories(rpcs3 PUBLIC ${X11_INCLUDE_DIR}) - target_link_libraries(rpcs3 ${X11_LIBRARIES}) + find_package(X11) + if(X11_FOUND) + target_include_directories(rpcs3 PUBLIC ${X11_INCLUDE_DIR}) + target_link_libraries(rpcs3 ${X11_LIBRARIES}) + target_compile_definitions(rpcs3 INTERFACE -DHAVE_X11) + # This has been checked in 3rdparty/CMakeLists.txt already. + elseif(NOT WAYLAND_FOUND) + message(FATAL_ERROR "RPCS3 requires either X11 or Wayland (or both) for Vulkan.") + endif() endif() if(UNIX) diff --git a/rpcs3/Emu/RSX/GL/OpenGL.cpp b/rpcs3/Emu/RSX/GL/OpenGL.cpp index c6e54ae070..8c2a7f8886 100644 --- a/rpcs3/Emu/RSX/GL/OpenGL.cpp +++ b/rpcs3/Emu/RSX/GL/OpenGL.cpp @@ -34,7 +34,7 @@ void gl::init() #ifdef __unix__ glewExperimental = true; glewInit(); -#ifndef __APPLE__ +#ifdef HAVE_X11 glxewInit(); #endif #endif @@ -44,7 +44,7 @@ void gl::set_swapinterval(int interval) { #ifdef _WIN32 wglSwapIntervalEXT(interval); -#elif !defined(__APPLE__) +#elif defined(HAVE_X11) if (glXSwapIntervalEXT) { if (auto window = glXGetCurrentDrawable()) diff --git a/rpcs3/Emu/RSX/GL/OpenGL.h b/rpcs3/Emu/RSX/GL/OpenGL.h index 487745b837..2ecf773d79 100644 --- a/rpcs3/Emu/RSX/GL/OpenGL.h +++ b/rpcs3/Emu/RSX/GL/OpenGL.h @@ -22,11 +22,13 @@ typedef BOOL (WINAPI* PFNWGLSWAPINTERVALEXTPROC) (int interval); #include #else -#include #include +#ifdef HAVE_X11 +#include #include #include #endif +#endif #ifndef GL_TEXTURE_BUFFER_BINDING //During spec release, this enum was removed during upgrade from ARB equivalent diff --git a/rpcs3/Emu/RSX/GSRender.h b/rpcs3/Emu/RSX/GSRender.h index c01bafcbec..00ae59bde8 100644 --- a/rpcs3/Emu/RSX/GSRender.h +++ b/rpcs3/Emu/RSX/GSRender.h @@ -8,7 +8,7 @@ #include #elif defined(__APPLE__) // nothing -#else +#elif defined(HAVE_X11) // Cannot include Xlib.h before Qt5 // and we don't need all of Xlib anyway using Display = struct _XDisplay; @@ -57,9 +57,12 @@ using display_handle_t = HWND; using display_handle_t = void*; // NSView #else using display_handle_t = std::variant< +#if defined(HAVE_X11) && defined(VK_USE_PLATFORM_WAYLAND_KHR) + std::pair, std::pair +#elif defined(HAVE_X11) std::pair -#ifdef VK_USE_PLATFORM_WAYLAND_KHR - , std::pair +#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) + std::pair #endif >; #endif diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index d3ff600d90..24bc1ed009 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -366,7 +366,7 @@ VKGSRender::VKGSRender() : GSRender() display_handle_t display = m_frame->handle(); -#if !defined(_WIN32) && !defined(__APPLE__) +#ifdef HAVE_X11 std::visit([this](auto&& p) { using T = std::decay_t; if constexpr (std::is_same_v>) @@ -653,7 +653,7 @@ VKGSRender::~VKGSRender() m_swapchain->destroy(); m_thread_context.close(); -#if !defined(_WIN32) && !defined(__APPLE__) && defined(HAVE_VULKAN) +#if defined(HAVE_X11) && defined(HAVE_VULKAN) if (m_display_handle) XCloseDisplay(m_display_handle); #endif diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.h b/rpcs3/Emu/RSX/VK/VKGSRender.h index d3e418fff0..9c99c60d30 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.h +++ b/rpcs3/Emu/RSX/VK/VKGSRender.h @@ -416,7 +416,7 @@ private: //Vertex layout rsx::vertex_input_layout m_vertex_layout; -#if !defined(_WIN32) && !defined(__APPLE__) && defined(HAVE_VULKAN) +#if defined(HAVE_X11) && defined(HAVE_VULKAN) Display *m_display_handle = nullptr; #endif diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index dc0def2ead..39431a64b3 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -10,7 +10,7 @@ #include #include -#if !defined(_WIN32) && !defined(__APPLE__) +#ifdef HAVE_X11 #include #endif @@ -2029,7 +2029,7 @@ public: { fmt::throw_exception("Native macOS swapchain is not implemented yet!"); } -#else +#elif defined(HAVE_X11) class swapchain_X11 : public native_swapchain_base { @@ -2136,6 +2136,37 @@ public: src.first = false; return VK_SUCCESS; } +#else + + class swapchain_Wayland : public native_swapchain_base + { + + public: + swapchain_Wayland(physical_device &gpu, uint32_t _present_queue, uint32_t _graphics_queue, VkFormat format = VK_FORMAT_B8G8R8A8_UNORM) + : native_swapchain_base(gpu, _present_queue, _graphics_queue, format) + {} + + ~swapchain_Wayland(){} + + bool init() override + { + fmt::throw_exception("Native Wayland swapchain is not implemented yet!"); + } + + void create(display_handle_t& window_handle) override + { + fmt::throw_exception("Native Wayland swapchain is not implemented yet!"); + } + + void destroy(bool full=true) override + { + fmt::throw_exception("Native Wayland swapchain is not implemented yet!"); + } + + VkResult present(VkSemaphore /*semaphore*/, u32 index) override + { + fmt::throw_exception("Native Wayland swapchain is not implemented yet!"); + } #endif VkResult acquire_next_swapchain_image(VkSemaphore /*semaphore*/, u64 /*timeout*/, u32* result) override @@ -2539,11 +2570,13 @@ public: extensions.push_back(VK_MVK_MACOS_SURFACE_EXTENSION_NAME); #else bool found_surface_ext = false; +#ifdef HAVE_X11 if (support.is_supported(VK_KHR_XLIB_SURFACE_EXTENSION_NAME)) { extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); found_surface_ext = true; } +#endif #ifdef VK_USE_PLATFORM_WAYLAND_KHR if (support.is_supported(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME)) { @@ -2642,12 +2675,17 @@ public: CHECK_RESULT(vkCreateMacOSSurfaceMVK(m_instance, &createInfo, NULL, &m_surface)); #else +#ifdef HAVE_X11 using swapchain_NATIVE = swapchain_X11; +#else + using swapchain_NATIVE = swapchain_Wayland; +#endif std::visit([&](auto&& p) { using T = std::decay_t; +#ifdef HAVE_X11 if constexpr (std::is_same_v>) { VkXlibSurfaceCreateInfoKHR createInfo = {}; @@ -2656,8 +2694,10 @@ public: createInfo.window = p.second; CHECK_RESULT(vkCreateXlibSurfaceKHR(this->m_instance, &createInfo, nullptr, &m_surface)); } + else +#endif #ifdef VK_USE_PLATFORM_WAYLAND_KHR - else if constexpr (std::is_same_v>) + if constexpr (std::is_same_v>) { VkWaylandSurfaceCreateInfoKHR createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; @@ -2667,10 +2707,10 @@ public: force_wm_reporting_off = true; } else +#endif { static_assert(std::conditional_t::value, "Unhandled window_handle type in std::variant"); } -#endif }, window_handle); #endif diff --git a/rpcs3/Emu/RSX/VK/VulkanAPI.h b/rpcs3/Emu/RSX/VK/VulkanAPI.h index 235f5061e3..9c726f6c36 100644 --- a/rpcs3/Emu/RSX/VK/VulkanAPI.h +++ b/rpcs3/Emu/RSX/VK/VulkanAPI.h @@ -4,7 +4,7 @@ #define VK_USE_PLATFORM_WIN32_KHR #elif defined(__APPLE__) #define VK_USE_PLATFORM_MACOS_MVK -#else +#elif HAVE_X11 #define VK_USE_PLATFORM_XLIB_KHR #endif diff --git a/rpcs3/rpcs3qt/gs_frame.cpp b/rpcs3/rpcs3qt/gs_frame.cpp index c7ad86213a..7c906ecc3a 100644 --- a/rpcs3/rpcs3qt/gs_frame.cpp +++ b/rpcs3/rpcs3qt/gs_frame.cpp @@ -26,8 +26,10 @@ #include #include #endif +#ifdef HAVE_X11 #include #endif +#endif constexpr auto qstr = QString::fromStdString; @@ -235,7 +237,11 @@ display_handle_t gs_frame::handle() const else { #endif +#ifdef HAVE_X11 return std::make_pair(XOpenDisplay(0), static_cast(this->winId())); +#else + fmt::throw_exception("Vulkan X11 support disabled at compile-time."); +#endif #ifdef VK_USE_PLATFORM_WAYLAND_KHR } #endif