mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
[dxgi] FindClosestMatchingMode: Fall back to 8-bit SRGB format
Fixes errors in various games which rely on this method.
This commit is contained in:
parent
7f7eedac35
commit
87d6fde5c4
@ -61,70 +61,61 @@ namespace dxvk {
|
|||||||
Logger::err("DxgiOutput::FindClosestMatchingMode: no pointer to device was provided for DXGI_FORMAT_UNKNOWN format");
|
Logger::err("DxgiOutput::FindClosestMatchingMode: no pointer to device was provided for DXGI_FORMAT_UNKNOWN format");
|
||||||
return DXGI_ERROR_INVALID_CALL;
|
return DXGI_ERROR_INVALID_CALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pModeToMatch->Format == DXGI_FORMAT_UNKNOWN) {
|
// If no format was specified, fall back to a standard
|
||||||
/* TODO: perform additional format matching
|
// SRGB format, which is supported on all devices.
|
||||||
https://msdn.microsoft.com/en-us/library/windows/desktop/bb174547(v=vs.85).aspx?f=255&MSPPError=-2147217396
|
DXGI_FORMAT formatToMatch = pModeToMatch->Format;
|
||||||
> If pConcernedDevice is NULL, Format CANNOT be DXGI_FORMAT_UNKNOWN.
|
|
||||||
and vice versa
|
if (formatToMatch == DXGI_FORMAT_UNKNOWN)
|
||||||
>If pConcernedDevice is NOT NULL, Format COULD be DXGI_FORMAT_UNKNOWN.
|
formatToMatch = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
|
||||||
|
|
||||||
But Format in structures from GetDisplayModeList() cannot be
|
// List all supported modes and filter
|
||||||
DXGI_FORMAT_UNKNOWN by definition.
|
// out those we don't actually need
|
||||||
|
|
||||||
There is way in case of DXGI_FORMAT_UNKNOWN and pDevice != nullptr we
|
|
||||||
should perform additional format matching. It may be just ignoring of
|
|
||||||
Format field or using some range of formats but MSDN nothing says
|
|
||||||
about of criteria.
|
|
||||||
*/
|
|
||||||
Logger::err("DxgiOutput::FindClosestMatchingMode: matching formats to device currently is not supported");
|
|
||||||
return DXGI_ERROR_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
DXGI_MODE_DESC modeToMatch = *pModeToMatch;
|
DXGI_MODE_DESC modeToMatch = *pModeToMatch;
|
||||||
UINT modesCount = 0;
|
UINT modeCount = 0;
|
||||||
GetDisplayModeList(pModeToMatch->Format, 0, &modesCount, nullptr);
|
GetDisplayModeList(formatToMatch, 0, &modeCount, nullptr);
|
||||||
|
|
||||||
if (modesCount == 0) {
|
if (modeCount == 0) {
|
||||||
Logger::err("DxgiOutput::FindClosestMatchingMode: no device formats were found");
|
Logger::err("DxgiOutput::FindClosestMatchingMode: No modes found");
|
||||||
return DXGI_ERROR_NOT_FOUND;
|
return DXGI_ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<DXGI_MODE_DESC> modes(modesCount);
|
std::vector<DXGI_MODE_DESC> modes(modeCount);
|
||||||
GetDisplayModeList(pModeToMatch->Format, 0, &modesCount, modes.data());
|
GetDisplayModeList(formatToMatch, 0, &modeCount, modes.data());
|
||||||
|
|
||||||
/* TODO: add scaling and scanline filter when we implement they */
|
// Filter out modes with different refresh rate
|
||||||
|
if (modeToMatch.RefreshRate.Denominator != 0
|
||||||
//filter out modes with different refresh rate if it was set
|
&& modeToMatch.RefreshRate.Numerator != 0) {
|
||||||
if (modeToMatch.RefreshRate.Denominator != 0 && modeToMatch.RefreshRate.Numerator != 0) {
|
UINT targetRefreshRate = modeToMatch.RefreshRate.Numerator
|
||||||
UINT targetRefreshRate = modeToMatch.RefreshRate.Numerator / modeToMatch.RefreshRate.Denominator;
|
/ modeToMatch.RefreshRate.Denominator;
|
||||||
for (auto it = modes.begin(); it != modes.end();) {
|
|
||||||
UINT modeRefreshRate = it->RefreshRate.Numerator / it->RefreshRate.Denominator;
|
for (auto it = modes.begin(); it != modes.end(); ) {
|
||||||
|
UINT modeRefreshRate = it->RefreshRate.Numerator
|
||||||
|
/ it->RefreshRate.Denominator;
|
||||||
|
|
||||||
if (modeRefreshRate != targetRefreshRate)
|
if (modeRefreshRate != targetRefreshRate)
|
||||||
it = modes.erase(it);
|
it = modes.erase(it);
|
||||||
else
|
else
|
||||||
++it;
|
it++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// return error when there is no modes with target refresh rate and scanline order
|
// No matching modes found
|
||||||
if(modes.size() == 0) {
|
if (modes.size() == 0)
|
||||||
Logger::err("DxgiOutput::FindClosestMatchingMode: no matched formats were found");
|
|
||||||
return DXGI_ERROR_NOT_FOUND;
|
return DXGI_ERROR_NOT_FOUND;
|
||||||
}
|
|
||||||
|
|
||||||
//select mode with minimal height+width difference
|
// Select mode with minimal height+width difference
|
||||||
UINT minDifference = UINT_MAX;
|
UINT minDifference = UINT_MAX;
|
||||||
for (auto& mode : modes) {
|
for (auto& mode : modes) {
|
||||||
UINT currDifference = abs((int)(modeToMatch.Width - mode.Width))
|
UINT currDifference = abs((int)(modeToMatch.Width - mode.Width))
|
||||||
+ abs((int)(modeToMatch.Height - mode.Height));
|
+ abs((int)(modeToMatch.Height - mode.Height));
|
||||||
|
|
||||||
if (currDifference < minDifference) {
|
if (currDifference < minDifference) {
|
||||||
minDifference = currDifference;
|
minDifference = currDifference;
|
||||||
*pClosestMatch = mode;
|
*pClosestMatch = mode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user