ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
59.2k stars 10.1k forks source link

(DX11 + Win32) Docking: VSync does not execute when the code is chopped #6682

Closed MentalIssue closed 1 year ago

MentalIssue commented 1 year ago

Version/Branch of Dear ImGui:

Version: 1.89.8 (18980) Branch: docking Back-ends: imgui_impl_win32.cpp + imgui_impl_dx11.cpp & imgui_impl_win32.cpp + imgui_impl_dx12.cpp Operating System: Windows 11 Pro (Windows Version: 22621.1992)

I'm making my own standalone for school projects.

My Issue:

XXX (please provide as much context as possible) My issue is in imgui_impl_dx11.cpp which is I chopped the original example to 5 types of file, [ui.cpp, ui.h, panel.cpp, panel.h, and main.h] in DX11 the VSync is not working, I found out what code the DX11 reading for the multi-ports windows which is this ImGui_ImplDX11_SwapBuffers(ImGuiViewport* viewport, void*) not the actual g_pSwapChain->Present from the Render() but I found the fix that IF I change the sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD to sd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD the g_pSwapChain->Present(VSync, 0) will be the active vsync code BUT in imgui_impl_dx12.cpp and the chopped example is WORKING fine


imgui_impl_dx11.cpp:

static void ImGui_ImplDX11_SwapBuffers(ImGuiViewport* viewport, void*)
{
    ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData;
    vd->SwapChain->Present(0, 0); // Present without vsync
}


ui.cpp void update in dx11:

void UI::Update()
{
    // io Declaration
    ImGuiIO& io = ImGui::GetIO(); (void)io;

    // Render Dear ImGui graphics
    const float clear_color_with_alpha[4] = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w };
    g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, nullptr);
    g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha);
    ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());

    // Update and Render additional Platform Windows
    if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
    {
        ImGui::UpdatePlatformWindows();
        ImGui::RenderPlatformWindowsDefault();
    }

    // VSync for ImGui
    g_pSwapChain->Present(VSync, 0); // Present without vsync
    //g_pSwapChain->Present(1, 0); // Present with vsync
}


ui.cpp void update in dx12:

void UI::Update()
{
    // io Declaration
    ImGuiIO& io = ImGui::GetIO(); (void)io;

    FrameContext* frameCtx = WaitForNextFrameResources();
    UINT backBufferIdx = g_pSwapChain->GetCurrentBackBufferIndex();
    frameCtx->CommandAllocator->Reset();

    D3D12_RESOURCE_BARRIER barrier = {};
    barrier.Type                   = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
    barrier.Flags                  = D3D12_RESOURCE_BARRIER_FLAG_NONE;
    barrier.Transition.pResource   = g_mainRenderTargetResource[backBufferIdx];
    barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
    barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
    barrier.Transition.StateAfter  = D3D12_RESOURCE_STATE_RENDER_TARGET;
    g_pd3dCommandList->Reset(frameCtx->CommandAllocator, nullptr);
    g_pd3dCommandList->ResourceBarrier(1, &barrier);

    // Render Dear ImGui graphics
    const float clear_color_with_alpha[4] = { 0 };
    g_pd3dCommandList->ClearRenderTargetView(g_mainRenderTargetDescriptor[backBufferIdx], clear_color_with_alpha, 0, nullptr);
    g_pd3dCommandList->OMSetRenderTargets(1, &g_mainRenderTargetDescriptor[backBufferIdx], FALSE, nullptr);
    g_pd3dCommandList->SetDescriptorHeaps(1, &g_pd3dSrvDescHeap);
    ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), g_pd3dCommandList);
    barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
    barrier.Transition.StateAfter  = D3D12_RESOURCE_STATE_PRESENT;
    g_pd3dCommandList->ResourceBarrier(1, &barrier);
    g_pd3dCommandList->Close();

    g_pd3dCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&g_pd3dCommandList);

    // Update and Render additional Platform Windows
    if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
    {
        ImGui::UpdatePlatformWindows();
        ImGui::RenderPlatformWindowsDefault(nullptr, (void*)g_pd3dCommandList);
    }

    // VSync for ImGui
    g_pSwapChain->Present(VSync, 0); // Present with vsync
    //g_pSwapChain->Present(0, 0); // Present without vsync

    UINT64 fenceValue = g_fenceLastSignaledValue + 1;
    g_pd3dCommandQueue->Signal(g_fence, fenceValue);
    g_fenceLastSignaledValue = fenceValue;
    frameCtx->FenceValue = fenceValue;
}

Screenshots/Video

The Video is too large so had to post it in youtube Please open the subtitle https://youtu.be/mauulXQ9Jhg

ocornut commented 1 year ago

Does it happens with examples/example_win32_directx11/main.cpp and examples/example_win32_directx12/main.cpp ?

ocornut commented 1 year ago

Going to save myself time, sorry but #1586