From bd9a37bc600a4281d74ef429fb23ee8e002b217d Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 29 Sep 2025 16:27:12 +0200 Subject: [PATCH] Backends: DX12: Use one fence instead of one by viewport. (docking) (#8961) --- backends/imgui_impl_dx12.cpp | 36 ++++++++++-------------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/backends/imgui_impl_dx12.cpp b/backends/imgui_impl_dx12.cpp index 9fbdc4426..68e379b03 100644 --- a/backends/imgui_impl_dx12.cpp +++ b/backends/imgui_impl_dx12.cpp @@ -152,9 +152,6 @@ struct ImGui_ImplDX12_ViewportData ID3D12DescriptorHeap* RtvDescHeap; IDXGISwapChain3* SwapChain; HANDLE SwapChainWaitableObject; - ID3D12Fence* Fence; - UINT64 FenceLastSignaledValue; - HANDLE FenceEvent; UINT NumFramesInFlight; ImGui_ImplDX12_FrameContext* FrameCtx; @@ -169,9 +166,6 @@ struct ImGui_ImplDX12_ViewportData RtvDescHeap = nullptr; SwapChain = nullptr; SwapChainWaitableObject = nullptr; - Fence = nullptr; - FenceLastSignaledValue = 0; - FenceEvent = nullptr; NumFramesInFlight = num_frames_in_flight; FrameCtx = new ImGui_ImplDX12_FrameContext[NumFramesInFlight]; FrameIndex = 0; @@ -196,8 +190,6 @@ struct ImGui_ImplDX12_ViewportData IM_ASSERT(RtvDescHeap == nullptr); IM_ASSERT(SwapChain == nullptr); IM_ASSERT(SwapChainWaitableObject == nullptr); - IM_ASSERT(Fence == nullptr); - IM_ASSERT(FenceEvent == nullptr); for (UINT i = 0; i < NumFramesInFlight; ++i) { @@ -1065,13 +1057,6 @@ static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport) IM_ASSERT(res == S_OK); vd->CommandList->Close(); - // Create fence. - res = bd->pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&vd->Fence)); - IM_ASSERT(res == S_OK); - - vd->FenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); - IM_ASSERT(vd->FenceEvent != nullptr); - // Create swap chain // FIXME-VIEWPORT: May want to copy/inherit swap chain settings from the user/application. DXGI_SWAP_CHAIN_DESC1 sd1; @@ -1146,22 +1131,24 @@ static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport) static void ImGui_WaitForPendingOperations(ImGui_ImplDX12_ViewportData* vd) { - HRESULT hr = vd->CommandQueue->Signal(vd->Fence, ++vd->FenceLastSignaledValue); + ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); + HRESULT hr = vd->CommandQueue->Signal(bd->Fence, ++bd->FenceLastSignaledValue); IM_ASSERT(hr == S_OK); - hr = vd->Fence->SetEventOnCompletion(vd->FenceLastSignaledValue, vd->FenceEvent); + hr = bd->Fence->SetEventOnCompletion(bd->FenceLastSignaledValue, bd->FenceEvent); IM_ASSERT(hr == S_OK); - ::WaitForSingleObject(vd->FenceEvent, INFINITE); + ::WaitForSingleObject(bd->FenceEvent, INFINITE); } static ImGui_ImplDX12_FrameContext* ImGui_WaitForNextFrameContext(ImGui_ImplDX12_ViewportData* vd) { + ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData(); ImGui_ImplDX12_FrameContext* frame_context = &vd->FrameCtx[vd->FrameIndex % vd->NumFramesInFlight]; - if (vd->Fence->GetCompletedValue() < frame_context->FenceValue) + if (bd->Fence->GetCompletedValue() < frame_context->FenceValue) { - HRESULT hr = vd->Fence->SetEventOnCompletion(frame_context->FenceValue, vd->FenceEvent); + HRESULT hr = bd->Fence->SetEventOnCompletion(frame_context->FenceValue, bd->FenceEvent); IM_ASSERT(hr == S_OK); - HANDLE waitableObjects[] = { vd->SwapChainWaitableObject, vd->FenceEvent }; + HANDLE waitableObjects[] = { vd->SwapChainWaitableObject, bd->FenceEvent }; ::WaitForMultipleObjects(2, waitableObjects, TRUE, INFINITE); } else @@ -1185,9 +1172,6 @@ static void ImGui_ImplDX12_DestroyWindow(ImGuiViewport* viewport) SafeRelease(vd->CommandList); SafeRelease(vd->SwapChain); SafeRelease(vd->RtvDescHeap); - SafeRelease(vd->Fence); - ::CloseHandle(vd->FenceEvent); - vd->FenceEvent = nullptr; for (UINT i = 0; i < bd->numFramesInFlight; i++) { @@ -1260,9 +1244,9 @@ static void ImGui_ImplDX12_RenderWindow(ImGuiViewport* viewport, void*) vd->CommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&cmd_list); - HRESULT hr = vd->CommandQueue->Signal(vd->Fence, ++vd->FenceLastSignaledValue); + HRESULT hr = vd->CommandQueue->Signal(bd->Fence, ++bd->FenceLastSignaledValue); IM_ASSERT(hr == S_OK); - frame_context->FenceValue = vd->FenceLastSignaledValue; + frame_context->FenceValue = bd->FenceLastSignaledValue; } static void ImGui_ImplDX12_SwapBuffers(ImGuiViewport* viewport, void*)