diff options
| author | Connor McLaughlin <stenzek@gmail.com> | 2019-10-31 23:42:38 +1000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-10-31 23:42:38 +1000 |
| commit | c6841a027a1c34a35b94e436e909cfdbfbbdbfc7 (patch) | |
| tree | f09efa7bee413d3f2e03c0391c73ebfed93923de /Source/Core/VideoBackends/Vulkan/SwapChain.cpp | |
| parent | d3ee0a4535cb34b2d7c27219d43a82cb1094e7f6 (diff) | |
| parent | 16f103ab42c6faca0cb2c4ce6e93546d22feb1a4 (diff) | |
Merge pull request #8372 from stenzek/vulkan-exclusive-fullscreen
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.cpp | 80 |
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; |
