[idd] edid: ensure the edid mode list is static

This commit is contained in:
Geoffrey McRae
2026-08-01 16:03:07 +10:00
parent 47905ec65e
commit 98bde6cf36
3 changed files with 18 additions and 29 deletions

View File

@@ -81,6 +81,15 @@ static const BYTE CTA_HDR_DESIRED_MIN_LUMINANCE = 0;
static const BYTE CTA_COLORIMETRY_BT2020_RGB = (BYTE)(1 << 7); static const BYTE CTA_COLORIMETRY_BT2020_RGB = (BYTE)(1 << 7);
// Keep the EDID mode list independent of the configured and dynamically
// requested modes. Windows uses the EDID as part of the monitor identity, so
// changing these timings at runtime can make it treat the IDD as a new monitor.
static const CSettings::DisplayMode EDID_DISPLAY_MODES[] =
{
{ 1024, 768, 60, true , false },
{ 800, 600, 60, false, false }
};
#pragma pack(push, 1) #pragma pack(push, 1)
struct EdidLe16 struct EdidLe16
{ {
@@ -534,7 +543,7 @@ bool CEdid::WriteDetailedTiming(BYTE* dtd, const CSettings::DisplayMode& mode)
return true; return true;
} }
void CEdid::Build(const CSettings::DisplayModes& modes, bool hdr) void CEdid::Build(bool hdr)
{ {
m_data.assign( m_data.assign(
static_cast<std::vector<BYTE, std::allocator<BYTE>>::size_type>( static_cast<std::vector<BYTE, std::allocator<BYTE>>::size_type>(
@@ -544,33 +553,16 @@ void CEdid::Build(const CSettings::DisplayModes& modes, bool hdr)
EdidBaseBlock baseBlock = {}; EdidBaseBlock baseBlock = {};
InitEdidBaseBlock(baseBlock, hdr); InitEdidBaseBlock(baseBlock, hdr);
CSettings::DisplayModes sorted = modes;
std::stable_sort(sorted.begin(), sorted.end(),
[](const CSettings::DisplayMode& a, const CSettings::DisplayMode& b)
{
if (a.preferred != b.preferred)
return a.preferred && !b.preferred;
if (a.width != b.width)
return a.width > b.width;
if (a.height != b.height)
return a.height > b.height;
return a.refresh > b.refresh;
});
UINT modeIndex = 0; UINT modeIndex = 0;
UINT baseDtdIndex = 0; UINT baseDtdIndex = 0;
for (; modeIndex < sorted.size() && for (; modeIndex < ARRAYSIZE(EDID_DISPLAY_MODES) &&
baseDtdIndex < EDID_BASE_DETAILED_TIMING_COUNT; baseDtdIndex < EDID_BASE_DETAILED_TIMING_COUNT;
++modeIndex) ++modeIndex)
{ {
// never include the extra mode in the EDID
if (sorted[modeIndex].extraMode)
continue;
if (MakeDetailedTiming( if (MakeDetailedTiming(
baseBlock.descriptors[baseDtdIndex].detailedTiming, baseBlock.descriptors[baseDtdIndex].detailedTiming,
sorted[modeIndex])) EDID_DISPLAY_MODES[modeIndex]))
{ {
++baseDtdIndex; ++baseDtdIndex;
} }
@@ -600,15 +592,12 @@ void CEdid::Build(const CSettings::DisplayModes& modes, bool hdr)
ctaBlock.flags = 0x00; ctaBlock.flags = 0x00;
UINT ctaDtdWrite = dataOffset; UINT ctaDtdWrite = dataOffset;
for (; modeIndex < sorted.size() && for (; modeIndex < ARRAYSIZE(EDID_DISPLAY_MODES) &&
ctaDtdWrite + EDID_DTD_SIZE <= EDID_BLOCK_SIZE - 1; ctaDtdWrite + EDID_DTD_SIZE <= EDID_BLOCK_SIZE - 1;
++modeIndex) ++modeIndex)
{ {
// never include the extra mode in the EDID if (WriteDetailedTiming(cta + ctaDtdWrite,
if (sorted[modeIndex].extraMode) EDID_DISPLAY_MODES[modeIndex]))
continue;
if (WriteDetailedTiming(cta + ctaDtdWrite, sorted[modeIndex]))
ctaDtdWrite += EDID_DTD_SIZE; ctaDtdWrite += EDID_DTD_SIZE;
} }

View File

@@ -42,7 +42,7 @@ public:
UINT64 pixelClock; UINT64 pixelClock;
}; };
void Build(const CSettings::DisplayModes& modes, bool hdr); void Build(bool hdr);
static bool GetTiming(Timing& timing, static bool GetTiming(Timing& timing,
const CSettings::DisplayMode& mode); const CSettings::DisplayMode& mode);

View File

@@ -127,7 +127,7 @@ void CIndirectDeviceContext::InitializeEdid()
{ {
AcquireSRWLockExclusive(&m_modeLock); AcquireSRWLockExclusive(&m_modeLock);
if (!m_edid.Size()) if (!m_edid.Size())
m_edid.Build(m_displayModes, CanProcessFP16()); m_edid.Build(CanProcessFP16());
ReleaseSRWLockExclusive(&m_modeLock); ReleaseSRWLockExclusive(&m_modeLock);
} }
@@ -331,7 +331,7 @@ void CIndirectDeviceContext::InitAdapter()
// The monitor has not been created yet, so replace the provisional HDR // The monitor has not been created yet, so replace the provisional HDR
// EDID before Windows can observe it. // EDID before Windows can observe it.
AcquireSRWLockExclusive(&m_modeLock); AcquireSRWLockExclusive(&m_modeLock);
m_edid.Build(m_displayModes, false); m_edid.Build(false);
ReleaseSRWLockExclusive(&m_modeLock); ReleaseSRWLockExclusive(&m_modeLock);
caps.Flags = (IDDCX_ADAPTER_FLAGS)(caps.Flags & ~IDDCX_ADAPTER_FLAGS_CAN_PROCESS_FP16); caps.Flags = (IDDCX_ADAPTER_FLAGS)(caps.Flags & ~IDDCX_ADAPTER_FLAGS_CAN_PROCESS_FP16);
ZeroMemory(&initOut, sizeof(initOut)); ZeroMemory(&initOut, sizeof(initOut));