From 4685e4c619a4f65cde5f73ea67902f90c18a900f Mon Sep 17 00:00:00 2001 From: WinterSnowfall Date: Tue, 9 Jul 2024 21:39:06 +0300 Subject: [PATCH] [d3d9] Add a forceModeHeights config option --- dxvk.conf | 13 +++++++++++++ src/d3d9/d3d9_adapter.cpp | 16 ++++++++++++++++ src/d3d9/d3d9_adapter.h | 2 ++ src/d3d9/d3d9_options.cpp | 1 + src/d3d9/d3d9_options.h | 3 +++ 5 files changed, 35 insertions(+) diff --git a/dxvk.conf b/dxvk.conf index 68d51a46c68..1d896e30b20 100644 --- a/dxvk.conf +++ b/dxvk.conf @@ -614,6 +614,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 b40ef2454f3..3a943cb2e26 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 = 0; + for (auto height : str::split(options.forceModeHeights, ",")) { + std::from_chars(height.data(), height.data() + height.size(), forcedHeight); + m_forcedModeHeights.emplace_back(forcedHeight); + } + } } template @@ -816,6 +826,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 0cf74981971..e6e6fabf342 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 e535d610c5e..93eb60724b6 100644 --- a/src/d3d9/d3d9_options.cpp +++ b/src/d3d9/d3d9_options.cpp @@ -65,6 +65,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 7339f8cbb2f..70a904cc42e 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; + /// Always use a spec constant to determine sampler type (instead of just in PS 1.x) /// Works around a game bug in Halo CE where it gives cube textures to 2d/volume samplers bool forceSamplerTypeSpecConstants;