Jump to content

VR

From NixOS Wiki
Revision as of 14:41, 10 October 2025 by Ardenet (talk | contribs) (Created page with "这绕过了 bubblewrap 中预设的安全机制,并允许所有其他由 steam 启动或通过 steam-run 运行的软件也获得这些能力。")

Monado

Monado 是一個開源的 OpenXR 運行時。它使用內置驅動程序支持各種硬件,使其可以運行任何 OpenXR 程序,並且在 OpenComposite 的幫助下,還可以運行大多數 OpenVR 應用程式。

可以使用其 NixOS 選項 services.monado.enable 配置 Monado:

❄︎ /etc/nixos/configuration.nix
services.monado = {
  enable = true;
  defaultRuntime = true; # Register as default OpenXR runtime
};

為了配置 Monado,您可能需要添加其他環境變量:

❄︎ /etc/nixos/configuration.nix
systemd.user.services.monado.environment = {
  STEAMVR_LH_ENABLE = "1";
  XRT_COMPOSITOR_COMPUTE = "1";
};

配置完成後,Monado 可以在 systemd 用戶會話中啟動和停止。

例如,以下命令將啟動 Monado,然後打印其日誌輸出:

$ systemctl --user start monado.service
$ journalctl --user --follow --unit monado.service

手部追蹤

您可能會注意到,由於缺少手部追蹤數據,運行 monado-services 會失敗。有兩種方法可以解決這個問題:完全禁用手部追蹤,或下載手部追蹤數據。

要禁用手部追蹤,請修改環境變量以包含 WMR_HANDTRACKING = "0";,使其如下所示。

❄︎ /etc/nixos/configuration.nix
systemd.user.services.monado.environment = {
  STEAMVR_LH_ENABLE = "1";
  XRT_COMPOSITOR_COMPUTE = "1";
  WMR_HANDTRACKING = "0";
};

要使手部追蹤功能正常工作,您需要啟用 git-lfs。啟用 git-lfs 的標準方法是通過以下配置

❄︎ /etc/nixos/configuration.nix
programs.git = {
  enable = true;
  lfs.enable = true;
};

確保 git-lfs 功能啟用後,運行以下命令並重新啟動 monado-service

$ mkdir -p ~/.local/share/monado
$ cd ~/.local/share/monado
$ git clone https://gitlab.freedesktop.org/monado/utilities/hand-tracking-models

有關可用環境變量和調整的更多信息,請參閱 Linux VR Adventures wikiMonado 文檔關於環境變量的部分

OpenComposite

OpenComposite 是一個兼容層,用於在 Monado 等 OpenXR 運行時上運行 OpenVR 應用程式。它與 DXVK 或 vkd3d 等工具類似,但用於將 OpenVR 調用轉換為 OpenXR。

為了在 SteamVR 以外的任何平台上運行 OpenVR 遊戲,您需要配置 ~/.config/openvr/openvrpaths.vrpath 中定義的 OpenVR 運行時路徑。一個可靠的方法是使用 Home Manager 創建此文件。

⚠︎
Warning: 舊版本的 Proton 將始終查詢當前的 OpenVR 和 OpenXR 運行時。如果您使用 OpenComposite,並且它無法初始化 OpenXR 環境,Proton 將無法啟動。解決方法是刪除 ~/.config/openvr/openvrpaths.vrpath 文件,然後重試啟動遊戲。

如果此文件未設置為只讀,SteamVR 將添加其運行時路徑,因此可以使用 Home Manager。

啟用 OpenComposite 的示例配置可能如下所示:

❄︎ ~/.config/home-manager/home.nix
# For Monado:
xdg.configFile."openxr/1/active_runtime.json".source = "${pkgs.monado}/share/openxr/1/openxr_monado.json";

# For WiVRn v0.22 and below:
xdg.configFile."openxr/1/active_runtime.json".source = "${pkgs.wivrn}/share/openxr/1/openxr_wivrn.json";

