diff --git a/dxvk.conf b/dxvk.conf index e3ceeae9b..68d51a46c 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -18,6 +18,18 @@ # dxgi.enableHDR = True +# Allows the Vulkan driver to opt-in to exclusive full-screen mode on +# Windows. Certain features, such as variable refresh rate or HDR, will +# not work without this setting, however enabling it will break certain +# games that use additional GDI windows, and it will also break alt+tab. +# +# This setting has no effect on non-Windows platforms. +# +# Supported values: True, False + +# dxvk.allowFse = False + + # Enables Unreal Engine 4 HDR workarounds for games that do not follow # the standard -Win64-Shipping.exe naming scheme. May be needed to avoid # crashes in D3D11 games on HDR-enabled systems due to statically linked diff --git a/src/dxvk/dxvk_options.cpp b/src/dxvk/dxvk_options.cpp index 44be3f3d1..c939a7a41 100644 --- a/src/dxvk/dxvk_options.cpp +++ b/src/dxvk/dxvk_options.cpp @@ -14,6 +14,7 @@ namespace dxvk { tearFree = config.getOption("dxvk.tearFree", Tristate::Auto); hideIntegratedGraphics = config.getOption ("dxvk.hideIntegratedGraphics", false); zeroMappedMemory = config.getOption ("dxvk.zeroMappedMemory", false); + allowFse = config.getOption ("dxvk.allowFse", false); deviceFilter = config.getOption("dxvk.deviceFilter", ""); } diff --git a/src/dxvk/dxvk_options.h b/src/dxvk/dxvk_options.h index b2b65f4ae..0994f1d5f 100644 --- a/src/dxvk/dxvk_options.h +++ b/src/dxvk/dxvk_options.h @@ -45,6 +45,9 @@ namespace dxvk { /// Clears all mapped memory to zero. bool zeroMappedMemory = false; + /// Allows full-screen exclusive mode on Windows + bool allowFse = false; + // Device name std::string deviceFilter; }; diff --git a/src/dxvk/dxvk_presenter.cpp b/src/dxvk/dxvk_presenter.cpp index 84599baa9..27d6bb12c 100644 --- a/src/dxvk/dxvk_presenter.cpp +++ b/src/dxvk/dxvk_presenter.cpp @@ -14,6 +14,13 @@ namespace dxvk { : m_device(device), m_signal(signal), m_vki(device->instance()->vki()), m_vkd(device->vkd()) { + // Only enable FSE if the user explicitly opts in. On Windows, FSE + // is required to support VRR or HDR, but blocks alt-tabbing or + // overlapping windows, which breaks a number of games. + m_fullscreenMode = m_device->config().allowFse + ? VK_FULL_SCREEN_EXCLUSIVE_ALLOWED_EXT + : VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT; + // If a frame signal was provided, launch thread that synchronizes // with present operations and periodically signals the event if (m_device->features().khrPresentWait.presentWait && m_signal != nullptr) @@ -171,7 +178,7 @@ namespace dxvk { return VK_ERROR_SURFACE_LOST_KHR; VkSurfaceFullScreenExclusiveInfoEXT fullScreenExclusiveInfo = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT }; - fullScreenExclusiveInfo.fullScreenExclusive = VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT; + fullScreenExclusiveInfo.fullScreenExclusive = m_fullscreenMode; VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR }; surfaceInfo.surface = m_surface; @@ -300,7 +307,7 @@ namespace dxvk { m_info.imageCount = pickImageCount(minImageCount, maxImageCount, desc.imageCount); VkSurfaceFullScreenExclusiveInfoEXT fullScreenInfo = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT }; - fullScreenInfo.fullScreenExclusive = VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT; + fullScreenInfo.fullScreenExclusive = m_fullscreenMode; VkSwapchainPresentModesCreateInfoEXT modeInfo = { VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_MODES_CREATE_INFO_EXT }; modeInfo.presentModeCount = compatibleModes.size(); @@ -457,7 +464,7 @@ namespace dxvk { uint32_t numFormats = 0; VkSurfaceFullScreenExclusiveInfoEXT fullScreenInfo = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT }; - fullScreenInfo.fullScreenExclusive = VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT; + fullScreenInfo.fullScreenExclusive = m_fullscreenMode; VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, &fullScreenInfo }; surfaceInfo.surface = m_surface; @@ -499,7 +506,7 @@ namespace dxvk { uint32_t numModes = 0; VkSurfaceFullScreenExclusiveInfoEXT fullScreenInfo = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT }; - fullScreenInfo.fullScreenExclusive = VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT; + fullScreenInfo.fullScreenExclusive = m_fullscreenMode; VkPhysicalDeviceSurfaceInfo2KHR surfaceInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, &fullScreenInfo }; surfaceInfo.surface = m_surface; diff --git a/src/dxvk/dxvk_presenter.h b/src/dxvk/dxvk_presenter.h index 50c54d47b..1cbf7edc2 100644 --- a/src/dxvk/dxvk_presenter.h +++ b/src/dxvk/dxvk_presenter.h @@ -238,6 +238,8 @@ namespace dxvk { VkSurfaceKHR m_surface = VK_NULL_HANDLE; VkSwapchainKHR m_swapchain = VK_NULL_HANDLE; + VkFullScreenExclusiveEXT m_fullscreenMode = VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT; + std::vector m_images; std::vector m_semaphores;