[idd] driver: handle command queue failures gracefully

This commit is contained in:
Geoffrey McRae 2025-03-30 18:58:03 +11:00
parent 63a9365377
commit 94fbbad21c
3 changed files with 38 additions and 19 deletions

View File

@ -63,8 +63,10 @@ bool CD3D12CommandQueue::Init(ID3D12Device3 * device, D3D12_COMMAND_LIST_TYPE ty
&m_waitHandle, &m_waitHandle,
m_event.Get(), m_event.Get(),
[](PVOID param, BOOLEAN timeout){ [](PVOID param, BOOLEAN timeout){
if (!timeout) CD3D12CommandQueue * queue = (CD3D12CommandQueue*)param;
((CD3D12CommandQueue*)param)->OnCompletion(); if (timeout)
queue->m_completionResult = false;
queue->OnCompletion();
}, },
this, this,
INFINITE, INFINITE,
@ -88,28 +90,35 @@ void CD3D12CommandQueue::DeInit()
bool CD3D12CommandQueue::Execute() bool CD3D12CommandQueue::Execute()
{ {
m_needsReset = true;
m_completionResult = true;
HRESULT hr = m_gfxList->Close(); HRESULT hr = m_gfxList->Close();
if (FAILED(hr)) if (FAILED(hr))
{ {
m_completionResult = false;
SetEvent(m_event.Get());
DEBUG_ERROR_HR(hr, "Failed to close the command list (%ls)", m_name); DEBUG_ERROR_HR(hr, "Failed to close the command list (%ls)", m_name);
return false; return false;
} }
ID3D12CommandList * lists[] = { m_cmdList.Get() }; ID3D12CommandList * lists[] = { m_cmdList.Get() };
m_queue->ExecuteCommandLists(1, lists); m_queue->ExecuteCommandLists(1, lists);
m_pending = true;
m_needsReset = true;
++m_fenceValue; ++m_fenceValue;
m_fence->SetEventOnCompletion(m_fenceValue, m_event.Get()); hr = m_fence->SetEventOnCompletion(m_fenceValue, m_event.Get());
m_queue->Signal(m_fence.Get(), m_fenceValue);
if (FAILED(hr)) if (FAILED(hr))
{ {
m_completionResult = false;
SetEvent(m_event.Get());
DEBUG_ERROR_HR(hr, "Failed to set the fence signal (%ls)", m_name); DEBUG_ERROR_HR(hr, "Failed to set the fence signal (%ls)", m_name);
return false; return false;
} }
m_pending = true;
m_queue->Signal(m_fence.Get(), m_fenceValue);
return true; return true;
} }
@ -152,5 +161,3 @@ bool CD3D12CommandQueue::Reset()
m_needsReset = false; m_needsReset = false;
return true; return true;
} }

View File

@ -26,15 +26,19 @@ class CD3D12CommandQueue
UINT64 m_fenceValue = 0; UINT64 m_fenceValue = 0;
bool m_needsReset = false; bool m_needsReset = false;
typedef void (*CompletionFunction)(CD3D12CommandQueue * queue, void * param1, void * param2); typedef void (*CompletionFunction)(CD3D12CommandQueue * queue,
bool result, void * param1, void * param2);
CompletionFunction m_completionCallback = nullptr; CompletionFunction m_completionCallback = nullptr;
void * m_completionParams[2]; void * m_completionParams[2];
bool m_completionResult = true;
void OnCompletion() void OnCompletion()
{ {
if (m_completionCallback) if (m_completionCallback)
m_completionCallback( m_completionCallback(
this, this,
m_completionResult,
m_completionParams[0], m_completionParams[0],
m_completionParams[1]); m_completionParams[1]);
m_pending = false; m_pending = false;

View File

@ -153,13 +153,21 @@ void CSwapChainProcessor::SwapChainThreadCore()
} }
} }
void CSwapChainProcessor::CompletionFunction(CD3D12CommandQueue * queue, void * param1, void * param2) void CSwapChainProcessor::CompletionFunction(
CD3D12CommandQueue * queue, bool result, void * param1, void * param2)
{ {
UNREFERENCED_PARAMETER(queue); UNREFERENCED_PARAMETER(queue);
auto sc = (CSwapChainProcessor *)param1; auto sc = (CSwapChainProcessor *)param1;
auto fbRes = (CFrameBufferResource*)param2; auto fbRes = (CFrameBufferResource*)param2;
// fail gracefully
if (!result)
{
sc->m_devContext->FinalizeFrameBuffer(fbRes->GetFrameIndex());
return;
}
if (sc->m_dx12Device->IsIndirectCopy()) if (sc->m_dx12Device->IsIndirectCopy())
sc->m_devContext->WriteFrameBuffer( sc->m_devContext->WriteFrameBuffer(
fbRes->GetFrameIndex(), fbRes->GetFrameIndex(),