From 76884d31f2b258d7951d80241e785c70c3ccb5e0 Mon Sep 17 00:00:00 2001 From: WinterSnowfall Date: Mon, 5 Feb 2024 15:35:16 +0200 Subject: [PATCH] [d3d9] Add a modeHeightFilter config option --- dxvk.conf | 13 +++++++++++++ src/d3d9/d3d9_adapter.cpp | 12 ++++++++++++ src/d3d9/d3d9_adapter.h | 2 ++ src/d3d9/d3d9_options.cpp | 1 + src/d3d9/d3d9_options.h | 3 +++ 5 files changed, 31 insertions(+) diff --git a/dxvk.conf b/dxvk.conf index 516aec4f..9b493ed9 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -555,6 +555,19 @@ # d3d9.forceAspectRatio = "" +# Mode Height Filter +# +# Only exposes modes with certain heights, if they are +# also supported by the adapter. Can be used in conjunction +# with forceAspectRatio to further restrict reported modes. +# Useful for titles that break when too many modes are reported, +# e.g., AquaNox, AquaNox 2: Revelation. +# +# Supported values: +# - A list of mode heights, ie. "480,720,1080" + +# d3d9.modeHeightFilter = "" + # Enumerate by Displays # # Whether we should enumerate D3D9 adapters by display (windows behaviour) diff --git a/src/d3d9/d3d9_adapter.cpp b/src/d3d9/d3d9_adapter.cpp index 44b631a4..e0ab9a86 100644 --- a/src/d3d9/d3d9_adapter.cpp +++ b/src/d3d9/d3d9_adapter.cpp @@ -771,6 +771,14 @@ namespace dxvk { uint32_t modeIndex = 0; const auto forcedRatio = Ratio(options.forceAspectRatio); + + if (!options.modeHeightFilter.empty() && m_forcedHeights.empty()) { + uint32_t forcedHeight; + for (auto height : str::split(options.modeHeightFilter, ",")) { + std::from_chars(height.data(), height.data() + height.size(), forcedHeight); + m_forcedHeights.emplace_back(forcedHeight); + } + } while (wsi::getDisplayMode(wsi::getDefaultMonitor(), modeIndex++, &devMode)) { // Skip interlaced modes altogether @@ -784,6 +792,10 @@ namespace dxvk { if (!forcedRatio.undefined() && Ratio(devMode.width, devMode.height) != forcedRatio) continue; + if (!m_forcedHeights.empty() && + std::find(m_forcedHeights.begin(), m_forcedHeights.end(), devMode.height) == m_forcedHeights.end()) + continue; + D3DDISPLAYMODEEX mode = ConvertDisplayMode(devMode); // Fix up the D3DFORMAT to match what we are enumerating mode.Format = static_cast(Format); diff --git a/src/d3d9/d3d9_adapter.h b/src/d3d9/d3d9_adapter.h index 0cf74981..7d83ff50 100644 --- a/src/d3d9/d3d9_adapter.h +++ b/src/d3d9/d3d9_adapter.h @@ -107,6 +107,8 @@ namespace dxvk { const D3D9VkFormatTable m_d3d9Formats; + std::vector m_forcedHeights; + }; } \ No newline at end of file diff --git a/src/d3d9/d3d9_options.cpp b/src/d3d9/d3d9_options.cpp index 190ca29b..dc979786 100644 --- a/src/d3d9/d3d9_options.cpp +++ b/src/d3d9/d3d9_options.cpp @@ -66,6 +66,7 @@ namespace dxvk { this->forceSwapchainMSAA = config.getOption ("d3d9.forceSwapchainMSAA", -1); this->forceSampleRateShading = config.getOption ("d3d9.forceSampleRateShading", false); this->forceAspectRatio = config.getOption ("d3d9.forceAspectRatio", ""); + this->modeHeightFilter = config.getOption ("d3d9.modeHeightFilter", ""); this->enumerateByDisplays = config.getOption ("d3d9.enumerateByDisplays", true); this->longMad = config.getOption ("d3d9.longMad", false); this->cachedDynamicBuffers = config.getOption ("d3d9.cachedDynamicBuffers", false); diff --git a/src/d3d9/d3d9_options.h b/src/d3d9/d3d9_options.h index f5b1fce4..95700957 100644 --- a/src/d3d9/d3d9_options.h +++ b/src/d3d9/d3d9_options.h @@ -103,6 +103,9 @@ namespace dxvk { /// Forced aspect ratio, disable other modes std::string forceAspectRatio; + /// Restrict modes based on height + std::string modeHeightFilter; + /// Enable dialog mode (ie. no exclusive fullscreen) bool enableDialogMode;