From aaf284a4b05e06f03666a147339042d3e180f524 Mon Sep 17 00:00:00 2001 From: "Herman S." <429230+has207@users.noreply.github.com> Date: Mon, 19 Jan 2026 10:49:48 +0900 Subject: [PATCH] [Vulkan] Fix fullscreen corrupting HDR state on Windows --- src/xenia/ui/vulkan/vulkan_device.cc | 5 +++++ src/xenia/ui/vulkan/vulkan_device.h | 4 ++++ src/xenia/ui/vulkan/vulkan_presenter.cc | 16 ++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/src/xenia/ui/vulkan/vulkan_device.cc b/src/xenia/ui/vulkan/vulkan_device.cc index 36143a2ff..ab34ce38f 100644 --- a/src/xenia/ui/vulkan/vulkan_device.cc +++ b/src/xenia/ui/vulkan/vulkan_device.cc @@ -167,6 +167,11 @@ std::unique_ptr 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; diff --git a/src/xenia/ui/vulkan/vulkan_device.h b/src/xenia/ui/vulkan/vulkan_device.h index 30295e358..f655d4f9d 100644 --- a/src/xenia/ui/vulkan/vulkan_device.h +++ b/src/xenia/ui/vulkan/vulkan_device.h @@ -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_; } diff --git a/src/xenia/ui/vulkan/vulkan_presenter.cc b/src/xenia/ui/vulkan/vulkan_presenter.cc index 7151586c4..36f1b55bf 100644 --- a/src/xenia/ui/vulkan/vulkan_presenter.cc +++ b/src/xenia/ui/vulkan/vulkan_presenter.cc @@ -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 =