GFX.WaitForRenderThreads seems to some how take up remaining frame time

I am using Unity 2019.4.7f1 targeting Oculus Quest using Vulkan and the standard renderer with multi-view using the Oculus XR Plugin. I noticed in my frames that I am consistently getting this behavior:

There is a large Gfx.WaitForRenderThread in the middle of my frame even though the Render thread is doing no work at this point (PlayerEndOfFrame). It seems like there are two possibilities:

  1. Unity knows how long the frame should take based on previous frame and will stall the CPU until it thinks its time for rendering to start so that the rendering will complete just in time to submit the frame for presentation/warping
  2. There is a bug in the profiler that is showing this in the middle of the frame when there is actually something going on that is causing lower performance.

The issue I see is spiking behavior where it will render one or a series of frames close to the frame rate (13.77 ms) and then the next frame will be a skip causing a spike:
6198478--680092--upload_2020-8-12_22-58-30.png

However even when I have little to no graphics the WaitForRenderThread seems to take up what remaining CPU time I would have:

2 Likes

Same thing happens in 2020.1.2f1 in editor and on device. There should be plenty of headroom here on PC but the same thing happens.

2 Likes

In d3d11 player I see a similar issue, but instead of the middle of the frame, it happens at the beginning of the frame:

6198773--680126--upload_2020-8-13_1-2-0.png

2 Likes

Hey there @Katerpilet ,

I’m experiencing similar issues w/ Unity for Oculus PC. Did you ever figure out what was causing this?

Thanks!
Kai

Hi!

If I am correct, “GFX.WaitForRenderThreads” means your CPU is waiting for your GPU (or at least waiting for a long task on your Render Thread). It probably means that you are GPU bound and you should make graphics optimizations.

Edit: Some tasks, like updating your Skinned Mesh Renderers are usually done on the Render Thread, so a big number of Skinned Mesh Renderers can also be the source of the issue. Be also careful to not have lot of multiple little meshes for a character, but a single one instead.

1 Like

@NatureSimsVR , no I did not, I think it’s just a bug in the predictive frame timing code. I did find a mitigation which is to use GLES 3 with multi-pass instead of mutl-view.

@abegue_1 - The GPU finishes its work long before the stall, the issue is that the VR logic tries to present late so that it can get latest head and controller pose, but the timing is off.

After further investigation here’s what I found:

@abegue_1 was right,
Turning multi-threaded rendering off made it easier to profile the application; I think what was happening was that the GPU was missing it’s present time, but that was hidden in the middle of the frame instead of the end of the frame. Turning off multi-threaded rendering showed the stall during that frame.

In terms of other performance learnings:

  • Multi-view GLES works fine in URP but has issues in the standard pipeline
  • Vulkan was slower for me across the board
2 Likes

I’ve only just started optimising a demo build but I’ve found multi-view more stable as well. I thought multipass was meant to be the more performant one. I’m using GLES 3 and built in render pipeline as well.

Yeap this worked for me after lots of searching.