{ den, modules, ... }: { modules.wivrn = { homeManager = { pkgs, ... }: { # nixpkgs builds wivrn with NVENC off (WIVRN_USE_NVENC follows cudaSupport); # without it "nvenc" in config.json fails with "Failed to find a suitable video encoder" nixpkgs.overlays = [ (final: prev: { wivrn = prev.wivrn.override { cudaSupport = true; }; }) ]; home.packages = with pkgs; [ wivrn wayvr ]; }; nixos = { pkgs, lib, ... }: { # nixpkgs only enables the NVENC encoder (WIVRN_USE_NVENC) when cudaSupport is set; # without it "nvenc" in config.json fails with "Failed to find a suitable video encoder" nixpkgs.overlays = [ (final: prev: { wivrn = prev.wivrn.override { cudaSupport = true; }; }) ]; services.wivrn = { enable = true; openFirewall = true; autoStart = true; highPriority = true; # Low-latency encoder config extraServerFlags = [ ]; monadoEnvironment = { # Monado OpenXR runtime env vars }; steam = { enable = true; importOXRRuntimes = true; }; # Optimal config for low latency: # - Vulkan encoder (newer kernels) or vaapi (AMD/Intel) # - H265 codec (3ms overhead, better quality than H264) # - 90Hz refresh rate (balance quality/battery) # - 140% render resolution with quality supersampling # - Up to 200Mbit/s bitrate on good networks config.enable = true; config.json = { encoder = { encoder = "nvenc"; codec = "h265"; }; # Enable mDNS discovery "publish-service" = "avahi"; # High priority for async reprojection highPriority = true; }; }; # Include monado-vulkan-layers for VR rendering environment.systemPackages = with pkgs; [ monado-vulkan-layers ]; }; }; }