mirror of
https://github.com/ocornut/imgui.git
synced 2025-10-03 00:28:35 +00:00
Backends: DX12: Rework synchronization logic. (master) (#8961)
This commit is contained in:
@@ -91,6 +91,7 @@ Other Changes:
|
|||||||
- Examples: SDL2+DirectX11: Try WARP software driver if hardware driver is
|
- Examples: SDL2+DirectX11: Try WARP software driver if hardware driver is
|
||||||
not available. (#5924, #5562)
|
not available. (#5924, #5562)
|
||||||
- Examples: SDL3+DirectX11: Added SDL3+DirectX11 example. (#8956, #8957) [@tomaz82]
|
- Examples: SDL3+DirectX11: Added SDL3+DirectX11 example. (#8956, #8957) [@tomaz82]
|
||||||
|
- Examples: Win32+DirectX12: Rework synchronization logic. (#8961) [@RT2Code]
|
||||||
- Examples: made examples's main.cpp consistent with returning 1 on error.
|
- Examples: made examples's main.cpp consistent with returning 1 on error.
|
||||||
|
|
||||||
|
|
||||||
|
@@ -102,8 +102,8 @@ bool CreateDeviceD3D(HWND hWnd);
|
|||||||
void CleanupDeviceD3D();
|
void CleanupDeviceD3D();
|
||||||
void CreateRenderTarget();
|
void CreateRenderTarget();
|
||||||
void CleanupRenderTarget();
|
void CleanupRenderTarget();
|
||||||
void WaitForLastSubmittedFrame();
|
void WaitForPendingOperations();
|
||||||
FrameContext* WaitForNextFrameResources();
|
FrameContext* WaitForNextFrameContext();
|
||||||
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
// Main code
|
// Main code
|
||||||
@@ -256,7 +256,7 @@ int main(int, char**)
|
|||||||
// Rendering
|
// Rendering
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
|
|
||||||
FrameContext* frameCtx = WaitForNextFrameResources();
|
FrameContext* frameCtx = WaitForNextFrameContext();
|
||||||
UINT backBufferIdx = g_pSwapChain->GetCurrentBackBufferIndex();
|
UINT backBufferIdx = g_pSwapChain->GetCurrentBackBufferIndex();
|
||||||
frameCtx->CommandAllocator->Reset();
|
frameCtx->CommandAllocator->Reset();
|
||||||
|
|
||||||
@@ -282,19 +282,17 @@ int main(int, char**)
|
|||||||
g_pd3dCommandList->Close();
|
g_pd3dCommandList->Close();
|
||||||
|
|
||||||
g_pd3dCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&g_pd3dCommandList);
|
g_pd3dCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&g_pd3dCommandList);
|
||||||
|
g_pd3dCommandQueue->Signal(g_fence, ++g_fenceLastSignaledValue);
|
||||||
|
frameCtx->FenceValue = g_fenceLastSignaledValue;
|
||||||
|
|
||||||
// Present
|
// Present
|
||||||
HRESULT hr = g_pSwapChain->Present(1, 0); // Present with vsync
|
HRESULT hr = g_pSwapChain->Present(1, 0); // Present with vsync
|
||||||
//HRESULT hr = g_pSwapChain->Present(0, 0); // Present without vsync
|
//HRESULT hr = g_pSwapChain->Present(0, 0); // Present without vsync
|
||||||
g_SwapChainOccluded = (hr == DXGI_STATUS_OCCLUDED);
|
g_SwapChainOccluded = (hr == DXGI_STATUS_OCCLUDED);
|
||||||
|
g_frameIndex++;
|
||||||
UINT64 fenceValue = g_fenceLastSignaledValue + 1;
|
|
||||||
g_pd3dCommandQueue->Signal(g_fence, fenceValue);
|
|
||||||
g_fenceLastSignaledValue = fenceValue;
|
|
||||||
frameCtx->FenceValue = fenceValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WaitForLastSubmittedFrame();
|
WaitForPendingOperations();
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
ImGui_ImplDX12_Shutdown();
|
ImGui_ImplDX12_Shutdown();
|
||||||
@@ -465,49 +463,33 @@ void CreateRenderTarget()
|
|||||||
|
|
||||||
void CleanupRenderTarget()
|
void CleanupRenderTarget()
|
||||||
{
|
{
|
||||||
WaitForLastSubmittedFrame();
|
WaitForPendingOperations();
|
||||||
|
|
||||||
for (UINT i = 0; i < APP_NUM_BACK_BUFFERS; i++)
|
for (UINT i = 0; i < APP_NUM_BACK_BUFFERS; i++)
|
||||||
if (g_mainRenderTargetResource[i]) { g_mainRenderTargetResource[i]->Release(); g_mainRenderTargetResource[i] = nullptr; }
|
if (g_mainRenderTargetResource[i]) { g_mainRenderTargetResource[i]->Release(); g_mainRenderTargetResource[i] = nullptr; }
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaitForLastSubmittedFrame()
|
void WaitForPendingOperations()
|
||||||
{
|
{
|
||||||
FrameContext* frameCtx = &g_frameContext[g_frameIndex % APP_NUM_FRAMES_IN_FLIGHT];
|
g_pd3dCommandQueue->Signal(g_fence, ++g_fenceLastSignaledValue);
|
||||||
|
|
||||||
UINT64 fenceValue = frameCtx->FenceValue;
|
g_fence->SetEventOnCompletion(g_fenceLastSignaledValue, g_fenceEvent);
|
||||||
if (fenceValue == 0)
|
::WaitForSingleObject(g_fenceEvent, INFINITE);
|
||||||
return; // No fence was signaled
|
|
||||||
|
|
||||||
frameCtx->FenceValue = 0;
|
|
||||||
if (g_fence->GetCompletedValue() >= fenceValue)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_fence->SetEventOnCompletion(fenceValue, g_fenceEvent);
|
|
||||||
WaitForSingleObject(g_fenceEvent, INFINITE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameContext* WaitForNextFrameResources()
|
FrameContext* WaitForNextFrameContext()
|
||||||
{
|
{
|
||||||
UINT nextFrameIndex = g_frameIndex + 1;
|
FrameContext* frame_context = &g_frameContext[g_frameIndex % APP_NUM_FRAMES_IN_FLIGHT];
|
||||||
g_frameIndex = nextFrameIndex;
|
if (g_fence->GetCompletedValue() < frame_context->FenceValue)
|
||||||
|
|
||||||
HANDLE waitableObjects[] = { g_hSwapChainWaitableObject, nullptr };
|
|
||||||
DWORD numWaitableObjects = 1;
|
|
||||||
|
|
||||||
FrameContext* frameCtx = &g_frameContext[nextFrameIndex % APP_NUM_FRAMES_IN_FLIGHT];
|
|
||||||
UINT64 fenceValue = frameCtx->FenceValue;
|
|
||||||
if (fenceValue != 0) // means no fence was signaled
|
|
||||||
{
|
{
|
||||||
frameCtx->FenceValue = 0;
|
g_fence->SetEventOnCompletion(frame_context->FenceValue, g_fenceEvent);
|
||||||
g_fence->SetEventOnCompletion(fenceValue, g_fenceEvent);
|
HANDLE waitableObjects[] = { g_hSwapChainWaitableObject, g_fenceEvent };
|
||||||
waitableObjects[1] = g_fenceEvent;
|
::WaitForMultipleObjects(2, waitableObjects, TRUE, INFINITE);
|
||||||
numWaitableObjects = 2;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
::WaitForSingleObject(g_hSwapChainWaitableObject, INFINITE);
|
||||||
|
|
||||||
WaitForMultipleObjects(numWaitableObjects, waitableObjects, TRUE, INFINITE);
|
return frame_context;
|
||||||
|
|
||||||
return frameCtx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward declare message handler from imgui_impl_win32.cpp
|
// Forward declare message handler from imgui_impl_win32.cpp
|
||||||
@@ -528,7 +510,6 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||||||
case WM_SIZE:
|
case WM_SIZE:
|
||||||
if (g_pd3dDevice != nullptr && wParam != SIZE_MINIMIZED)
|
if (g_pd3dDevice != nullptr && wParam != SIZE_MINIMIZED)
|
||||||
{
|
{
|
||||||
WaitForLastSubmittedFrame();
|
|
||||||
CleanupRenderTarget();
|
CleanupRenderTarget();
|
||||||
HRESULT result = g_pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), DXGI_FORMAT_UNKNOWN, DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT);
|
HRESULT result = g_pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), DXGI_FORMAT_UNKNOWN, DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT);
|
||||||
assert(SUCCEEDED(result) && "Failed to resize swapchain.");
|
assert(SUCCEEDED(result) && "Failed to resize swapchain.");
|
||||||
|
Reference in New Issue
Block a user