Skip to content

Commit

Permalink
add a hidden option to prevent switching to exclusive full screen mode
Browse files Browse the repository at this point in the history
this is helpful for people streaming RPCS3, or to prevent disabling HDR mode in Windows
  • Loading branch information
13xforever committed Feb 14, 2021
1 parent 5b044a9 commit 5a267c2
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 6 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -119,3 +119,5 @@ yaml-cpp.pc

# ssl certificate
cacert.pem

_ReSharper.*/
9 changes: 8 additions & 1 deletion rpcs3/Emu/RSX/VK/vkutils/device.cpp
Expand Up @@ -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)
Expand Down Expand Up @@ -517,6 +518,12 @@ 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();
Expand Down
2 changes: 2 additions & 0 deletions rpcs3/Emu/RSX/VK/vkutils/device.h
Expand Up @@ -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:
Expand Down Expand Up @@ -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;

Expand Down
7 changes: 6 additions & 1 deletion rpcs3/Emu/RSX/VK/vkutils/instance.hpp
Expand Up @@ -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__)
Expand Down Expand Up @@ -413,7 +418,7 @@ namespace vk

color_space = surfFormats[0].colorSpace;

return new swapchain_WSI(dev, presentQueueNodeIndex, graphicsQueueNodeIndex, format, m_surface, color_space, force_wm_reporting_off);
return new swapchain_WSI(dev, presentQueueNodeIndex, graphicsQueueNodeIndex, format, m_surface, window_handle, color_space, force_wm_reporting_off);
}
};
}
62 changes: 59 additions & 3 deletions rpcs3/Emu/RSX/VK/vkutils/swapchain.hpp
Expand Up @@ -493,6 +493,7 @@ namespace vk
class swapchain_WSI : public WSI_swapchain_base
{
VkSurfaceKHR m_surface = VK_NULL_HANDLE;
display_handle_t m_window_handle = NULL;
VkColorSpaceKHR m_color_space = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
VkSwapchainKHR m_vk_swapchain = nullptr;

Expand Down Expand Up @@ -524,7 +525,7 @@ namespace vk
}

public:
swapchain_WSI(vk::physical_device& gpu, u32 _present_queue, u32 _graphics_queue, VkFormat format, VkSurfaceKHR surface, VkColorSpaceKHR color_space, bool force_wm_reporting_off)
swapchain_WSI(vk::physical_device& gpu, u32 _present_queue, u32 _graphics_queue, VkFormat format, VkSurfaceKHR surface, display_handle_t window_handle, VkColorSpaceKHR color_space, bool force_wm_reporting_off)
: WSI_swapchain_base(gpu, _present_queue, _graphics_queue, format)
{
createSwapchainKHR = reinterpret_cast<PFN_vkCreateSwapchainKHR>(vkGetDeviceProcAddr(dev, "vkCreateSwapchainKHR"));
Expand All @@ -534,6 +535,7 @@ namespace vk
queuePresentKHR = reinterpret_cast<PFN_vkQueuePresentKHR>(vkGetDeviceProcAddr(dev, "vkQueuePresentKHR"));

m_surface = surface;
m_window_handle = window_handle;
m_color_space = color_space;

if (!force_wm_reporting_off)
Expand Down Expand Up @@ -586,8 +588,49 @@ namespace vk
VkSwapchainKHR old_swapchain = m_vk_swapchain;
vk::physical_device& gpu = const_cast<vk::physical_device&>(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;
bool should_disable_exclusive_full_screen = false;
#ifdef _WIN32
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<void*>(&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<void*>(&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)
Expand Down Expand Up @@ -693,6 +736,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<void*>(&full_screen_exclusive_info);
}

rsx_log.success("Swapchain: requesting full screen exclusive mode %d.", static_cast<int>(full_screen_exclusive_info.fullScreenExclusive));
#endif

createSwapchainKHR(dev, &swap_info, nullptr, &m_vk_swapchain);

if (old_swapchain)
Expand Down
3 changes: 2 additions & 1 deletion rpcs3/Emu/system_config.h
Expand Up @@ -166,7 +166,8 @@ 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 };

struct node_perf_overlay : cfg::node
Expand Down

0 comments on commit 5a267c2

Please sign in to comment.