[idd] adapter: defer render selection until initialization
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled
build / client-tests (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client-tests (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client-tests (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client-tests (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client-tests (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client-tests (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client-tests (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client-tests (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled

This commit is contained in:
Geoffrey McRae
2026-08-06 05:04:22 +10:00
parent 650636ccee
commit 770bce4ec0
3 changed files with 35 additions and 27 deletions

View File

@@ -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);

View File

@@ -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();

View File

@@ -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;
}