[idd] hdr: use iddcx 1.10 if possible and expose HDR support

This commit is contained in:
Geoffrey McRae
2026-06-03 00:05:41 +10:00
committed by Geoffrey McRae
parent dbb80ebd66
commit a10efc9e23
6 changed files with 337 additions and 27 deletions

View File

@@ -123,7 +123,7 @@ void CEdid::Build(const CSettings::DisplayModes& modes)
base[17] = 36; // 1990 + 36 = 2026
base[18] = 1;
base[19] = 4;
base[20] = 0xa5; // digital input, 10-bit capable
base[20] = 0xb2; // digital input, 10-bit HDMI-A
base[21] = 52;
base[22] = 29;
base[23] = 0x78; // gamma 2.2
@@ -163,19 +163,42 @@ void CEdid::Build(const CSettings::DisplayModes& modes)
cta[1] = 0x03;
UINT dataOffset = 4;
// CTA extended colorimetry data block: advertise BT.2020 colorimetry.
// CTA HDR Static Metadata data block: HDR, PQ and HLG with type 1 metadata and luminance data.
cta[dataOffset++] = (7 << 5) | 6;
cta[dataOffset++] = 0x06;
cta[dataOffset++] = 0x0d;
cta[dataOffset++] = 0x01;
cta[dataOffset++] = 0xa2;
cta[dataOffset++] = 0xa2;
cta[dataOffset++] = 0x10;
// CTA extended colorimetry data block: advertise BT.2020 and DCI-P3 colorimetry.
cta[dataOffset++] = (7 << 5) | 3;
cta[dataOffset++] = 0x05;
cta[dataOffset++] = 0xe0;
cta[dataOffset++] = 0xd8;
cta[dataOffset++] = 0x00;
// CTA HDR Static Metadata data block: SDR, traditional HDR, PQ and HLG with type 1 metadata.
cta[dataOffset++] = (7 << 5) | 4;
cta[dataOffset++] = 0x06;
cta[dataOffset++] = 0x0f;
// HDMI Forum vendor-specific data block.
cta[dataOffset++] = (3 << 5) | 7;
cta[dataOffset++] = 0xd8;
cta[dataOffset++] = 0x5d;
cta[dataOffset++] = 0xc4;
cta[dataOffset++] = 0x01;
cta[dataOffset++] = 0x6e;
cta[dataOffset++] = 0x80;
cta[dataOffset++] = 0x00;
// HDMI vendor-specific data block.
cta[dataOffset++] = (3 << 5) | 8;
cta[dataOffset++] = 0x03;
cta[dataOffset++] = 0x0c;
cta[dataOffset++] = 0x00;
cta[dataOffset++] = 0x00;
cta[dataOffset++] = 0x00;
cta[dataOffset++] = 0x30;
cta[dataOffset++] = 0x00;
cta[dataOffset++] = 0x0b;
UINT ctaDtdOffset = dataOffset;
if (ctaDtdOffset < 4)
ctaDtdOffset = 4;

View File

