diff --git a/dxvk.conf b/dxvk.conf index 4f1a443a..9479f1e5 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -592,6 +592,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 e0f1a185..c917aa80 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 fc3d0b48..ef039a72 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 034c85d3..ed382d11 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;