[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

@ -33,7 +33,7 @@ bool CD3D12CommandQueue::Init(ID3D12Device3 * device, D3D12_COMMAND_LIST_TYPE ty
}
m_gfxList->SetName(name);
m_cmdList = m_gfxList;
m_cmdList = m_gfxList;
if (!m_cmdList)
{
DEBUG_ERROR_HR(hr, "Failed to get the CommandList (%ls)", name);
@ -58,13 +58,15 @@ bool CD3D12CommandQueue::Init(ID3D12Device3 * device, D3D12_COMMAND_LIST_TYPE ty
{
ULONG flags = (callbackMode == FAST) ?
WT_EXECUTEINWAITTHREAD : WT_EXECUTEINPERSISTENTTHREAD;
RegisterWaitForSingleObject(
&m_waitHandle,
m_event.Get(),
[](PVOID param, BOOLEAN timeout){
if (!timeout)
((CD3D12CommandQueue*)param)->OnCompletion();
CD3D12CommandQueue * queue = (CD3D12CommandQueue*)param;
if (timeout)
queue->m_completionResult = false;
queue->OnCompletion();
},
this,
INFINITE,
@ -88,28 +90,35 @@ void CD3D12CommandQueue::DeInit()
bool CD3D12CommandQueue::Execute()
{
m_needsReset = true;
m_completionResult = true;
HRESULT hr = m_gfxList->Close();
if (FAILED(hr))
{
m_completionResult = false;
SetEvent(m_event.Get());
DEBUG_ERROR_HR(hr, "Failed to close the command list (%ls)", m_name);
return false;
}
ID3D12CommandList * lists[] = { m_cmdList.Get() };
m_queue->ExecuteCommandLists(1, lists);
m_pending = true;
m_needsReset = true;
++m_fenceValue;
m_fence->SetEventOnCompletion(m_fenceValue, m_event.Get());
m_queue->Signal(m_fence.Get(), m_fenceValue);
hr = m_fence->SetEventOnCompletion(m_fenceValue, m_event.Get());
if (FAILED(hr))
{
m_completionResult = false;
SetEvent(m_event.Get());
DEBUG_ERROR_HR(hr, "Failed to set the fence signal (%ls)", m_name);
return false;
}
m_pending = true;
m_queue->Signal(m_fence.Get(), m_fenceValue);
return true;
}
@ -134,7 +143,7 @@ bool CD3D12CommandQueue::Reset()
return true;
HRESULT hr;
hr = m_allocator->Reset();
if (FAILED(hr))
{
@ -152,5 +161,3 @@ bool CD3D12CommandQueue::Reset()
m_needsReset = false;
return true;
}

View File

@ -26,15 +26,19 @@ class CD3D12CommandQueue
UINT64 m_fenceValue = 0;
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;
void * m_completionParams[2];
bool m_completionResult = true;
void OnCompletion()
{
if (m_completionCallback)
m_completionCallback(
this,
m_completionResult,
m_completionParams[0],
m_completionParams[1]);
m_pending = false;
@ -71,4 +75,4 @@ class CD3D12CommandQueue
ComPtr<ID3D12CommandQueue > GetCmdQueue() { return m_queue; }
ComPtr<ID3D12GraphicsCommandList> GetGfxList() { return m_gfxList; }
};
};

View File

@ -71,7 +71,7 @@ void CSwapChainProcessor::SwapChainThread()
}
void CSwapChainProcessor::SwapChainThreadCore()
{
{
ComPtr<IDXGIDevice> dxgiDevice;
HRESULT hr = m_dx11Device->GetDevice().As(&dxgiDevice);
if (FAILED(hr))
@ -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);
auto sc = (CSwapChainProcessor *)param1;
auto fbRes = (CFrameBufferResource*)param2;
// fail gracefully
if (!result)
{
sc->m_devContext->FinalizeFrameBuffer(fbRes->GetFrameIndex());
return;
}
if (sc->m_dx12Device->IsIndirectCopy())
sc->m_devContext->WriteFrameBuffer(
fbRes->GetFrameIndex(),
@ -170,7 +178,7 @@ void CSwapChainProcessor::CompletionFunction(CD3D12CommandQueue * queue, void *
bool CSwapChainProcessor::SwapChainNewFrame(ComPtr<IDXGIResource> acquiredBuffer)
{
ComPtr<ID3D11Texture2D> texture;
ComPtr<ID3D11Texture2D> texture;
HRESULT hr = acquiredBuffer.As(&texture);
if (FAILED(hr))
{
@ -221,7 +229,7 @@ bool CSwapChainProcessor::SwapChainNewFrame(ComPtr<IDXGIResource> acquiredBuffer
}
copyQueue->SetCompletionCallback(&CompletionFunction, this, fbRes);
D3D12_TEXTURE_COPY_LOCATION srcLoc = {};
srcLoc.pResource = srcRes->GetRes().Get();
srcLoc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
@ -243,4 +251,4 @@ bool CSwapChainProcessor::SwapChainNewFrame(ComPtr<IDXGIResource> acquiredBuffer
copyQueue->Execute();
return true;
}
}