VR Performance Improvement progress

I had originally asked a question, but I figured that since I found what the issue was, it would be better to make a separate topic to document my current progress.

I was having an issue while trying to develop a VR game in Unreal Engine 5.2.

Even using the starter sample project or an empty world, the World Tick Time seemed to be bottlenecked even when nothing had been added or changed in the level yet. It ended up making the cpu frame time go over 11.1ms so it wasn’t hitting my target 90hz.

I tried to profile it, but was getting stuck at World Tick Time > Self (see image).

I eventually went far enough to find what was happening.

The problem with World Tick Time I found is that the frame time gets unsynched when Garbage Collection runs.

Afterward, every xrWaitFrame waits an unnecessary amount of time, of which it can increase further on more garbage collections or other thread stalls.

I found that if I measure the time xrWaitFrame takes and it is over a threshold (I set mine to 1ms), and I make it immediately return on the next pass, it fixes the issue. Though obviously not fully ideal since every time GC is run you will get a 1 frame skip. If you have GC running once per minute, you’ll notice the skip every minute. I combined this with extending the “Time Between Purging Pending Kill Objects” setting to 10 minutes and now don’t really have any issues. Just that once every 10 minutes you may or may not notice a frame skip. Would be better if instead of skipping it was able to sync the timings up another way, but still need to figure that out.

Runs great now though…

I made my changes in the FOpenXRHMD::OnBeginSimulation_GameThread() function in OpenXRHMD.cpp.

5 Likes

Thanks for tracking this down. Since you posted this more than a year ago I thought that the problem might have been fixed in newer versions of the open xr plugin but Im seeing a fixed 13 milliseconds on the game thread with only a few things running in game in the latest unreal 5.4 release.
However, because Im using a metaquest headset I thought I would try the metaquestXR plugin for 5.4. This plugin doesn’t seem to have the problem, and the game thread immediately dropped to 8 milliseconds no longer bottlenecking the frame.

Im sure that Im going to go over 13 milliseconds at some point but at least thats no longer the baseline. Im wondering if Epic can do anything about the openxr version of the plugin?

1 Like

The 8 millisecond gamethread was running the VR preview btw. It dropped to 3.5 milliseconds in a development build!

1 Like

Does this require modifying and building from Source or is there any simple way to test this with the Launcher version?

Update:
I was able to try this out on the Launcher Version by following this video: https://www.youtube.com/watch?v=2di0GzD6ViM

Update 2:
While I initially thought this was a magical solution that seemed to drastically improve the framerate being reported in Unreal, the load on my GPU (3080) from any packaged Unreal VR project (including a brand new VR template) would sit at almost 100% causing very high temps (throttling), loud fans and pretty terrible overall performance across my whole PC.
If I revert the OpenXR changes and package the same project, the GPU utilization is generally under half of what it was with the customizations.

That sounds like it would be the expected behavior when running that on an already correctly working system. Removing half the frame sync calls when the GPU utilization is above 50% would make it max out (and per the spec the OpenXR runtime would drop every other frame you submit since they haven’t been waited for).

If you are seeing xrWaitFrame waiting longer after missing frame targets, it’s most likely an intentional feature of the runtime throttling the application back in order to better do ASW/motion smoothing. If or when it throttles is entirely up to the individual HMD vendors runtimes.

1 Like