mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-29 17:19:44 -06:00
Drop Host_GetRenderSurface and pass display to backend
This commit is contained in:
@ -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
|
||||
|
Reference in New Issue
Block a user