summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Vulkan/SwapChain.cpp
diff options
context:
space:
mode:
authorStenzek <stenzek@gmail.com>2019-10-01 01:10:08 +1000
committerStenzek <stenzek@gmail.com>2019-10-31 22:45:59 +1000
commit16f103ab42c6faca0cb2c4ce6e93546d22feb1a4 (patch)
treef09efa7bee413d3f2e03c0391c73ebfed93923de /Source/Core/VideoBackends/Vulkan/SwapChain.cpp
parent6fc6444687a7cdd7ece0ce4841f59323b00c3df6 (diff)
Vulkan: Exclusive fullscreen support via VK_EXT_full_screen_exclusive
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan/SwapChain.cpp')
-rw-r--r--Source/Core/VideoBackends/Vulkan/SwapChain.cpp80
1 files changed, 77 insertions, 3 deletions
diff --git a/Source/Core/VideoBackends/Vulkan/SwapChain.cpp b/Source/Core/VideoBackends/Vulkan/SwapChain.cpp
index ef9b6f7265..66f20e5a6e 100644
--- a/Source/Core/VideoBackends/Vulkan/SwapChain.cpp
+++ b/Source/Core/VideoBackends/Vulkan/SwapChain.cpp
@@ -25,7 +25,8 @@
namespace Vulkan
{
SwapChain::SwapChain(const WindowSystemInfo& wsi, VkSurfaceKHR surface, bool vsync)
- : m_wsi(wsi), m_surface(surface), m_vsync_enabled(vsync)
+ : m_wsi(wsi), m_surface(surface), m_vsync_enabled(vsync),
+ m_fullscreen_supported(g_vulkan_context->SupportsExclusiveFullscreen(wsi, surface))
{
}
@@ -290,6 +291,7 @@ bool SwapChain::CreateSwapChain()
// Store the old/current swap chain when recreating for resize
VkSwapchainKHR old_swap_chain = m_swap_chain;
+ m_swap_chain = VK_NULL_HANDLE;
// Now we can actually create the swap chain
VkSwapchainCreateInfoKHR swap_chain_info = {VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
@@ -322,8 +324,36 @@ bool SwapChain::CreateSwapChain()
swap_chain_info.pQueueFamilyIndices = indices.data();
}
- res =
- vkCreateSwapchainKHR(g_vulkan_context->GetDevice(), &swap_chain_info, nullptr, &m_swap_chain);
+#ifdef SUPPORTS_VULKAN_EXCLUSIVE_FULLSCREEN
+ if (m_fullscreen_supported)
+ {
+ VkSurfaceFullScreenExclusiveInfoEXT fullscreen_support = {};
+ swap_chain_info.pNext = &fullscreen_support;
+ fullscreen_support.sType = VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT;
+ fullscreen_support.fullScreenExclusive = VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT;
+
+ auto platform_info = g_vulkan_context->GetPlatformExclusiveFullscreenInfo(m_wsi);
+ fullscreen_support.pNext = &platform_info;
+
+ res = vkCreateSwapchainKHR(g_vulkan_context->GetDevice(), &swap_chain_info, nullptr,
+ &m_swap_chain);
+ if (res != VK_SUCCESS)
+ {
+ // Try without exclusive fullscreen.
+ WARN_LOG(VIDEO, "Failed to create exclusive fullscreen swapchain, trying without.");
+ swap_chain_info.pNext = nullptr;
+ g_Config.backend_info.bSupportsExclusiveFullscreen = false;
+ g_ActiveConfig.backend_info.bSupportsExclusiveFullscreen = false;
+ m_fullscreen_supported = false;
+ }
+ }
+#endif
+
+ if (m_swap_chain == VK_NULL_HANDLE)
+ {
+ res = vkCreateSwapchainKHR(g_vulkan_context->GetDevice(), &swap_chain_info, nullptr,
+ &m_swap_chain);
+ }
if (res != VK_SUCCESS)
{
LOG_VULKAN_ERROR(res, "vkCreateSwapchainKHR failed: ");
@@ -414,6 +444,10 @@ void SwapChain::DestroySwapChain()
if (m_swap_chain == VK_NULL_HANDLE)
return;
+ // Release exclusive fullscreen before destroying.
+ if (m_current_fullscreen_state)
+ SetFullscreenState(false);
+
vkDestroySwapchainKHR(g_vulkan_context->GetDevice(), m_swap_chain, nullptr);
m_swap_chain = VK_NULL_HANDLE;
}
@@ -464,6 +498,39 @@ bool SwapChain::SetVSync(bool enabled)
return RecreateSwapChain();
}
+bool SwapChain::SetFullscreenState(bool state)
+{
+#ifdef SUPPORTS_VULKAN_EXCLUSIVE_FULLSCREEN
+ if (m_current_fullscreen_state == state)
+ return true;
+
+ if (state)
+ {
+ VkResult res = vkAcquireFullScreenExclusiveModeEXT(g_vulkan_context->GetDevice(), m_swap_chain);
+ if (res != VK_SUCCESS)
+ {
+ LOG_VULKAN_ERROR(res, "vkAcquireFullScreenExclusiveModeEXT failed:");
+ return false;
+ }
+
+ INFO_LOG(VIDEO, "Exclusive fullscreen acquired.");
+ }
+ else
+ {
+ VkResult res = vkReleaseFullScreenExclusiveModeEXT(g_vulkan_context->GetDevice(), m_swap_chain);
+ if (res != VK_SUCCESS)
+ LOG_VULKAN_ERROR(res, "vkReleaseFullScreenExclusiveModeEXT failed:");
+
+ INFO_LOG(VIDEO, "Exclusive fullscreen released.");
+ }
+
+ m_current_fullscreen_state = state;
+ return true;
+#else
+ return false;
+#endif
+}
+
bool SwapChain::RecreateSurface(void* native_handle)
{
// Destroy the old swap chain, images, and surface.
@@ -493,6 +560,13 @@ bool SwapChain::RecreateSurface(void* native_handle)
return false;
}
+ // Update exclusive fullscreen support (unlikely to change).
+ m_fullscreen_supported = g_vulkan_context->SupportsExclusiveFullscreen(m_wsi, m_surface);
+ g_Config.backend_info.bSupportsExclusiveFullscreen = m_fullscreen_supported;
+ g_ActiveConfig.backend_info.bSupportsExclusiveFullscreen = m_fullscreen_supported;
+ m_current_fullscreen_state = false;
+ m_next_fullscreen_state = false;
+
// Finally re-create the swap chain
if (!CreateSwapChain() || !SetupSwapChainImages())
return false;