From 76518d4c590051944ff978b594361c0a65059002 Mon Sep 17 00:00:00 2001 From: 13xforever Date: Sun, 14 Feb 2021 15:25:25 +0500 Subject: [PATCH] add a hidden option to prevent switching to exclusive full screen mode this is helpful for people streaming RPCS3, or to prevent disabling HDR mode in Windows --- .gitignore | 2 + rpcs3/Emu/RSX/VK/vkutils/device.cpp | 8 +++- rpcs3/Emu/RSX/VK/vkutils/device.h | 2 + rpcs3/Emu/RSX/VK/vkutils/instance.hpp | 5 +++ rpcs3/Emu/RSX/VK/vkutils/swapchain.hpp | 58 +++++++++++++++++++++++++- rpcs3/Emu/system_config.h | 1 + 6 files changed, 73 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 26600c6f61..90327a4ddd 100644 --- a/.gitignore +++ b/.gitignore @@ -119,3 +119,5 @@ yaml-cpp.pc # ssl certificate cacert.pem + +_ReSharper.*/ diff --git a/rpcs3/Emu/RSX/VK/vkutils/device.cpp b/rpcs3/Emu/RSX/VK/vkutils/device.cpp index 3f9b53ceb0..14eaf2d710 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/device.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/device.cpp @@ -56,8 +56,9 @@ namespace vk stencil_export_support = device_extensions.is_supported(VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME); conditional_render_support = device_extensions.is_supported(VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME); - external_memory_host_support = device_extensions.is_supported(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME); + external_memory_host_support = device_extensions.is_supported(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME); unrestricted_depth_range_support = device_extensions.is_supported(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME); + surface_capabilities_2_support = instance_extensions.is_supported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); } void physical_device::create(VkInstance context, VkPhysicalDevice pdev, bool allow_extensions) @@ -517,6 +518,11 @@ namespace vk return pgpu->external_memory_host_support; } + bool render_device::get_surface_capabilities_2_support() const + { + return pgpu->surface_capabilities_2_support; + } + mem_allocator_base* render_device::get_allocator() const { return m_allocator.get(); diff --git a/rpcs3/Emu/RSX/VK/vkutils/device.h b/rpcs3/Emu/RSX/VK/vkutils/device.h index e627580cd9..040ae78290 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/device.h +++ b/rpcs3/Emu/RSX/VK/vkutils/device.h @@ -51,6 +51,7 @@ namespace vk bool conditional_render_support = false; bool external_memory_host_support = false; bool unrestricted_depth_range_support = false; + bool surface_capabilities_2_support = false; friend class render_device; private: @@ -116,6 +117,7 @@ namespace vk bool get_conditional_render_support() const; bool get_unrestricted_depth_range_support() const; bool get_external_memory_host_support() const; + bool get_surface_capabilities_2_support() const; mem_allocator_base* get_allocator() const; diff --git a/rpcs3/Emu/RSX/VK/vkutils/instance.hpp b/rpcs3/Emu/RSX/VK/vkutils/instance.hpp index 7b88614f9d..ce1d6818b8 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/instance.hpp +++ b/rpcs3/Emu/RSX/VK/vkutils/instance.hpp @@ -154,6 +154,11 @@ namespace vk { extensions.push_back(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME); } + + if (support.is_supported(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) + { + extensions.push_back(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME); + } #ifdef _WIN32 extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); #elif defined(__APPLE__) diff --git a/rpcs3/Emu/RSX/VK/vkutils/swapchain.hpp b/rpcs3/Emu/RSX/VK/vkutils/swapchain.hpp index 70cc5c5f36..1e77fd36ce 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/swapchain.hpp +++ b/rpcs3/Emu/RSX/VK/vkutils/swapchain.hpp @@ -586,8 +586,49 @@ namespace vk VkSwapchainKHR old_swapchain = m_vk_swapchain; vk::physical_device& gpu = const_cast(dev.gpu()); - VkSurfaceCapabilitiesKHR surface_descriptors = {}; - CHECK_RESULT(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu, m_surface, &surface_descriptors)); + VkSurfaceCapabilities2KHR pSurfaceCapabilities = {}; + pSurfaceCapabilities.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR; + + VkPhysicalDeviceSurfaceInfo2KHR pSurfaceInfo = {}; + pSurfaceInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR; + pSurfaceInfo.surface = m_surface; + + VkSurfaceCapabilitiesKHR surface_descriptors; + bool init_surface_descriptors = true; + #ifdef _WIN32 + bool should_disable_exclusive_full_screen = false; + if (g_cfg.video.vk.force_disable_exclusive_fullscreen_mode && dev.get_surface_capabilities_2_support()) + { + HMONITOR hmonitor = MonitorFromWindow(window_handle, MONITOR_DEFAULTTOPRIMARY); + if (hmonitor) + { + VkSurfaceCapabilitiesFullScreenExclusiveEXT full_screen_exclusive_capabilities = {}; + VkSurfaceFullScreenExclusiveWin32InfoEXT full_screen_exclusive_win32_info = {}; + full_screen_exclusive_capabilities.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT; + + pSurfaceCapabilities.pNext = reinterpret_cast(&full_screen_exclusive_capabilities); + + full_screen_exclusive_win32_info.sType = VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT; + full_screen_exclusive_win32_info.hmonitor = hmonitor; + + pSurfaceInfo.pNext = reinterpret_cast(&full_screen_exclusive_win32_info); + + CHECK_RESULT(vkGetPhysicalDeviceSurfaceCapabilities2KHR(gpu, &pSurfaceInfo, &pSurfaceCapabilities)); + + surface_descriptors = pSurfaceCapabilities.surfaceCapabilities; + init_surface_descriptors = false; + should_disable_exclusive_full_screen = !!full_screen_exclusive_capabilities.fullScreenExclusiveSupported; + } + else + rsx_log.warning("Swapchain: failed to get monitor for the window"); + } + #endif + + if (init_surface_descriptors) + { + surface_descriptors = {}; + CHECK_RESULT(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu, m_surface, &surface_descriptors)); + } if (surface_descriptors.maxImageExtent.width < m_width || surface_descriptors.maxImageExtent.height < m_height) @@ -693,6 +734,19 @@ namespace vk swap_info.imageExtent.width = std::max(m_width, surface_descriptors.minImageExtent.width); swap_info.imageExtent.height = std::max(m_height, surface_descriptors.minImageExtent.height); + #ifdef _WIN32 + VkSurfaceFullScreenExclusiveInfoEXT full_screen_exclusive_info = {}; + if (should_disable_exclusive_full_screen) + { + full_screen_exclusive_info.sType = VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT; + full_screen_exclusive_info.fullScreenExclusive = VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT; + + swap_info.pNext = reinterpret_cast(&full_screen_exclusive_info); + } + + rsx_log.notice("Swapchain: requesting full screen exclusive mode %d.", static_cast(full_screen_exclusive_info.fullScreenExclusive)); + #endif + createSwapchainKHR(dev, &swap_info, nullptr, &m_vk_swapchain); if (old_swapchain) diff --git a/rpcs3/Emu/system_config.h b/rpcs3/Emu/system_config.h index ec4a558b03..cdec6c43b0 100644 --- a/rpcs3/Emu/system_config.h +++ b/rpcs3/Emu/system_config.h @@ -166,6 +166,7 @@ struct cfg_root : cfg::node cfg::string adapter{ this, "Adapter" }; cfg::_bool force_fifo{ this, "Force FIFO present mode" }; cfg::_bool force_primitive_restart{ this, "Force primitive restart flag" }; + cfg::_bool force_disable_exclusive_fullscreen_mode{this, "Force Disable Exclusive Fullscreen Mode"}; } vk{ this };