From 013013737fa729619534ade16915619b2683e91f Mon Sep 17 00:00:00 2001 From: SergeyN Date: Mon, 13 Apr 2020 15:22:27 +0200 Subject: [PATCH] Viewports, Backends: DX12: Fix for crash caused by early resource release. (#3121) --- examples/imgui_impl_dx12.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/examples/imgui_impl_dx12.cpp b/examples/imgui_impl_dx12.cpp index 3ead29c5..446546fb 100644 --- a/examples/imgui_impl_dx12.cpp +++ b/examples/imgui_impl_dx12.cpp @@ -815,7 +815,8 @@ static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport) desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; desc.NodeMask = 1; - IM_ASSERT(g_pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&data->RtvDescHeap)) == S_OK); + HRESULT hr = g_pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&data->RtvDescHeap)); + IM_ASSERT(hr == S_OK); SIZE_T rtv_descriptor_size = g_pd3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle = data->RtvDescHeap->GetCPUDescriptorHandleForHeapStart(); @@ -847,12 +848,24 @@ static void ImGui_ImplDX12_DestroyWindow(ImGuiViewport* viewport) // The main viewport (owned by the application) will always have RendererUserData == NULL since we didn't create the data for it. if (ImGuiViewportDataDx12* data = (ImGuiViewportDataDx12*)viewport->RendererUserData) { + // Wait for pending operations to complete to safely release objects below + HRESULT hr; + if (data->CommandQueue && data->Fence && data->FenceEvent) + { + hr = data->CommandQueue->Signal(data->Fence, ++data->FenceSignaledValue); + IM_ASSERT(hr == S_OK); + ::WaitForSingleObject(data->FenceEvent, 0); // Reset any forgotten waits + hr = data->Fence->SetEventOnCompletion(data->FenceSignaledValue, data->FenceEvent); + IM_ASSERT(hr == S_OK); + ::WaitForSingleObject(data->FenceEvent, INFINITE); + } + SafeRelease(data->CommandQueue); SafeRelease(data->CommandList); SafeRelease(data->SwapChain); SafeRelease(data->RtvDescHeap); SafeRelease(data->Fence); - ::CloseHandle(data->FenceEvent); + ::CloseHandle(data->FenceEvent); data->FenceEvent = NULL; for (UINT i = 0; i < g_numFramesInFlight; i++)