summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Vulkan
diff options
context:
space:
mode:
authorStenzek <stenzek@users.noreply.github.com>2018-10-24 14:51:21 +1100
committerGitHub <noreply@github.com>2018-10-24 14:51:21 +1100
commitc4d1e4adffcd380cc87b841069ce2fe8b62d7b60 (patch)
treec61a0a07c14ccc3c1f7247bdcc82927a82c145bb /Source/Core/VideoBackends/Vulkan
parent9c9d598ec006527bc47aea306e5171d03c12c5f5 (diff)
parent2c6d96433c322b50470705d43005fd6308506d49 (diff)
Merge pull request #7450 from stenzek/glcontext
GLInterface refactoring/cleanup and runtime platform selection
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan')
-rw-r--r--Source/Core/VideoBackends/Vulkan/Renderer.cpp48
-rw-r--r--Source/Core/VideoBackends/Vulkan/Renderer.h2
-rw-r--r--Source/Core/VideoBackends/Vulkan/SwapChain.cpp26
-rw-r--r--Source/Core/VideoBackends/Vulkan/SwapChain.h9
-rw-r--r--Source/Core/VideoBackends/Vulkan/VideoBackend.h4
-rw-r--r--Source/Core/VideoBackends/Vulkan/main.cpp11
6 files changed, 38 insertions, 62 deletions
diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp
index 38d7bd0992..ce52b0718d 100644
--- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp
+++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp
@@ -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();
@@ -914,9 +889,6 @@ void Renderer::CheckForSurfaceResize()
if (!m_surface_resized.TestAndClear())
return;
- m_backbuffer_width = m_new_backbuffer_width;
- m_backbuffer_height = m_new_backbuffer_height;
-
// If we don't have a surface, how can we resize the swap chain?
// CheckForSurfaceChange should handle this case.
if (!m_swap_chain)
diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.h b/Source/Core/VideoBackends/Vulkan/Renderer.h
index ce15d12592..ba8fd889bd 100644
--- a/Source/Core/VideoBackends/Vulkan/Renderer.h
+++ b/Source/Core/VideoBackends/Vulkan/Renderer.h
@@ -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;
diff --git a/Source/Core/VideoBackends/Vulkan/SwapChain.cpp b/Source/Core/VideoBackends/Vulkan/SwapChain.cpp
index 3294b944ef..5222d88114 100644
--- a/Source/Core/VideoBackends/Vulkan/SwapChain.cpp
+++ b/Source/Core/VideoBackends/Vulkan/SwapChain.cpp
@@ -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
diff --git a/Source/Core/VideoBackends/Vulkan/SwapChain.h b/Source/Core/VideoBackends/Vulkan/SwapChain.h
index 1561103cb8..8cf2776a36 100644
--- a/Source/Core/VideoBackends/Vulkan/SwapChain.h
+++ b/Source/Core/VideoBackends/Vulkan/SwapChain.h
@@ -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 = {};
diff --git a/Source/Core/VideoBackends/Vulkan/VideoBackend.h b/Source/Core/VideoBackends/Vulkan/VideoBackend.h
index d4f284962b..83d960330e 100644
--- a/Source/Core/VideoBackends/Vulkan/VideoBackend.h
+++ b/Source/Core/VideoBackends/Vulkan/VideoBackend.h
@@ -12,11 +12,11 @@ namespace Vulkan
class VideoBackend : public VideoBackendBase
{
public:
- bool Initialize(void* window_handle) override;
+ bool Initialize(const WindowSystemInfo& wsi) override;
void Shutdown() override;
std::string GetName() const override { return "Vulkan"; }
std::string GetDisplayName() const override { return _trans("Vulkan"); }
void InitBackendInfo() override;
};
-}
+} // namespace Vulkan
diff --git a/Source/Core/VideoBackends/Vulkan/main.cpp b/Source/Core/VideoBackends/Vulkan/main.cpp
index 9bd4039138..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* window_handle)
+bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
{
if (!LoadVulkanLibrary())
{
@@ -107,7 +107,7 @@ bool VideoBackend::Initialize(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* window_handle)
VkSurfaceKHR surface = VK_NULL_HANDLE;
if (enable_surface)
{
- surface = SwapChain::CreateVulkanSurface(instance, 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* 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(wsi.display_connection, wsi.render_surface, surface, g_Config.IsVSync());
if (!swap_chain)
{
PanicAlert("Failed to create Vulkan swap chain.");
@@ -271,4 +272,4 @@ void VideoBackend::Shutdown()
ShutdownShared();
UnloadVulkanLibrary();
}
-}
+} // namespace Vulkan