Setup Monado, libsurvive and OpenComposite for the Valve Index
This guide will walk you through installing the free VR stack on an Arch Linux system.
Important note: The following is a guide on how to bypass steamvr entirely. Make no mistake: this is not a SteamVR plugin, you will be entirely subverting the use of Valve’s SteamVR. In any case, it is still possible to go back to SteamVR.
It will focus on using a Valve Index HMD, lighthouses V2 and Valve Index knuckles. It will also assume you have a recent AMD GPU (Polaris and newer) running the latest stable mesa graphics stack.
This stack is composed of:
- monado - OpenXR runtime and hardware drivers
- libsurvive - Open source lighthouse tracking software
- OpenComposite - Converts OpenVR calls to OpenXR
1. Initial setup
You will need to install libsurvive-git
as well as monado-git
(both available in the AUR), in this order. It’s important to install libsurvive first since otherwise monado won’t recognize it at build time and fail to use it for 6 degree of freedom (6dof) motion tracking.
After installing these packages, it is essential to run the following:
sudo setcap CAP_SYS_NICE=eip /usr/bin/monado-service
Should you be using an AMD GPU, you will also need to set your GPU power state to VR mode for an acceptable experience:
sudo sh -c 'echo "4" > /sys/class/drm/card0/device/pp_power_profile_mode'
2. Calibration
Make sure your lighthouses are powered on and in the “On” state (as opposed to “Sleep”).
Make sure your controllers, VR knuckles and VR trackers are powered off as they may disrupt the solve.
Plug in your HMD and place it on the floor at the center of your room, making sure it has an uninterrupted line of sight with the lighthouses.
Run the following:
survive-cli --steamvr-calibration
Wait approximately 20 to 30 seconds, then terminate the command with ^C
.
Because of a bug, you will need to run the above command again, wait again around 20 to 30 seconds, then terminate the command with ^C
.
2.1 Import the SteamVR calibration into libsurvive
If you find that the calibration isn’t working well enough for you (tracking is still inconsistent, it jumps a lot), you can try the following:
If you’re coming back here after following section 5, make sure to relink your openvrpaths
file back to the SteamVR one, then back to the OpenComposite one once you’re done.
The above section 2 method attempts to import your OpenVR/SteamVR calibration into libsurvive’s config, bypassing the native lighthouse solving difficulties of libsurvive. Should you still notice tracking is poor it may actually be your OpenVR calibration at fault.
Plug in your HMD (plugging in the DisplayPort cable is optional, we are purely looking to have it attached by USB so it can track on the proprietary drivers) and run steamvr as you are best able (either on Windows or Linux).
Take your HMD while SteamVR is running and while the HMD icon is active green and gently carry it all around the room posing it in many different orientations your head would naturally assume while playing. SteamVR will produce a better quality solve that survive will naturally be able to import from this data.
If you primarily use Windows for your playspace it would be a good idea to simply import the lighthousedb.json
file directly from your Windows install drive/partition, as it will feature the strongest solve and highest runtime usage.
Delete the existing libsurvive calibration:
rm ~/.config/libsurvive/config.json
Place again your headset in the middle of the room, on the floor, in direct line of sight with the lighthouses.
Run the calibration like this twice, waiting 20-30 seconds before stopping each run:
survive-cli --steamvr-calibration ~/.steam/steam/config/lighthouse/lighthousedb.json
3. Configure the OpenXR runtime
Edit this file: ~/.config/openxr/1/active_runtime.json
, changing its contents to the following:
{
"file_format_version": "1.0.0",
"runtime": {
"library_path": "../../../../../usr/lib64/libopenxr_monado.so"
}
}
Please note that library_path
must be a relative path from the ~/.config/openxr/1/
directory to the monado libopenxr file.
If you installed monado through the AUR, or via another system wide package, then the above should be set automatically at a system level in the file /usr/share/openxr/1/openxr_monado.json
, if not please adjust it accordingly in the home folder.
4. Testing the tracking
Install xrgears
(available in the AUR), then start the monado service with the following environment variables, like so:
XRT_COMPOSITOR_SCALE_PERCENTAGE=140 XRT_COMPOSITOR_COMPUTE=1 SURVIVE_GLOBALSCENESOLVER=0 SURVIVE_TIMECODE_OFFSET_MS=-6.94 monado-service
Then, in another terminal run:
xrgears
Make sure the tracking is working correctly, and that you experience the full 6dof (you can move around the room, not just rotate your head around a fixed point in space).
If everything is working correctly, move on, otherwise repeat the steps detailed in section 2.
At this point you might want to back up your libsurvive configuration:
cp ~/.config/libsurvive/config.json ~/.config/libsurvive/config.json.bak
You may shut down monado-service
with ^C
.
5. Setting up OpenComposite
OpenComposite cannot be installed as a system package, otherwise it won’t be picked up by the Steam runtime sandbox.
Clone the OpenOVR repository. The official repository is https://gitlab.com/znixian/OpenOVR
git clone https://gitlab.com/znixian/OpenOVR.git --recurse-submodules
cd OpenOVR
mkdir build
cd build
cmake ..
make -j16
If make
fails, possibly after an update, you can try running make clean
, then make -j16
again.
Back up your openvrpaths
file:
cp ~/.config/openvr/openvrpaths.vrpath ~/.config/openvr/openvrpaths.vrpath.steamvr
Create a new file ~/.config/openvr/openvrpaths.vrpath.opencomp
, with the following content:
{
"config": [
"/home/username/.local/share/Steam/config"
],
"external_drivers": null,
"jsonid": "vrpathreg",
"log": [
"/home/username/.local/share/Steam/logs"
],
"runtime": [
"/home/username/git/OpenOVR/build/"
],
"version": 1
}
Please replace username
in the paths above with your username, or otherwise make sure /home/username/
is replaced with your own home folder.
Also make sure that the path listed under runtime
reflects the correct path of your OpenComposite build directory.
Make both files read only like this:
chmod 444 ~/.config/openvr/openvrpaths.vrpath.steamvr ~/.config/openvr/openvrpaths.vrpath.opencomp
Then link your new Open Composite file as your main openvrpaths
file, like so:
ln -sf $HOME/.config/openvr/openvrpaths.vrpath.opencomp $HOME/.config/openvr/openvrpaths.vrpath
If later on you want to switch back to SteamVR, you can do so by linking openvrpaths.vrpath.steamvr
back to openvrpaths.vrpath
.
6. Running Steam games through the free VR stack
Set the following launch options for your Steam game:
XR_RUNTIME_JSON=/run/host/usr/share/openxr/1/openxr_monado.json PRESSURE_VESSEL_FILESYSTEMS_RW=$XDG_RUNTIME_DIR/monado_comp_ipc %command%
Turn on your Index knuckles first, then start the monado service:
XRT_COMPOSITOR_SCALE_PERCENTAGE=140 XRT_COMPOSITOR_COMPUTE=1 SURVIVE_GLOBALSCENESOLVER=0 SURVIVE_TIMECODE_OFFSET_MS=-6.94 monado-service
Finally, start your game from Steam.
NOTE: If your game doesn’t start, close steam and reopen it through the command line to see more logs. If there is an error related to libcjson.so.1
you will need to build Monado with the cmake option -DXRT_HAVE_SYSTEM_CJSON=off
.
7. Setting up monado’s systemd socket
If you prefer, you can enable monado’s systemd socket so that whenever you’re running a VR application, monado-service is automatically started up, and shut down when you’re done.
To do so:
systemctl --user enable monado.socket
At this point you will need to tweak your game launch options to also include the environment variables you would normally pass to monado-service
.
Change your game launch options to the following:
XRT_COMPOSITOR_SCALE_PERCENTAGE=140 XRT_COMPOSITOR_COMPUTE=1 SURVIVE_GLOBALSCENESOLVER=0 SURVIVE_TIMECODE_OFFSET_MS=-6.94 XR_RUNTIME_JSON=/run/host/usr/share/openxr/1/openxr_monado.json PRESSURE_VESSEL_FILESYSTEMS_RW=$XDG_RUNTIME_DIR/monado_comp_ipc %command%
Additional notes
- Despite what the OpenComposite/OpenOVR readme tells you, DO NOT set the
VR_OVERRIDE
environment variable. We have not yet identified a functional configuration using this value as a replacement to theopenvrpaths.vrpath
symlink setup. - The Nvidia 530 driver is plagued by a bug which makes HMDs not appear in the display server. Please downgrade to the latest working 525 driver or feel free to beta test the latest 530+ driver should they happen to fix the issue.
- Wayland absolutely works, and works best on AMD, but only on KDE Plasma and some wlroots based compositors. Hybrid graphics such as laptops are fully supported in an open mesa configuration for VR on Wayland.
- Ensure you are launhing your Monado service and all associated games on the same GPU or the display will be garbled.
- Without the proper launch options in place, and if the particular game doesn’t work with OpenComposite, Steam Proton games will fail to launch until SteamVR is restored by switching back to the SteamVR
openvrpaths
file, as described at the bottom of section 5.- This happens because Proton has to probe OpenVR as an init test. Disabling SteamVR and failing to provide a suitable replacement (OpenComposite) will make this test fail.
- If your HMD is stuck showing only white or light gray inside the display when trying to run games, your calibration in libsurvive may be bad, you can re-run it by following section 2.
- Both the current Monado tree driver, and libsurvive do not support hotplugging. If you turn off a controller while your session is active, or if you forget to turn it on in the first place, you will need to reset your entire Monado session to get it back. Survive improvements are planned. Contributors welcome.
- OpenComposite does not yet support full body tracking. Work is being done at the time of writing.
- Preliminary work on finger curls in OpenComposite is complete. There is an active merge request if you would like to patch it in, yourself, at the time of writing.
Credits
Special thanks to @BabbleBones for helping with the setup and detailing all of the steps.
This guide was written by Gabriele Musco.