CertainLach/VivePro2-Linux-Driver

Very High Latency (vsync_to_photon issue?)

Opened this issue · 15 comments

I'm experiencing high latency with my head movements (it's not particularly noticeable when I move my controllers, though it's probably still present, but it's super obvious just looking side to side or when my head shakes from movement in Beat Saber).

I did a SteamVR system report and saw something like 0.0004 vsync_to_photon latency reported, where the official driver was between 0.008 and 0.014 (approximately, I'll edit this once I can check again, but it was between 8ms and 14ms).

I think that this explains the latency, as if I use the debug menu to increment this value, the latency disappears. The problem is accuracy. I've had this debug menu method work perfectly once or twice, but other times, I just can't get it feeling right ever, and if I overshoot, things begin to feel jittery, either of which (too high latency or the jitter) makes me nauseous.

I will share the headset sections of these reports in a few hours to help with debugging.

Is this a known issue, and are there any ideas for fixes?

RX 6800, Fedora 39

There is two ways to obtain vsync_to_photon, one using valve config:
https://github.com/CertainLach/VivePro2-Linux-Driver/blob/master/crates/vive-hid/src/lib.rs#L75-L76

And one using vive config:
https://github.com/CertainLach/VivePro2-Linux-Driver/blob/master/crates/vive-hid/src/lib.rs#L144-L145

Valve config is used by SteamVR by default, as it is also present for Valve Index, and OG Vive.
For me, values in both configs are equal, thus everything works out of the box, as for your case...

Can you check, if value is different between vive config and valve config?

It might be required to explicitly pass the value from vive config, instead of letting steamvr use valve config, but it is strange to me if those values are different between those configs for you.

Also, do you use CoreCtrl for your GPU?

On windows, SteamVR automatically updates GPU profile to VR for better performance and latency, but on Linux gpu always uses default profile, which will result in poor VR performance.

For testing, you can try providing your own values, like I do provide framerate here:
#31

I haven't implemented reading this value from config on this branch, because I don't think it will work, but if values are different between configs for you - I will add this too.

There is two ways to obtain vsync_to_photon, one using valve config: https://github.com/CertainLach/VivePro2-Linux-Driver/blob/master/crates/vive-hid/src/lib.rs#L75-L76

And one using vive config: https://github.com/CertainLach/VivePro2-Linux-Driver/blob/master/crates/vive-hid/src/lib.rs#L144-L145

Valve config is used by SteamVR by default, as it is also present for Valve Index, and OG Vive. For me, values in both configs are equal, thus everything works out of the box, as for your case...

Can you check, if value is different between vive config and valve config?

It might be required to explicitly pass the value from vive config, instead of letting steamvr use valve config, but it is strange to me if those values are different between those configs for you.

Apologies, but I'm not sure how to check whether these are different. Would these be saved into files somewhere?

Also, do you use CoreCtrl for your GPU?

On windows, SteamVR automatically updates GPU profile to VR for better performance and latency, but on Linux gpu always uses default profile, which will result in poor VR performance.

Yeah, I know about this issue and the VR profile solution

For testing, you can try providing your own values, like I do provide framerate here: #31

I haven't implemented reading this value from config on this branch, because I don't think it will work, but if values are different between configs for you - I will add this too.

This doesn't seem to affect my FPS, more details mentioned in #27

As I mentioned that I'd send in the first message (I forgot earlier)

Here are the reported Vsync to Photon latencies from the official driver from a SteamVR system report in Windows
2448x1224@120hz - VSync to Photons: 0.00833333
3264x1632@90 - VSync to Photons: 0.0140811
3672x1836@90 - VSync to Photons: 0.0144311
4896x2448@90 - VSync to Photons: 0.0111111
4896x2448@120 - VSync to Photons: 0.00833333

Here is the repoted Vsync to Photon latency from this Linux driver no matter what
VSync to Photons: 0.0004

Go to crates/vive-hid/src/lib.rs

Add this to the end of file:

#[test]
fn test() -> Result<()> {
	let dev = ViveDevice::open_first()?;
	dbg!(dev.read_config()?);
	let dev = SteamDevice::open_first()?;
	dbg!(dev.read_config()?);
	Ok(())
}

Open terminal in crates/vive-hid directory
Run this test:

cargo test -- --nocapture 2> configs.txt

SteamVR uses timings from SteamDevice, but they should be equal to timings from ViveDevice (That's how it works for me)

The [crates/vive-hid/src/lib.rs:335:2] section says: seconds_from_vsync_to_photons: 0.00039999998989515007
The [crates/vive-hid/src/lib.rs:337:2] section says: seconds_from_vsync_to_photons: 0.00039999998989515007

So, they do match, but are lower than what I'd expect based on the SteamVR Reports from Windows

After all, 0.00039 seconds is 0.39ms, which seems much too low given 90hz refreshes every 11ms and 120hz every 8ms, and no LCD is going to have 0.4ms response times

Yep, that's not right. Values written on my device are much higher, and I don't observe this problem
Well, seems like they needs to be provided from somewhere else

What are your values, and is there a way to test hardcoded values that equal yours to see if this solves the issue for me, before a proper solution is found?

I have updated my PR.
I'm not sure how vive devices are being provisioned, so I think I need to also port some of the other values which vive driver adjusts by himself.

For me, seconds_from_vsync_tp_photons written in device config is 0.011111111111111112, so it just works.

In PR, I have implemented logic from the original driver,
image
(mode here = vive-hid mode id - 1)
image

So the values will be exactly as you have.

I wonder if there's something more going on here, based on how quickly the application is rendering. In the SteamVR void, these values seemed nearly correct, but as I got into Beat Saber, and much more so as I got into a level, especially at higher resolutions, latency and shakiness came back.

Maybe the value is dynamic and only the initial value is reported by the SteamVR Report?

It's an improvement, and at lower resolutions felt nearly right, but off enough that I couldn't properly play since there was some small shakiness from things still not quite being synced to my head. Another reason that this might somehow be dynamic is that this is kind of what adjusting the vsync_to_photon latency manually using debug commands lead to (sometimes being able to get it right for a short while, before becoming wrong again)

vsync_to_photon is only read on device activation, and updates are ignored later, this delay is constant.
Is everything ok with frame times? Do you have vulkanAsync enabled?
It might be caused by ValveSoftware/SteamVR-for-Linux#269

Also, please try with non-120Hz mode, as there is something fishy with it in your case.

I'm not using a 120hz resolution or mode in SteamVR, and frametimes are fine, not spiky, and VulkanAsync is disabled
image

If I enable VulkanAsync, things actually seem a bit better, but that might be placebo, there's not much of a diference.