Adding OpenVR/Vive support to my project. (1.10 DX11)

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Adding OpenVR/Vive support to my project. (1.10 DX11)

Post by mkultra333 »

2nd Oct 2016 Edit: Since this is a long thread with a lot of failed experiments, you might want to jump directly to the tips that actually worked. See this post,
http://www.ogre3d.org/forums/viewtopic. ... 25#p530114
_____________________________________________________________________________________________________________



Got my Vive yesterday. After initial trouble setting it up (caused by my antivirus and an infrared transmitter for a different device, nothing wrong with the Vive) I've got it all running smoothly and I'm quite impressed. So now the idea is to add OpenVR to my game.

I'll make various notes on how it goes. I'm hardly a coding prodigy, so no doubt there'll be some difficulty, to be expected. So far I'm just downloading the OpenVR code.
Last edited by mkultra333 on Sun Oct 02, 2016 6:29 am, edited 2 times in total.
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
cherrychalk
Gnoblar
Posts: 6
Joined: Wed May 11, 2016 5:15 pm
x 1

Re: Adding OpenVR/Vive support to my project.

Post by cherrychalk »

I have OpenVR hacked in -- OpenGL only at the moment. Basically it's a mashup of Kojack's Oculus SDK example (http://www.ogre3d.org/forums/viewtopic. ... 00#p525592) and one of the examples that came with OpenVR.

So, yeah, it's a hack.

If I can clean it up a bit tonight I'll post what I have so far.
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: Adding OpenVR/Vive support to my project.

Post by mkultra333 »

Cool, that'd be great. I'm using DX11, Ogre 1.10.

Which example in OpenVR did you use?
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
cherrychalk
Gnoblar
Posts: 6
Joined: Wed May 11, 2016 5:15 pm
x 1

Re: Adding OpenVR/Vive support to my project.

Post by cherrychalk »

hellovr_opengl

...but nothing from there that's really OpenGL specific. It just lays out how to initialize OpenVR and collect all the tracked device data.

Interestingly, that example sets up a shader to deal with lens distortion - but as far as I can tell that's not needed with my DK2 -- maybe since it's still going through the Oculus drivers? I'm not sure. I'm curious if that's only needed for Vive.
cherrychalk
Gnoblar
Posts: 6
Joined: Wed May 11, 2016 5:15 pm
x 1

Re: Adding OpenVR/Vive support to my project.

Post by cherrychalk »

I tossed it up on github:
https://github.com/jkac/ogre-openvr

Both OpenGL and DirectX are working now. It's basically just plugging OpenVR into Kojack's Oculus example and it works the same way - just call OgreOpenVR::initOpenVR after initializing your render window and scene manager, and then instead of renderOneFrame call OgreOpenVR::update
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: Adding OpenVR/Vive support to my project.

Post by mkultra333 »

Thanks a lot for that. I'll do some tests and see if I can get a scene working.

Could you add some license info to that? MIT or compatible? I never use code if I don't know the license.

[Edit: I guess it depends on what the license in the OpenVR sample is. Just had a look, seems to be the 3-clause BSD license, which is good, compatible with MIT.]
Copyright (c) 2015, Valve Corporation
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: Adding OpenVR/Vive support to my project.

Post by mkultra333 »

Ok, first bone-headed stumbling block. Wasted all day on this, http://www.ogre3d.org/forums/viewtopic.php?f=2&t=85883
Goddam unresolved externals...
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
cherrychalk
Gnoblar
Posts: 6
Joined: Wed May 11, 2016 5:15 pm
x 1

Re: Adding OpenVR/Vive support to my project.

Post by cherrychalk »

mkultra333 wrote:Thanks a lot for that. I'll do some tests and see if I can get a scene working.

Could you add some license info to that? MIT or compatible? I never use code if I don't know the license.

[Edit: I guess it depends on what the license in the OpenVR sample is. Just had a look, seems to be the 3-clause BSD license, which is good, compatible with MIT.]
My contribution to it is MIT. I don't know if anything left is directly from OpenVR's samples, but it's certainly based on theirs so there should be some mention of that. I'll see if I can add some info into my repos tonight.

Kojack hinted that OpenVR/OculusSDK might be combined at some point since they're quite similar; so what I did was sort of proof-of-concept more than anything. I would like to continue working on it, but if it's getting wrapped in with Kojack's then that might not be necessary.
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: Adding OpenVR/Vive support to my project.

Post by mkultra333 »

Thanks cherrychalk, I'll add you to the license in my project as MIT.

Got a sample running just this morning. Uses a lot of your code, but since I'm in 1.10 a lot is different too. No compositors, and I use 2 textures for rendering instead of 1. The code is a bit of a Frankenstein's monster as far as style goes, naming conventions are all over the place since half is based on my starter framework.

I'm going to try and add some controller support today, and then I'll post a complete project later.
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: Adding OpenVR/Vive support to my project.

Post by mkultra333 »

Meh, I'll work on controllers later today. For now, here's the project, includes a exe ready to go. Just puts you inside a colourful cube. You might get a moment of black screen when you start while it sets up the VR, if it hasn't been running recently.

https://drive.google.com/file/d/0BwGgmM ... sp=sharing

If you're compiling the project (for ogre 1.10) you'll have to change the project settings to suit your own folder locations for the Ogre 1.10 SDK. Most the tricky VR stuff is just taken more or less directly from cherrychalk's work. I'm pretty happy with how relatively painless this has all been so far. Most the time I wasted on a stupid unresolved external issue for some stuff I didn't end up using anyway. The code itself is not particularly neat or consistent, and has a bit of unnecessary junk here or there, due to my programming, but it's all pretty short and concise anyway so it's pretty easy to find your way around.

cherrychalk, I've included you in the license as "cherrychalk" and used the same 3-clause BSD as Valve. If you'd like me to change that, let me know.

Edit: Oops, just saw you wanted MIT instead of BSD. I'll fix that.
Edit: Fixed.
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: Adding OpenVR/Vive support to my project. (1.10 DX11)

Post by mkultra333 »

Interestingly, that example sets up a shader to deal with lens distortion - but as far as I can tell that's not needed with my DK2 -- maybe since it's still going through the Oculus drivers? I'm not sure. I'm curious if that's only needed for Vive.
It's weird, I see that code, I'm not using it, yet it really doesn't look like the Vive needs it. At least, I can't see any distortion in the image, and my scene has all straight lines and squares on the walls so any distortion should be obvious. Can't see any chromatic aberration either, at least nothing serious.

I think they might do the distortion automatically.
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: Adding OpenVR/Vive support to my project. (1.10 DX11)

Post by mkultra333 »

Did a test today adding the distortion, just to check. It messes things up. It seems that the distortion is done automatically, so doing it again is double distortion.
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: Adding OpenVR/Vive support to my project. (1.10 DX11)

Post by mkultra333 »

Ok, figure that's enough just for testing. I've put it on bitbucket, https://bitbucket.org/mkultra333/openvrtest

It demonstrates the following.
Setup OpenVR.
Tracking for the HMD and two hand controllers.
Input from the two hand controllers.
Create a model and associated texture of the two hand controllers using OpenVR.
Get and display the chaperone/play area.

It takes place in a coloured cube, you can use the controller to move around in the cube. There are also four information panels that display input from one of the controllers.
Screenshot here: http://www.ogre3d.org/forums/viewtopic. ... 19#p526219
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: Adding OpenVR/Vive support to my project. (1.10 DX11)

Post by mkultra333 »

Did my first test of adding OpenVR to my actual project today.

It isn't great. The problem is the central function of OpenVR, vr::VRCompositor()->WaitGetPoses. This is the function that renders the two images you've given it to the HMD and also updates the positions of the HMD and controllers. It should be super fast, it's just passing some textures from one place to another.

Instead it is stalling and working at a crawl. I've got it so that my engine and rendering two view takes about 7-8ms. That should be plenty fast. But WaitGetPoses suddenly bogs things down, and takes up to 25ms if I pass it full sized images. Even cutting the image sizes down to a grotty looking half resolution still takes 5ms. Not only that, but it's weirdly sensitive to my other shaders. My SSAO shader, which executes fine normally, causes WaitGetPoses to take even longer, adding another 5-10ms.

It's horrible.
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: Adding OpenVR/Vive support to my project. (1.10 DX11)

Post by mkultra333 »

Been doing timings and experiments. Everything I'm about to say could be totally wrong.

I've read that WaitGetPoses will basically stall until the next HMD vertical sync. The HMD vertical sync runs at 90Hz, so that's 11.1ms. If you miss that, it'll hold until the next vsync, so basically add an extra 11.1ms to the frame time.

However WaitGetPoses takes it's own time off that. I've read there's roughly 3 ms "warm up" and then there seems to be extra time on top of that. It looks to me like how much depends on how much other work the GPU was doing in the lead up. At best the total time for WaitGetPoses is about 4.5 ms, but easily goes to 6 ms or more.

So if my own pre-WaitGetPoses frame time is over about 5 ms, I'm in trouble, because minus the 5-to-6-ish milliseconds WaitGetPoses takes, 11.1 ms per frame drops down to 5-6 ms per frame. I thought I was doing good getting my engine plus stereo rendering down to 7-8 ms, but it seems that isn't good enough.

However, in the thick of play, only getting 45 fps instead of 90 fps doesn't look or feel too bad. What does look bad is spikes and big stalls. They happen a bit too frequently, but I might be able to smooth them over as I work on cutting down my own frame render time even more.

I guess I was naive, I kinda thought the actual passing of the frames and getting the HMD/controller position updates would be almost instantaneous, 1 or 2 ms at most, but it's actually a lot more than that.
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
xrgo
OGRE Expert User
OGRE Expert User
Posts: 1148
Joined: Sat Jul 06, 2013 10:59 pm
Location: Chile
x 168

Re: Adding OpenVR/Vive support to my project. (1.10 DX11)

Post by xrgo »

that is really discouraging =(
btw the bitbucket link says I don't have access :P
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: Adding OpenVR/Vive support to my project. (1.10 DX11)

Post by mkultra333 »

Bitbucket might work now. I'm not that familiar with it, I had the repository set to private.

I'm very much in the experimental stage with the Vive and OpenVR, so I might be doing something wrong. If not, I think I can probably get my frames down to 5-6 ms with a bit of work. But it isn't ideal, would have been great to have 9-10 ms to play with.
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
xrgo
OGRE Expert User
OGRE Expert User
Posts: 1148
Joined: Sat Jul 06, 2013 10:59 pm
Location: Chile
x 168

Re: Adding OpenVR/Vive support to my project. (1.10 DX11)

Post by xrgo »

We will join your adventure soon, we already have the vive, but first we have to port our engine to Windows. So thank you very much for sharing your work. =)
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: Adding OpenVR/Vive support to my project. (1.10 DX11)

Post by mkultra333 »

No problemo! It was Kojack and cherrychalk who did the tricky stuff anyway. :)

