Performance spikes due to WaitOnSwapChain (only on build)

Hi everyone,
I have been looking through what feels like hundreds of forums for an answer to my predicament but no ‘answer’ seems to work for me, so here I am, making my own specific question.

My issue arises from what the profiler identifies to be DXGI.WaitOnSwapChain, a process taking up around 99% of performance. It creates massive spikes periodically and I haven’t the faintest clue as to what might be causing it but no matter if I am not doing anything in the game, the map is disabled, the UI is disabled - even if its an empty scene - I get the same result. Its worth mentioning, I have heavily optimised my rendering in particular. When I play the game in the editor, it runs perfectly; just as beautifully smooth as I want it to be, but as soon as I build the project, while my fps counter gives me high numbers, the game has huge stutters and lurching (which I’m assuming is down to the performance spiking). I also have vsync disabled and no framerate specified but I have trialled through combinations of vsync being on and off and with different target frames; they have not been successful or ideal. If I have not specified enough information, then please let me know what I’m missing. I will attach a picture of the profiler below and any help would be greatly appreciated.


^ In editor - no issues here, everything runs just how I’d like


^ In Build - Huge spikes in GPU and CPU usage, the main culprit being WaitOnSwapChain.

Both readings above are with no Vsync and a framerate of as quick as possible (-1). This is how I’d like it to be by default but I would most likely add an option for vsync on and off in future.

Thanks in advance!!

This is explained in the documentation on Profiler Markers (the relevant part is WaitForLastPresent not WaitOnSwapChain):

<GraphicsAPIName>.WaitForLastPresent

Samples with this marker appear when the main thread waited for the GPU to flip the frame number to the screen (Time.frameCount - QualitySettings.maxQueuedFrames + 1). This means that if QualitySettings.maxQueuedFrames is greater than one, this time is spent waiting for the GPU to flip a frame that your application requested to render in a previous main thread frame.

For more details on this sample and an overview of Unity’s Frame Pipeline, see Unity’s blog post on fixing Delta Time.

i.e. your build is GPU-bound and the CPU is waiting for the GPU to finish rendering. You probably don’t see this in the editor because the editor itself is using a lot of CPU resources and the GPU ends up not being such a big bottleneck.

Ok, so have you any advice on how I might fix it? I’m fairly certain its not really an optimisation issue as like Ive mentioned: I have optimised a lot and it persists even in an empty scene. Thanks!!

I think WaitForLastPresent is a red herring. It’s not a spike in the usual sense that can cause frame drops, it just means the CPU has rendered enough frames ahead of the GPU and waits for it to catch up. It shouldn’t impact the rendering result.

You might want to try a GPU profiler to better see what’s happening there. The profiler screenshot you posted shows big “Other” spikes on the GPU. If the GPU cannot render frames fast enough, it would then cause the CPU to wait for it in WaitForLastPresent. You’d see that spike on the CPU side but the actual issue is on the GPU.

There’s also the Frame Timing Manager but I’m not sure how useful it’s data would be in this case.

Hi again Adrian,

I did check out the Frame Timing Manager but it wasn’t really making sense how to set it up. I have however, collected GPU usage through the Task Manager. Hopefully this is useful-
image
Above is what I got when running the build and it looks just fine to me but perhaps you can see something wrong.


And in editor…

Task Manager only shows you a very high-level view of the GPU, I meant an actual GPU profiler, usually offered by the graphics card vender. AMD, NVIDIA or Intel each have their own. They will show you exactly what is being executed on the graphics card and you should be able to see what the GPU is doing during those spikes.

I’ve been looking for a NVIDIA profiler but it’s not been straightforward (or maybe I’m just extremely stupid) and I can’t get any kind of profiler. If you could point me in a direction that would be wonderful. I’m sorry if this is supposed to be common knowledge!