Backends: DX12: Use one fence instead of one by viewport. (docking) (#8961)

This commit is contained in:
ocornut
2025-09-29 16:27:12 +02:00
parent 778aadca65
commit bd9a37bc60

View File

@@ -152,9 +152,6 @@ struct ImGui_ImplDX12_ViewportData
ID3D12DescriptorHeap* RtvDescHeap; ID3D12DescriptorHeap* RtvDescHeap;
IDXGISwapChain3* SwapChain; IDXGISwapChain3* SwapChain;
HANDLE SwapChainWaitableObject; HANDLE SwapChainWaitableObject;
ID3D12Fence* Fence;
UINT64 FenceLastSignaledValue;
HANDLE FenceEvent;
UINT NumFramesInFlight; UINT NumFramesInFlight;
ImGui_ImplDX12_FrameContext* FrameCtx; ImGui_ImplDX12_FrameContext* FrameCtx;
@@ -169,9 +166,6 @@ struct ImGui_ImplDX12_ViewportData
RtvDescHeap = nullptr; RtvDescHeap = nullptr;
SwapChain = nullptr; SwapChain = nullptr;
SwapChainWaitableObject = nullptr; SwapChainWaitableObject = nullptr;
Fence = nullptr;
FenceLastSignaledValue = 0;
FenceEvent = nullptr;
NumFramesInFlight = num_frames_in_flight; NumFramesInFlight = num_frames_in_flight;
FrameCtx = new ImGui_ImplDX12_FrameContext[NumFramesInFlight]; FrameCtx = new ImGui_ImplDX12_FrameContext[NumFramesInFlight];
FrameIndex = 0; FrameIndex = 0;
@@ -196,8 +190,6 @@ struct ImGui_ImplDX12_ViewportData
IM_ASSERT(RtvDescHeap == nullptr); IM_ASSERT(RtvDescHeap == nullptr);
IM_ASSERT(SwapChain == nullptr); IM_ASSERT(SwapChain == nullptr);
IM_ASSERT(SwapChainWaitableObject == nullptr); IM_ASSERT(SwapChainWaitableObject == nullptr);
IM_ASSERT(Fence == nullptr);
IM_ASSERT(FenceEvent == nullptr);
for (UINT i = 0; i < NumFramesInFlight; ++i) for (UINT i = 0; i < NumFramesInFlight; ++i)
{ {
@@ -1065,13 +1057,6 @@ static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport)
IM_ASSERT(res == S_OK); IM_ASSERT(res == S_OK);
vd->CommandList->Close(); 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 // Create swap chain
// FIXME-VIEWPORT: May want to copy/inherit swap chain settings from the user/application. // FIXME-VIEWPORT: May want to copy/inherit swap chain settings from the user/application.
DXGI_SWAP_CHAIN_DESC1 sd1; DXGI_SWAP_CHAIN_DESC1 sd1;
@@ -1146,22 +1131,24 @@ static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport)
static void ImGui_WaitForPendingOperations(ImGui_ImplDX12_ViewportData* vd) 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); 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); IM_ASSERT(hr == S_OK);
::WaitForSingleObject(vd->FenceEvent, INFINITE); ::WaitForSingleObject(bd->FenceEvent, INFINITE);
} }
static ImGui_ImplDX12_FrameContext* ImGui_WaitForNextFrameContext(ImGui_ImplDX12_ViewportData* vd) 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]; 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); IM_ASSERT(hr == S_OK);
HANDLE waitableObjects[] = { vd->SwapChainWaitableObject, vd->FenceEvent }; HANDLE waitableObjects[] = { vd->SwapChainWaitableObject, bd->FenceEvent };
::WaitForMultipleObjects(2, waitableObjects, TRUE, INFINITE); ::WaitForMultipleObjects(2, waitableObjects, TRUE, INFINITE);
} }
else else
@@ -1185,9 +1172,6 @@ static void ImGui_ImplDX12_DestroyWindow(ImGuiViewport* viewport)
SafeRelease(vd->CommandList); SafeRelease(vd->CommandList);
SafeRelease(vd->SwapChain); SafeRelease(vd->SwapChain);
SafeRelease(vd->RtvDescHeap); SafeRelease(vd->RtvDescHeap);
SafeRelease(vd->Fence);
::CloseHandle(vd->FenceEvent);
vd->FenceEvent = nullptr;
for (UINT i = 0; i < bd->numFramesInFlight; i++) 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); 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); IM_ASSERT(hr == S_OK);
frame_context->FenceValue = vd->FenceLastSignaledValue; frame_context->FenceValue = bd->FenceLastSignaledValue;
} }
static void ImGui_ImplDX12_SwapBuffers(ImGuiViewport* viewport, void*) static void ImGui_ImplDX12_SwapBuffers(ImGuiViewport* viewport, void*)