[Vulkan] Fix fullscreen corrupting HDR state on Windows

This commit is contained in:
Herman S.
2026-01-19 10:49:48 +09:00
parent 9c37af4621
commit aaf284a4b0
3 changed files with 25 additions and 0 deletions

View File

@@ -167,6 +167,11 @@ std::unique_ptr<VulkanDevice> VulkanDevice::CreateIfSupported(
if (with_swapchain) {
// #2.
XE_UI_VULKAN_STRUCT_EXTENSION(KHR_swapchain)
#if XE_PLATFORM_WIN32
// #256. Windows-only extension to control fullscreen exclusive behavior.
// Used to prevent HDR state corruption during fullscreen transitions.
XE_UI_VULKAN_STRUCT_EXTENSION(EXT_full_screen_exclusive)
#endif
}
bool ext_1_2_KHR_sampler_mirror_clamp_to_edge = false;

View File

@@ -183,6 +183,10 @@ class VulkanDevice {
bool ext_EXT_memory_budget = false; // #238
// Has optional features not implied by this being true.
bool ext_1_3_KHR_maintenance4 = false; // #414
#if XE_PLATFORM_WIN32
// VK_EXT_full_screen_exclusive (#256, Windows only)
bool ext_EXT_full_screen_exclusive = false;
#endif
};
const Extensions& extensions() const { return extensions_; }

View File

@@ -1142,6 +1142,22 @@ VkSwapchainKHR VulkanPresenter::PaintContext::CreateSwapchainForVulkanSurface(
VkSwapchainCreateInfoKHR swapchain_create_info;
swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
swapchain_create_info.pNext = nullptr;
#if XE_PLATFORM_WIN32
// On Windows, use VK_EXT_full_screen_exclusive to explicitly disallow
// fullscreen exclusive mode. This prevents HDR state corruption when
// entering/exiting fullscreen, as the Windows compositor remains in control
// of the display state throughout the transition.
VkSurfaceFullScreenExclusiveInfoEXT full_screen_exclusive_info;
if (vulkan_device->extensions().ext_EXT_full_screen_exclusive) {
full_screen_exclusive_info.sType =
VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT;
full_screen_exclusive_info.pNext = nullptr;
full_screen_exclusive_info.fullScreenExclusive =
VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT;
swapchain_create_info.pNext = &full_screen_exclusive_info;
}
#endif
swapchain_create_info.flags = 0;
swapchain_create_info.surface = surface;
swapchain_create_info.minImageCount =