From 946f1b3d694d043a79c64248fd36ba8c15376f0c Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Tue, 21 Jul 2026 10:14:31 +0200 Subject: [PATCH] fix(steamdeck): build the host with vulkan-encode, and wire up what it needs to actually engage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SteamOS scripts built the host featureless, so PlatformAuto could never pick the Vulkan Video backend (default-on since 84329205) and every session silently ran libav VAAPI — unlike the deb/arch/rpm/sysext builds, which all pass the feature. Three gaps, found live on a Deck host: - install.sh/update.sh: cargo build with --features punktfunk-host/vulkan-encode (matches the packaged builds; pure-Rust ash, no new system dep). - host.env: RADV_PERFTEST=video_encode — Van Gogh RADV still gates VK_KHR_video_encode_* behind it, so without it the backend can't open and falls back to VAAPI. Harmless where encode is exposed by default. - io.unom.Punktfunk.Host.desktop (Exec rewritten to this install's binary): KWin only grants zkde_screencast_unstable_v1/org_kde_kwin_fake_input to an exe a .desktop authorizes — without it Desktop-Mode capture fails outright and a mid-stream Game↔Desktop switch strands the stream on the old backend. update.sh retrofits the last two idempotently so existing installs get them without a reinstall. Validated on a SteamOS 3.8.14 Deck (Van Gogh): Vulkan HEVC opened on both the KWin and gamescope paths at 5120x1440 — in-place ABR reconfigure (no IDR, no encoder rebuild) vs the VAAPI path's full teardown per ABR step, and Desktop capture came up without a re-login. Co-Authored-By: Claude Opus 4.8 (1M context) --- scripts/steamdeck/install.sh | 21 +++++++++++++++++++-- scripts/steamdeck/update.sh | 17 ++++++++++++++++- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/scripts/steamdeck/install.sh b/scripts/steamdeck/install.sh index fafa031b..fe630a31 100755 --- a/scripts/steamdeck/install.sh +++ b/scripts/steamdeck/install.sh @@ -101,10 +101,13 @@ ok "build deps ready" # --- 2. build host (+ web) ------------------------------------------------- log "Building punktfunk-host (release) — first build is slow (~10-15 min)" +# vulkan-encode matches the packaged builds (deb/arch): the raw Vulkan Video HEVC/AV1 backend +# (real RFI loss recovery). Pure-Rust ash — no extra system dep. A featureless hand build would +# silently fall back to libav VAAPI. distrobox enter "$BOX" -- bash -lc " set -e export PATH=\$HOME/.cargo/bin:\$PATH CARGO_TARGET_DIR='$TARGET_DIR' -cd '$SRC' && cargo build -r -p punktfunk-host +cd '$SRC' && cargo build -r -p punktfunk-host --features punktfunk-host/vulkan-encode " [ -x "$BIN" ] || die "build did not produce $BIN" ok "host binary: $BIN" @@ -126,8 +129,12 @@ mkdir -p "$CONFIG" if [ ! -f "$CONFIG/host.env" ]; then cat > "$CONFIG/host.env" <<'EOF' # punktfunk Steam Deck host config (sourced by the punktfunk-host user service). -# Auto encoder: VAAPI on the Deck's AMD GPU, NVENC on NVIDIA. +# Auto encoder: Vulkan Video (or VAAPI fallback) on the Deck's AMD GPU, NVENC on NVIDIA. PUNKTFUNK_ENCODER=auto +# Van Gogh (LCD/OLED Deck) RADV still gates VK_KHR_video_encode_* behind this perftest flag; +# without it the Vulkan backend can't open and sessions fall back to libav VAAPI. Harmless on +# GPUs where encode is exposed by default. +RADV_PERFTEST=video_encode # The host auto-detects the live session (Game Mode gamescope / Desktop KDE) per connect. # Override the compositor only if detection misbehaves: PUNKTFUNK_COMPOSITOR=gamescope EOF @@ -136,6 +143,16 @@ else ok "host.env exists (left as-is)" fi +# KWin authorization for Desktop-Mode streaming (and mid-stream Game↔Desktop switches): KWin +# resolves a connecting client's /proc//exe against a .desktop `Exec=` and only then grants +# the restricted Wayland globals it lists (see packaging/linux/io.unom.Punktfunk.Host.desktop). +# Exec must therefore be THIS install's binary path, not the packaged /usr/bin one. KWin reads +# grants at session start — after first install, restart the Desktop session (Game Mode and back). +mkdir -p "$HOME/.local/share/applications" +sed "s|^Exec=.*|Exec=$BIN|" "$SRC/packaging/linux/io.unom.Punktfunk.Host.desktop" \ + > "$HOME/.local/share/applications/io.unom.Punktfunk.Host.desktop" +ok "KWin desktop-capture authorization (io.unom.Punktfunk.Host.desktop → $BIN)" + if [ "$WITH_WEB" = 1 ] && [ ! -f "$CONFIG/web.env" ]; then # Random login password + session secret for the web console, generated once. # `|| true` swallows the SIGPIPE `tr` takes when `head` closes the pipe (pipefail would abort). diff --git a/scripts/steamdeck/update.sh b/scripts/steamdeck/update.sh index d00dff72..80eed916 100755 --- a/scripts/steamdeck/update.sh +++ b/scripts/steamdeck/update.sh @@ -21,7 +21,8 @@ if [ "${1:-}" = "--pull" ]; then fi log "Rebuilding host (release)" -distrobox enter "$BOX" -- bash -lc "set -e; export PATH=\$HOME/.cargo/bin:\$PATH CARGO_TARGET_DIR='$TARGET_DIR'; cd '$SRC' && cargo build -r -p punktfunk-host" +# vulkan-encode matches the packaged builds (deb/arch) — see install.sh. +distrobox enter "$BOX" -- bash -lc "set -e; export PATH=\$HOME/.cargo/bin:\$PATH CARGO_TARGET_DIR='$TARGET_DIR'; cd '$SRC' && cargo build -r -p punktfunk-host --features punktfunk-host/vulkan-encode" ok "host rebuilt" if [ "$WEB" = 1 ]; then log "Rebuilding web console" @@ -29,6 +30,20 @@ if [ "$WEB" = 1 ]; then ok "web rebuilt" fi +# Retrofit config that install.sh now writes but older installs predate (both idempotent): +# RADV_PERFTEST — Van Gogh RADV still gates VK_KHR_video_encode_* behind it; without it the +# Vulkan backend can't open and sessions silently fall back to libav VAAPI. The KWin .desktop — +# KWin only grants the restricted capture/input globals to the exe a .desktop authorizes. +HOST_ENV="$HOME/.config/punktfunk/host.env" +if [ -f "$HOST_ENV" ] && ! grep -q '^RADV_PERFTEST=' "$HOST_ENV"; then + printf '\n# Van Gogh RADV gates VK_KHR_video_encode_* behind this (Vulkan Video encode).\nRADV_PERFTEST=video_encode\n' >> "$HOST_ENV" + ok "host.env: added RADV_PERFTEST=video_encode" +fi +mkdir -p "$HOME/.local/share/applications" +sed "s|^Exec=.*|Exec=$TARGET_DIR/release/punktfunk-host|" "$SRC/packaging/linux/io.unom.Punktfunk.Host.desktop" \ + > "$HOME/.local/share/applications/io.unom.Punktfunk.Host.desktop" +ok "KWin desktop-capture authorization refreshed" + log "Restarting services" systemctl --user restart punktfunk-host.service ok "punktfunk-host restarted"