Weird Unity 6.3 LTS (DX12) periodic ~54ms CPU spikes from GfxDeviceD3D12.WaitForLastPresentation.WaitForGPU (Editor only, builds unaffected)

Similar (unsolved) issue here with slight variations:

  • WaitForLastPresentation takes around 12 ms every single frame, not only during the spikes (which are in the “other” category for me)
  • Disabling GSync globally in the NVIDIA Control Panel does not help
  • Using DX11 instead of DX12 does not help either
  • [EDIT] I use URP (not HDRP as op)

Importantly, I tried switching to DX11 in an empty project and, there, it does remove the issue! (with DX12 in this empty project, I still have WaitForLastPresentation taking 12 ms per frame)

I don’t understand why the fix works in an empty project and not on my main project.

Note that I am unsure whether I am correctly switching to DX11. What I did is changing the order of the graphics API in Project Settings > Player > Other Settings > Rendering > Graphics API for Windows and having Direct3D11 at the top of the list. Is this the right way to have Unity using DX11 both in editor and in player?

More info:

  • I see the issue in my main project both in the usual scene as in an empty scene (as can be seen in the screenshot)
  • Windows 11
  • Unity 6.3 (6000.3.17f1)
  • RTX 4080 with driver up to date (610.62)
  • No issue in builds

You can see the active graphics API right at the top :

image

Thanks! I can confirm that in my case the issue persists with DX11 (and GSync off).

[EDIT] I forgot to mention that I am using URP and not HDRP as op.

Did you try disabling vsync in the resolution drop-down?

*edited

I don’t see where this resolution dropdown is. Is it in Preferences? In Project Settings?

What I did is disabling GSync globally in NVIDIA Control Panel (see screenshot below)


Note that this is “G”-Sync, not “V”-Sync, because this is Nvidia’s vsync technology I guess, but correct me if I am wrong.

I also set QualitySettings.vSyncCount to 0 but I guess this is irrelevant because that affects the game and we are talking about the editor.

Disable vSync and recheck WaitForLastPresentation. Rendering won’t sync with your monitor’s refresh rate. That wait can look like a pause if you aren’t expecting it.

G-SYNC and AMD FreeSync are basically “variable refresh rate” technologies which require a compatible monitor. The idea is that it behaves like VSync on but the framerate can be variable within a range determined by the monitor, ie 30 Hz to 120 Hz or 60 Hz to 240 Hz. You don’t get any tearing even if the framerate fluctuates.

Vsync operates strictly on a fixed refresh rate set by the GPU or OS. And whenever the rendering doesn’t hit the target framerate, it drops down to the next lower level. On a 60 Hz monitor if a game only renders 55 fps with vsync off, with vsync on it would only refresh every other frame and thus the effective framerate drops sharply to 30 Hz (and then 20, 15, 12, 10 … ie two 60th, three 60th, four 60th etc).

Well, it was actually disabled :upside_down_face:
Interestingly, enabling it transfers the computation in the “Others” CPU usage category. Idk if it helps drawing any conclusion.

With vSyncCount = 1 (enabled in the UI), Unity syncs presentation to the display refresh. On a 60 Hz display that targets ~60 FPS if frames are ready. If the game renders only 55 FPS, you’d expect uneven pacing or occasional repeated frames, not a hard drop to 30 FPS.

That can happen only with vsync off or the other “modern” vsync options which disable Vsync dynamically or force it at alternating frames (“every other”).

The classic Vsync will always drop down to the next nearest integer divisable of 60 if the frame is not ready within the vertical synchronization duration.

With vsync and 60 Hz you have 1/60th or 0.0166666 seconds to render a frame. If a game consistently takes 0.017 seconds to get the frame ready to display, it will consistently have to wait for the next vsync. This causes the framerate to drop to 2/60th because the minimum wait time is now 0.0333333 seconds. There is nothing in between.

The misleading aspect is framerate displays which typically show an average of the most recent frames. So where a game consistently renders at an alternating 60-30-60-30 framerate, a framerate counter would show 45 fps which is mathematically correct but doesn’t tell the whole story.