diff --git a/dxvk.conf b/dxvk.conf index 3416dd4dc864..2b827f4450ce 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -594,6 +594,19 @@ # d3d9.forceAspectRatio = "" +# Force Mode Heights +# +# 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, i.e. "480,720,1080" + +# d3d9.forceModeHeights = "" + # 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 75120417b828..c7a79ecab5c4 100644 --- a/src/d3d9/d3d9_adapter.cpp +++ b/src/d3d9/d3d9_adapter.cpp @@ -44,6 +44,16 @@ namespace dxvk { m_modeCacheFormat (D3D9Format::Unknown), m_d3d9Formats (Adapter, m_parent->GetOptions()) { m_adapter->logAdapterInfo(); + + auto& options = m_parent->GetOptions(); + + if (!options.forceModeHeights.empty()) { + uint32_t forcedHeight; + for (auto height : str::split(options.forceModeHeights, ",")) { + std::from_chars(height.data(), height.data() + height.size(), forcedHeight); + m_forcedModeHeights.emplace_back(forcedHeight); + } + } } template @@ -809,6 +819,12 @@ namespace dxvk { if (!forcedRatio.undefined() && Ratio(devMode.width, devMode.height) != forcedRatio) continue; + if (!m_forcedModeHeights.empty() && + std::find(m_forcedModeHeights.begin(), + m_forcedModeHeights.end(), + devMode.height) == m_forcedModeHeights.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 0cf749819719..e6e6fabf3424 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_forcedModeHeights; + }; } \ No newline at end of file diff --git a/src/d3d9/d3d9_options.cpp b/src/d3d9/d3d9_options.cpp index f16212ed0b71..f257b97c8a12 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->forceModeHeights = config.getOption ("d3d9.forceModeHeights", ""); this->enumerateByDisplays = config.getOption ("d3d9.enumerateByDisplays", true); this->cachedDynamicBuffers = config.getOption ("d3d9.cachedDynamicBuffers", false); this->deviceLocalConstantBuffers = config.getOption ("d3d9.deviceLocalConstantBuffers", false); diff --git a/src/d3d9/d3d9_options.h b/src/d3d9/d3d9_options.h index db4bdba01c9f..c2fc2720e186 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 forceModeHeights; + /// Enable dialog mode (ie. no exclusive fullscreen) bool enableDialogMode;