From d5744e5a81fdefa575dffa3901a10b5c997d3b31 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 13 Jan 2025 00:27:08 +0100 Subject: [PATCH] [dxvk] Enable automatic fallbacks for HDR color spaces The swap chain blitter can deal with the conversion. --- src/dxvk/dxvk_presenter.cpp | 32 ++++++++++++++++++++++---------- src/dxvk/dxvk_presenter.h | 2 ++ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/dxvk/dxvk_presenter.cpp b/src/dxvk/dxvk_presenter.cpp index 44975c63a..9b96fe64f 100644 --- a/src/dxvk/dxvk_presenter.cpp +++ b/src/dxvk/dxvk_presenter.cpp @@ -7,6 +7,13 @@ namespace dxvk { + const std::array, 2> Presenter::s_colorSpaceFallbacks = {{ + { VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT, VK_COLOR_SPACE_HDR10_ST2084_EXT }, + + { VK_COLOR_SPACE_HDR10_ST2084_EXT, VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT }, + }}; + + Presenter::Presenter( const Rc& device, const Rc& signal, @@ -215,6 +222,11 @@ namespace dxvk { for (const auto& surfaceFormat : surfaceFormats) { if (surfaceFormat.colorSpace == colorspace) return true; + + for (const auto& fallback : s_colorSpaceFallbacks) { + if (fallback.first == colorspace && fallback.second == surfaceFormat.colorSpace) + return true; + } } return false; @@ -658,7 +670,8 @@ namespace dxvk { const VkSurfaceFormatKHR& desired) { VkSurfaceFormatKHR result = { }; result.colorSpace = pickColorSpace(numSupported, pSupported, desired.colorSpace); - result.format = pickFormat(numSupported, pSupported, result.colorSpace, desired.format); + result.format = pickFormat(numSupported, pSupported, result.colorSpace, + result.colorSpace == desired.colorSpace ? desired.format : VK_FORMAT_UNDEFINED); return result; } @@ -667,18 +680,17 @@ namespace dxvk { uint32_t numSupported, const VkSurfaceFormatKHR* pSupported, VkColorSpaceKHR desired) { - static const std::array, 2> fallbacks = {{ - { VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT, VK_COLOR_SPACE_HDR10_ST2084_EXT }, - - { VK_COLOR_SPACE_HDR10_ST2084_EXT, VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT }, - }}; + VkColorSpaceKHR fallback = pSupported[0].colorSpace; for (uint32_t i = 0; i < numSupported; i++) { if (pSupported[i].colorSpace == desired) return desired; + + if (pSupported[i].colorSpace == VK_COLORSPACE_SRGB_NONLINEAR_KHR) + fallback = pSupported[i].colorSpace; } - for (const auto& f : fallbacks) { + for (const auto& f : s_colorSpaceFallbacks) { if (f.first != desired) continue; @@ -688,8 +700,8 @@ namespace dxvk { } } - Logger::warn(str::format("No fallback color space found for ", desired, ", using ", pSupported[0].colorSpace)); - return pSupported[0].colorSpace; + Logger::warn(str::format("No fallback color space found for ", desired, ", using ", fallback)); + return fallback; } @@ -790,7 +802,7 @@ namespace dxvk { } } - if (!desiredFound) + if (!desiredFound && format) Logger::warn(str::format("Desired format ", format, " not in compatibility list for ", colorSpace, ", using ", fallback)); return fallback; diff --git a/src/dxvk/dxvk_presenter.h b/src/dxvk/dxvk_presenter.h index d840dea93..6ed2ed890 100644 --- a/src/dxvk/dxvk_presenter.h +++ b/src/dxvk/dxvk_presenter.h @@ -249,6 +249,8 @@ namespace dxvk { alignas(CACHE_LINE_SIZE) FpsLimiter m_fpsLimiter; + static const std::array, 2> s_colorSpaceFallbacks; + void updateSwapChain(); VkResult recreateSwapChain();