xdg.configFile."openvr/openvrpaths.vrpath".text = ''
  {
    "config" :
    [
      "${config.xdg.dataHome}/Steam/config"
    ],
    "external_drivers" : null,
    "jsonid" : "vrpathreg",
    "log" :
    [
      "${config.xdg.dataHome}/Steam/logs"
    ],
    "runtime" :
    [
      "${pkgs.opencomposite}/lib/opencomposite"
    ],
    "version" : 1
  }
'';

如果您計劃在 Steam 上玩任何 OpenVR 遊戲或通過 Proton 遊玩 OpenXR 遊戲,則必須以這種方式使用 OpenComposite。在大多數情況下,您還必須允許 Steam 運行時訪問您的 OpenXR 運行時的 Socket 路徑,方法是使用以下 Steam 上 XR 應用程式的啟動選項:env PRESSURE_VESSEL_FILESYSTEMS_RW=$XDG_RUNTIME_DIR/monado_comp_ipc %command%。此示例適用於 Monado,其他 XR 運行時可能有所不同。

WiVRn

WiVRn 是一款基於 Monado 構建的 OpenXR 流媒體應用程式。它能夠將獨立的 VR 頭戴設備無線連接到 Linux 計算機。如果您的頭戴設備不是無線的,請查閱 Monado。 WiVRn 模塊的示例用法:

⚠︎
Warning: 從 WiVRn 0.23 版本開始,WiVRn 會自行管理 opencomposite 路徑。僅在使用低於 v0.23 的版本時使用上述 opencomposite 配置。
❄︎ /etc/nixos/configuration.nix
services.wivrn = {
  enable = true;
  openFirewall = true;

  # Write information to /etc/xdg/openxr/1/active_runtime.json, VR applications
  # will automatically read this and work with WiVRn (Note: This does not currently
  # apply for games run in Valve's Proton)
    defaultRuntime = true;

  # Run WiVRn as a systemd service on startup
  autoStart = true;

  # Config for WiVRn (https://github.com/WiVRn/WiVRn/blob/master/docs/configuration.md)
  config = {
    enable = true;
    json = {
      # 1.0x foveation scaling
      scale = 1.0;
      # 100 Mb/s
      bitrate = 100000000;
      encoders = [
        {
          encoder = "vaapi";
          codec = "h265";
          # 1.0 x 1.0 scaling
          width = 1.0;
          height = 1.0;
          offset_x = 0.0;
          offset_y = 0.0;
        }
      ];
    };
  };
};

與 Monado 一樣,您還須添加 WiVRn 的啟動參數以允許訪問 Socket:PRESSURE_VESSEL_FILESYSTEMS_RW=$XDG_RUNTIME_DIR/wivrn/comp_ipc %command%

Envision

Envision 是用於 FOSS VR 程序棧的編排器(Orchestrator)。它負責構建和配置 Monado、WiVRn、OpenComposite 以及 FOSS VR 程序棧的其他實用程序,例如 Lighthouse 驅動程序、OpenHMD、Survive 和 WMR。您可以使用 Envision 模塊啟用它:

❄︎ /etc/nixos/configuration.nix
programs.envision = {
  enable = true;
  openFirewall = true; # This is set true by default
};

SteamVR

SteamVR 是一個專有的 OpenVR 運行時,兼容 OpenXR。它是 Steam 的一部分,除了啟用 Steam 之外,在 NixOS 上無需進行任何其他設置。

通過 Steam 安裝 SteamVR 並插入兼容 SteamVR 的耳機後,SteamVR 應該就可以正常工作。

在初始設置時,SteamVR 會請求提升權限,以便為其某個二進制文件設置文件能力(file capability)。這是使異步再投影技術正常工作所必需的。客戶端需要擁有 CAP_SYS_NICE 授權來獲取高優先級環境,這是異步再投影技術的必要條件。

Note: Steam 在基於 bubblewrap 的 FHS 環境中運行。此環境在用戶命名空間中運行 Steam,這阻止它使用任何能力(capabilities)或為二進制文件 setuid。這意味着除非修補內核以完全消除這些限制或修改用於運行 Steam 的 bubblewrap 二進制文件以消除這些功能保護,否則異步再投影技術無法在 NixOS 上使用。這兩種解決方法都有各自的安全隱患。請參閱此 Nixpkgs 問題

