From 770bce4ec0f757b66d403162fd8ce75878739c02 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Thu, 6 Aug 2026 05:04:22 +1000 Subject: [PATCH] [idd] adapter: defer render selection until initialization --- idd/LGIdd/CIndirectDeviceContext.cpp | 41 ++++++++++++++++------------ idd/LGIdd/CIndirectDeviceContext.h | 19 +++++++------ idd/LGIdd/Device.cpp | 2 +- 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/idd/LGIdd/CIndirectDeviceContext.cpp b/idd/LGIdd/CIndirectDeviceContext.cpp index cca6d999..472cc19b 100644 --- a/idd/LGIdd/CIndirectDeviceContext.cpp +++ b/idd/LGIdd/CIndirectDeviceContext.cpp @@ -315,8 +315,8 @@ void CIndirectDeviceContext::InitAdapter() // Select the render adapter before advertising capabilities. If no hardware // adapter is available, this is a software-rendered display and must remain // SDR-only; the software path must never depend on compute processing. - bool havePreferredRenderAdapter = false; - LUID preferredRenderAdapter = {}; + m_havePreferredRenderAdapter = false; + m_preferredRenderAdapter = {}; IDXGIFactory1 * factory = NULL; HRESULT factoryStatus = CreateDXGIFactory1( __uuidof(IDXGIFactory1), (void **)&factory); @@ -362,15 +362,15 @@ void CIndirectDeviceContext::InitAdapter() DEBUG_INFO("Selected render adapter %ls (vendor 0x%04x, device 0x%04x)", adapterDesc.Description, adapterDesc.VendorId, adapterDesc.DeviceId); - preferredRenderAdapter = adapterDesc.AdapterLuid; - havePreferredRenderAdapter = true; + m_preferredRenderAdapter = adapterDesc.AdapterLuid; + m_havePreferredRenderAdapter = true; break; } factory->Release(); } - m_softwareMode = !havePreferredRenderAdapter; + m_softwareMode = !m_havePreferredRenderAdapter; if (m_softwareMode) DEBUG_INFO("No hardware render adapter available; using SDR software mode"); @@ -471,21 +471,10 @@ void CIndirectDeviceContext::InitAdapter() return; } - DEBUG_INFO("IddCxAdapterInitAsync started successfully (adapter %p)", - m_adapter); - - // Try to co-exist with the virtual video device by telling IddCx which - // hardware adapter we prefer to render on. - if (havePreferredRenderAdapter) - { - IDARG_IN_ADAPTERSETRENDERADAPTER args = {}; - args.PreferredRenderAdapter = preferredRenderAdapter; - IddCxAdapterSetRenderAdapter(m_adapter, &args); - DEBUG_INFO("Preferred render adapter set"); - } - auto * wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(m_adapter); wrapper->context = this; + DEBUG_INFO("IddCxAdapterInitAsync started successfully (adapter %p)", + m_adapter); DEBUG_INFO("Adapter context attached; waiting for initialization callback"); // Adapter is up; no need to keep retrying. @@ -494,6 +483,22 @@ void CIndirectDeviceContext::InitAdapter() DEBUG_INFO("Adapter initialization request complete; returning to IddCx"); } +void CIndirectDeviceContext::FinishAdapterInit(UINT connectorIndex) +{ + // Try to co-exist with the virtual video device by telling IddCx which + // hardware adapter we prefer to render on. Do this only after the adapter + // has finished initializing, but before adding its monitor. + if (m_havePreferredRenderAdapter) + { + IDARG_IN_ADAPTERSETRENDERADAPTER args = {}; + args.PreferredRenderAdapter = m_preferredRenderAdapter; + IddCxAdapterSetRenderAdapter(m_adapter, &args); + DEBUG_INFO("Preferred render adapter set"); + } + + FinishInit(connectorIndex); +} + void CIndirectDeviceContext::FinishInit(UINT connectorIndex) { DEBUG_INFO("Creating monitor on connector %u", connectorIndex); diff --git a/idd/LGIdd/CIndirectDeviceContext.h b/idd/LGIdd/CIndirectDeviceContext.h index 87019877..cb0afb8c 100644 --- a/idd/LGIdd/CIndirectDeviceContext.h +++ b/idd/LGIdd/CIndirectDeviceContext.h @@ -64,14 +64,16 @@ class CIndirectDeviceContext { private: WDFDEVICE m_wdfDevice; - IDDCX_ADAPTER m_adapter = nullptr; - IDDCX_MONITOR m_monitor = nullptr; - bool m_replugMonitor = false; - bool m_replugPending = false; - bool m_monitorDeparted = false; - bool m_swapChainAssigned = false; - bool m_swapChainReady = false; - bool m_waitForSwapChainRelease = false; + IDDCX_ADAPTER m_adapter = nullptr; + IDDCX_MONITOR m_monitor = nullptr; + LUID m_preferredRenderAdapter = {}; + bool m_havePreferredRenderAdapter = false; + bool m_replugMonitor = false; + bool m_replugPending = false; + bool m_monitorDeparted = false; + bool m_swapChainAssigned = false; + bool m_swapChainReady = false; + bool m_waitForSwapChainRelease = false; // Guards the adapter/monitor init handshake and the replug state machine // (monitor/replug/swap-chain state, m_doSetMode, m_setMode). These are @@ -227,6 +229,7 @@ public: bool PopulateDefaultModes(); void InitAdapter(); + void FinishAdapterInit(UINT connectorIndex); void FinishInit(UINT connectorIndex); void ReplugMonitor(); diff --git a/idd/LGIdd/Device.cpp b/idd/LGIdd/Device.cpp index ca7b5482..e8f44c7b 100644 --- a/idd/LGIdd/Device.cpp +++ b/idd/LGIdd/Device.cpp @@ -92,7 +92,7 @@ NTSTATUS LGIddAdapterInitFinished(IDDCX_ADAPTER adapter, const IDARG_IN_ADAPTER_ } DEBUG_INFO("Adapter initialized, creating monitor"); - wrapper->context->FinishInit(0); + wrapper->context->FinishAdapterInit(0); return STATUS_SUCCESS; }