Deadlock with low latency setup

Hi,

I think we identified an engine bug that leads to a deadlock when the engine is configured for low latency.

When we use the parameters r.VSync=True, r.GTSyncType=2 and set r.OneFrameThreadLag=0 then the engine will stuck after the second frame present. It appears that the engine enqueues a sync point at the end of the frame which is supposed to be triggered after the present, but this never happens. The RHITriggerTaskEventOnFlip() is never called, most likely because the GT, RT and RHI threads all end up running in the same frame.

A generic latency question. Do you know if the display latency with D3D12 (from input to complete scanout) at 30Hz is expected to be 99ms? We noticed that going below 60Hz will result in an additional frame of latency (i.e. 99ms instead of 66ms). We have no idea where the additional frame of latency comes from (even the Microsoft premium support could not help us with this). We could reproduce this with the engine and a minimal test app.

Best regards,

Ilja

Steps to Reproduce

  1. Create an empty BP project
  2. Add these parameters to the DefaultEngine.ini
    1. r.VSync=True
    2. r.GTSyncType=2
    3. r.OneFrameThreadLag=0
  3. Lauch the project with the -game parameter: “<…>\UnrealEditor.exe” “<…>\ReproduceDeadlock.uproject” -game
  4. Result: The engine deadlocks after the second Present()

Hi Ilja

Thanks for reporting this. I reproed this locally and have submitted a fix in CL 44753093 to //UE5/Main. Please let me know if that change fixes the deadlock for you.

As for the latency question, it can be difficult to answer as there are a multitude of console variables and configuration in the engine that can affect the total length of the renderer pipeline. I remember that a 30hz title on console under default engine settings can have up to ~120ms of latency, which was why we had to add the “r.GTSyncType” console variable to reduce that.

I should note that “r.GTSyncType 2” is only implemented on certain console platforms. On PC, it behaves the same as “r.GTSyncType 1”, which (under default settings for other cvars) causes the game thread to synchronize with the N-1 frame on the RHI thread. Running with “r.OneFrameThreadLag 0” will cause the game thread to wait for the current frame (i.e. frame N) on the RHI thread instead. After that, there’s still the latency introduced by the GPU and swapchain. If the swapchain is triple-buffered, there can be an additional frame of latency there.

We do have a console variable (“r.VsyncInformationInsights”) that enables additional information in Unreal Insights, adding events where each frame flips, along with the frame number. You can use these to figure out the total game thread -> frame flip end-to-end latency.

Cheers,

Luke

Hi Luke,

thanks for the quick reply and the clarification regarding r.GTSyncType.

We modified the engine a bit and could bring down the latency to one frame at 60Hz. The one weird thing is that if you use a display with <60Hz, the OS or driver will introduce an additional frame of latency (we did some measurements with a photodiode and an oscilloscope). I asked this random latency question because I hoped that you might have encountered a similar problem.

Anyway thanks for the quick fix. We will merge the fix and report back with the results.

The fix helped. The deadlock does not occur anymore. Thanks for the help.