I'm thinking I might give up on 90Hz and go for 45Hz, it still looks and feels good and I don't have to gut my graphics, since my game is not just aimed at VR. But if I was starting a new project, I'd aim for 90 Hz and go for simpler graphics.

More experiments, and I'm seeing that keeping synchronized with the HMD seems to be key. At it's best, WaitGetPoses seems to take 4.7ms, I saw the occasional flash of 4.5 or 4.6 but they were extremely transient. Running my game at 45 Hz I see the time WaitGetPoses takes gradually drift up to 11 ms until a HMD vsync frame is missed and it suddenly snaps back to 4.7ms. This is obviously as my game frames gradually go out of sync with the Vive. So I'm thinking if I can keep sync, I can keep WaitGetPoses at around 4.7 ms and have 6.4 ms all to myself (or 17.5 ms at 45 fps!). Adjusting my framerate very carefully, to 44.766, I maintained 4.7 ms for quite a while before synchronization slowly drifted off. I figure I can adjust dynamically assuming I leave a little slack.

Framerates inbetween 45 and 90 look horrible, because of the bad synchronization. There's a visual jerk at a constant low frequency as the vive and game go in and out of sync with each other.

Edit: On the developer forums I was told I should have an 11.1ms budget minus 0.5ms or so, but that "gpu bubbles" can subtract from that. Hmm...
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: Adding OpenVR/Vive support to my project. (1.10 DX11)

Post by mkultra333 »

Doing more timing experiments, on a loop that just renders some text to the hmd. So my part of the rendering takes less than a millisecond. Again, keep in mind that everything I say might be wrong.

Basically it's all about synchronization with the HMD, your game has to march to the step of the HMD and not vice versa. You have to call WaitGetPoses about 3 ms before it has its next vsync. (On the developer forum the 3 ms was referred to as "offset" or "warmup".) WaitGetPoses will return the moment it is finished its vsync, so if the HMD vsync is every 11.1 ms, you need to call WaitGetPoses again in 8.1 ms. (8.1 ms to do your game engine and rendering, 3 ms for WaitGetPoses.)

Actually WaitGetPoses seems to be a bit faster than that. Provided I was synchronized, I found hitting WaitGetPoses 2.5ms before HMD vsync was fine. But hitting it 1 ms or 2 ms before vsync was too late, and it rolls over an entire HMD frame, so you just waste an additional 11.1 ms on top of everything else.

You can't do anything on the GPU at the same time WaitGetPoses is running, you'll get a crash, but you can run other threads. So it's fine to have the game engine running on another thread as WaitGetPoses runs. But basically your GPU work has to fit into 8.1 ms, and you have to hit WaitGetPoses no later than 3 ms before its vsync. If you do that, in theory, you can get a full 90 fps.

However, that's with a graphics card under minimal load. I'm still seeing how this will work out when the GPU is doing some real work before GetWaitPoses, I've had some weird results there in the past. I'm flushing the GPU buffer (via occlusion queries) after finishing my stereo frames so I don't think it's a GPU command buffer issue. Now that I understand the basic timing mechanism better I might get better results.

On a side note, the frequency of my Vive's HMD update varies a little from frame to frame. We are talking fractions of a millisecond. Working out an average based on 3 runs of 10,000 frames, and excluding outliers in the bottom quarter and top quarter of timings, the averages on a full frame limited only by GetWaitPoses were 11.170255 ms, 11.169934 ms and 11.169742 ms. So on average it runs a tiny fraction slower than 90 Hz, about 89.53 Hz.
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: Adding OpenVR/Vive support to my project. (1.10 DX11)

Post by mkultra333 »

Ugh, trying to get the drawing synchronized to the HMD in practice is a nightmare. I'm not having much luck. WaitGetPoses doesn't really return right at the end of a vsync, so it isn't much use for that.

The best thing so far is to call vr::VRCompositor()->GetFrameTimeRemaining() and draw 3 ms before that time is up. But it seems to overestimate, especially if your frame is fast. That means that even if I've drawn my stuff in under 8.1 ms, it'll make me take two HMD vsyncs to draw it, meaning I only get 45 fps. But for longer frames it seems ok, and at least it doesn't lead to oscillations where the HMD jumps back and forth between taking one and two vsyncs, which looks really bad.

You can always just run without any synchronization at all as well, that works if your frames are very fast. But if your frame sits on the border between about 6 and 9 ms, you can get horrible oscillations like I mentioned above.

Sick of working on this, so for now I'm using GetFrameTimeRemaining. It's ok if your framerates aren't super fast.
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
User avatar
Kojack
OGRE Moderator
OGRE Moderator
Posts: 7157
Joined: Sun Jan 25, 2004 7:35 am
Location: Brisbane, Australia
x 534

Re: Adding OpenVR/Vive support to my project. (1.10 DX11)

Post by Kojack »

mkultra333 wrote:Sick of working on this, so for now I'm using GetFrameTimeRemaining.
I don't blame you, that sounds painful.
User avatar
Zonder
Ogre Magi
Posts: 1168
Joined: Mon Aug 04, 2008 7:51 pm
Location: Manchester - England
x 73

