-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Game freeze when headset goes to sleep #55
Comments
After updating godot_openvr, I've noticed this also occasionally happens when entering and exiting the SteamVR "pause menu". |
Were you ever able to replicate this? This seems to be now happening after removing my eyes from the HMD for a few seconds and then returning them. I'm finally able to try updating godot/godot_openvr and will see if the problem still persists. |
Compiling
I am able to run Simula (our Godot VR compositor) and the Rendering options. Simula uses
vs. the
I changed to the demo to GLES2, etc and was unable to get freezes in it, so I don't think this is it. Initialization. Simula essentially uses (which I hope is legible as psuedo-code in case you've never used Haskell): -- | Initialize the ARVRInterface and return the success/failure
initVR :: GodotNode -> GodotARVRInterface -> IO VRInitResult
initVR node vri =
G.initialize vri >>= \case
True -> initSuccess
False -> initFailed
where
initSuccess :: IO VRInitResult
initSuccess = do
G.get_viewport node >>= (`G.set_use_arvr` True)
G.get_viewport node >>= (`G.set_hdr` False) -- Not needed with GLES2 renderer
getSingleton Godot_OS "OS" >>= (`G.set_use_vsync` False) -- Vsync must be disabled or we're limited to 60fps
getSingleton Godot_Engine "Engine" >>= (`G.set_target_fps` 90) -- Boost FPS to 90 without vsync
InitVRSuccess <$ godotPrint "Initialized VR interface."
initFailed :: IO VRInitResult
initFailed = do
InitVRFailed <$ godotPrint "Failed to initialize VR interface." while the if arvr_interface and arvr_interface.initialize():
# switch to ARVR mode
get_viewport().arvr = true
# keep linear color space, not needed with the GLES2 renderer
get_viewport().keep_3d_linear = true
# make sure vsync is disabled or we'll be limited to 60fps
OS.vsync_enabled = false
# up our physics to 90fps to get in sync with our rendering
Engine.target_fps = 90 Environment options. Simula uses
vs the
It's conceptually unclear to me why turning this on would prevent HMD freezes. Does it make sense that this could be the issue? |
The I think that having meshes in view significantly increase the chances of an HMD freeze occurring. |
I also just verified that setting |
I was able to duplicate an HMD freeze in the godot_openvr/demo when stripping the
Comparing to the full version of Main.tscn, it is not clear to me what I stripped could be preventing these HMD freezing. |
Adding the
in our main scene that launches with Simula. It's unclear to me how this stuff could be preventing HMD freezes, but I'm happy nonetheless. |
My theory on this is too that when the headset goes to sleep it won't wake up again in Godot's case (check if when you remove the headset from your eyes it starts blinking in the VR monitor and possibly saying "sleeping"). Strange though adding Milkyway would work around the problem. In that case it also could be that Godot just doesn't resume rendering in some cases, and Milkyway somehow triggers it to resume. I'll have a closer look at how the sleeping is supposed to recover. |
I'm still at a loss to explain this either, hasn't been a problem for me so far with the Index which I guess is the closest to the Vive.. . |
Ugh. It turns out the "Milkyway environment fixes everything" was a total false alarm. I just got another freeze with the Milkyway environment loaded into Simula.
@BastiaanOlij BastiaanOlij What distro/GPU are you running? Is it possible/plausible that this could be a Vive only issue?
@beniwtv When removing the headset from my eyes, the HMD turns off. When placing it back on my eyes, it turns back on. Sometimes it works as expected. Sometimes it comes back frozen. I've had a few times where I didn't even take the headset fully off; instead, I just tilted the headset up barely up over my eyes and back so I could check something on my desk, and in that fraction of a second the HMD is frozen. Overall: let me know if there's anything I can do/look into to figure out what is causing this. This is the main thing making our Linux VR compositor completely unusable right now. 😢 |
One person using Simula noticed that HMD freezes tend to happen when the Vive goes out of (and returns into) the tracker bounds. I was unable to replicate this myself, but am just flagging it as a possibility. Also, in case it matters: both of us are only using 1 tracker station. |
That gives me a few vectors to to try and reproduce it. We set the textures in ARVRInterface.cpp: If anything, I'd expect it to fail there. |
Thanks: I'm running SteamVR 1.8.20. |
Unfortunately, I have not been able to reproduce this on my Valve Index. I tried both the regular demo, and the stripped down one, letting it sleep multiple times (and multiple minutes), going out of bounds and coming back in, and using only 1 tracking station. In every case it resumed rendering in the HMD fine. It's indeed possible that this is a Vive-only issue, back when I had the Vive I remember some game freezes happening when opening the dasboard, etc... However, I just updated the Linux build with the latest godot-cpp and OpenVR libs in master, could you try to reproduce the issue with that and Godot 3.2 beta? Also, can you try to reproduce with SteamVR beta? My brother now has my Vive, so it might be some time until I can get to it :( |
On the off chance it matters: our version of Godot 3.1 messes with SIGUSR1 signals (e.g. here). Is there a chance this has something to do with our freezes? I'm trying to replicate an HMD freeze with godot 3.1 (without SIGUSR1 modifications) and so far have been unable to replicate a freeze (but I've been fooled in the past into thinking freezes are fixed when they aren't :) In the meantime: I'll see if I can locate a Valve Index somewhere, and also will test with Godot 3.2 and report back. |
SIGUSR1 stuff isn't the issue. I stripped our godot binary of the SIGUSR1 modifications, and was able to still experience an HMD freeze in Simula, so that's not the issue either. Testing the latest
New godot_openvr demo testing: so far so good. On a more positive note: testing the latest |
❌ Just tried Simula w/the Valve Index and got a freeze within 30 seconds. On the bright side: at least it's not a hardware issue (since a lot of people are still using Vives). |
Strong hypothesis as to what is causing HMD freezes: maximizing the pancake mode view. Just tried in Simula and in the godot_openvr demo and it replicated. This is something I regularly do within the first 30 seconds of opening Simula, but not as much with the godot_openvr demo (explaining why freezes are happening so much with Simula). If this turns out to be the issue I will kick myself because it's so obvious in retrospect. @beniwtv Can you try this at some point with your Linux setup to see if it replicates? |
Interesting! Will try and let you know! |
✔️ Reproduced this with godot 3.2 alpha + SteamVR beta (1.9.4) + godot openvr demo. What I think I'm noticing is that the slightest CPU stutter (or perhaps GPU stutter?) causes a frame stutter, which then seems to cause an HMD freeze. It might be that maximizing the pancake mode viewport is causing a stutter, which then causes an HMD freeze. Is there a way to put a godot_openvr demo through a stress test to see if it induces a freeze? In a nutshell: |
Running a gprof test shows that
Of note:
3.9% vs. 0.89% EDIT: ALSA isn't to blame; I tried compiling godot 3.2 w/o support for ALSA, but was still able to induce a headset freeze. EDIT2: Comments from @KaneTW in Simula chat about the discrepencies between these two gprofs:
|
Unfortunately, I still can not reproduce the issue. I tried maximizing, turning it back to normal, going out of bounds, taking off the headset in between... Nothing go it to freeze. Then I stressed my CPU to 100% using s-tui, still no freeze using the same method as above. Then even running Unigine Superposition, which caused heavy stutter in the HMD, still no freeze though, no matter how hard I try :( Can you let me know the CPU & GPU of you and the users experiencing the freezes? |
@beniwtv I'm running EDIT: ❌ Just upgraded to Nvidia 440.26 and am still getting the freeze. |
Video demonstration of the freeze: https://www.youtube.com/watch?v=7-7kZdK6Lcs&feature=youtu.be The left window is the Godot pancake viewer (which when maximizes triggers the freeze); the right window is the Valve VR headset preview mode (which demonstrates the freeze). The bottom window is SteamVR's "Advanced Frame Timing" viewer, which shows a lot of spikes after the freeze is induced. |
Are the other users noticing the freeze also using Nvidia? As this seems to be more easily reproduced in Simula, would you be able to send me a precompiled version I can just run? |
Yes.
It's never happened in SteamVR Home or Tilt Brush. Right now Tilt Brush doesn't launch on the Valve Index so I can't do a proper test. Also: I suppose I'd need a game with a viewport to maximize?
Unfortunately not: making standalone binaries isn't easy with Haskell projects :/ The video I sent you though was using the godot_openvr/demo, not Simula. |
Apitrace. @KaneTW built the latest version of apitrace and ran it against an induced headset freeze. The apitrace can be inspected via qapitrace godot_openvr_freeze.trace # qapitrace must be the latest build using this godot_openvr_freeze.trace. Frame 261. We noticed that something weird is happening in frame 261 (about when the freeze is induced): Specifically, it looks like at this point a bunch of framebuffers are being deleted and regenerated. Here is the chat conversation I had w/@KaneTW for context:
|
The framebuffer errors were just an artifact of apitrace. The real culprit seems to be whatever triggers all the glDelete*/glGen* (or some consequence thereof) |
That would make sense. If the texture ID in Godot changed for some reason, and somehow the ARVR server would be sending us the old texture ID, which we would send to OpenVR, the head set would no longer update. Unfortunately, my knowledge of he Godot renderer (or renderers in general) is very limited, so no idea why that could happen. @BastiaanOlij any ideas what might be going on? |
My suspicion: The framebuffer OpenVR appears to use as the read framebuffer is (in that api trace) 105. FB105 gets established at call 7554 at the start, and assigned texture 152. |
Continuing on that thought, the GL call pattern matches the pattern in _render_target_clear exactly. So whenever _render_target_clear is called, this bug appears. I'm tempted to call this an OpenVR bug. You can't assume the texture is the same just because the ID remains unchanged just because the texture ID is identical. Edit: This is a known issue: ValveSoftware/openvr#216 |
From what I know the texture ID always remains the same though, or I am confusing it with texture IDs in Godot. In that case, what makes Godot delete / recreate it, seemingly on Nvidia hardware only? |
The OpenGL texture name (i.e. 152 here) is deleted on a _render_target_clear call (and presumably remade afterwards). It's happenstance/implementation detail that it gets assigned the same name every time. |
I've made a shitty workaround by alternately generating/deleting a dummy texture name on each _render_target_clear. Going to test it while upstream decides what to do. |
Hmm, very strange. By default Godot will create a render buffer for the main window based on the size of the window, the ARVR server will override this creation and recreate a new texture at the resolution the HMD has asked for. Now if the window resizes Godots default logic will run again which could indeed delete our render buffer and recreate one at the new required size, which subsequently will be tossed a way and replaced again the next frame the HMD renders. This is a bit of a flip flow between Godot wanting to be a desktop rendered game and us wanting to render on the HMD. While wasteful it shouldn't lead to an unreliable texture freezing rendering. If this is indeed the problem then there is a simple work around. Instead of turning the main viewports ARVR mode on, create a custom viewport in your scene, make sure the ARVROrigin node and everything underneath is a child and turn this into your ARVR viewport. DO make sure to set this viewport up correctly, it has to have a default size (for some reason the internal logic ignores viewports with the size of 0,0) and that its update mode is set to always. You're then free to render whatever you like to the main viewport. At the very least its worth the exercise to see if it resolves the freeze. |
I did a hacky test workaround just by creating a dummy texture name at the end of each _render_target_clear call, and that fixed the issue [by making each subsequent _render_target_allocate have different texture names]. This confirmed my theory about OpenVR making incorrect assumptions). I've filed an issue with OpenVR, but your solution seems reasonably elegant and doesn't require fiddling with texture name allocations. |
Setting up ARVR in the usual way leads to HMD freezes on, e.g., pancake mode maximization. Our solution/hack involves creating an extra viewport for the ARVRCamera, and a custom Camera (`GodotPancakeCamera`) that follows the PoV of the ARVRCamera every frame. - See GodotVR/godot_openvr#55 (comment)
✔️ We took this approach w/Simula and now HMD freezes appear completely fixed. Thanks to @beniwtv @BastiaanOlij for your help & patience throughout this bug debug. ❤️ |
Ok, that gives us a valid workaround! We still need to fix the original problem but at least we have an idea of where things are going wrong. Does sound like an upstream issue. |
Issue mentioned on reddit here: https://www.reddit.com/r/godot/comments/bxxo69/rendering_freezes_in_vive_headset_in_linux_glesv2/
Need to investigate this, see if we can reproduce it
The text was updated successfully, but these errors were encountered: