From 1e7672acf46a81e36b3cf35734c015326dd97d58 Mon Sep 17 00:00:00 2001 From: Ivan Zinkevich Date: Thu, 7 May 2020 23:50:51 +0300 Subject: [PATCH] Backends: DX12: Fixed OBJECT_DELETED_WHILE_STILL_IN_USE on viewport resizing. (#3210) Tested with detaching/attaching a viewport and resizing it. DX12 debug layer is clean. --- examples/imgui_impl_dx12.cpp | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/examples/imgui_impl_dx12.cpp b/examples/imgui_impl_dx12.cpp index bbe026e4..b10e8c65 100644 --- a/examples/imgui_impl_dx12.cpp +++ b/examples/imgui_impl_dx12.cpp @@ -846,22 +846,26 @@ static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport) } } +static void ImGui_WaitForPendingOperations(ImGuiViewportDataDx12* data) +{ + HRESULT hr = S_FALSE; + if (data && 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); + } +} + 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); - } + ImGui_WaitForPendingOperations(data); SafeRelease(data->CommandQueue); SafeRelease(data->CommandList); @@ -887,6 +891,8 @@ static void ImGui_ImplDX12_SetWindowSize(ImGuiViewport* viewport, ImVec2 size) { ImGuiViewportDataDx12* data = (ImGuiViewportDataDx12*)viewport->RendererUserData; + ImGui_WaitForPendingOperations(data); + for (UINT i = 0; i < g_numFramesInFlight; i++) SafeRelease(data->FrameCtx[i].RenderTarget);