Drop Host_GetRenderSurface and pass display to backend
This commit is contained in:
parent
134d967be2
commit
a3961750a7
|
@ -89,11 +89,6 @@ void Host_Message(HostMessageID id)
|
|||
}
|
||||
}
|
||||
|
||||
void* Host_GetRenderHandle()
|
||||
{
|
||||
return s_surf;
|
||||
}
|
||||
|
||||
void Host_UpdateTitle(const std::string& title)
|
||||
{
|
||||
__android_log_write(ANDROID_LOG_INFO, DOLPHIN_TAG, title.c_str());
|
||||
|
|
|
@ -78,6 +78,14 @@ struct BootParameters
|
|||
Parameters parameters;
|
||||
std::optional<std::string> 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
|
||||
|
|
|
@ -89,7 +89,6 @@ static bool s_is_stopping = false;
|
|||
static bool s_hardware_initialized = false;
|
||||
static bool s_is_started = false;
|
||||
static Common::Flag s_is_booting;
|
||||
static void* s_window_handle = nullptr;
|
||||
static std::thread s_emu_thread;
|
||||
static StateChangedCallbackFunc s_on_state_changed_callback;
|
||||
|
||||
|
@ -215,8 +214,6 @@ bool Init(std::unique_ptr<BootParameters> boot)
|
|||
|
||||
Host_UpdateMainFrame(); // Disable any menus or buttons at boot
|
||||
|
||||
s_window_handle = Host_GetRenderHandle();
|
||||
|
||||
// Start the emu thread
|
||||
s_emu_thread = std::thread(EmuThread, std::move(boot));
|
||||
return true;
|
||||
|
@ -441,7 +438,7 @@ static void EmuThread(std::unique_ptr<BootParameters> boot)
|
|||
g_video_backend->InitBackendInfo();
|
||||
g_Config.Refresh();
|
||||
|
||||
if (!g_video_backend->Initialize(s_window_handle))
|
||||
if (!g_video_backend->Initialize(boot->display_connection, boot->render_surface))
|
||||
{
|
||||
PanicAlert("Failed to initialize video backend!");
|
||||
return;
|
||||
|
@ -462,7 +459,7 @@ static void EmuThread(std::unique_ptr<BootParameters> boot)
|
|||
bool init_controllers = false;
|
||||
if (!g_controller_interface.IsInit())
|
||||
{
|
||||
g_controller_interface.Initialize(s_window_handle);
|
||||
g_controller_interface.Initialize(boot->render_surface);
|
||||
Pad::Initialize();
|
||||
Keyboard::Initialize();
|
||||
init_controllers = true;
|
||||
|
@ -958,4 +955,4 @@ void DoFrameStep()
|
|||
}
|
||||
}
|
||||
|
||||
} // Core
|
||||
} // namespace Core
|
||||
|
|
|
@ -44,6 +44,3 @@ void Host_UpdateMainFrame();
|
|||
void Host_UpdateTitle(const std::string& title);
|
||||
void Host_YieldToUI();
|
||||
void Host_UpdateProgressDialog(const char* caption, int position, int total);
|
||||
|
||||
// TODO (neobrain): Remove this from host!
|
||||
void* Host_GetRenderHandle();
|
||||
|
|
|
@ -71,6 +71,9 @@ public:
|
|||
}
|
||||
virtual void Shutdown() {}
|
||||
virtual ~Platform() {}
|
||||
|
||||
virtual void* GetDisplayHandle() { return nullptr; }
|
||||
virtual void* GetWindowHandle() { return nullptr; }
|
||||
};
|
||||
|
||||
static Platform* platform;
|
||||
|
@ -91,12 +94,6 @@ void Host_Message(HostMessageID id)
|
|||
updateMainFrameEvent.Set();
|
||||
}
|
||||
|
||||
static void* s_window_handle = nullptr;
|
||||
void* Host_GetRenderHandle()
|
||||
{
|
||||
return s_window_handle;
|
||||
}
|
||||
|
||||
void Host_UpdateTitle(const std::string& title)
|
||||
{
|
||||
platform->SetTitle(title);
|
||||
|
@ -187,7 +184,6 @@ class PlatformX11 : public Platform
|
|||
}
|
||||
XMapRaised(dpy, win);
|
||||
XFlush(dpy);
|
||||
s_window_handle = (void*)win;
|
||||
|
||||
if (SConfig::GetInstance().bDisableScreenSaver)
|
||||
X11Utils::InhibitScreensaver(win, true);
|
||||
|
@ -354,6 +350,10 @@ class PlatformX11 : public Platform
|
|||
|
||||
XCloseDisplay(dpy);
|
||||
}
|
||||
|
||||
void* GetDisplayHandle() override { return static_cast<void*>(dpy); }
|
||||
|
||||
void* GetWindowHandle() override { return reinterpret_cast<void*>(win); }
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -433,6 +433,9 @@ int main(int argc, char* argv[])
|
|||
|
||||
DolphinAnalytics::Instance()->ReportDolphinStart("nogui");
|
||||
|
||||
boot->display_connection = platform->GetDisplayHandle();
|
||||
boot->render_surface = platform->GetWindowHandle();
|
||||
|
||||
if (!BootManager::BootCore(std::move(boot)))
|
||||
{
|
||||
fprintf(stderr, "Could not boot the specified file\n");
|
||||
|
|
|
@ -30,14 +30,10 @@ Host* Host::GetInstance()
|
|||
return s_instance;
|
||||
}
|
||||
|
||||
void* Host::GetRenderHandle()
|
||||
{
|
||||
return m_render_handle;
|
||||
}
|
||||
|
||||
void Host::SetRenderHandle(void* handle)
|
||||
{
|
||||
m_render_handle = handle;
|
||||
if (g_renderer)
|
||||
g_renderer->ChangeSurface(handle);
|
||||
}
|
||||
|
||||
bool Host::GetRenderFocus()
|
||||
|
@ -94,11 +90,6 @@ void Host_UpdateTitle(const std::string& title)
|
|||
emit Host::GetInstance()->RequestTitle(QString::fromStdString(title));
|
||||
}
|
||||
|
||||
void* Host_GetRenderHandle()
|
||||
{
|
||||
return Host::GetInstance()->GetRenderHandle();
|
||||
}
|
||||
|
||||
bool Host_RendererHasFocus()
|
||||
{
|
||||
return Host::GetInstance()->GetRenderFocus();
|
||||
|
|
|
@ -20,7 +20,6 @@ class Host final : public QObject
|
|||
public:
|
||||
static Host* GetInstance();
|
||||
|
||||
void* GetRenderHandle();
|
||||
bool GetRenderFocus();
|
||||
bool GetRenderFullscreen();
|
||||
|
||||
|
|
|
@ -26,6 +26,10 @@
|
|||
#include "QtUtils/SignalDaemon.h"
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#endif
|
||||
|
||||
#include "Common/Version.h"
|
||||
|
||||
#include "Core/Boot/Boot.h"
|
||||
|
@ -98,7 +102,6 @@
|
|||
#include "VideoCommon/VideoConfig.h"
|
||||
|
||||
#if defined(HAVE_XRANDR) && HAVE_XRANDR
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#include "UICommon/X11Utils.h"
|
||||
#endif
|
||||
|
||||
|
@ -797,14 +800,26 @@ void MainWindow::StartGame(std::unique_ptr<BootParameters>&& parameters)
|
|||
m_pending_boot = std::move(parameters);
|
||||
return;
|
||||
}
|
||||
|
||||
// We need the render widget before booting.
|
||||
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.
|
||||
if (!BootManager::BootCore(std::move(parameters)))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Failed to init core"), QMessageBox::Ok);
|
||||
HideRenderWidget();
|
||||
return;
|
||||
}
|
||||
|
||||
ShowRenderWidget();
|
||||
#ifdef USE_DISCORD_PRESENCE
|
||||
if (!NetPlay::IsNetPlayRunning())
|
||||
Discord::UpdateDiscordPresence();
|
||||
|
|
|
@ -55,8 +55,6 @@ RenderWidget::RenderWidget(QWidget* parent) : QWidget(parent)
|
|||
connect(this, &RenderWidget::FocusChanged, Host::GetInstance(), &Host::SetRenderFocus,
|
||||
Qt::DirectConnection);
|
||||
|
||||
emit HandleChanged((void*)winId());
|
||||
|
||||
m_mouse_timer = new QTimer(this);
|
||||
connect(m_mouse_timer, &QTimer::timeout, this, &RenderWidget::HandleCursorTimer);
|
||||
m_mouse_timer->setSingleShot(true);
|
||||
|
@ -144,7 +142,7 @@ bool RenderWidget::event(QEvent* event)
|
|||
}
|
||||
break;
|
||||
case QEvent::WinIdChange:
|
||||
emit HandleChanged((void*)winId());
|
||||
emit HandleChanged(reinterpret_cast<void*>(winId()));
|
||||
break;
|
||||
case QEvent::WindowActivate:
|
||||
if (SConfig::GetInstance().m_PauseOnFocusLost && Core::GetState() == Core::State::Paused)
|
||||
|
|
|
@ -225,6 +225,11 @@ void Renderer::Create3DVisionTexture(int width, int height)
|
|||
DXGI_FORMAT_R8G8B8A8_UNORM, 1, 1, &sys_data);
|
||||
}
|
||||
|
||||
bool Renderer::IsHeadless() const
|
||||
{
|
||||
return D3D::swapchain == nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<AbstractTexture> Renderer::CreateTexture(const TextureConfig& config)
|
||||
{
|
||||
return std::make_unique<DXTexture>(config);
|
||||
|
@ -698,12 +703,12 @@ void Renderer::CheckForSurfaceChange()
|
|||
if (!m_surface_changed.TestAndClear())
|
||||
return;
|
||||
|
||||
m_surface_handle = m_new_surface_handle;
|
||||
m_new_surface_handle = nullptr;
|
||||
|
||||
SAFE_RELEASE(m_screenshot_texture);
|
||||
SAFE_RELEASE(m_3d_vision_texture);
|
||||
|
||||
D3D::Reset(reinterpret_cast<HWND>(m_new_surface_handle));
|
||||
m_new_surface_handle = nullptr;
|
||||
|
||||
UpdateBackbufferSize();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,9 @@ public:
|
|||
~Renderer() override;
|
||||
|
||||
StateCache& GetStateCache() { return m_state_cache; }
|
||||
|
||||
bool IsHeadless() const override;
|
||||
|
||||
std::unique_ptr<AbstractTexture> CreateTexture(const TextureConfig& config) override;
|
||||
std::unique_ptr<AbstractStagingTexture>
|
||||
CreateStagingTexture(StagingTextureType type, const TextureConfig& config) override;
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace DX11
|
|||
{
|
||||
class VideoBackend : public VideoBackendBase
|
||||
{
|
||||
bool Initialize(void*) override;
|
||||
bool Initialize(void* display_handle, void* window_handle) override;
|
||||
void Shutdown() override;
|
||||
|
||||
std::string GetName() const override;
|
||||
|
@ -19,4 +19,4 @@ class VideoBackend : public VideoBackendBase
|
|||
|
||||
void InitBackendInfo() override;
|
||||
};
|
||||
}
|
||||
} // namespace DX11
|
||||
|
|
|
@ -127,7 +127,7 @@ void VideoBackend::InitBackendInfo()
|
|||
DX11::D3D::UnloadD3D();
|
||||
}
|
||||
|
||||
bool VideoBackend::Initialize(void* window_handle)
|
||||
bool VideoBackend::Initialize(void* display_handle, void* window_handle)
|
||||
{
|
||||
if (window_handle == nullptr)
|
||||
return false;
|
||||
|
@ -188,4 +188,4 @@ void VideoBackend::Shutdown()
|
|||
|
||||
D3D::Close();
|
||||
}
|
||||
}
|
||||
} // namespace DX11
|
||||
|
|
|
@ -54,7 +54,7 @@ void VideoBackend::InitBackendInfo()
|
|||
g_Config.backend_info.AAModes = {1};
|
||||
}
|
||||
|
||||
bool VideoBackend::Initialize(void* window_handle)
|
||||
bool VideoBackend::Initialize(void* display_handle, void* window_handle)
|
||||
{
|
||||
InitializeShared();
|
||||
|
||||
|
@ -80,4 +80,4 @@ void VideoBackend::Shutdown()
|
|||
|
||||
ShutdownShared();
|
||||
}
|
||||
}
|
||||
} // namespace Null
|
||||
|
|
|
@ -24,6 +24,11 @@ Renderer::~Renderer()
|
|||
UpdateActiveConfig();
|
||||
}
|
||||
|
||||
bool Renderer::IsHeadless() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<AbstractTexture> Renderer::CreateTexture(const TextureConfig& config)
|
||||
{
|
||||
return std::make_unique<NullTexture>(config);
|
||||
|
|
|
@ -14,6 +14,8 @@ public:
|
|||
Renderer();
|
||||
~Renderer() override;
|
||||
|
||||
bool IsHeadless() const override;
|
||||
|
||||
std::unique_ptr<AbstractTexture> CreateTexture(const TextureConfig& config) override;
|
||||
std::unique_ptr<AbstractStagingTexture>
|
||||
CreateStagingTexture(StagingTextureType type, const TextureConfig& config) override;
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace Null
|
|||
{
|
||||
class VideoBackend : public VideoBackendBase
|
||||
{
|
||||
bool Initialize(void* window_handle) override;
|
||||
bool Initialize(void* display_handle, void* window_handle) override;
|
||||
void Shutdown() override;
|
||||
|
||||
std::string GetName() const override { return "Null"; }
|
||||
|
@ -22,4 +22,4 @@ class VideoBackend : public VideoBackendBase
|
|||
}
|
||||
void InitBackendInfo() override;
|
||||
};
|
||||
}
|
||||
} // namespace Null
|
||||
|
|
|
@ -804,6 +804,11 @@ Renderer::Renderer()
|
|||
|
||||
Renderer::~Renderer() = default;
|
||||
|
||||
bool Renderer::IsHeadless() const
|
||||
{
|
||||
return g_main_gl_context->IsHeadless();
|
||||
}
|
||||
|
||||
void Renderer::Shutdown()
|
||||
{
|
||||
::Renderer::Shutdown();
|
||||
|
@ -1499,9 +1504,8 @@ void Renderer::CheckForSurfaceChange()
|
|||
if (!m_surface_changed.TestAndClear())
|
||||
return;
|
||||
|
||||
m_surface_handle = m_new_surface_handle;
|
||||
g_main_gl_context->UpdateSurface(m_new_surface_handle);
|
||||
m_new_surface_handle = nullptr;
|
||||
g_main_gl_context->UpdateSurface(m_surface_handle);
|
||||
|
||||
// With a surface change, the window likely has new dimensions.
|
||||
m_backbuffer_width = g_main_gl_context->GetBackBufferWidth();
|
||||
|
|
|
@ -84,6 +84,8 @@ public:
|
|||
Renderer();
|
||||
~Renderer() override;
|
||||
|
||||
bool IsHeadless() const override;
|
||||
|
||||
void Init();
|
||||
void Shutdown() override;
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace OGL
|
|||
{
|
||||
class VideoBackend : public VideoBackendBase
|
||||
{
|
||||
bool Initialize(void*) override;
|
||||
bool Initialize(void* display_handle, void* window_handle) override;
|
||||
void Shutdown() override;
|
||||
|
||||
std::string GetName() const override;
|
||||
|
@ -23,4 +23,4 @@ private:
|
|||
bool InitializeGLExtensions();
|
||||
bool FillBackendInfo();
|
||||
};
|
||||
}
|
||||
} // namespace OGL
|
||||
|
|
|
@ -157,7 +157,7 @@ bool VideoBackend::FillBackendInfo()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool VideoBackend::Initialize(void* window_handle)
|
||||
bool VideoBackend::Initialize(void* display_handle, void* window_handle)
|
||||
{
|
||||
InitializeShared();
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <string>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/GL/GLContext.h"
|
||||
|
||||
#include "Core/Config/GraphicsSettings.h"
|
||||
#include "Core/HW/Memmap.h"
|
||||
|
@ -28,6 +29,11 @@ SWRenderer::SWRenderer()
|
|||
{
|
||||
}
|
||||
|
||||
bool SWRenderer::IsHeadless() const
|
||||
{
|
||||
return g_main_gl_context->IsHeadless();
|
||||
}
|
||||
|
||||
std::unique_ptr<AbstractTexture> SWRenderer::CreateTexture(const TextureConfig& config)
|
||||
{
|
||||
return std::make_unique<SW::SWTexture>(config);
|
||||
|
|
|
@ -13,6 +13,8 @@ class SWRenderer : public Renderer
|
|||
public:
|
||||
SWRenderer();
|
||||
|
||||
bool IsHeadless() const override;
|
||||
|
||||
std::unique_ptr<AbstractTexture> CreateTexture(const TextureConfig& config) override;
|
||||
std::unique_ptr<AbstractStagingTexture>
|
||||
CreateStagingTexture(StagingTextureType type, const TextureConfig& config) override;
|
||||
|
|
|
@ -78,7 +78,7 @@ void VideoSoftware::InitBackendInfo()
|
|||
g_Config.backend_info.AAModes = {1};
|
||||
}
|
||||
|
||||
bool VideoSoftware::Initialize(void* window_handle)
|
||||
bool VideoSoftware::Initialize(void* display_handle, void* window_handle)
|
||||
{
|
||||
InitializeShared();
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace SW
|
|||
{
|
||||
class VideoSoftware : public VideoBackendBase
|
||||
{
|
||||
bool Initialize(void* window_handle) override;
|
||||
bool Initialize(void* display_handle, void* window_handle) override;
|
||||
void Shutdown() override;
|
||||
|
||||
std::string GetName() const override;
|
||||
|
@ -19,4 +19,4 @@ class VideoSoftware : public VideoBackendBase
|
|||
|
||||
void InitBackendInfo() override;
|
||||
};
|
||||
}
|
||||
} // namespace SW
|
||||
|
|
|
@ -70,6 +70,11 @@ Renderer* Renderer::GetInstance()
|
|||
return static_cast<Renderer*>(g_renderer.get());
|
||||
}
|
||||
|
||||
bool Renderer::IsHeadless() const
|
||||
{
|
||||
return m_swap_chain == nullptr;
|
||||
}
|
||||
|
||||
bool Renderer::Initialize()
|
||||
{
|
||||
BindEFBToStateTracker();
|
||||
|
@ -860,12 +865,9 @@ void Renderer::BlitScreen(VkRenderPass render_pass, const TargetRectangle& dst_r
|
|||
|
||||
void Renderer::CheckForSurfaceChange()
|
||||
{
|
||||
if (!m_surface_changed.TestAndClear())
|
||||
if (!m_surface_changed.TestAndClear() || !m_swap_chain)
|
||||
return;
|
||||
|
||||
m_surface_handle = m_new_surface_handle;
|
||||
m_new_surface_handle = nullptr;
|
||||
|
||||
// Submit the current draws up until rendering the XFB.
|
||||
g_command_buffer_mgr->ExecuteCommandBuffer(false, false);
|
||||
g_command_buffer_mgr->WaitForGPUIdle();
|
||||
|
@ -873,37 +875,10 @@ void Renderer::CheckForSurfaceChange()
|
|||
// Clear the present failed flag, since we don't want to resize after recreating.
|
||||
g_command_buffer_mgr->CheckLastPresentFail();
|
||||
|
||||
// Did we previously have a swap chain?
|
||||
if (m_swap_chain)
|
||||
{
|
||||
if (!m_surface_handle)
|
||||
{
|
||||
// If there is no surface now, destroy the swap chain.
|
||||
m_swap_chain.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Recreate the surface. If this fails we're in trouble.
|
||||
if (!m_swap_chain->RecreateSurface(m_surface_handle))
|
||||
PanicAlert("Failed to recreate Vulkan surface. Cannot continue.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Previously had no swap chain. So create one.
|
||||
VkSurfaceKHR surface =
|
||||
SwapChain::CreateVulkanSurface(g_vulkan_context->GetVulkanInstance(), m_surface_handle);
|
||||
if (surface != VK_NULL_HANDLE)
|
||||
{
|
||||
m_swap_chain = SwapChain::Create(m_surface_handle, surface, g_ActiveConfig.IsVSync());
|
||||
if (!m_swap_chain)
|
||||
PanicAlert("Failed to create swap chain.");
|
||||
}
|
||||
else
|
||||
{
|
||||
PanicAlert("Failed to create surface.");
|
||||
}
|
||||
}
|
||||
// Recreate the surface. If this fails we're in trouble.
|
||||
if (!m_swap_chain->RecreateSurface(m_new_surface_handle))
|
||||
PanicAlert("Failed to recreate Vulkan surface. Cannot continue.");
|
||||
m_new_surface_handle = nullptr;
|
||||
|
||||
// Handle case where the dimensions are now different.
|
||||
OnSwapChainResized();
|
||||
|
|
|
@ -35,6 +35,8 @@ public:
|
|||
|
||||
static Renderer* GetInstance();
|
||||
|
||||
bool IsHeadless() const override;
|
||||
|
||||
std::unique_ptr<AbstractTexture> CreateTexture(const TextureConfig& config) override;
|
||||
std::unique_ptr<AbstractStagingTexture>
|
||||
CreateStagingTexture(StagingTextureType type, const TextureConfig& config) override;
|
||||
|
|
|
@ -25,8 +25,9 @@
|
|||
|
||||
namespace Vulkan
|
||||
{
|
||||
SwapChain::SwapChain(void* native_handle, VkSurfaceKHR surface, bool vsync)
|
||||
: m_native_handle(native_handle), m_surface(surface), m_vsync_enabled(vsync)
|
||||
SwapChain::SwapChain(void* display_handle, void* native_handle, VkSurfaceKHR surface, bool vsync)
|
||||
: m_display_handle(display_handle), m_native_handle(native_handle), m_surface(surface),
|
||||
m_vsync_enabled(vsync)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -37,7 +38,7 @@ SwapChain::~SwapChain()
|
|||
DestroySurface();
|
||||
}
|
||||
|
||||
VkSurfaceKHR SwapChain::CreateVulkanSurface(VkInstance instance, void* hwnd)
|
||||
VkSurfaceKHR SwapChain::CreateVulkanSurface(VkInstance instance, void* display_handle, void* hwnd)
|
||||
{
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR)
|
||||
VkWin32SurfaceCreateInfoKHR surface_create_info = {
|
||||
|
@ -59,15 +60,11 @@ VkSurfaceKHR SwapChain::CreateVulkanSurface(VkInstance instance, void* hwnd)
|
|||
return surface;
|
||||
|
||||
#elif defined(VK_USE_PLATFORM_XLIB_KHR)
|
||||
// Assuming the display handles are compatible, or shared. This matches what we do in the
|
||||
// GL backend, but it's not ideal.
|
||||
Display* display = XOpenDisplay(nullptr);
|
||||
|
||||
VkXlibSurfaceCreateInfoKHR surface_create_info = {
|
||||
VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, // VkStructureType sType
|
||||
nullptr, // const void* pNext
|
||||
0, // VkXlibSurfaceCreateFlagsKHR flags
|
||||
display, // Display* dpy
|
||||
static_cast<Display*>(display_handle), // Display* dpy
|
||||
reinterpret_cast<Window>(hwnd) // Window window
|
||||
};
|
||||
|
||||
|
@ -83,8 +80,7 @@ VkSurfaceKHR SwapChain::CreateVulkanSurface(VkInstance instance, void* hwnd)
|
|||
|
||||
#elif defined(VK_USE_PLATFORM_XCB_KHR)
|
||||
// If we ever switch to using xcb, we should pass the display handle as well.
|
||||
Display* display = XOpenDisplay(nullptr);
|
||||
xcb_connection_t* connection = XGetXCBConnection(display);
|
||||
xcb_connection_t* connection = XGetXCBConnection(display_handle);
|
||||
|
||||
VkXcbSurfaceCreateInfoKHR surface_create_info = {
|
||||
VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, // VkStructureType sType
|
||||
|
@ -127,10 +123,11 @@ VkSurfaceKHR SwapChain::CreateVulkanSurface(VkInstance instance, void* hwnd)
|
|||
#endif
|
||||
}
|
||||
|
||||
std::unique_ptr<SwapChain> SwapChain::Create(void* native_handle, VkSurfaceKHR surface, bool vsync)
|
||||
std::unique_ptr<SwapChain> SwapChain::Create(void* display_handle, void* native_handle,
|
||||
VkSurfaceKHR surface, bool vsync)
|
||||
{
|
||||
std::unique_ptr<SwapChain> swap_chain =
|
||||
std::make_unique<SwapChain>(native_handle, surface, vsync);
|
||||
std::make_unique<SwapChain>(display_handle, native_handle, surface, vsync);
|
||||
|
||||
if (!swap_chain->CreateSwapChain() || !swap_chain->CreateRenderPass() ||
|
||||
!swap_chain->SetupSwapChainImages())
|
||||
|
@ -467,7 +464,8 @@ bool SwapChain::RecreateSurface(void* native_handle)
|
|||
|
||||
// Re-create the surface with the new native handle
|
||||
m_native_handle = native_handle;
|
||||
m_surface = CreateVulkanSurface(g_vulkan_context->GetVulkanInstance(), native_handle);
|
||||
m_surface =
|
||||
CreateVulkanSurface(g_vulkan_context->GetVulkanInstance(), m_display_handle, native_handle);
|
||||
if (m_surface == VK_NULL_HANDLE)
|
||||
return false;
|
||||
|
||||
|
@ -499,4 +497,4 @@ void SwapChain::DestroySurface()
|
|||
vkDestroySurfaceKHR(g_vulkan_context->GetVulkanInstance(), m_surface, nullptr);
|
||||
m_surface = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
} // namespace Vulkan
|
||||
|
|
|
@ -19,15 +19,17 @@ class ObjectCache;
|
|||
class SwapChain
|
||||
{
|
||||
public:
|
||||
SwapChain(void* native_handle, VkSurfaceKHR surface, bool vsync);
|
||||
SwapChain(void* display_handle, void* native_handle, VkSurfaceKHR surface, bool vsync);
|
||||
~SwapChain();
|
||||
|
||||
// Creates a vulkan-renderable surface for the specified window handle.
|
||||
static VkSurfaceKHR CreateVulkanSurface(VkInstance instance, void* hwnd);
|
||||
static VkSurfaceKHR CreateVulkanSurface(VkInstance instance, void* display_handle, void* hwnd);
|
||||
|
||||
// Create a new swap chain from a pre-existing surface.
|
||||
static std::unique_ptr<SwapChain> Create(void* native_handle, VkSurfaceKHR surface, bool vsync);
|
||||
static std::unique_ptr<SwapChain> Create(void* display_handle, void* native_handle,
|
||||
VkSurfaceKHR surface, bool vsync);
|
||||
|
||||
void* GetDisplayHandle() const { return m_display_handle; }
|
||||
void* GetNativeHandle() const { return m_native_handle; }
|
||||
VkSurfaceKHR GetSurface() const { return m_surface; }
|
||||
VkSurfaceFormatKHR GetSurfaceFormat() const { return m_surface_format; }
|
||||
|
@ -81,6 +83,7 @@ private:
|
|||
VkFramebuffer framebuffer;
|
||||
};
|
||||
|
||||
void* m_display_handle;
|
||||
void* m_native_handle;
|
||||
VkSurfaceKHR m_surface = VK_NULL_HANDLE;
|
||||
VkSurfaceFormatKHR m_surface_format = {};
|
||||
|
|
|
@ -12,11 +12,11 @@ namespace Vulkan
|
|||
class VideoBackend : public VideoBackendBase
|
||||
{
|
||||
public:
|
||||
bool Initialize(void* window_handle) override;
|
||||
bool Initialize(void* display_handle, void* window_handle) override;
|
||||
void Shutdown() override;
|
||||
|
||||
std::string GetName() const override { return "Vulkan"; }
|
||||
std::string GetDisplayName() const override { return _trans("Vulkan"); }
|
||||
void InitBackendInfo() override;
|
||||
};
|
||||
}
|
||||
} // namespace Vulkan
|
||||
|
|
|
@ -89,7 +89,7 @@ static bool ShouldEnableDebugReports(bool enable_validation_layers)
|
|||
return enable_validation_layers || IsHostGPULoggingEnabled();
|
||||
}
|
||||
|
||||
bool VideoBackend::Initialize(void* window_handle)
|
||||
bool VideoBackend::Initialize(void* display_handle, void* window_handle)
|
||||
{
|
||||
if (!LoadVulkanLibrary())
|
||||
{
|
||||
|
@ -146,7 +146,7 @@ bool VideoBackend::Initialize(void* window_handle)
|
|||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||
if (enable_surface)
|
||||
{
|
||||
surface = SwapChain::CreateVulkanSurface(instance, window_handle);
|
||||
surface = SwapChain::CreateVulkanSurface(instance, display_handle, window_handle);
|
||||
if (surface == VK_NULL_HANDLE)
|
||||
{
|
||||
PanicAlert("Failed to create Vulkan surface.");
|
||||
|
@ -209,7 +209,7 @@ bool VideoBackend::Initialize(void* window_handle)
|
|||
std::unique_ptr<SwapChain> swap_chain;
|
||||
if (surface != VK_NULL_HANDLE)
|
||||
{
|
||||
swap_chain = SwapChain::Create(window_handle, surface, g_Config.IsVSync());
|
||||
swap_chain = SwapChain::Create(display_handle, window_handle, surface, g_Config.IsVSync());
|
||||
if (!swap_chain)
|
||||
{
|
||||
PanicAlert("Failed to create Vulkan swap chain.");
|
||||
|
@ -271,4 +271,4 @@ void VideoBackend::Shutdown()
|
|||
ShutdownShared();
|
||||
UnloadVulkanLibrary();
|
||||
}
|
||||
}
|
||||
} // namespace Vulkan
|
||||
|
|
|
@ -86,7 +86,6 @@ Renderer::Renderer(int backbuffer_width, int backbuffer_height)
|
|||
if (SConfig::GetInstance().bWii)
|
||||
m_aspect_wide = Config::Get(Config::SYSCONF_WIDESCREEN);
|
||||
|
||||
m_surface_handle = Host_GetRenderHandle();
|
||||
m_last_host_config_bits = ShaderHostConfig::GetCurrent().bits;
|
||||
m_last_efb_multisamples = g_ActiveConfig.iMultisamples;
|
||||
}
|
||||
|
@ -408,7 +407,7 @@ float Renderer::CalculateDrawAspectRatio() const
|
|||
|
||||
bool Renderer::IsHeadless() const
|
||||
{
|
||||
return !m_surface_handle;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Renderer::ChangeSurface(void* new_surface_handle)
|
||||
|
|
|
@ -77,6 +77,8 @@ public:
|
|||
|
||||
using ClearColor = std::array<float, 4>;
|
||||
|
||||
virtual bool IsHeadless() const = 0;
|
||||
|
||||
virtual void SetPipeline(const AbstractPipeline* pipeline) {}
|
||||
virtual void SetScissorRect(const MathUtil::Rectangle<int>& rc) {}
|
||||
virtual void SetTexture(u32 index, const AbstractTexture* texture) {}
|
||||
|
@ -134,7 +136,6 @@ public:
|
|||
|
||||
const TargetRectangle& GetTargetRectangle() const { return m_target_rectangle; }
|
||||
float CalculateDrawAspectRatio() const;
|
||||
bool IsHeadless() const;
|
||||
|
||||
std::tuple<float, float> ScaleToDisplayAspectRatio(int width, int height) const;
|
||||
void UpdateDrawRectangle();
|
||||
|
@ -236,7 +237,6 @@ protected:
|
|||
|
||||
std::unique_ptr<PostProcessingShaderImplementation> m_post_processor;
|
||||
|
||||
void* m_surface_handle = nullptr;
|
||||
void* m_new_surface_handle = nullptr;
|
||||
Common::Flag m_surface_changed;
|
||||
Common::Flag m_surface_resized;
|
||||
|
|
|
@ -35,7 +35,7 @@ class VideoBackendBase
|
|||
{
|
||||
public:
|
||||
virtual ~VideoBackendBase() {}
|
||||
virtual bool Initialize(void* window_handle) = 0;
|
||||
virtual bool Initialize(void* display_handle, void* window_handle) = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
virtual std::string GetName() const = 0;
|
||||
|
|
|
@ -19,10 +19,6 @@ void Host_RefreshDSPDebuggerWindow()
|
|||
void Host_Message(HostMessageID)
|
||||
{
|
||||
}
|
||||
void* Host_GetRenderHandle()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
void Host_UpdateTitle(const std::string&)
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue