VideoBackends: Pass window system info from host on creation

This commit is contained in:
Stenzek 2018-10-03 23:03:22 +10:00
parent 9c57a98723
commit eb284b5d66
26 changed files with 148 additions and 75 deletions

View File

@ -25,6 +25,7 @@
#include "Common/Logging/LogManager.h" #include "Common/Logging/LogManager.h"
#include "Common/MsgHandler.h" #include "Common/MsgHandler.h"
#include "Common/Version.h" #include "Common/Version.h"
#include "Common/WindowSystemInfo.h"
#include "Core/Analytics.h" #include "Core/Analytics.h"
#include "Core/Boot/Boot.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; s_have_wm_user_stop = false;
std::unique_ptr<BootParameters> boot = BootParameters::GenerateFromFile(path, savestate_path); std::unique_ptr<BootParameters> boot = BootParameters::GenerateFromFile(path, savestate_path);
boot->delete_savestate = delete_savestate; 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 TIMEOUT = 10000;
static constexpr int WAIT_STEP = 25; static constexpr int WAIT_STEP = 25;

View File

@ -82,8 +82,7 @@ void* GLContext::GetFuncAddress(const std::string& name)
return nullptr; return nullptr;
} }
std::unique_ptr<GLContext> GLContext::Create(void* display_handle, void* window_handle, bool stereo, std::unique_ptr<GLContext> GLContext::Create(const WindowSystemInfo& wsi, bool stereo, bool core)
bool core)
{ {
std::unique_ptr<GLContext> context; std::unique_ptr<GLContext> context;
#if defined(__APPLE__) #if defined(__APPLE__)
@ -103,7 +102,7 @@ std::unique_ptr<GLContext> GLContext::Create(void* display_handle, void* window_
#else #else
return nullptr; return nullptr;
#endif #endif
if (!context->Initialize(display_handle, window_handle, stereo, core)) if (!context->Initialize(wsi.display_connection, wsi.render_surface, stereo, core))
return nullptr; return nullptr;
return context; return context;

View File

@ -8,6 +8,7 @@
#include <string> #include <string>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/WindowSystemInfo.h"
class GLContext class GLContext
{ {
@ -44,8 +45,8 @@ public:
virtual void* GetFuncAddress(const std::string& name); virtual void* GetFuncAddress(const std::string& name);
// Creates an instance of GLInterface specific to the platform we are running on. // Creates an instance of GLInterface specific to the platform we are running on.
static std::unique_ptr<GLContext> Create(void* display_handle, void* window_handle, static std::unique_ptr<GLContext> Create(const WindowSystemInfo& wsi, bool stereo = false,
bool stereo = false, bool core = true); bool core = true);
protected: protected:
virtual bool Initialize(void* display_handle, void* window_handle, bool stereo, bool core); virtual bool Initialize(void* display_handle, void* window_handle, bool stereo, bool core);

View File

@ -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;
};

View File

@ -78,14 +78,6 @@ struct BootParameters
Parameters parameters; Parameters parameters;
std::optional<std::string> savestate_path; std::optional<std::string> savestate_path;
bool delete_savestate = false; 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 class CBoot

View File

@ -222,7 +222,7 @@ static GPUDeterminismMode ParseGPUDeterminismMode(const std::string& mode)
} }
// Boot the ISO or file // Boot the ISO or file
bool BootCore(std::unique_ptr<BootParameters> boot) bool BootCore(std::unique_ptr<BootParameters> boot, const WindowSystemInfo& wsi)
{ {
if (!boot) if (!boot)
return false; return false;
@ -403,12 +403,14 @@ bool BootCore(std::unique_ptr<BootParameters> boot)
std::holds_alternative<BootParameters::Disc>(boot->parameters); std::holds_alternative<BootParameters::Disc>(boot->parameters);
if (load_ipl) if (load_ipl)
{ {
return Core::Init(std::make_unique<BootParameters>( return Core::Init(
BootParameters::IPL{StartUp.m_region, std::make_unique<BootParameters>(
std::move(std::get<BootParameters::Disc>(boot->parameters))}, BootParameters::IPL{StartUp.m_region,
boot->savestate_path)); std::move(std::get<BootParameters::Disc>(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 // SYSCONF can be modified during emulation by the user and internally, which makes it

View File

@ -7,12 +7,13 @@
#include <memory> #include <memory>
struct BootParameters; struct BootParameters;
struct WindowSystemInfo;
namespace BootManager namespace BootManager
{ {
bool BootCore(std::unique_ptr<BootParameters> parameters); bool BootCore(std::unique_ptr<BootParameters> parameters, const WindowSystemInfo& wsi);
// Synchronise Dolphin's configuration with the SYSCONF (which may have changed during emulation), // 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. // and restore settings that were overriden by per-game INIs or for some other reason.
void RestoreConfig(); void RestoreConfig();
} } // namespace BootManager

View File

@ -107,7 +107,7 @@ static std::queue<HostJob> s_host_jobs_queue;
static thread_local bool tls_is_cpu_thread = false; static thread_local bool tls_is_cpu_thread = false;
static void EmuThread(std::unique_ptr<BootParameters> boot); static void EmuThread(std::unique_ptr<BootParameters> boot, WindowSystemInfo wsi);
bool GetIsThrottlerTempDisabled() bool GetIsThrottlerTempDisabled()
{ {
@ -190,7 +190,7 @@ bool WantsDeterminism()
// This is called from the GUI thread. See the booting call schedule in // This is called from the GUI thread. See the booting call schedule in
// BootManager.cpp // BootManager.cpp
bool Init(std::unique_ptr<BootParameters> boot) bool Init(std::unique_ptr<BootParameters> boot, const WindowSystemInfo& wsi)
{ {
if (s_emu_thread.joinable()) if (s_emu_thread.joinable())
{ {
@ -215,7 +215,7 @@ bool Init(std::unique_ptr<BootParameters> boot)
Host_UpdateMainFrame(); // Disable any menus or buttons at boot Host_UpdateMainFrame(); // Disable any menus or buttons at boot
// Start the emu thread // 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; return true;
} }
@ -386,7 +386,7 @@ static void FifoPlayerThread(const std::optional<std::string>& savestate_path,
// Initialize and create emulation thread // Initialize and create emulation thread
// Call browser: Init():s_emu_thread(). // Call browser: Init():s_emu_thread().
// See the BootManager.cpp file description for a complete call schedule. // See the BootManager.cpp file description for a complete call schedule.
static void EmuThread(std::unique_ptr<BootParameters> boot) static void EmuThread(std::unique_ptr<BootParameters> boot, WindowSystemInfo wsi)
{ {
const SConfig& core_parameter = SConfig::GetInstance(); const SConfig& core_parameter = SConfig::GetInstance();
s_is_booting.Set(); s_is_booting.Set();
@ -438,7 +438,7 @@ static void EmuThread(std::unique_ptr<BootParameters> boot)
g_video_backend->InitBackendInfo(); g_video_backend->InitBackendInfo();
g_Config.Refresh(); 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!"); PanicAlert("Failed to initialize video backend!");
return; return;
@ -459,7 +459,7 @@ static void EmuThread(std::unique_ptr<BootParameters> boot)
bool init_controllers = false; bool init_controllers = false;
if (!g_controller_interface.IsInit()) if (!g_controller_interface.IsInit())
{ {
g_controller_interface.Initialize(boot->render_surface); g_controller_interface.Initialize(wsi.display_connection);
Pad::Initialize(); Pad::Initialize();
Keyboard::Initialize(); Keyboard::Initialize();
init_controllers = true; init_controllers = true;

View File

@ -18,6 +18,7 @@
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
struct BootParameters; struct BootParameters;
struct WindowSystemInfo;
namespace Core namespace Core
{ {
@ -35,7 +36,7 @@ enum class State
Starting, Starting,
}; };
bool Init(std::unique_ptr<BootParameters> boot); bool Init(std::unique_ptr<BootParameters> boot, const WindowSystemInfo& wsi);
void Stop(); void Stop();
void Shutdown(); void Shutdown();
@ -104,4 +105,4 @@ void HostDispatchJobs();
void DoFrameStep(); void DoFrameStep();
} // namespace } // namespace Core

View File

@ -72,8 +72,9 @@ public:
virtual void Shutdown() {} virtual void Shutdown() {}
virtual ~Platform() {} virtual ~Platform() {}
virtual void* GetDisplayHandle() { return nullptr; } virtual WindowSystemType GetWindowSystem() const { return WindowSystemType::Headless; }
virtual void* GetWindowHandle() { return nullptr; } virtual void* GetDisplayHandle() const { return nullptr; }
virtual void* GetWindowHandle() const { return nullptr; }
}; };
static Platform* platform; static Platform* platform;
@ -342,9 +343,9 @@ class PlatformX11 : public Platform
XCloseDisplay(dpy); XCloseDisplay(dpy);
} }
void* GetDisplayHandle() override { return static_cast<void*>(dpy); } WindowSystemType GetWindowSystem() const override { return WindowSystemType::X11; }
void* GetDisplayHandle() const override { return static_cast<void*>(dpy); }
void* GetWindowHandle() override { return reinterpret_cast<void*>(win); } void* GetWindowHandle() const override { return reinterpret_cast<void*>(win); }
}; };
#endif #endif
@ -424,10 +425,10 @@ int main(int argc, char* argv[])
DolphinAnalytics::Instance()->ReportDolphinStart("nogui"); DolphinAnalytics::Instance()->ReportDolphinStart("nogui");
boot->display_connection = platform->GetDisplayHandle(); WindowSystemInfo wsi(platform->GetWindowSystem(), platform->GetDisplayHandle(),
boot->render_surface = platform->GetWindowHandle(); platform->GetWindowHandle());
if (!BootManager::BootCore(std::move(boot))) if (!BootManager::BootCore(std::move(boot), wsi))
{ {
fprintf(stderr, "Could not boot the specified file\n"); fprintf(stderr, "Could not boot the specified file\n");
return 1; return 1;

View File

@ -16,6 +16,7 @@
#include <QProgressDialog> #include <QProgressDialog>
#include <QStackedWidget> #include <QStackedWidget>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QWindow>
#include <future> #include <future>
#include <optional> #include <optional>
@ -31,6 +32,7 @@
#endif #endif
#include "Common/Version.h" #include "Common/Version.h"
#include "Common/WindowSystemInfo.h"
#include "Core/Boot/Boot.h" #include "Core/Boot/Boot.h"
#include "Core/BootManager.h" #include "Core/BootManager.h"
@ -122,6 +124,45 @@ static void InstallSignalHandler()
} }
#endif #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<void*>(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<void*>(window->winId()) : nullptr;
#endif
return wsi;
}
MainWindow::MainWindow(std::unique_ptr<BootParameters> boot_parameters) : QMainWindow(nullptr) MainWindow::MainWindow(std::unique_ptr<BootParameters> boot_parameters) : QMainWindow(nullptr)
{ {
setWindowTitle(QString::fromStdString(Common::scm_rev_str)); setWindowTitle(QString::fromStdString(Common::scm_rev_str));
@ -804,16 +845,9 @@ void MainWindow::StartGame(std::unique_ptr<BootParameters>&& parameters)
// We need the render widget before booting. // We need the render widget before booting.
ShowRenderWidget(); ShowRenderWidget();
// Populate the video backend fields of the boot parameters.
parameters->render_surface = reinterpret_cast<void*>(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. // 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); QMessageBox::critical(this, tr("Error"), tr("Failed to init core"), QMessageBox::Ok);
HideRenderWidget(); HideRenderWidget();

View File

@ -68,6 +68,9 @@ RenderWidget::RenderWidget(QWidget* parent) : QWidget(parent)
OnKeepOnTopChanged(Settings::Instance().IsKeepWindowOnTopEnabled()); OnKeepOnTopChanged(Settings::Instance().IsKeepWindowOnTopEnabled());
m_mouse_timer->start(MOUSE_HIDE_DELAY); m_mouse_timer->start(MOUSE_HIDE_DELAY);
// We need a native window to render into.
setAttribute(Qt::WA_NativeWindow);
SetFillBackground(true); SetFillBackground(true);
} }

View File

@ -429,10 +429,13 @@ HRESULT Create(HWND wnd)
// prevent DXGI from responding to Alt+Enter, unfortunately DXGI_MWA_NO_ALT_ENTER // 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 // 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. // may make it more difficult for DXGI to handle display mode changes.
hr = s_dxgi_factory->MakeWindowAssociation(wnd, DXGI_MWA_NO_WINDOW_CHANGES); if (wnd)
if (FAILED(hr)) {
MessageBox(wnd, _T("Failed to associate the window"), _T("Dolphin Direct3D 11 backend"), hr = s_dxgi_factory->MakeWindowAssociation(wnd, DXGI_MWA_NO_WINDOW_CHANGES);
MB_OK | MB_ICONERROR); if (FAILED(hr))
MessageBox(wnd, _T("Failed to associate the window"), _T("Dolphin Direct3D 11 backend"),
MB_OK | MB_ICONERROR);
}
SetDebugObjectName(context, "device context"); SetDebugObjectName(context, "device context");

View File

@ -11,7 +11,7 @@ namespace DX11
{ {
class VideoBackend : public VideoBackendBase class VideoBackend : public VideoBackendBase
{ {
bool Initialize(void* display_handle, void* window_handle) override; bool Initialize(const WindowSystemInfo& wsi) override;
void Shutdown() override; void Shutdown() override;
std::string GetName() const override; std::string GetName() const override;

View File

@ -127,14 +127,11 @@ void VideoBackend::InitBackendInfo()
DX11::D3D::UnloadD3D(); 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(); InitializeShared();
if (FAILED(D3D::Create(reinterpret_cast<HWND>(window_handle)))) if (FAILED(D3D::Create(reinterpret_cast<HWND>(wsi.render_surface))))
{ {
PanicAlert("Failed to create D3D device."); PanicAlert("Failed to create D3D device.");
return false; return false;

View File

@ -54,7 +54,7 @@ void VideoBackend::InitBackendInfo()
g_Config.backend_info.AAModes = {1}; g_Config.backend_info.AAModes = {1};
} }
bool VideoBackend::Initialize(void* display_handle, void* window_handle) bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
{ {
InitializeShared(); InitializeShared();

View File

@ -11,7 +11,7 @@ namespace Null
{ {
class VideoBackend : public VideoBackendBase class VideoBackend : public VideoBackendBase
{ {
bool Initialize(void* display_handle, void* window_handle) override; bool Initialize(const WindowSystemInfo& wsi) override;
void Shutdown() override; void Shutdown() override;
std::string GetName() const override { return "Null"; } std::string GetName() const override { return "Null"; }

View File

@ -11,7 +11,7 @@ namespace OGL
{ {
class VideoBackend : public VideoBackendBase class VideoBackend : public VideoBackendBase
{ {
bool Initialize(void* display_handle, void* window_handle) override; bool Initialize(const WindowSystemInfo& wsi) override;
void Shutdown() override; void Shutdown() override;
std::string GetName() const override; std::string GetName() const override;

View File

@ -157,12 +157,11 @@ bool VideoBackend::FillBackendInfo()
return true; return true;
} }
bool VideoBackend::Initialize(void* display_handle, void* window_handle) bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
{ {
InitializeShared(); InitializeShared();
g_main_gl_context = GLContext::Create(display_handle, window_handle, g_main_gl_context = GLContext::Create(wsi, g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer);
g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer);
if (!g_main_gl_context) if (!g_main_gl_context)
return false; return false;

View File

@ -13,9 +13,9 @@
std::unique_ptr<SWOGLWindow> SWOGLWindow::s_instance; std::unique_ptr<SWOGLWindow> 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) if (!g_main_gl_context)
{ {
ERROR_LOG(VIDEO, "GLInterface::Create failed."); ERROR_LOG(VIDEO, "GLInterface::Create failed.");

View File

@ -12,11 +12,12 @@
#include "VideoCommon/VideoCommon.h" #include "VideoCommon/VideoCommon.h"
class AbstractTexture; class AbstractTexture;
struct WindowSystemInfo;
class SWOGLWindow class SWOGLWindow
{ {
public: public:
static void Init(void* display_handle, void* window_handle); static void Init(const WindowSystemInfo& wsi);
static void Shutdown(); static void Shutdown();
void Prepare(); void Prepare();

View File

@ -78,11 +78,11 @@ void VideoSoftware::InitBackendInfo()
g_Config.backend_info.AAModes = {1}; g_Config.backend_info.AAModes = {1};
} }
bool VideoSoftware::Initialize(void* display_handle, void* window_handle) bool VideoSoftware::Initialize(const WindowSystemInfo& wsi)
{ {
InitializeShared(); InitializeShared();
SWOGLWindow::Init(display_handle, window_handle); SWOGLWindow::Init(wsi);
Clipper::Init(); Clipper::Init();
Rasterizer::Init(); Rasterizer::Init();

View File

@ -11,7 +11,7 @@ namespace SW
{ {
class VideoSoftware : public VideoBackendBase class VideoSoftware : public VideoBackendBase
{ {
bool Initialize(void* display_handle, void* window_handle) override; bool Initialize(const WindowSystemInfo& wsi) override;
void Shutdown() override; void Shutdown() override;
std::string GetName() const override; std::string GetName() const override;

View File

@ -12,7 +12,7 @@ namespace Vulkan
class VideoBackend : public VideoBackendBase class VideoBackend : public VideoBackendBase
{ {
public: public:
bool Initialize(void* display_handle, void* window_handle) override; bool Initialize(const WindowSystemInfo& wsi) override;
void Shutdown() override; void Shutdown() override;
std::string GetName() const override { return "Vulkan"; } std::string GetName() const override { return "Vulkan"; }

View File

@ -89,7 +89,7 @@ static bool ShouldEnableDebugReports(bool enable_validation_layers)
return enable_validation_layers || IsHostGPULoggingEnabled(); return enable_validation_layers || IsHostGPULoggingEnabled();
} }
bool VideoBackend::Initialize(void* display_handle, void* window_handle) bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
{ {
if (!LoadVulkanLibrary()) 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. // 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. // 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); bool enable_debug_reports = ShouldEnableDebugReports(enable_validation_layer);
VkInstance instance = VulkanContext::CreateVulkanInstance(enable_surface, enable_debug_reports, VkInstance instance = VulkanContext::CreateVulkanInstance(enable_surface, enable_debug_reports,
enable_validation_layer); enable_validation_layer);
@ -146,7 +146,7 @@ bool VideoBackend::Initialize(void* display_handle, void* window_handle)
VkSurfaceKHR surface = VK_NULL_HANDLE; VkSurfaceKHR surface = VK_NULL_HANDLE;
if (enable_surface) 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) if (surface == VK_NULL_HANDLE)
{ {
PanicAlert("Failed to create Vulkan surface."); PanicAlert("Failed to create Vulkan surface.");
@ -209,7 +209,8 @@ bool VideoBackend::Initialize(void* display_handle, void* window_handle)
std::unique_ptr<SwapChain> swap_chain; std::unique_ptr<SwapChain> swap_chain;
if (surface != VK_NULL_HANDLE) 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) if (!swap_chain)
{ {
PanicAlert("Failed to create Vulkan swap chain."); PanicAlert("Failed to create Vulkan swap chain.");

View File

@ -9,6 +9,7 @@
#include <vector> #include <vector>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/WindowSystemInfo.h"
#include "VideoCommon/PerfQueryBase.h" #include "VideoCommon/PerfQueryBase.h"
namespace MMIO namespace MMIO
@ -35,7 +36,7 @@ class VideoBackendBase
{ {
public: public:
virtual ~VideoBackendBase() {} virtual ~VideoBackendBase() {}
virtual bool Initialize(void* display_handle, void* window_handle) = 0; virtual bool Initialize(const WindowSystemInfo& wsi) = 0;
virtual void Shutdown() = 0; virtual void Shutdown() = 0;
virtual std::string GetName() const = 0; virtual std::string GetName() const = 0;