Skip to content

Vsync frame latency issues #3157

@BlackCurtainStudio

Description

@BlackCurtainStudio

Release Type: Official Release

Version: 4.2.0.2381 (and probably every other version)

Platform(s): Only tested on Windows

Describe the bug
I'm not technically versed with the issue, so I will be quoting from contributions channel on Discord:

Just debugging render freeze issues on a very special setup. While doing so wrote a little native app with a trivial D3D11 render loop. Looking at official documentation I ran into the topic of frame latency, good article here: https://learn.microsoft.com/en-us/windows/uwp/gaming/reduce-latency-with-dxgi-1-3-swap-chains
Did a grep search in Stride, and found that the UWP swap chain implementation actually changes the default from 3 to 1, while the desktop one doesn't touch the parameter at all, meaning we run with a latency of 3.
Looking at the output window with a tool like PresentMon confirms it, we have a latency of 66ms (4 * 16.6ms). Shouldn't that parameter at least be exposed to the user? I also wonder myself why no one ever complained... especially when you use the technique explained in the article (wait for swap chain to say it's ready for a new frame, process input events, render and present) vs what we do now, the difference is huge. With minimum latency the ImGui window I am rendering reacts immediately while with default settings (3 frames latency) it lags behind the mouse quite noticeable.

My findings so far:
We use DXGI_SWAP_EFFECT_FLIP_DISCARD, BufferCount = 2, we don't touch MaxFrameLatency (defaults to 3, see https://learn.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-idxgidevice1-setmaximumframelatency)
PresentMon shows latency of 66ms
If I set Device.SetMaxFrameLatency to 2, the latency drops to 50ms
If I set it to 1, the latency drops to 33ms
I can also set it to the max value of 16, and latency goes to 280ms
Not sure how they implemented that internally, because we setup our swapchain with buffer count of 2, but never mind, that how it behaves.

NOW, if I change the render loop to the pattern as outlined in the article further up (reduce latency with waitable swap chains) then the behaviour is different:
First of all, it's now about SwapChain.SetMaxFrameLatency (defaults to 1) and not DEVICE.SetMaxFrameLatency.
That value is further clamped by what we specify as buffer count on the swap chain. For example setting the latency to 16 with a buffer count of 2 doesn't do a thing. So somehow that's more logical then the setting on the device itself.
The PresentationInterval property is used for the Present call and controls for how long a frame stays on screen - at least that's how I understood it

So it's about different topics I guess
a) Keeping everything as is, but changing the default of Device.MaxFrameLatency to a lower value than 3? 66ms is a lot. Downside as far as I understand is that a value of 1 means the GPU can do less in parallel. Therefor maybe it should get exposed for the game developer to decide? Or is there a property already which we should tie to it? Somehow make an educated decision of what the best value would be?
b) Changing the whole render loop for low latency. That means WaitOnSwapChain, Process events, Render. See example in article.

To Reproduce
Steps to reproduce the behavior:
1.

Expected behavior
From what I've gathered, fields for latency settings should be exposed, either through code, via the game settings asset or somewhere else in the editor. The frame latency issues are quite noticeable in first person games.

Screenshots
If applicable, add screenshots to help explain your problem (use GitHub drag & drop)

Log and callstacks
If any, please attach here any log or callstack (preferably in a .txt file using GitHub drag and drop)

Additional context
Add any other context about the problem here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions