mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-05 01:24:14 +01:00
[dxgi] Normalize display metadata to something rational
Sometimes we can't get an EDID if things aren't plumbed fully, or some displays just have broken EDIDs. This accounts for both of those cases by using some dummy data if we are missing information. Fixes value reporting to match Windows on common displays such as LG OLEDs.
This commit is contained in:
parent
f453d6ee2a
commit
f25475d05e
@ -19,6 +19,61 @@
|
||||
#include "../util/util_time.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
static void NormalizeDisplayMetadata(wsi::WsiDisplayMetadata& metadata) {
|
||||
// Use some dummy info when we have no hdr static metadata for the
|
||||
// display or we were unable to obtain an EDID.
|
||||
//
|
||||
// These dummy values are the same as what Windows DXGI will output
|
||||
// for panels with broken EDIDs such as LG OLEDs displays which
|
||||
// have an entirely zeroed out luminance section in the hdr static
|
||||
// metadata block.
|
||||
//
|
||||
// (Spec has 0 as 'undefined', which isn't really useful for an app
|
||||
// to tonemap against.)
|
||||
if (metadata.minLuminance == 0.0f)
|
||||
metadata.minLuminance = 0.01f;
|
||||
|
||||
if (metadata.maxLuminance == 0.0f)
|
||||
metadata.maxLuminance = 1499.0f;
|
||||
|
||||
if (metadata.maxFullFrameLuminance == 0.0f)
|
||||
metadata.maxFullFrameLuminance = 799.0f;
|
||||
|
||||
// If we have no RedPrimary/GreenPrimary/BluePrimary/WhitePoint due to
|
||||
// the lack of a monitor exposing the chroma block or the lack of an EDID,
|
||||
// simply just fall back to Rec.709 or Rec.2020 values depending on the default
|
||||
// ColorSpace we started in.
|
||||
// (Don't change based on punting, as this should be static for a display.)
|
||||
if (metadata.redPrimary[0] == 0.0f && metadata.redPrimary[1] == 0.0f
|
||||
&& metadata.greenPrimary[0] == 0.0f && metadata.greenPrimary[1] == 0.0f
|
||||
&& metadata.bluePrimary[0] == 0.0f && metadata.bluePrimary[1] == 0.0f
|
||||
&& metadata.whitePoint[0] == 0.0f && metadata.whitePoint[1] == 0.0f) {
|
||||
if (DxgiMonitorInfo::DefaultColorSpace() == DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709) {
|
||||
// sRGB ColorSpace -> Rec.709 Primaries
|
||||
metadata.redPrimary[0] = 0.640f;
|
||||
metadata.redPrimary[1] = 0.330f;
|
||||
metadata.greenPrimary[0] = 0.300f;
|
||||
metadata.greenPrimary[1] = 0.600f;
|
||||
metadata.bluePrimary[0] = 0.150f;
|
||||
metadata.bluePrimary[1] = 0.060f;
|
||||
metadata.whitePoint[0] = 0.3127f;
|
||||
metadata.whitePoint[1] = 0.3290f;
|
||||
} else {
|
||||
// HDR10 ColorSpace -> Rec.2020 Primaries
|
||||
// (Notably much bigger than any display is actually going to expose.)
|
||||
metadata.redPrimary[0] = 0.708f;
|
||||
metadata.redPrimary[1] = 0.292f;
|
||||
metadata.greenPrimary[0] = 0.170f;
|
||||
metadata.greenPrimary[1] = 0.797f;
|
||||
metadata.bluePrimary[0] = 0.131f;
|
||||
metadata.bluePrimary[1] = 0.046f;
|
||||
metadata.whitePoint[0] = 0.3127f;
|
||||
metadata.whitePoint[1] = 0.3290f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DxgiOutput::DxgiOutput(
|
||||
const Com<DxgiFactory>& factory,
|
||||
@ -665,6 +720,10 @@ namespace dxvk {
|
||||
else
|
||||
Logger::err("DXGI: Failed to parse display metadata + colorimetry info, using blank.");
|
||||
|
||||
// Normalize either the display metadata we got back, or our
|
||||
// blank one to get something sane here.
|
||||
NormalizeDisplayMetadata(m_metadata);
|
||||
|
||||
monitorData.FrameStats.SyncQPCTime.QuadPart = dxvk::high_resolution_clock::get_counter();
|
||||
monitorData.GammaCurve.Scale = { 1.0f, 1.0f, 1.0f };
|
||||
monitorData.GammaCurve.Offset = { 0.0f, 0.0f, 0.0f };
|
||||
|
Loading…
Reference in New Issue
Block a user