From 648fca7caa5a2e60c88484d784a522b3293e1a1e Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Fri, 28 Mar 2025 23:47:31 +0000 Subject: [PATCH] [idd] driver: re-plug the monitor if the heap test failed --- idd/LGIdd/CD3D12Device.cpp | 23 ++++++++++------------- idd/LGIdd/CD3D12Device.h | 9 ++++++++- idd/LGIdd/CIndirectDeviceContext.cpp | 8 ++++---- idd/LGIdd/CIndirectDeviceContext.h | 2 +- idd/LGIdd/CIndirectMonitorContext.cpp | 15 ++++++++++++--- 5 files changed, 35 insertions(+), 22 deletions(-) diff --git a/idd/LGIdd/CD3D12Device.cpp b/idd/LGIdd/CD3D12Device.cpp index 8ff01f97..3d56d779 100644 --- a/idd/LGIdd/CD3D12Device.cpp +++ b/idd/LGIdd/CD3D12Device.cpp @@ -39,30 +39,29 @@ static void CALLBACK _D3D12DebugCallback( description); } -bool CD3D12Device::Init(CIVSHMEM &ivshmem, UINT64 &alignSize) +CD3D12Device::InitResult CD3D12Device::Init(CIVSHMEM &ivshmem, UINT64 &alignSize) { -reInit: HRESULT hr; hr = CreateDXGIFactory2(m_debug ? DXGI_CREATE_FACTORY_DEBUG : 0, IID_PPV_ARGS(&m_factory)); if (FAILED(hr)) { DEBUG_ERROR_HR(hr, "Failed to create the DXGI factory"); - return false; + return InitResult::FAILURE; } hr = m_factory->EnumAdapterByLuid(m_adapterLuid, IID_PPV_ARGS(&m_adapter)); if (FAILED(hr)) { DEBUG_ERROR_HR(hr, "Failed to enumerate the adapter"); - return false; + return InitResult::FAILURE; } hr = D3D12CreateDevice(m_adapter.Get(), D3D_FEATURE_LEVEL_12_0, IID_PPV_ARGS(&m_device)); if (FAILED(hr)) { DEBUG_ERROR_HR(hr, "Failed to create the DirectX12 device"); - return false; + return InitResult::FAILURE; } if (m_debug) @@ -84,7 +83,8 @@ reInit: if (FAILED(hr)) { DEBUG_ERROR_HR(hr, "Failed to open IVSHMEM as a D3D12Heap"); - return false; + m_indirectCopy = true; + return InitResult::RETRY; } m_ivshmemHeap->SetName(L"IVSHMEM"); @@ -98,23 +98,20 @@ reInit: // failure often results in the device being removed and we need to completely reinit when this occurs m_indirectCopy = true; - m_device.Reset(); - m_adapter.Reset(); - m_factory.Reset(); - goto reInit; + return InitResult::RETRY; } DEBUG_INFO("Using IVSHMEM as a D3D12Heap"); } if (!m_copyQueue.Init(m_device.Get(), D3D12_COMMAND_LIST_TYPE_COPY, L"Copy")) - return false; + return InitResult::FAILURE; //if (!m_computeQueue.Init(m_device.Get(), D3D12_COMMAND_LIST_TYPE_COMPUTE, L"Compute")) - //return false; + //return InitResult::FAILURE; DEBUG_INFO("Created CD3D12Device"); - return true; + return InitResult::SUCCESS; } void CD3D12Device::DeInit() diff --git a/idd/LGIdd/CD3D12Device.h b/idd/LGIdd/CD3D12Device.h index ce8522f8..fe77a6d4 100644 --- a/idd/LGIdd/CD3D12Device.h +++ b/idd/LGIdd/CD3D12Device.h @@ -36,7 +36,14 @@ struct CD3D12Device CD3D12Device(LUID adapterLUID); ~CD3D12Device() { DeInit(); } - bool Init(CIVSHMEM &ivshmem, UINT64 &alignSize); + enum InitResult + { + RETRY, + FAILURE, + SUCCESS + }; + + InitResult Init(CIVSHMEM &ivshmem, UINT64 &alignSize); void DeInit(); ComPtr GetDevice() { return m_device; } diff --git a/idd/LGIdd/CIndirectDeviceContext.cpp b/idd/LGIdd/CIndirectDeviceContext.cpp index 4a1c48a0..90b574cf 100644 --- a/idd/LGIdd/CIndirectDeviceContext.cpp +++ b/idd/LGIdd/CIndirectDeviceContext.cpp @@ -188,18 +188,18 @@ void CIndirectDeviceContext::FinishInit(UINT connectorIndex) } } -void CIndirectDeviceContext::ReplugMonitor(UINT connectorIndex) +void CIndirectDeviceContext::ReplugMonitor() { if (m_monitor == WDF_NO_HANDLE) { - FinishInit(connectorIndex); + FinishInit(0); return; } if (m_replugMonitor) return; - DEBUG_TRACE("ReplugMonitor %u", connectorIndex); + DEBUG_TRACE("ReplugMonitor"); m_replugMonitor = true; NTSTATUS status = IddCxMonitorDeparture(m_monitor); if (!NT_SUCCESS(status)) @@ -529,7 +529,7 @@ void CIndirectDeviceContext::LGMPTimer() m.refresh = 120; m.preferred = true; m_displayModes.push_back(m); - ReplugMonitor(0); + ReplugMonitor(); } } diff --git a/idd/LGIdd/CIndirectDeviceContext.h b/idd/LGIdd/CIndirectDeviceContext.h index 9577431e..de14bdf8 100644 --- a/idd/LGIdd/CIndirectDeviceContext.h +++ b/idd/LGIdd/CIndirectDeviceContext.h @@ -94,7 +94,7 @@ public: void InitAdapter(); void FinishInit(UINT connectorIndex); - void ReplugMonitor(UINT connectorIndex); + void ReplugMonitor(); void UnassignSwapChain(); NTSTATUS ParseMonitorDescription( diff --git a/idd/LGIdd/CIndirectMonitorContext.cpp b/idd/LGIdd/CIndirectMonitorContext.cpp index bb9d046e..806787fe 100644 --- a/idd/LGIdd/CIndirectMonitorContext.cpp +++ b/idd/LGIdd/CIndirectMonitorContext.cpp @@ -49,10 +49,19 @@ void CIndirectMonitorContext::AssignSwapChain(IDDCX_SWAPCHAIN swapChain, LUID re UINT64 alignSize = CPlatformInfo::GetPageSize(); m_dx12Device = std::make_shared(renderAdapter); - if (!m_dx12Device->Init(m_devContext->GetIVSHMEM(), alignSize)) + switch (m_dx12Device->Init(m_devContext->GetIVSHMEM(), alignSize)) { - WdfObjectDelete(swapChain); - return; + case CD3D12Device::SUCCESS: + break; + + case CD3D12Device::FAILURE: + WdfObjectDelete(swapChain); + return; + + case CD3D12Device::RETRY: + WdfObjectDelete(swapChain); + m_devContext->ReplugMonitor(); + return; } if (!m_devContext->SetupLGMP(alignSize))