@@ -43,6 +43,59 @@ static const struct LGMPQueueConfig POINTER_QUEUE_CONFIG =
1000 //subTimeout
};
static const UINT IDDCX_VERSION_1_10 = 0x1A00;
#if defined(IDDCX_VERSION_MAJOR) && defined(IDDCX_VERSION_MINOR) && \
(IDDCX_VERSION_MAJOR > 1 || (IDDCX_VERSION_MAJOR == 1 && IDDCX_VERSION_MINOR >= 10))
static inline IDDCX_WIRE_BITS_PER_COMPONENT GetWireBitsPerComponent(bool hdr)
{
IDDCX_WIRE_BITS_PER_COMPONENT bits = {};
bits.Rgb = IDDCX_BITS_PER_COMPONENT_8;
if (hdr)
bits.Rgb = (IDDCX_BITS_PER_COMPONENT)(bits.Rgb | IDDCX_BITS_PER_COMPONENT_10);
bits.YCbCr444 = IDDCX_BITS_PER_COMPONENT_NONE;
bits.YCbCr422 = IDDCX_BITS_PER_COMPONENT_NONE;
bits.YCbCr420 = IDDCX_BITS_PER_COMPONENT_NONE;
return bits;
}
#endif
void CIndirectDeviceContext::QueryIddCxCapabilities()
{
IDARG_OUT_GETVERSION ver = {};
NTSTATUS status = IddCxGetVersion(&ver);
if (!NT_SUCCESS(status))
{
m_iddCxVersion = 0;
m_canProcessFP16 = false;
DEBUG_ERROR_HR(status, "IddCxGetVersion Failed");
return;
}
m_iddCxVersion = ver.IddCxVersion;
#if defined(IDDCX_VERSION_MAJOR) && defined(IDDCX_VERSION_MINOR) && \
(IDDCX_VERSION_MAJOR > 1 || (IDDCX_VERSION_MAJOR == 1 && IDDCX_VERSION_MINOR >= 10))
const bool hasIddCx110DDIs =
!!IDD_IS_FUNCTION_AVAILABLE(IddCxSwapChainReleaseAndAcquireBuffer2) &&
!!IDD_IS_FUNCTION_AVAILABLE(IddCxMonitorQueryHardwareCursor3) &&
!!IDD_IS_FUNCTION_AVAILABLE(IddCxMonitorUpdateModes2) &&
IDD_IS_FIELD_AVAILABLE(IDD_CX_CLIENT_CONFIG, EvtIddCxAdapterQueryTargetInfo) &&
IDD_IS_FIELD_AVAILABLE(IDD_CX_CLIENT_CONFIG, EvtIddCxAdapterCommitModes2) &&
IDD_IS_FIELD_AVAILABLE(IDD_CX_CLIENT_CONFIG, EvtIddCxParseMonitorDescription2) &&
IDD_IS_FIELD_AVAILABLE(IDD_CX_CLIENT_CONFIG, EvtIddCxMonitorQueryTargetModes2) &&
IDD_IS_FIELD_AVAILABLE(IDD_CX_CLIENT_CONFIG, EvtIddCxMonitorSetDefaultHdrMetaData) &&
IDD_IS_FIELD_AVAILABLE(IDD_CX_CLIENT_CONFIG, EvtIddCxMonitorSetGammaRamp);
#else
const bool hasIddCx110DDIs = false;
#endif
m_canProcessFP16 = m_iddCxVersion >= IDDCX_VERSION_1_10 && hasIddCx110DDIs;
DEBUG_INFO("IddCx version: 0x%04x", m_iddCxVersion);
DEBUG_INFO("IddCx 1.10 HDR/WCG DDIs: %s", m_canProcessFP16 ? "available" : "unavailable");
}
void CIndirectDeviceContext::PopulateDefaultModes()
{
g_settings.LoadModes();
@@ -60,6 +113,7 @@ void CIndirectDeviceContext::InitAdapter()
if (!m_ivshmem.Init() || !m_ivshmem.Open())
return;
QueryIddCxCapabilities();
PopulateDefaultModes();
IDDCX_ADAPTER_CAPS caps = {};
@@ -72,6 +126,11 @@ void CIndirectDeviceContext::InitAdapter()
* driver will not work. This behaviour is not documented by Microsoft.
*/
caps.Flags = IDDCX_ADAPTER_FLAGS_USE_SMALLEST_MODE;
#if defined(IDDCX_VERSION_MAJOR) && defined(IDDCX_VERSION_MINOR) && \
(IDDCX_VERSION_MAJOR > 1 || (IDDCX_VERSION_MAJOR == 1 && IDDCX_VERSION_MINOR >= 10))
if (CanUseIddCx110DDIs())
caps.Flags |= IDDCX_ADAPTER_FLAGS_CAN_PROCESS_FP16;
#endif
caps.MaxMonitorsSupported = 1;
@@ -99,6 +158,17 @@ void CIndirectDeviceContext::InitAdapter()
IDARG_OUT_ADAPTER_INIT initOut;
NTSTATUS status = IddCxAdapterInitAsync(&init, &initOut);
if (!NT_SUCCESS(status) && CanUseIddCx110DDIs())
{
DEBUG_WARN(
"IddCxAdapterInitAsync rejected FP16 adapter capabilities (0x%08x), retrying without HDR/WCG",
status);
m_canProcessFP16 = false;
caps.Flags = (IDDCX_ADAPTER_FLAGS)(caps.Flags & ~IDDCX_ADAPTER_FLAGS_CAN_PROCESS_FP16);
ZeroMemory(&initOut, sizeof(initOut));
status = IddCxAdapterInitAsync(&init, &initOut);
}
if (!NT_SUCCESS(status))
{
DEBUG_ERROR_HR(status, "IddCxAdapterInitAsync Failed");
@@ -237,6 +307,7 @@ NTSTATUS CIndirectDeviceContext::ParseMonitorDescription(
IDARG_OUT_PARSEMONITORDESCRIPTION* outArgs)
{
outArgs->MonitorModeBufferOutputCount = (UINT)m_displayModes.size();
outArgs->PreferredMonitorModeIdx = 0;
if (inArgs->MonitorModeBufferInputCount < (UINT)m_displayModes.size())
return (inArgs->MonitorModeBufferInputCount > 0) ? STATUS_BUFFER_TOO_SMALL : STATUS_SUCCESS;
@@ -260,6 +331,7 @@ NTSTATUS CIndirectDeviceContext::MonitorGetDefaultModes(
IDARG_OUT_GETDEFAULTDESCRIPTIONMODES* outArgs)
{
outArgs->DefaultMonitorModeBufferOutputCount = (UINT)m_displayModes.size();
outArgs->PreferredMonitorModeIdx = 0;
if (inArgs->DefaultMonitorModeBufferInputCount < (UINT)m_displayModes.size())
return (inArgs->DefaultMonitorModeBufferInputCount > 0) ? STATUS_BUFFER_TOO_SMALL : STATUS_SUCCESS;
@@ -296,6 +368,59 @@ NTSTATUS CIndirectDeviceContext::MonitorQueryTargetModes(
return STATUS_SUCCESS;
}
#if defined(IDDCX_VERSION_MAJOR) && defined(IDDCX_VERSION_MINOR) && \
(IDDCX_VERSION_MAJOR > 1 || (IDDCX_VERSION_MAJOR == 1 && IDDCX_VERSION_MINOR >= 10))
NTSTATUS CIndirectDeviceContext::ParseMonitorDescription2(
const IDARG_IN_PARSEMONITORDESCRIPTION2* inArgs,
IDARG_OUT_PARSEMONITORDESCRIPTION* outArgs)
{
outArgs->MonitorModeBufferOutputCount = (UINT)m_displayModes.size();
outArgs->PreferredMonitorModeIdx = 0;
if (inArgs->MonitorModeBufferInputCount < (UINT)m_displayModes.size())
return (inArgs->MonitorModeBufferInputCount > 0) ? STATUS_BUFFER_TOO_SMALL : STATUS_SUCCESS;
auto * mode = inArgs->pMonitorModes;
for (auto it = m_displayModes.cbegin(); it != m_displayModes.cend(); ++it, ++mode)
{
ZeroMemory(mode, sizeof(*mode));
mode->Size = sizeof(IDDCX_MONITOR_MODE2);
mode->Origin = IDDCX_MONITOR_MODE_ORIGIN_MONITORDESCRIPTOR;
FillSignalInfo(mode->MonitorVideoSignalInfo, it->width, it->height, it->refresh, true);
mode->BitsPerComponent = GetWireBitsPerComponent(CanUseIddCx110DDIs());
if (it->preferred)
outArgs->PreferredMonitorModeIdx =
(UINT)std::distance(m_displayModes.cbegin(), it);
}
return STATUS_SUCCESS;
}
NTSTATUS CIndirectDeviceContext::MonitorQueryTargetModes2(
const IDARG_IN_QUERYTARGETMODES2* inArgs,
IDARG_OUT_QUERYTARGETMODES* outArgs)
{
outArgs->TargetModeBufferOutputCount = (UINT)m_displayModes.size();
if (inArgs->TargetModeBufferInputCount < (UINT)m_displayModes.size())
return STATUS_SUCCESS;
if (!inArgs->pTargetModes)
return STATUS_INVALID_PARAMETER;
auto* mode = inArgs->pTargetModes;
for (auto it = m_displayModes.cbegin(); it != m_displayModes.cend(); ++it, ++mode)
{
ZeroMemory(mode, sizeof(*mode));
mode->Size = sizeof(IDDCX_TARGET_MODE2);
FillSignalInfo(mode->TargetVideoSignalInfo.targetVideoSignalInfo, it->width, it->height, it->refresh, false);
mode->BitsPerComponent = GetWireBitsPerComponent(CanUseIddCx110DDIs());
}
return STATUS_SUCCESS;
}
#endif
void CIndirectDeviceContext::SetResolution(int width, int height)
{
m_setMode.width = width;

View File

@@ -85,6 +85,12 @@ private:
DXGI_FORMAT m_format = DXGI_FORMAT_UNKNOWN;
bool m_hasFrame = false;
UINT m_iddCxVersion = 0;
bool m_canProcessFP16 = false;
void QueryIddCxCapabilities();
bool CanUseIddCx110DDIs() const { return m_canProcessFP16; }
void DeInitLGMP();
void LGMPTimer();
void ResendCursor();
@@ -118,10 +124,19 @@ public:
NTSTATUS MonitorQueryTargetModes(
const IDARG_IN_QUERYTARGETMODES* inArgs, IDARG_OUT_QUERYTARGETMODES* outArgs);
#if defined(IDDCX_VERSION_MAJOR) && defined(IDDCX_VERSION_MINOR) && \
(IDDCX_VERSION_MAJOR > 1 || (IDDCX_VERSION_MAJOR == 1 && IDDCX_VERSION_MINOR >= 10))
NTSTATUS ParseMonitorDescription2(
const IDARG_IN_PARSEMONITORDESCRIPTION2* inArgs, IDARG_OUT_PARSEMONITORDESCRIPTION* outArgs);
NTSTATUS MonitorQueryTargetModes2(
const IDARG_IN_QUERYTARGETMODES2* inArgs, IDARG_OUT_QUERYTARGETMODES* outArgs);
#endif
void SetResolution(int width, int height);
size_t GetAlignSize() { return m_alignSize; }
size_t GetMaxFrameSize() { return m_maxFrameSize; }
size_t GetAlignSize() { return m_alignSize; }
size_t GetMaxFrameSize() { return m_maxFrameSize; }
bool CanProcessFP16() const { return m_canProcessFP16; }
struct PreparedFrameBuffer
{

View File

@@ -130,9 +130,40 @@ void CSwapChainProcessor::SwapChainThreadCore()
UINT lastFrameNumber = 0;
for (;;)
{
IDARG_OUT_RELEASEANDACQUIREBUFFER buffer = {};
UINT frameNumber = 0;
ComPtr<IDXGIResource> surface;
#if defined(IDDCX_VERSION_MAJOR) && defined(IDDCX_VERSION_MINOR) && \
(IDDCX_VERSION_MAJOR > 1 || (IDDCX_VERSION_MAJOR == 1 && IDDCX_VERSION_MINOR >= 10))
if (m_devContext->CanProcessFP16())
{
IDARG_IN_RELEASEANDACQUIREBUFFER2 acquireIn = {};
acquireIn.Size = sizeof(acquireIn);
acquireIn.AcquireSystemMemoryBuffer = FALSE;
IDARG_OUT_RELEASEANDACQUIREBUFFER2 buffer = {};
buffer.MetaData.Size = sizeof(buffer.MetaData);
hr = IddCxSwapChainReleaseAndAcquireBuffer2(m_hSwapChain, &acquireIn, &buffer);
if (SUCCEEDED(hr))
{
frameNumber = buffer.MetaData.PresentationFrameNumber;
surface = buffer.MetaData.pSurface;
}
}
else
#endif
{
IDARG_OUT_RELEASEANDACQUIREBUFFER buffer = {};
hr = IddCxSwapChainReleaseAndAcquireBuffer(m_hSwapChain, &buffer);
if (SUCCEEDED(hr))
{
frameNumber = buffer.MetaData.PresentationFrameNumber;
surface = buffer.MetaData.pSurface;
}
}
hr = IddCxSwapChainReleaseAndAcquireBuffer(m_hSwapChain, &buffer);
if (hr == E_PENDING)
{
HANDLE waitHandles[] =
@@ -153,10 +184,10 @@ void CSwapChainProcessor::SwapChainThreadCore()
}
else if (SUCCEEDED(hr))
{
if (buffer.MetaData.PresentationFrameNumber != lastFrameNumber)
if (frameNumber != lastFrameNumber)
{
lastFrameNumber = buffer.MetaData.PresentationFrameNumber;
SwapChainNewFrame(buffer.MetaData.pSurface);
lastFrameNumber = frameNumber;
SwapChainNewFrame(surface);
// report that all GPU processing for this frame has been queued
hr = IddCxSwapChainFinishedProcessingFrame(m_hSwapChain);
@@ -296,7 +327,25 @@ bool CSwapChainProcessor::QueryHWCursor()
in.ShapeBufferSizeInBytes = 512 * 512 * 4;
IDARG_OUT_QUERY_HWCURSOR out = {};
NTSTATUS status = IddCxMonitorQueryHardwareCursor(m_monitor, &in, &out);
NTSTATUS status;
#if defined(IDDCX_VERSION_MAJOR) && defined(IDDCX_VERSION_MINOR) && \
(IDDCX_VERSION_MAJOR > 1 || (IDDCX_VERSION_MAJOR == 1 && IDDCX_VERSION_MINOR >= 10))
if (m_devContext->CanProcessFP16())
{
IDARG_OUT_QUERY_HWCURSOR3 out3 = {};
status = IddCxMonitorQueryHardwareCursor3(m_monitor, &in, &out3);
out.IsCursorVisible = out3.IsCursorVisible;
out.X = out3.X;
out.Y = out3.Y;
out.IsCursorShapeUpdated = out3.IsCursorShapeUpdated;
out.CursorShapeInfo = out3.CursorShapeInfo;
}
else
#endif
{
status = IddCxMonitorQueryHardwareCursor(m_monitor, &in, &out);
}
if (FAILED(status))
{
// this occurs if the display went away (ie, screen blanking or disabled)

View File

@@ -36,6 +36,28 @@
WDFDEVICE l_wdfDevice = nullptr;
static const UINT IDDCX_VERSION_1_10 = 0x1A00;
static bool LGIddCanUseIddCx110DDIs(UINT iddCxVersion)
{
#if defined(IDDCX_VERSION_MAJOR) && defined(IDDCX_VERSION_MINOR) && \
(IDDCX_VERSION_MAJOR > 1 || (IDDCX_VERSION_MAJOR == 1 && IDDCX_VERSION_MINOR >= 10))
return iddCxVersion >= IDDCX_VERSION_1_10 &&
!!IDD_IS_FUNCTION_AVAILABLE(IddCxSwapChainReleaseAndAcquireBuffer2) &&
!!IDD_IS_FUNCTION_AVAILABLE(IddCxMonitorQueryHardwareCursor3) &&
!!IDD_IS_FUNCTION_AVAILABLE(IddCxMonitorUpdateModes2) &&
IDD_IS_FIELD_AVAILABLE(IDD_CX_CLIENT_CONFIG, EvtIddCxAdapterQueryTargetInfo) &&
IDD_IS_FIELD_AVAILABLE(IDD_CX_CLIENT_CONFIG, EvtIddCxAdapterCommitModes2) &&
IDD_IS_FIELD_AVAILABLE(IDD_CX_CLIENT_CONFIG, EvtIddCxParseMonitorDescription2) &&
IDD_IS_FIELD_AVAILABLE(IDD_CX_CLIENT_CONFIG, EvtIddCxMonitorQueryTargetModes2) &&
IDD_IS_FIELD_AVAILABLE(IDD_CX_CLIENT_CONFIG, EvtIddCxMonitorSetDefaultHdrMetaData) &&
IDD_IS_FIELD_AVAILABLE(IDD_CX_CLIENT_CONFIG, EvtIddCxMonitorSetGammaRamp);
#else
UNREFERENCED_PARAMETER(iddCxVersion);
return false;
#endif
}
NTSTATUS LGIddDeviceD0Entry(WDFDEVICE device, WDF_POWER_DEVICE_STATE previousState)
{
UNREFERENCED_PARAMETER(previousState);
@@ -104,6 +126,65 @@ NTSTATUS LGIddMonitorQueryTargetModes(IDDCX_MONITOR monitor, const IDARG_IN_QUER
return wrapper->context->GetDeviceContext()->MonitorQueryTargetModes(inArgs, outArgs);
}
#if defined(IDDCX_VERSION_MAJOR) && defined(IDDCX_VERSION_MINOR) && \
(IDDCX_VERSION_MAJOR > 1 || (IDDCX_VERSION_MAJOR == 1 && IDDCX_VERSION_MINOR >= 10))
NTSTATUS LGIddParseMonitorDescription2(const IDARG_IN_PARSEMONITORDESCRIPTION2* inArgs,
IDARG_OUT_PARSEMONITORDESCRIPTION* outArgs)
{
if (!l_wdfDevice)
return STATUS_INVALID_PARAMETER;
auto* wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(l_wdfDevice);
return wrapper->context->ParseMonitorDescription2(inArgs, outArgs);
}
NTSTATUS LGIddAdapterQueryTargetInfo(IDDCX_ADAPTER adapter,
IDARG_IN_QUERYTARGET_INFO* inArgs, IDARG_OUT_QUERYTARGET_INFO* outArgs)
{
UNREFERENCED_PARAMETER(adapter);
UNREFERENCED_PARAMETER(inArgs);
outArgs->TargetCaps =
(IDDCX_TARGET_CAPS)(IDDCX_TARGET_CAPS_WIDE_COLOR_SPACE | IDDCX_TARGET_CAPS_HIGH_COLOR_SPACE);
outArgs->DitheringSupport.Rgb =
(IDDCX_BITS_PER_COMPONENT)(IDDCX_BITS_PER_COMPONENT_8 | IDDCX_BITS_PER_COMPONENT_10);
outArgs->DitheringSupport.YCbCr444 = IDDCX_BITS_PER_COMPONENT_NONE;
outArgs->DitheringSupport.YCbCr422 = IDDCX_BITS_PER_COMPONENT_NONE;
outArgs->DitheringSupport.YCbCr420 = IDDCX_BITS_PER_COMPONENT_NONE;
return STATUS_SUCCESS;
}
NTSTATUS LGIddAdapterCommitModes2(IDDCX_ADAPTER adapter, const IDARG_IN_COMMITMODES2* args)
{
UNREFERENCED_PARAMETER(adapter);
UNREFERENCED_PARAMETER(args);
return STATUS_SUCCESS;
}
NTSTATUS LGIddMonitorSetDefaultHdrMetadata(IDDCX_MONITOR monitor,
const IDARG_IN_MONITOR_SET_DEFAULT_HDR_METADATA* inArgs)
{
UNREFERENCED_PARAMETER(monitor);
UNREFERENCED_PARAMETER(inArgs);
return STATUS_SUCCESS;
}
NTSTATUS LGIddMonitorSetGammaRamp(IDDCX_MONITOR monitor, const IDARG_IN_SET_GAMMARAMP* inArgs)
{
UNREFERENCED_PARAMETER(monitor);
UNREFERENCED_PARAMETER(inArgs);
return STATUS_SUCCESS;
}
NTSTATUS LGIddMonitorQueryTargetModes2(IDDCX_MONITOR monitor, const IDARG_IN_QUERYTARGETMODES2* inArgs,
IDARG_OUT_QUERYTARGETMODES* outArgs)
{
auto* wrapper = WdfObjectGet_CIndirectMonitorContextWrapper(monitor);
return wrapper->context->GetDeviceContext()->MonitorQueryTargetModes2(inArgs, outArgs);
}
#endif
NTSTATUS LGIddMonitorAssignSwapChain(IDDCX_MONITOR monitor, const IDARG_IN_SETSWAPCHAIN* inArgs)
{
auto * wrapper = WdfObjectGet_CIndirectMonitorContextWrapper(monitor);
@@ -131,7 +212,9 @@ NTSTATUS LGIddCreateDevice(_Inout_ PWDFDEVICE_INIT deviceInit)
DEBUG_ERROR("IddCxGetVersion Failed");
return status;
}
const bool hasIddCx110DDIs = LGIddCanUseIddCx110DDIs(ver.IddCxVersion);
DEBUG_INFO("Version: 0x%04x", ver.IddCxVersion);
DEBUG_INFO("IddCx 1.10 HDR/WCG DDIs: %s", hasIddCx110DDIs ? "available" : "unavailable");
WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
@@ -141,13 +224,29 @@ NTSTATUS LGIddCreateDevice(_Inout_ PWDFDEVICE_INIT deviceInit)
IDD_CX_CLIENT_CONFIG config;
IDD_CX_CLIENT_CONFIG_INIT(&config);
config.EvtIddCxAdapterInitFinished = LGIddAdapterInitFinished;
config.EvtIddCxAdapterCommitModes = LGIddAdapterCommitModes;
config.EvtIddCxParseMonitorDescription = LGIddParseMonitorDescription;
config.EvtIddCxMonitorGetDefaultDescriptionModes = LGIddMonitorGetDefaultModes;
config.EvtIddCxMonitorQueryTargetModes = LGIddMonitorQueryTargetModes;
config.EvtIddCxMonitorAssignSwapChain = LGIddMonitorAssignSwapChain;
config.EvtIddCxMonitorUnassignSwapChain = LGIddMonitorUnassignSwapChain;
#if defined(IDDCX_VERSION_MAJOR) && defined(IDDCX_VERSION_MINOR) && \
(IDDCX_VERSION_MAJOR > 1 || (IDDCX_VERSION_MAJOR == 1 && IDDCX_VERSION_MINOR >= 10))
if (hasIddCx110DDIs)
{
config.EvtIddCxParseMonitorDescription2 = LGIddParseMonitorDescription2;
config.EvtIddCxMonitorQueryTargetModes2 = LGIddMonitorQueryTargetModes2;
config.EvtIddCxAdapterCommitModes2 = LGIddAdapterCommitModes2;
config.EvtIddCxAdapterQueryTargetInfo = LGIddAdapterQueryTargetInfo;
config.EvtIddCxMonitorSetDefaultHdrMetaData = LGIddMonitorSetDefaultHdrMetadata;
config.EvtIddCxMonitorSetGammaRamp = LGIddMonitorSetGammaRamp;
}
else
#endif
{
config.EvtIddCxAdapterCommitModes = LGIddAdapterCommitModes;
config.EvtIddCxParseMonitorDescription = LGIddParseMonitorDescription;
config.EvtIddCxMonitorQueryTargetModes = LGIddMonitorQueryTargetModes;
}
status = IddCxDeviceInitConfig(deviceInit, &config);
if (!NT_SUCCESS(status))
return status;
@@ -168,9 +267,8 @@ NTSTATUS LGIddCreateDevice(_Inout_ PWDFDEVICE_INIT deviceInit)
return status;
/*
* Because we are limited to IddCx 1.5 to retain Windows 10 support we have
* no way of getting the device context in `LGIdddapterCommitModes`, as such
* we need to store this for later.
* Keep the WDF device cached so callbacks that do not provide an adapter or
* monitor context can still reach the device context on down-level IddCx.
*/
l_wdfDevice = device;

View File

@@ -104,7 +104,7 @@
<Driver_SpectreMitigation>Spectre</Driver_SpectreMitigation>
<IndirectDisplayDriver>true</IndirectDisplayDriver>
<IDDCX_VERSION_MAJOR>1</IDDCX_VERSION_MAJOR>
<IDDCX_VERSION_MINOR>9</IDDCX_VERSION_MINOR>
<IDDCX_VERSION_MINOR>10</IDDCX_VERSION_MINOR>
<UMDF_VERSION_MINOR>25</UMDF_VERSION_MINOR>
<UMDF_MINIMUM_VERSION_REQUIRED>25</UMDF_MINIMUM_VERSION_REQUIRED>
<_NT_TARGET_VERSION>0xA000005</_NT_TARGET_VERSION>
@@ -116,7 +116,7 @@
<Driver_SpectreMitigation>Spectre</Driver_SpectreMitigation>
<IndirectDisplayDriver>true</IndirectDisplayDriver>
<IDDCX_VERSION_MAJOR>1</IDDCX_VERSION_MAJOR>
<IDDCX_VERSION_MINOR>9</IDDCX_VERSION_MINOR>
<IDDCX_VERSION_MINOR>10</IDDCX_VERSION_MINOR>
<UMDF_VERSION_MINOR>25</UMDF_VERSION_MINOR>
<UMDF_MINIMUM_VERSION_REQUIRED>25</UMDF_MINIMUM_VERSION_REQUIRED>
<_NT_TARGET_VERSION>0xA000005</_NT_TARGET_VERSION>
@@ -175,7 +175,7 @@
<WppEnabled>true</WppEnabled>
<WppRecorderEnabled>true</WppRecorderEnabled>
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=9 /DIDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=10 /DIDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;$(ProjectDir)..\..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
@@ -190,7 +190,7 @@
<WppEnabled>true</WppEnabled>
<WppRecorderEnabled>true</WppRecorderEnabled>
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=9 /DIDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=10 /DIDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\repos\LGMP\lgmp\include;$(ProjectDir)..\..\vendor;$(ProjectDir)..\..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
@@ -205,7 +205,7 @@
<WppEnabled>true</WppEnabled>
<WppRecorderEnabled>true</WppRecorderEnabled>
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=9 /DIDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=10 /DIDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(SolutionDir)LGCommon;$(SolutionDir)..\repos\LGMP\lgmp\include;$(SolutionDir)..\vendor;$(SolutionDir)..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
@@ -220,7 +220,7 @@
<WppEnabled>true</WppEnabled>
<WppRecorderEnabled>true</WppRecorderEnabled>
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">trace.h</WppScanConfigurationData>
<AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=9 /DIDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions>/EHsc /D_ATL_NO_WIN_SUPPORT /DIDDCX_VERSION_MAJOR=1 /DIDDCX_VERSION_MINOR=10 /DIDDCX_MINIMUM_VERSION_REQUIRED=4 %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>$(SolutionDir)LGCommon;$(SolutionDir)..\repos\LGMP\lgmp\include;$(SolutionDir)..\vendor;$(SolutionDir)..\common\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>