Re: Adding OpenVR/Vive support to my project. (1.10 DX11)

Post by Zonder »

Kojack wrote:
mkultra333 wrote:Sick of working on this, so for now I'm using GetFrameTimeRemaining.
I don't blame you, that sounds painful.
I have to agree. Maybe hack it so your thread is delayed a few ms for fast threads.
There are 10 types of people in the world: Those who understand binary, and those who don't...
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: Adding OpenVR/Vive support to my project. (1.10 DX11)

Post by mkultra333 »

Yes. Painful and complicated and confusing. I'm pretty sure all this pain can be avoided if you render fast enough. Then you don't need to worry about synchronization at all.

A big part of the problem is that I'm trying to add VR to my pre-existing engine, instead of starting from scratch with VR in mind. My game was made to run at 60Hz and render a single frame. In that state, I had all the time in the world, 16.666 ms per image. Now suddenly the ideal state is to run at 90Hz and render two frames for stereo vision, plus a 3 ms overhead from the HMD, meaning I only have 4.05ms per image. Basically the workload suddenly quadrupled, and added a nasty synchronization requirement on top of that.

(In theory the HMD update doesn't really take 3ms, I just have to hit it 3ms before it updates... or something. In practice, it seems to take at least 3 ms.)

As far as threading goes, I can do a little bit with the HMD update, but the requirement is that nothing can access the GPU for the time that HMD update is running. My engine is partially broken into a thread for Physics and a thread for the GameLogic+GPU. That means I can thread the HMD update so that it runs over the top of the Physics and GameLogic, but not the GPU.

On top of that, there seems to be special situations where the HMD will add an extra vsync frame. For instance, if I try to update after the 3ms warmup but before the actual vsync, I'll miss this frame but get the next one. But if I miss the 3ms warmup AND just miss the actual vsync too, it won't put me on the next frame but instead the one after that, leaving a huge dead spot almost two frames long in the HMD frame rate where nothing is happening. I'm trying some experiments at the moment with a "placeholder" render that renders an old stereo frame halfway through my own update, just so I don't pay any extra penalty for just missing the next frame.

I have also had more success using a function called GetTimeSinceLastVsync. Using that and some simple timing code, I can maintain a good, consistent 45 fps with no oscillations provided my total render time is less than 11.111ms, a HMD vsync period. This is that situation where I miss the 3ms warmup but don't stray over the next vsync as well. But that's pretty wastefull, basically half the time is spent doing nothing. But worst case scenario, this is simple to implement, fairly reliable, and I can probably work with it.

It's also possible I'm being overly neurotic about hitting the synchronization at either 90 or 45 Hz. But I think it looks horrible if you miss them, the experience is jerky and rough.
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: Adding OpenVR/Vive support to my project. (1.10 DX11)

Post by mkultra333 »

There is a timing structure called Compositor_FrameTiming you can access just after a call to WaitGetPoses that has heaps of timing data. Of particular use are:
m_flSystemTimeInSeconds, which gives the time of the last HMD vertical sync according to the HMD's own internal clock.
m_flCompositorIdleCpuMs, which tells you how long the compositor was sitting around doing nothing after you called WaitGetPoses. This tells you how much you came in too early and wasted time you could be rendering more.

According to m_flCompositorIdleCpuMs, I'm hitting the sync right on the nose, something like 0.01ms wasted. So that isn't my problem.

m_flSystemTimeInSeconds is interesting though, if I keep track of of this and compare it to itself from the previous frame, I get a measure of the time between my vsync updates. In theory, GetTimeSinceLastVsync() does exactly the same thing, except it gives it to me relative to when I call it, and I can subtract that from my system time to get the time of the last vsync according to my computer.

So, two numbers. Both represent the time between the vsyncs that I hit with a frame to render. They should be virtually identical, the difference between them should be approximately zero. However that isn't what I'm finding.
LVST: LastVerticalSyncTime according to GetTimeSinceLastVsync(), converted to milliseconds.
STIS: SystemTimeInSeconds, according to the Compositor_FrameTiming structure. Converted to milliseconds.
LVST-Old: The time between this vsync and the last vsync, according to GetTimeSinceLastVSync(). This refers to the vysnc that I hit.
STIS-Old: Same thing, only according Compositor_FrameTiming.
Diff: The difference in the time between vsyncs that I hit, according to the two different ways of working it out. It should be almost zero.

Code: Select all

LVST 27397.88  STIS 27190.01  LVST-Old 33.51  STIS-Old 33.51  Diff 0.00
LVST 27431.40  STIS 27223.52  LVST-Old 33.52  STIS-Old 33.51  Diff 0.01
LVST 27464.90  STIS 27257.03  LVST-Old 33.51  STIS-Old 33.51  Diff -0.00
LVST 27498.41  STIS 27290.54  LVST-Old 33.50  STIS-Old 33.51  Diff -0.01
LVST 27531.92  STIS 27324.05  LVST-Old 33.52  STIS-Old 33.51  Diff 0.01
LVST 27565.43  STIS 27357.55  LVST-Old 33.51  STIS-Old 33.51  Diff 0.00
LVST 27598.94  STIS 27391.06  LVST-Old 33.51  STIS-Old 33.51  Diff 0.00
LVST 27621.28  STIS 27424.51  LVST-Old 22.34  STIS-Old 33.45  Diff -11.11
LVST 27654.76  STIS 27446.91  LVST-Old 33.48  STIS-Old 22.40  Diff 11.08
LVST 27688.30  STIS 27480.43  LVST-Old 33.54  STIS-Old 33.52  Diff 0.03
LVST 27710.63  STIS 27513.87  LVST-Old 22.33  STIS-Old 33.44  Diff -11.11
LVST 27744.14  STIS 27536.27  LVST-Old 33.51  STIS-Old 22.40  Diff 11.11
LVST 27777.65  STIS 27569.78  LVST-Old 33.51  STIS-Old 33.51  Diff 0.00
LVST 27811.16  STIS 27603.29  LVST-Old 33.51  STIS-Old 33.51  Diff 0.00
LVST 27844.67  STIS 27636.79  LVST-Old 33.51  STIS-Old 33.51  Diff 0.00
LVST 27867.01  STIS 27670.24  LVST-Old 22.34  STIS-Old 33.45  Diff -11.11
LVST 27900.52  STIS 27692.64  LVST-Old 33.51  STIS-Old 22.40  Diff 11.11

There are frequent judders and oscillations where the two different methods disagree, either ahead or behind by a full vsync frame.

Another way to look at it is simply the difference between GetTimeSinceLastVsync() and m_flSystemTimeInSeconds. Because one is by the HMD's internal clock and the other I calculate according to my own CPU's time, this should be a near constant value that represents the offset between the two clocks.

Code: Select all

LVST 37466.75  STIS 37294.90  LVST-STIS 171.84
LVST 37489.01  STIS 37317.24  LVST-STIS 171.77
LVST 37511.41  STIS 37339.57  LVST-STIS 171.85
LVST 37533.76  STIS 37361.92  LVST-STIS 171.84
LVST 37556.10  STIS 37384.25  LVST-STIS 171.85
LVST 37578.43  STIS 37406.59  LVST-STIS 171.85
LVST 37611.95  STIS 37428.98  LVST-STIS 182.96
LVST 37634.29  STIS 37462.44  LVST-STIS 171.85
LVST 37667.80  STIS 37484.84  LVST-STIS 182.96
LVST 37701.30  STIS 37518.34  LVST-STIS 182.96
LVST 37723.64  STIS 37551.80  LVST-STIS 171.84
LVST 37757.15  STIS 37574.20  LVST-STIS 182.96
LVST 37779.48  STIS 37607.64  LVST-STIS 171.85
LVST 37813.00  STIS 37630.04  LVST-STIS 182.96
LVST 37835.33  STIS 37663.49  LVST-STIS 171.84
LVST 37868.84  STIS 37685.88  LVST-STIS 182.96
TimeSinceLastVSync is frequently adding on an extra 11.1ms, but in a random way. No wonder synchronization is so torturous.
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
Post Reply