[idd] driver: re-plug the monitor if the heap test failed

This commit is contained in:
Geoffrey McRae 2025-03-28 23:47:31 +00:00
parent 868504d22d
commit 648fca7caa
5 changed files with 35 additions and 22 deletions

View File

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

View File

@ -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<ID3D12Device3> GetDevice() { return m_device; }

View File

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

View File

@ -94,7 +94,7 @@ public:
void InitAdapter();
void FinishInit(UINT connectorIndex);
void ReplugMonitor(UINT connectorIndex);
void ReplugMonitor();
void UnassignSwapChain();
NTSTATUS ParseMonitorDescription(

View File

@ -49,10 +49,19 @@ void CIndirectMonitorContext::AssignSwapChain(IDDCX_SWAPCHAIN swapChain, LUID re
UINT64 alignSize = CPlatformInfo::GetPageSize();
m_dx12Device = std::make_shared<CD3D12Device>(renderAdapter);
if (!m_dx12Device->Init(m_devContext->GetIVSHMEM(), alignSize))
switch (m_dx12Device->Init(m_devContext->GetIVSHMEM(), alignSize))
{
case CD3D12Device::SUCCESS:
break;
case CD3D12Device::FAILURE:
WdfObjectDelete(swapChain);
return;
case CD3D12Device::RETRY:
WdfObjectDelete(swapChain);
m_devContext->ReplugMonitor();
return;
}
if (!m_devContext->SetupLGMP(alignSize))