mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-13 16:08:50 +01:00
[dxgi] Fix refresh rate filtering in FindClosestMatchingMode
We need to operate on the pre-filtered list, or otherwise we may run into problems where not all refresh rates are supported for all display modes.
This commit is contained in:
parent
55c4aba4d0
commit
b53c3057e1
@ -527,31 +527,7 @@ namespace dxvk {
|
|||||||
void DxgiOutput::FilterModesByDesc(
|
void DxgiOutput::FilterModesByDesc(
|
||||||
std::vector<DXGI_MODE_DESC1>& Modes,
|
std::vector<DXGI_MODE_DESC1>& Modes,
|
||||||
const DXGI_MODE_DESC1& TargetMode) {
|
const DXGI_MODE_DESC1& TargetMode) {
|
||||||
uint32_t minDiffResolution = 0;
|
// Filter modes based on format properties
|
||||||
uint32_t minDiffRefreshRate = 0;
|
|
||||||
|
|
||||||
if (TargetMode.Width) {
|
|
||||||
minDiffResolution = std::accumulate(
|
|
||||||
Modes.begin(), Modes.end(), std::numeric_limits<uint32_t>::max(),
|
|
||||||
[&TargetMode] (uint32_t current, const DXGI_MODE_DESC1& mode) {
|
|
||||||
uint32_t diff = std::abs(int32_t(TargetMode.Width - mode.Width))
|
|
||||||
+ std::abs(int32_t(TargetMode.Height - mode.Height));
|
|
||||||
return std::min(current, diff);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TargetMode.RefreshRate.Numerator && TargetMode.RefreshRate.Denominator) {
|
|
||||||
minDiffRefreshRate = std::accumulate(
|
|
||||||
Modes.begin(), Modes.end(), std::numeric_limits<uint64_t>::max(),
|
|
||||||
[&TargetMode] (uint64_t current, const DXGI_MODE_DESC1& mode) {
|
|
||||||
uint64_t rate = uint64_t(mode.RefreshRate.Numerator)
|
|
||||||
* uint64_t(TargetMode.RefreshRate.Denominator)
|
|
||||||
/ uint64_t(mode.RefreshRate.Denominator);
|
|
||||||
uint64_t diff = std::abs(int64_t(rate - uint64_t(TargetMode.RefreshRate.Numerator)));
|
|
||||||
return std::min(current, diff);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool testScanlineOrder = false;
|
bool testScanlineOrder = false;
|
||||||
bool testScaling = false;
|
bool testScaling = false;
|
||||||
bool testFormat = false;
|
bool testFormat = false;
|
||||||
@ -577,21 +553,53 @@ namespace dxvk {
|
|||||||
if (testFormat)
|
if (testFormat)
|
||||||
skipMode |= it->Format != TargetMode.Format;
|
skipMode |= it->Format != TargetMode.Format;
|
||||||
|
|
||||||
if (TargetMode.Width) {
|
it = skipMode ? Modes.erase(it) : ++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter by closest resolution
|
||||||
|
uint32_t minDiffResolution = 0;
|
||||||
|
|
||||||
|
if (TargetMode.Width) {
|
||||||
|
minDiffResolution = std::accumulate(
|
||||||
|
Modes.begin(), Modes.end(), std::numeric_limits<uint32_t>::max(),
|
||||||
|
[&TargetMode] (uint32_t current, const DXGI_MODE_DESC1& mode) {
|
||||||
|
uint32_t diff = std::abs(int32_t(TargetMode.Width - mode.Width))
|
||||||
|
+ std::abs(int32_t(TargetMode.Height - mode.Height));
|
||||||
|
return std::min(current, diff);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (auto it = Modes.begin(); it != Modes.end(); ) {
|
||||||
uint32_t diff = std::abs(int32_t(TargetMode.Width - it->Width))
|
uint32_t diff = std::abs(int32_t(TargetMode.Width - it->Width))
|
||||||
+ std::abs(int32_t(TargetMode.Height - it->Height));
|
+ std::abs(int32_t(TargetMode.Height - it->Height));
|
||||||
skipMode |= diff != minDiffResolution;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TargetMode.RefreshRate.Numerator && TargetMode.RefreshRate.Denominator) {
|
bool skipMode = diff != minDiffResolution;
|
||||||
|
it = skipMode ? Modes.erase(it) : ++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter by closest refresh rate
|
||||||
|
uint32_t minDiffRefreshRate = 0;
|
||||||
|
|
||||||
|
if (TargetMode.RefreshRate.Numerator && TargetMode.RefreshRate.Denominator) {
|
||||||
|
minDiffRefreshRate = std::accumulate(
|
||||||
|
Modes.begin(), Modes.end(), std::numeric_limits<uint64_t>::max(),
|
||||||
|
[&TargetMode] (uint64_t current, const DXGI_MODE_DESC1& mode) {
|
||||||
|
uint64_t rate = uint64_t(mode.RefreshRate.Numerator)
|
||||||
|
* uint64_t(TargetMode.RefreshRate.Denominator)
|
||||||
|
/ uint64_t(mode.RefreshRate.Denominator);
|
||||||
|
uint64_t diff = std::abs(int64_t(rate - uint64_t(TargetMode.RefreshRate.Numerator)));
|
||||||
|
return std::min(current, diff);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (auto it = Modes.begin(); it != Modes.end(); ) {
|
||||||
uint64_t rate = uint64_t(it->RefreshRate.Numerator)
|
uint64_t rate = uint64_t(it->RefreshRate.Numerator)
|
||||||
* uint64_t(TargetMode.RefreshRate.Denominator)
|
* uint64_t(TargetMode.RefreshRate.Denominator)
|
||||||
/ uint64_t(it->RefreshRate.Denominator);
|
/ uint64_t(it->RefreshRate.Denominator);
|
||||||
uint64_t diff = std::abs(int64_t(rate - uint64_t(TargetMode.RefreshRate.Numerator)));
|
uint64_t diff = std::abs(int64_t(rate - uint64_t(TargetMode.RefreshRate.Numerator)));
|
||||||
skipMode |= diff != minDiffRefreshRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
it = skipMode ? Modes.erase(it) : ++it;
|
bool skipMode = diff != minDiffRefreshRate;
|
||||||
|
it = skipMode ? Modes.erase(it) : ++it;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user