diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp index 83fefce338..5d3c03e767 100644 --- a/Source/Android/jni/MainAndroid.cpp +++ b/Source/Android/jni/MainAndroid.cpp @@ -25,6 +25,7 @@ #include "Common/Logging/LogManager.h" #include "Common/MsgHandler.h" #include "Common/Version.h" +#include "Common/WindowSystemInfo.h" #include "Core/Analytics.h" #include "Core/Boot/Boot.h" @@ -560,7 +561,8 @@ static void Run(const std::string& path, bool first_open, s_have_wm_user_stop = false; std::unique_ptr boot = BootParameters::GenerateFromFile(path, savestate_path); boot->delete_savestate = delete_savestate; - if (BootManager::BootCore(std::move(boot))) + WindowSystemInfo wsi(WindowSystemType::Android, nullptr, s_surf); + if (BootManager::BootCore(std::move(boot), wsi)) { static constexpr int TIMEOUT = 10000; static constexpr int WAIT_STEP = 25; diff --git a/Source/Core/Common/GL/GLContext.cpp b/Source/Core/Common/GL/GLContext.cpp index 0b7f0238c1..da3e47aa26 100644 --- a/Source/Core/Common/GL/GLContext.cpp +++ b/Source/Core/Common/GL/GLContext.cpp @@ -82,8 +82,7 @@ void* GLContext::GetFuncAddress(const std::string& name) return nullptr; } -std::unique_ptr GLContext::Create(void* display_handle, void* window_handle, bool stereo, - bool core) +std::unique_ptr GLContext::Create(const WindowSystemInfo& wsi, bool stereo, bool core) { std::unique_ptr context; #if defined(__APPLE__) @@ -103,7 +102,7 @@ std::unique_ptr GLContext::Create(void* display_handle, void* window_ #else return nullptr; #endif - if (!context->Initialize(display_handle, window_handle, stereo, core)) + if (!context->Initialize(wsi.display_connection, wsi.render_surface, stereo, core)) return nullptr; return context; diff --git a/Source/Core/Common/GL/GLContext.h b/Source/Core/Common/GL/GLContext.h index 46df03dba8..c9e1d8c457 100644 --- a/Source/Core/Common/GL/GLContext.h +++ b/Source/Core/Common/GL/GLContext.h @@ -8,6 +8,7 @@ #include #include "Common/CommonTypes.h" +#include "Common/WindowSystemInfo.h" class GLContext { @@ -44,8 +45,8 @@ public: virtual void* GetFuncAddress(const std::string& name); // Creates an instance of GLInterface specific to the platform we are running on. - static std::unique_ptr Create(void* display_handle, void* window_handle, - bool stereo = false, bool core = true); + static std::unique_ptr Create(const WindowSystemInfo& wsi, bool stereo = false, + bool core = true); protected: virtual bool Initialize(void* display_handle, void* window_handle, bool stereo, bool core); diff --git a/Source/Core/Common/WindowSystemInfo.h b/Source/Core/Common/WindowSystemInfo.h new file mode 100644 index 0000000000..897d034c2c --- /dev/null +++ b/Source/Core/Common/WindowSystemInfo.h @@ -0,0 +1,35 @@ +// Copyright 2018 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +enum class WindowSystemType +{ + Headless, + Windows, + MacOS, + Android, + X11, + Wayland +}; + +struct WindowSystemInfo +{ + WindowSystemInfo() = default; + WindowSystemInfo(WindowSystemType type_, void* display_connection_, void* render_surface_) + : type(type_), display_connection(display_connection_), render_surface(render_surface_) + { + } + + // Window system type. Determines which GL context or Vulkan WSI is used. + WindowSystemType type = WindowSystemType::Headless; + + // Connection to a display server. This is used on X11 and Wayland platforms. + void* display_connection = nullptr; + + // Render surface. This is a pointer to the native window handle, which depends + // on the platform. e.g. HWND for Windows, Window for X11. If the surface is + // set to nullptr, the video backend will run in headless mode. + void* render_surface = nullptr; +}; diff --git a/Source/Core/Core/Boot/Boot.h b/Source/Core/Core/Boot/Boot.h index f229c7d560..589b9b2056 100644 --- a/Source/Core/Core/Boot/Boot.h +++ b/Source/Core/Core/Boot/Boot.h @@ -78,14 +78,6 @@ struct BootParameters Parameters parameters; std::optional savestate_path; bool delete_savestate = false; - - // Connection to a display server. This is used on X11 and Wayland platforms. - void* display_connection = nullptr; - - // Render surface. This is a pointer to the native window handle, which depends - // on the platform. e.g. HWND for Windows, Window for X11. If the surface is - // set to nullptr, the video backend will run in headless mode. - void* render_surface = nullptr; }; class CBoot diff --git a/Source/Core/Core/BootManager.cpp b/Source/Core/Core/BootManager.cpp index 7f7130ce66..9e5f205113 100644 --- a/Source/Core/Core/BootManager.cpp +++ b/Source/Core/Core/BootManager.cpp @@ -222,7 +222,7 @@ static GPUDeterminismMode ParseGPUDeterminismMode(const std::string& mode) } // Boot the ISO or file -bool BootCore(std::unique_ptr boot) +bool BootCore(std::unique_ptr boot, const WindowSystemInfo& wsi) { if (!boot) return false; @@ -403,12 +403,14 @@ bool BootCore(std::unique_ptr boot) std::holds_alternative(boot->parameters); if (load_ipl) { - return Core::Init(std::make_unique( - BootParameters::IPL{StartUp.m_region, - std::move(std::get(boot->parameters))}, - boot->savestate_path)); + return Core::Init( + std::make_unique( + BootParameters::IPL{StartUp.m_region, + std::move(std::get(boot->parameters))}, + boot->savestate_path), + wsi); } - return Core::Init(std::move(boot)); + return Core::Init(std::move(boot), wsi); } // SYSCONF can be modified during emulation by the user and internally, which makes it diff --git a/Source/Core/Core/BootManager.h b/Source/Core/Core/BootManager.h index 7f236c6ea0..d9c66c370c 100644 --- a/Source/Core/Core/BootManager.h +++ b/Source/Core/Core/BootManager.h @@ -7,12 +7,13 @@ #include struct BootParameters; +struct WindowSystemInfo; namespace BootManager { -bool BootCore(std::unique_ptr parameters); +bool BootCore(std::unique_ptr parameters, const WindowSystemInfo& wsi); // Synchronise Dolphin's configuration with the SYSCONF (which may have changed during emulation), // and restore settings that were overriden by per-game INIs or for some other reason. void RestoreConfig(); -} +} // namespace BootManager diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 8831db5908..93d4cd4491 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -107,7 +107,7 @@ static std::queue s_host_jobs_queue; static thread_local bool tls_is_cpu_thread = false; -static void EmuThread(std::unique_ptr boot); +static void EmuThread(std::unique_ptr boot, WindowSystemInfo wsi); bool GetIsThrottlerTempDisabled() { @@ -190,7 +190,7 @@ bool WantsDeterminism() // This is called from the GUI thread. See the booting call schedule in // BootManager.cpp -bool Init(std::unique_ptr boot) +bool Init(std::unique_ptr boot, const WindowSystemInfo& wsi) { if (s_emu_thread.joinable()) { @@ -215,7 +215,7 @@ bool Init(std::unique_ptr boot) Host_UpdateMainFrame(); // Disable any menus or buttons at boot // Start the emu thread - s_emu_thread = std::thread(EmuThread, std::move(boot)); + s_emu_thread = std::thread(EmuThread, std::move(boot), wsi); return true; } @@ -386,7 +386,7 @@ static void FifoPlayerThread(const std::optional& savestate_path, // Initialize and create emulation thread // Call browser: Init():s_emu_thread(). // See the BootManager.cpp file description for a complete call schedule. -static void EmuThread(std::unique_ptr boot) +static void EmuThread(std::unique_ptr boot, WindowSystemInfo wsi) { const SConfig& core_parameter = SConfig::GetInstance(); s_is_booting.Set(); @@ -438,7 +438,7 @@ static void EmuThread(std::unique_ptr boot) g_video_backend->InitBackendInfo(); g_Config.Refresh(); - if (!g_video_backend->Initialize(boot->display_connection, boot->render_surface)) + if (!g_video_backend->Initialize(wsi)) { PanicAlert("Failed to initialize video backend!"); return; @@ -459,7 +459,7 @@ static void EmuThread(std::unique_ptr boot) bool init_controllers = false; if (!g_controller_interface.IsInit()) { - g_controller_interface.Initialize(boot->render_surface); + g_controller_interface.Initialize(wsi.display_connection); Pad::Initialize(); Keyboard::Initialize(); init_controllers = true; diff --git a/Source/Core/Core/Core.h b/Source/Core/Core/Core.h index 708d2d234f..056e5ed3a1 100644 --- a/Source/Core/Core/Core.h +++ b/Source/Core/Core/Core.h @@ -18,6 +18,7 @@ #include "Common/CommonTypes.h" struct BootParameters; +struct WindowSystemInfo; namespace Core { @@ -35,7 +36,7 @@ enum class State Starting, }; -bool Init(std::unique_ptr boot); +bool Init(std::unique_ptr boot, const WindowSystemInfo& wsi); void Stop(); void Shutdown(); @@ -104,4 +105,4 @@ void HostDispatchJobs(); void DoFrameStep(); -} // namespace +} // namespace Core diff --git a/Source/Core/DolphinNoGUI/MainNoGUI.cpp b/Source/Core/DolphinNoGUI/MainNoGUI.cpp index 6447f6948b..6cd71bd353 100644 --- a/Source/Core/DolphinNoGUI/MainNoGUI.cpp +++ b/Source/Core/DolphinNoGUI/MainNoGUI.cpp @@ -72,8 +72,9 @@ public: virtual void Shutdown() {} virtual ~Platform() {} - virtual void* GetDisplayHandle() { return nullptr; } - virtual void* GetWindowHandle() { return nullptr; } + virtual WindowSystemType GetWindowSystem() const { return WindowSystemType::Headless; } + virtual void* GetDisplayHandle() const { return nullptr; } + virtual void* GetWindowHandle() const { return nullptr; } }; static Platform* platform; @@ -342,9 +343,9 @@ class PlatformX11 : public Platform XCloseDisplay(dpy); } - void* GetDisplayHandle() override { return static_cast(dpy); } - - void* GetWindowHandle() override { return reinterpret_cast(win); } + WindowSystemType GetWindowSystem() const override { return WindowSystemType::X11; } + void* GetDisplayHandle() const override { return static_cast(dpy); } + void* GetWindowHandle() const override { return reinterpret_cast(win); } }; #endif @@ -424,10 +425,10 @@ int main(int argc, char* argv[]) DolphinAnalytics::Instance()->ReportDolphinStart("nogui"); - boot->display_connection = platform->GetDisplayHandle(); - boot->render_surface = platform->GetWindowHandle(); + WindowSystemInfo wsi(platform->GetWindowSystem(), platform->GetDisplayHandle(), + platform->GetWindowHandle()); - if (!BootManager::BootCore(std::move(boot))) + if (!BootManager::BootCore(std::move(boot), wsi)) { fprintf(stderr, "Could not boot the specified file\n"); return 1; diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index 0a2ebfe101..b80a0bd2ab 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -31,6 +32,7 @@ #endif #include "Common/Version.h" +#include "Common/WindowSystemInfo.h" #include "Core/Boot/Boot.h" #include "Core/BootManager.h" @@ -122,6 +124,45 @@ static void InstallSignalHandler() } #endif +static WindowSystemType GetWindowSystemType() +{ + // Determine WSI type based on Qt platform. + QString platform_name = QGuiApplication::platformName(); + if (platform_name == QStringLiteral("windows")) + return WindowSystemType::Windows; + else if (platform_name == QStringLiteral("cocoa")) + return WindowSystemType::MacOS; + else if (platform_name == QStringLiteral("xcb")) + return WindowSystemType::X11; + else if (platform_name == QStringLiteral("wayland")) + return WindowSystemType::Wayland; + + QMessageBox::critical( + nullptr, QStringLiteral("Error"), + QString::asprintf("Unknown Qt platform: %s", platform_name.toStdString().c_str())); + return WindowSystemType::Headless; +} + +static WindowSystemInfo GetWindowSystemInfo(QWindow* window) +{ + WindowSystemInfo wsi; + wsi.type = GetWindowSystemType(); + + // Our Win32 Qt external doesn't have the private API. +#if defined(WIN32) || defined(__APPLE__) + wsi.render_surface = window ? reinterpret_cast(window->winId()) : nullptr; +#else + QPlatformNativeInterface* pni = QGuiApplication::platformNativeInterface(); + wsi.display_connection = pni->nativeResourceForWindow("display", window); + if (wsi.type == WindowSystemType::Wayland) + wsi.render_surface = window ? pni->nativeResourceForWindow("surface", window) : nullptr; + else + wsi.render_surface = window ? reinterpret_cast(window->winId()) : nullptr; +#endif + + return wsi; +} + MainWindow::MainWindow(std::unique_ptr boot_parameters) : QMainWindow(nullptr) { setWindowTitle(QString::fromStdString(Common::scm_rev_str)); @@ -804,16 +845,9 @@ void MainWindow::StartGame(std::unique_ptr&& parameters) // We need the render widget before booting. ShowRenderWidget(); - // Populate the video backend fields of the boot parameters. - parameters->render_surface = reinterpret_cast(m_render_widget->winId()); -#ifndef WIN32 - parameters->display_connection = - QGuiApplication::platformNativeInterface()->nativeResourceForWindow("display", - windowHandle()); -#endif - // Boot up, show an error if it fails to load the game. - if (!BootManager::BootCore(std::move(parameters))) + if (!BootManager::BootCore(std::move(parameters), + GetWindowSystemInfo(m_render_widget->windowHandle()))) { QMessageBox::critical(this, tr("Error"), tr("Failed to init core"), QMessageBox::Ok); HideRenderWidget(); diff --git a/Source/Core/DolphinQt/RenderWidget.cpp b/Source/Core/DolphinQt/RenderWidget.cpp index 6846de5dd5..1581782e5c 100644 --- a/Source/Core/DolphinQt/RenderWidget.cpp +++ b/Source/Core/DolphinQt/RenderWidget.cpp @@ -68,6 +68,9 @@ RenderWidget::RenderWidget(QWidget* parent) : QWidget(parent) OnKeepOnTopChanged(Settings::Instance().IsKeepWindowOnTopEnabled()); m_mouse_timer->start(MOUSE_HIDE_DELAY); + // We need a native window to render into. + setAttribute(Qt::WA_NativeWindow); + SetFillBackground(true); } diff --git a/Source/Core/VideoBackends/D3D/D3DBase.cpp b/Source/Core/VideoBackends/D3D/D3DBase.cpp index 6c4478c492..333fd969f5 100644 --- a/Source/Core/VideoBackends/D3D/D3DBase.cpp +++ b/Source/Core/VideoBackends/D3D/D3DBase.cpp @@ -429,10 +429,13 @@ HRESULT Create(HWND wnd) // prevent DXGI from responding to Alt+Enter, unfortunately DXGI_MWA_NO_ALT_ENTER // does not work so we disable all monitoring of window messages. However this // may make it more difficult for DXGI to handle display mode changes. - hr = s_dxgi_factory->MakeWindowAssociation(wnd, DXGI_MWA_NO_WINDOW_CHANGES); - if (FAILED(hr)) - MessageBox(wnd, _T("Failed to associate the window"), _T("Dolphin Direct3D 11 backend"), - MB_OK | MB_ICONERROR); + if (wnd) + { + hr = s_dxgi_factory->MakeWindowAssociation(wnd, DXGI_MWA_NO_WINDOW_CHANGES); + if (FAILED(hr)) + MessageBox(wnd, _T("Failed to associate the window"), _T("Dolphin Direct3D 11 backend"), + MB_OK | MB_ICONERROR); + } SetDebugObjectName(context, "device context"); diff --git a/Source/Core/VideoBackends/D3D/VideoBackend.h b/Source/Core/VideoBackends/D3D/VideoBackend.h index 2470401dd3..e288dddb9a 100644 --- a/Source/Core/VideoBackends/D3D/VideoBackend.h +++ b/Source/Core/VideoBackends/D3D/VideoBackend.h @@ -11,7 +11,7 @@ namespace DX11 { class VideoBackend : public VideoBackendBase { - bool Initialize(void* display_handle, void* window_handle) override; + bool Initialize(const WindowSystemInfo& wsi) override; void Shutdown() override; std::string GetName() const override; diff --git a/Source/Core/VideoBackends/D3D/main.cpp b/Source/Core/VideoBackends/D3D/main.cpp index 36c5558435..7df5358b16 100644 --- a/Source/Core/VideoBackends/D3D/main.cpp +++ b/Source/Core/VideoBackends/D3D/main.cpp @@ -127,14 +127,11 @@ void VideoBackend::InitBackendInfo() DX11::D3D::UnloadD3D(); } -bool VideoBackend::Initialize(void* display_handle, void* window_handle) +bool VideoBackend::Initialize(const WindowSystemInfo& wsi) { - if (window_handle == nullptr) - return false; - InitializeShared(); - if (FAILED(D3D::Create(reinterpret_cast(window_handle)))) + if (FAILED(D3D::Create(reinterpret_cast(wsi.render_surface)))) { PanicAlert("Failed to create D3D device."); return false; diff --git a/Source/Core/VideoBackends/Null/NullBackend.cpp b/Source/Core/VideoBackends/Null/NullBackend.cpp index 6d2edb79b5..147d5916ff 100644 --- a/Source/Core/VideoBackends/Null/NullBackend.cpp +++ b/Source/Core/VideoBackends/Null/NullBackend.cpp @@ -54,7 +54,7 @@ void VideoBackend::InitBackendInfo() g_Config.backend_info.AAModes = {1}; } -bool VideoBackend::Initialize(void* display_handle, void* window_handle) +bool VideoBackend::Initialize(const WindowSystemInfo& wsi) { InitializeShared(); diff --git a/Source/Core/VideoBackends/Null/VideoBackend.h b/Source/Core/VideoBackends/Null/VideoBackend.h index 3d0353f073..3076f7aed0 100644 --- a/Source/Core/VideoBackends/Null/VideoBackend.h +++ b/Source/Core/VideoBackends/Null/VideoBackend.h @@ -11,7 +11,7 @@ namespace Null { class VideoBackend : public VideoBackendBase { - bool Initialize(void* display_handle, void* window_handle) override; + bool Initialize(const WindowSystemInfo& wsi) override; void Shutdown() override; std::string GetName() const override { return "Null"; } diff --git a/Source/Core/VideoBackends/OGL/VideoBackend.h b/Source/Core/VideoBackends/OGL/VideoBackend.h index 96864f3ecc..2a1360542f 100644 --- a/Source/Core/VideoBackends/OGL/VideoBackend.h +++ b/Source/Core/VideoBackends/OGL/VideoBackend.h @@ -11,7 +11,7 @@ namespace OGL { class VideoBackend : public VideoBackendBase { - bool Initialize(void* display_handle, void* window_handle) override; + bool Initialize(const WindowSystemInfo& wsi) override; void Shutdown() override; std::string GetName() const override; diff --git a/Source/Core/VideoBackends/OGL/main.cpp b/Source/Core/VideoBackends/OGL/main.cpp index edfb861eea..56cd60fc47 100644 --- a/Source/Core/VideoBackends/OGL/main.cpp +++ b/Source/Core/VideoBackends/OGL/main.cpp @@ -157,12 +157,11 @@ bool VideoBackend::FillBackendInfo() return true; } -bool VideoBackend::Initialize(void* display_handle, void* window_handle) +bool VideoBackend::Initialize(const WindowSystemInfo& wsi) { InitializeShared(); - g_main_gl_context = GLContext::Create(display_handle, window_handle, - g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer); + g_main_gl_context = GLContext::Create(wsi, g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer); if (!g_main_gl_context) return false; diff --git a/Source/Core/VideoBackends/Software/SWOGLWindow.cpp b/Source/Core/VideoBackends/Software/SWOGLWindow.cpp index fb6731b4b7..d9694c17aa 100644 --- a/Source/Core/VideoBackends/Software/SWOGLWindow.cpp +++ b/Source/Core/VideoBackends/Software/SWOGLWindow.cpp @@ -13,9 +13,9 @@ std::unique_ptr SWOGLWindow::s_instance; -void SWOGLWindow::Init(void* display_handle, void* window_handle) +void SWOGLWindow::Init(const WindowSystemInfo& wsi) { - g_main_gl_context = GLContext::Create(display_handle, window_handle); + g_main_gl_context = GLContext::Create(wsi); if (!g_main_gl_context) { ERROR_LOG(VIDEO, "GLInterface::Create failed."); diff --git a/Source/Core/VideoBackends/Software/SWOGLWindow.h b/Source/Core/VideoBackends/Software/SWOGLWindow.h index a393194ed7..2d85770e61 100644 --- a/Source/Core/VideoBackends/Software/SWOGLWindow.h +++ b/Source/Core/VideoBackends/Software/SWOGLWindow.h @@ -12,11 +12,12 @@ #include "VideoCommon/VideoCommon.h" class AbstractTexture; +struct WindowSystemInfo; class SWOGLWindow { public: - static void Init(void* display_handle, void* window_handle); + static void Init(const WindowSystemInfo& wsi); static void Shutdown(); void Prepare(); diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp index 2aa099e9e9..070cf74b69 100644 --- a/Source/Core/VideoBackends/Software/SWmain.cpp +++ b/Source/Core/VideoBackends/Software/SWmain.cpp @@ -78,11 +78,11 @@ void VideoSoftware::InitBackendInfo() g_Config.backend_info.AAModes = {1}; } -bool VideoSoftware::Initialize(void* display_handle, void* window_handle) +bool VideoSoftware::Initialize(const WindowSystemInfo& wsi) { InitializeShared(); - SWOGLWindow::Init(display_handle, window_handle); + SWOGLWindow::Init(wsi); Clipper::Init(); Rasterizer::Init(); diff --git a/Source/Core/VideoBackends/Software/VideoBackend.h b/Source/Core/VideoBackends/Software/VideoBackend.h index 336a96325b..bad120d6a1 100644 --- a/Source/Core/VideoBackends/Software/VideoBackend.h +++ b/Source/Core/VideoBackends/Software/VideoBackend.h @@ -11,7 +11,7 @@ namespace SW { class VideoSoftware : public VideoBackendBase { - bool Initialize(void* display_handle, void* window_handle) override; + bool Initialize(const WindowSystemInfo& wsi) override; void Shutdown() override; std::string GetName() const override; diff --git a/Source/Core/VideoBackends/Vulkan/VideoBackend.h b/Source/Core/VideoBackends/Vulkan/VideoBackend.h index ddf0ab4342..83d960330e 100644 --- a/Source/Core/VideoBackends/Vulkan/VideoBackend.h +++ b/Source/Core/VideoBackends/Vulkan/VideoBackend.h @@ -12,7 +12,7 @@ namespace Vulkan class VideoBackend : public VideoBackendBase { public: - bool Initialize(void* display_handle, void* window_handle) override; + bool Initialize(const WindowSystemInfo& wsi) override; void Shutdown() override; std::string GetName() const override { return "Vulkan"; } diff --git a/Source/Core/VideoBackends/Vulkan/main.cpp b/Source/Core/VideoBackends/Vulkan/main.cpp index 2617de2191..40798934e7 100644 --- a/Source/Core/VideoBackends/Vulkan/main.cpp +++ b/Source/Core/VideoBackends/Vulkan/main.cpp @@ -89,7 +89,7 @@ static bool ShouldEnableDebugReports(bool enable_validation_layers) return enable_validation_layers || IsHostGPULoggingEnabled(); } -bool VideoBackend::Initialize(void* display_handle, void* window_handle) +bool VideoBackend::Initialize(const WindowSystemInfo& wsi) { if (!LoadVulkanLibrary()) { @@ -107,7 +107,7 @@ bool VideoBackend::Initialize(void* display_handle, void* window_handle) // Create Vulkan instance, needed before we can create a surface, or enumerate devices. // We use this instance to fill in backend info, then re-use it for the actual device. - bool enable_surface = window_handle != nullptr; + bool enable_surface = wsi.render_surface != nullptr; bool enable_debug_reports = ShouldEnableDebugReports(enable_validation_layer); VkInstance instance = VulkanContext::CreateVulkanInstance(enable_surface, enable_debug_reports, enable_validation_layer); @@ -146,7 +146,7 @@ bool VideoBackend::Initialize(void* display_handle, void* window_handle) VkSurfaceKHR surface = VK_NULL_HANDLE; if (enable_surface) { - surface = SwapChain::CreateVulkanSurface(instance, display_handle, window_handle); + surface = SwapChain::CreateVulkanSurface(instance, wsi.display_connection, wsi.render_surface); if (surface == VK_NULL_HANDLE) { PanicAlert("Failed to create Vulkan surface."); @@ -209,7 +209,8 @@ bool VideoBackend::Initialize(void* display_handle, void* window_handle) std::unique_ptr swap_chain; if (surface != VK_NULL_HANDLE) { - swap_chain = SwapChain::Create(display_handle, window_handle, surface, g_Config.IsVSync()); + swap_chain = + SwapChain::Create(wsi.display_connection, wsi.render_surface, surface, g_Config.IsVSync()); if (!swap_chain) { PanicAlert("Failed to create Vulkan swap chain."); diff --git a/Source/Core/VideoCommon/VideoBackendBase.h b/Source/Core/VideoCommon/VideoBackendBase.h index 3b106bff98..83a74b0608 100644 --- a/Source/Core/VideoCommon/VideoBackendBase.h +++ b/Source/Core/VideoCommon/VideoBackendBase.h @@ -9,6 +9,7 @@ #include #include "Common/CommonTypes.h" +#include "Common/WindowSystemInfo.h" #include "VideoCommon/PerfQueryBase.h" namespace MMIO @@ -35,7 +36,7 @@ class VideoBackendBase { public: virtual ~VideoBackendBase() {} - virtual bool Initialize(void* display_handle, void* window_handle) = 0; + virtual bool Initialize(const WindowSystemInfo& wsi) = 0; virtual void Shutdown() = 0; virtual std::string GetName() const = 0;