修補 AMDGPU 以允許高優先級隊列

通過應用 此補丁,AMDGPU 內核驅動程序將忽略進程權限並允許任何應用程式創建高優先級環境(high priority contexts)。

⚠︎
Warning: 這將移除內核中特意設置的限制,並可能導致調度問題。雖然目前尚未收到導致問題的報告,但這應被視為不受支持的配置。

作為 NixOS 內核補丁進行應用

為了解決 CAP_SYS_NICE 要求,我們可以使用以下 NixOS 配置片段應用內核補丁:

❄︎ /etc/nixos/configuration.nix
boot.kernelPatches = [
  {
    name = "amdgpu-ignore-ctx-privileges";
    patch = pkgs.fetchpatch {
      name = "cap_sys_nice_begone.patch";
      url = "https://github.com/Frogging-Family/community-patches/raw/master/linux61-tkg/cap_sys_nice_begone.mypatch";
      hash = "sha256-Y3a0+x2xvHsfLax/uwycdJf3xLxvVfkfDVqjkxNaYEo=";
    };
  }
];

也可以只修補 amdgpu 並將其構建為樹外模塊(out-of-tree module),如 Pacthing a single In-tree Kernel Module 中所述

修補 bubblewrap 以允許啟用能力(capabilities)

通過修改用於運行 Steam 的 bubblewrap 二進制文件,您可以允許該 FHS 環境中的進程獲取能力。這樣就無需直接修補內核了。

⚠︎
Warning: 這繞過了 bubblewrap 中預設的安全機制,並允許所有其他由 steam 啟動或通過 steam-run 運行的軟件也獲得這些能力。
❄︎ /etc/nixos/configuration.nix
programs.steam = let
  patchedBwrap = pkgs.bubblewrap.overrideAttrs (o: {
    patches = (o.patches or []) ++ [
      ./bwrap.patch
    ];
  });
in {
  enable = true;
  package = pkgs.steam.override {
    buildFHSEnv = (args: ((pkgs.buildFHSEnv.override {
      bubblewrap = patchedBwrap;
    }) (args // {
      extraBwrapArgs = (args.extraBwrapArgs or []) ++ [ "--cap-add ALL" ];
    })));
  };
};
≡︎ /etc/nixos/bwrap.patch
diff --git a/bubblewrap.c b/bubblewrap.c
index 8322ea0..4e20262 100644
--- a/bubblewrap.c
+++ b/bubblewrap.c
@@ -868,13 +868,6 @@ acquire_privs (void)
       /* Keep only the required capabilities for setup */
       set_required_caps ();
     }
-  else if (real_uid != 0 && has_caps ())
-    {
-      /* We have some capabilities in the non-setuid case, which should not happen.
-         Probably caused by the binary being setcap instead of setuid which we
-         don't support anymore */
-      die ("Unexpected capabilities but not setuid, old file caps config?");
-    }
   else if (real_uid == 0)
     {
       /* If our uid is 0, default to inheriting all caps; the caller

as an additional change, you may also need to replace Steam's own bwrap binary with a symbolic link to this modified bwrap binary, found at ~/.local/share/Steam/ubuntu12_32/steam-runtime/usr/libexec/steam-runtime-tools-0/srt-bwrap.

Steam will periodically replace this modification with its own binary when steam-runtime updates, so you may need to re-apply this change if it breaks.

wlx-overlay-s

wlx-overlay-s 是一個輕量級的 OpenXR/OpenVR 覆蓋層,適用於 Wayland 和 X11 桌面。它原生兼容 SteamVR 以及 Monado/WiVRn。

SteamVR 自動啟動

在 SteamVR(或任何 OpenVR 合成器)中啟動 wlx-overlay-s 時,它會註冊一個自動啟動清單。目前,此清單將引用 wlx-overlay-s 的 Nix 存儲路徑,該路徑可能會在重建 NixOS/Nix 配置文件後被垃圾回收。一種解決方法是定期運行以下命令來更新清單的存儲路徑:
# 运行 wlx-overlay-s 并替换任何正在运行的实例
$ wlx-overlay-s --replace
{{{1}}}

另見