Search Unity

[FPS Problems] XR.WaitForGPU() consuming a lot of time (20-30ms) with Oculus SDK

Discussion in 'AR/VR (XR) Discussion' started by ArcadiaBlur, Jan 24, 2018.

  1. ArcadiaBlur

    ArcadiaBlur

    Joined:
    Jun 29, 2015
    Posts:
    7
    Hello!

    I am having a blocking performance issue with the Oculus Rift SDK and Unity related to the XR.WaitForGPU() function. My application renders a mesh that consist roughly of a million vertices. When the mesh is static, the application runs smoothly at 100+ FPS as the rendering is very basic and takes less than 1.0 ms for frame.

    However, when moving it around, zooming it, the FPS drop at around 25-30 FPS. The rendering time on the GPU is still around 1.0ms (300+ FPS), but looking at the profiler a new variable appears, XR.WaitForGPU(), that takes like 30ms, reducing the FPS drastically. Find attached a screenshot of the profiler.



    Is this a known issue related to the VSync? Even disabling it somehow Oculus forces it again... The application works perfectly when VR is disabled but turning it on makes this waitForGPU internal function to reduce my FPS from 100 to 20, and it would make sense if the scene took like a similar time to render (20ms), but it takes likes 0.15ms, there isn't even that much geometry on the scene ...

    Any ideas on how could I fix this? I am using Unity 2017.3.0f and the Oculus SDK 1.19
     
  2. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    Are you profiling with Play in Editor? I believe what you are seeing is an artifact of that. Try deploying the application and running it stand alone connected to the Unity profiler.
     
  3. ArcadiaBlur

    ArcadiaBlur

    Joined:
    Jun 29, 2015
    Posts:
    7
    Hello! Thanks for answering @joejo . The huge FPS drop is also appearing when deploying the application connected to the profiler (see attached image).

    The problem seems to be this WaitForGPU, or the Finish Rendering of the device. The Rendering on the GPU is performed almost instantly and it is not so complex, so I think it is not a problem of the number of vertices / faces to compute, it does it almost instantly, so I do not know where this is coming from, because it's consuming a lot of CPU...

    Cheers!!


    PD: I checked that maybe is something related to DX12, but trying it with DX11 gives the exact same results. The connected profiler looks like:

     
    Last edited: Jan 24, 2018
  4. Aaron-Meyers

    Aaron-Meyers

    Joined:
    Dec 8, 2009
    Posts:
    305
    I'm running into this same thing today. I'm seeing huge spikes in the XR.WaitForGPU process. It seems to ebb and flow in terms of intensity, but as far as I can tell, has no correspondence with anything happening in my scene.

    I am also running the Oculus SDK.
     
  5. Aaron-Meyers

    Aaron-Meyers

    Joined:
    Dec 8, 2009
    Posts:
    305
    Its all very erratic and XR.WaitForGPU seems to eat up a lot of time when everything else in the scene is shut off too.

    I tried closing the Oculus software and letting it re-open on its own on the next Play and after a short while of running at ~60fps, it tanked and went down to 10-15fps with XR.WaitForGPU eating up ~70ms :(

    upload_2018-1-25_12-44-16.png
     
  6. callen

    callen

    Joined:
    Dec 31, 2013
    Posts:
    33
    I'm seeing the same issue. It is in a fairly basic scene (21 draw calls) and when I profile it on the GearVR device I see this XR.WaitForGPU method add about 20ms, but seems to happen every 4 or 5 frames, not every frame. The normal frame render time is ~15ms, but jumps to 35ms on these frames. Does anyone know what this value is supposed to represent? Thanks!
     
  7. sgower

    sgower

    Joined:
    Mar 9, 2015
    Posts:
    316
    I'm seeing the same issue. When I run my built VR game (for the Vive), I sometimes see lots of dropped frames, even when the game starts and only a simple menu is being displayed. But this problem is intermittent. It doesn't always happen. Some of the time, everything is just fine, but then it gets into a bad state and the performance is terrible. When I connect the profiler, I see XR.WaitForGPU is talking around 27ms. Here's a screenshot of what the problem looks like in the profiler, and you can see when the problem corrects itself. I'm not doing anything to make the correction happen. It just seems to suddenly start working properly. I don't think this is related to my code. It seems to be malfunctioning. This is in Unity 2017.3.1p1

    upload_2018-3-9_15-16-30.png
     
  8. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    XR.WaitForGPU is a sync point where we wait for the GPU Command Buffer to flush before we go to render the next frame. If you are seeing this then most likely something is causing the GPU to take longer than 1 frame bounds to complete writing/rendering. For mobile devices that would usually imply thermal thottling. For desktop you might want to look at the GPU when this happens (Render doc or maybe Frame Debugger) and see if you can determine what might be happening.

    If you are on Desktop and not mobile, you should be able to add the GPU profiler to the profiler window and get some GPU data out of that.
     
    callen likes this.
  9. Percy-Pea

    Percy-Pea

    Joined:
    Aug 31, 2014
    Posts:
    75
    I also see this in 2017.3.1p2. But in 2017.1 it's fine. We get huge XR.WaitForGPU spikes when using Graphics.DrawMeshInstanced. We use DrawMeshInstance for the krill ball in this project (very briefly shown in the video with the squid around this point
    ). When the krill ball first comes in we rapidly increase the number of instances over a few seconds, and there seems to be spikes regularly over this increase. Have just done a test where the number of instances are set to the maximum just once, and the spike is only on that initiating, so it seems change the instance number causes the spikes.

    This is our line of code :-
    Graphics.DrawMeshInstanced(_mesh, 0, _material, _matrices, _numSpawn,_props, UnityEngine.Rendering.ShadowCastingMode.Off, false);

    If we increase _numSpawn over time, we get the spike regularly (multiple times a second) over that increase. If we just make it a constant, the spike is only the first time that function is called, subsequent rendering is fine.

    As mentioned, in 2017.1 there is no performance issue/spike, so seems to be something to do with the new XR settings possibly (or how 2017.3 handles drawmeshinstanced).
     
  10. Percy-Pea

    Percy-Pea

    Joined:
    Aug 31, 2014
    Posts:
    75
    Ah ha! found our problem, the key text was here on this page :-
    "From Unity 2017.3, you need to warm up shaders to use instancing on OpenGL if you want absolutely smooth rendering when the shader renders for the first time. If you warm up shaders for instancing on a platform that doesn’t require shader warm up, nothing will happen."

    Warming up the shader we used fixed our issue, hopefully it may help others here.