This effect is more pronounced on Monado and variable on SteamVR.
Reproduction is simple, run any app which could be as simple as xrgears, on the Monado runtime with a headset like a valve index and the effect will immediate present as a delayed viewport almost like the contents are being double composited. A VR headset MUST be used to visualize the effect.
Make sure to enable the Monado compute compositor and select the proper steamvr_lh driver if using a Valve lighthouse type headset:
STEAMVR_LH_ENABLE=true
XRT_COMPOSITOR_COMPUTE=true
All display managers, all graphics APIs, all apps, any nvidia kernel module, any combination of kernel parameters.
It is most uncomfortable for even short term usage and is only present on Nvidia proprietary userland. Nouveau, AMD, Intel, all feel fine for simple low-load usage in comparison.
Some users have partial success in delaying the composition using U_PACING_COMP_MIN_TIME_MS to reduce the effect but it is quite far from a cure, just improves comfort modestly when set to about 10.
This bug currently runs back as far as the 550 driver as far as we can tell and is present in the latest releases.
options nvidia NVreg_RegistryDwords=RMLockingMode=1 was used in an attempt to resolve the issue alongside setting the CPU gov to performance state.
Some mild stutter under extreme loads was improved but the visual swim or drag was still present with seemingly no effect on it, the sensation like the lease is being double composited.
SteamVR appears to variably swim while monado seems to be fairly consistent in how it wobbles and the U_PACING_COMP_MIN_TIME_MS=10 env var on monado appears to move the sensation from maximally sickening to mildly sickening. Substantial improvement from there reported, when user switched to AMD.
A secondary issue worthy of mentioning is some people with VRR capable monitors enabled and working appear to experience tearing in HMD while VRR is active in kernel or in userspace. Disabling VRR at any of these stages prevents the tearing in the HMD.
After more review of member testing it likely is not a regression in Monado and more likely to be an issue in the Nvidia driver itself.
One member reports that their HMD operates with no visual drag while another reports pretty obvious drag in the view. Included are the display configuration EDID pulled from KDE. The “broken” config presenting the issue is taken after they switched to AMD to alleviate the issue but still wanted to provide their info in case it would help.
Ignore the empty valve index EDID on the working config, it does that on initial boot and a replug of the device solves, unrelated issue.
For the time being I have patched monado to use VK_PRESENT_MODE_IMMEDIATE_KHR which seems to “fix” the latency issue at the cost of having tearing in VR with the tearline staying mostly out of my view (better than getting motion sickness…)
Now the question is why there are latency problems with the other presentation modes but not immediate mode. I can think it’s either one of:
Somehow we get a swapchain that is one frame too long (would be consistent with ~11 ms delay I experience)
It’s not the swapchain something about vblank timestamps from the driver that somehow throws the pacing off significantly.
FWIW my patch is available here.
Start Monado with XRT_PRESENT_MODE=0
Hello, I did some extensive testing and comparison of NVIDIA and AMD regarding latency. I’m observing that VR headset latency on NVIDIA varies slightly between launches, but consistently introduces at least a single frame of delay beyond what should be (try running the headset at 90Hz to notice it more easily by setting the XRT_PRESENT_MODE=0 environment variable in Monado). The best way to test this is to shake your head, which will introduce a “wobble effect”, causing diziness. In the Monado Debug GUI, within the “Timing” card, there’s a “Present to display offset (ms)” slider. I’ve found that setting this to 20ms or 30ms (this value varies between launches) slightly mitigates the issue. Finally, I’ve noticed that there is a screen tearing present only when a second DisplayPort monitor is connected (even with VRR disabled), but not when using HDMI (!).
Renewed issue summary, this issue appears to be unconditional but a few things have masked general awareness of it being:
It presents as less severe the higher the refresh of the HMD, often lowering to 90Hz or below is enough to exacerbate it to see very plainly visible almost every time.
Debug and testing requires you make yourself sick with visuals for testing, few have interest in doing so.
It’s notably random in how much delay gets applied to the HMD, all users were reporting random values being helpful or sometimes none at all because a random amount of offset is needed for comfort each time the XR session is run.
Some users are simply more resistant to poor visuals and self reporting of the issue with these people included made it very hard to identify and some users having a large brick tied to their face would simply move their head less and not see it. Most simply quietly endure the issue.
However the issue remains,
Setting 90Hz on the HMD refresh and shaking your head violently left to right or in a circle should show the wobble plainly. Everything is affected and the wobble degree is randomized each session start but everything, everywhere, is affected.
It’s completely independent of the display surfaces plugged into the GPU doing other things and RMLockingMode is not of help for this.
Best we can tell this started to become an issue on driver 440. Quite a while back now… Old reports that 435 was fine for task.
And yes I believe this is important to the issue it appears as if some kind of double buffering is occurring as using immediate vulkan presentation mode which allows for tearing completely works around the problem, in exchange for the leased display tearing instead of wobbling!
After even further testing, the at runtime latency is variable!
The drag felt in the HMD routinely shifts at runtime and should change after just a few minutes of use-time. Give this a try for reproduction if you do not notice it on first glance wait a few minutes to see it.
I believe that wobble effect is a Monado bug. It’s due to missing distortion compensation for the rolling shutter effect of the Vive Pro. That issue is unrelated to the latency problem, and should be happening on AMD as well. Making sure you're not a bot!
Meanwhile I would expect it to not be present in SteamVR.
Re: screen tearing, it is to be always expected if you use my hack with XRT_PRESENT_MODE=0, since that essentially disables vsync. I only use it because I’d rather have tearing than latency.
There does exist a separate bug though with VRR which will cause tearing in the leased display even when requesting a non-tearing presentation mode such as FIFO.
Anyway this is the wrong thread for both of these bugs, this thread is about the excessive latency when using SteamVR or Monado (the latency problem presents in basically the same way in both).
Yes, this matches my experience too. This is especially noticeable in SteamVR, as opening the SteamVR dashboard tends to reset the latency for whatever reason, so you will be fine for a minute or so before the latency starts becoming really terrible again.
Using VK_PRESENT_MODE_IMMEDIATE_KHR with their mentioned patch does in fact seem to “fix” the latency issue with the cost of the tear-line as @bountyjedi said, but thought I should add more detail as far as behavior I’ve witnessed with a Valve Index, since they use a Vive Pro.
For Valve Index users:
When usingXRT_PRESENT_MODE=0 with their patch, it causes the tearline to be near the middle of the screen. Above the tear-line appears to have about no latency, but there’s still a significant amount of latency below the tear-line.
I was looking into if I can move this tear-line to a less noticeable spot by changing the refresh rate.
I launched monado-service with XRT_COMPOSITION_LOG=debug which listed the resolutions@refreshrate to the console:
DEBUG [choose_best_vk_mode_auto] Available Vk direct mode 0: [email protected]
DEBUG [choose_best_vk_mode_auto] Available Vk direct mode 1: [email protected]
DEBUG [choose_best_vk_mode_auto] Available Vk direct mode 2: [email protected]
DEBUG [choose_best_vk_mode_auto] Available Vk direct mode 3: [email protected]
DEBUG [choose_best_vk_mode_auto] Auto choosing Vk direct mode 3: [email protected]
This shows the index defaults to 144hz, which is different than the Vive Pro’s max of 120hz, resulting in a different tear-line from the mentioned user when using this patch.
I changed the refresh rate by using XRT_COMPOSITOR_DESIRED_MODE=2 which sets it to [email protected]. This moved the tear-line towards the bottom of the screen where it’s mostly out of view, which matches the mentioned user’s behavior when used with XRT_PRESENT_MODE=0.
Summary: Valve Index users should use their patch and start Monado with XRT_PRESENT_MODE=0 and XRT_COMPOSITOR_DESIRED_MODE=2
With this temporary workaround in mind for Valve Index users, this is still a major problem for NVIDIA users on Wired headsets and really hope we come to a resolution soon.
Also please ensure for wired VR testing that you use steamvr_lh monado driver. The vive and survive drivers both will not be representative of the usecase nor will they feature very well dialed in poses and could easily misrepresent issues.
Make sure you install steam with steamvr for it to work not in a flatpak and all in the default install locations so driver_lighthouse.so may be easily found by monado.
You will have easy reproduction of this problem on steamvr_lh where the stock settings should produce a perfectly comfortable pose for the user’s head. If anything is noticeably wrong at any point it’s worth digging into.
It would be helpful if someone share nvidia bug report from repro state as we did not encounter similar issue internally.
We will try to match config as close as possible and re-attempt for local repro.
Note for reproduction: It can sometimes take a while for the latency to manifest itself, as the latency seems to be floating randomly. Sometimes it can take a few minutes to get really bad. You will notice this mostly on head movements. Also noticeability varies depending on your VR application. Try one where load varies a lot. I typically test with VRChat. Meanwhile in Beat Saber the latency is not very noticeably during songs, only in the menus.
Also another note for reproduction: Some patches just hit monado master that actually fix the latency by swapping out vkAcquireNextImageKHR, which was assumed to block until frame is presented, to vkWaitForPresentKHR. So if you want to reproduce you should try commit efde64d6eec900fd2f7b2eb02dfe297abd3fd79f or earlier.
SteamVR continues to exhibit the problem, however. So you should also be able to reproduce with SteamVR. We assume it is also because SteamVR assumes that vkAcquireNextImageKHR in direct output with a two-image FIFO blocks until presentation.
I have found that on SteamVR, opening the SteamVR dash “resets” the latency, so it feels ok for a minute or so, only for it to start increasing and becoming increasingly bad.
PS. The fix to use the VK_KHR_present_wait extension instead has some issues with causing stutters (compositor frame drops) to be more likely instead. For low load XR apps locking GPU clocks using nvidia-smi helps. Also increasing the value of U_PACING_COMP_MIN_TIME_MS helps. For me, with a 90 Hz Vive Pro (frame time 11 ms), setting it to 10 gets rid of most but not all stuttering.
To give you a summary here from our group’s internal testing:
We could effectively solve the latency issues on the headset by using the newly merged code on mainline monado via the environment variable XRT_COMPOSITOR_USE_PRESENT_WAIT=1
This swaps out the implicit next image behavior monado is utilizing, for explicit behavior which is applicable to more than just mesa.
Upon doing this it was discovered that Nvidia has trouble prioritizing the reprojection, while the strange latent effect is now gone, our testers report frequent stutter by means of random GPU time blowouts as the reprojection compute shader cannot operate in time to submit for the new present. We’re not quite sure if this is just down to highly variable calls caused by some logic issue, the GPU firmware sched inappropriately throttling the GPU, or the realtime compute shader simply not being prioritized for execution time once submitted to the GPU. But however it’s occurring there is frequent and violent stutter if you use this env var combined with a reasonably graphically heavy application (near to 100% GPU util).
Current methods to stress testing the runtime on GPU driver involve VRChat worlds with raymarching shaders, geometry heavy worlds like framerate forest, or simply packed lobbies full of players which can reliably load the GPU and are perfectly representative of the usecase.
OpenComposite or XRizer must be used in order to run VRChat specifically, on Monado.
Operation is understandably up to probability given most GPUs lack real hardware preemption but AMD with compute tunneling in the driver on RDNA generation chips is able to nearly guarantee reprojection success under any amount of GPU demand, so we would urge you to investigate these areas with XRT_COMPOSITOR_USE_PRESENT_WAIT enabled on your runtime with an extremely GPU bound application.
Aleksander has sent you the details by email there and hopefully it will contain enough to narrow down the problem after the UB causing the latency was cleared away.