ci / web (push) Successful in 1m9s
ci / docs-site (push) Successful in 1m14s
ci / rust-arm64 (push) Successful in 3m28s
deb / build-publish-client-arm64 (push) Successful in 2m28s
docker / builders (--build-arg FEDORA_VERSION=44, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm, -f44) (push) Successful in 10s
docker / builders (ci/android-ci.Dockerfile, punktfunk-android-ci) (push) Successful in 9s
docker / builders (ci/arch-ci.Dockerfile, punktfunk-arch-ci) (push) Successful in 11s
docker / builders (ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 8s
docker / builders (ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 9s
docker / builders (ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 12s
docker / apps (., web/Dockerfile, punktfunk-web) (push) Successful in 29s
android / android (push) Successful in 5m47s
docker / apps (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 1m16s
docker / builders-arm64cross (push) Successful in 9s
deb / build-publish (push) Successful in 6m5s
docker / deploy-docs (push) Successful in 35s
deb / build-publish-host (push) Successful in 6m35s
ci / rust (push) Successful in 6m38s
arch / build-publish (push) Successful in 9m13s
apple / swift (push) Failing after 13m37s
apple / screenshots (push) Skipped
windows-host / package (push) Successful in 17m4s
windows-host / winget-source (push) Skipped
windows-host / canary-manifest (push) Successful in 20s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 16m17s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Canceled after 39s
Field report (RX 5700 / SteamOS): 10-bit HEVC "unsupported" — but the GPU was
never the blocker (RADV probed Main10 fine on that box). The session stayed SDR
because stock gamescope offers no 10-bit PQ capture formats and nothing shipped
our pipewire-hdr build outside the Bazzite sysext, while PUNKTFUNK_GAMESCOPE_HDR
additionally defaulted off everywhere. Close all three gaps:
- PUNKTFUNK_GAMESCOPE_HDR now defaults ON (explicit-off grammar, the flip the
config comment planned post-canary). Safe by construction: the +pfhdr banner
probe, managed-spawn term, and client 10-bit cap keep stock-gamescope boxes on
the exact 8-bit path. The nix module's gamescopeHdr (default true now) only
controls whether the patched binary is on PATH; it no longer sets the env.
- SteamOS: new scripts/steamdeck/build-gamescope.sh builds the HDR gamescope in
the same pf2 trixie distrobox (apt dep list validated by a full build in a
debian:trixie container), installs ~/.local/bin/punktfunk-gamescope, and
maintains PUNKTFUNK_GAMESCOPE_BIN in host.env ONLY while the binary passes its
on-glass --version/+pfhdr check — a stale absolute override would break
session spawning, not just HDR. Wired into install.sh (§3b), update.sh
(retrofit), and rebuild-check.sh (ldd-probes it like the host binary).
- Arch: build-sysext.sh gains a --gamescope fold-in (banner-verified by
execution, host-image-only), and punktfunk-host optdepends the companion.
Deliberately NO CI-published host sysext: per the 2026-07-22 packaging
verdict a prebuilt SteamOS host breaks on A/B soname bumps (and /var is
per-partition-set), so arch.yml records that instead — SteamOS hosts use the
distrobox flow above.
Also fixes a latent bug that made build-sysext.sh fail every invocation as
documented: a literal `}` inside `${1:?usage …{host,client}…}` terminates the
expansion early and corrupts $PKG (caught by the new synthetic-package test,
which also covers the fold-in, the unmarked-gamescope refusal, and the
client-image guard).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
123 lines
6.4 KiB
Bash
Executable File
123 lines
6.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# punktfunk — build the HDR-capable `punktfunk-gamescope` for a SteamOS host (called by
|
|
# install.sh and update.sh; safe to run by hand).
|
|
#
|
|
# Stock gamescope offers no 10-bit PQ formats on its PipeWire capture node, so every session on
|
|
# the gamescope backend stays 8-bit SDR. This builds gamescope + punktfunk's `pipewire-hdr`
|
|
# patches (the ONE canonical recipe, packaging/gamescope/build-punktfunk-gamescope.sh) inside the
|
|
# same Debian-trixie distrobox the host is built in, installs it as
|
|
# ~/.local/bin/punktfunk-gamescope, and pins the host to it via PUNKTFUNK_GAMESCOPE_BIN in
|
|
# host.env. HDR is on by default in the host; with this binary present a 10-bit-capable client
|
|
# streams true HDR10 from Game Mode.
|
|
#
|
|
# BEST-EFFORT BY DESIGN, mirroring the CI packaging paths: streaming works without it (sessions
|
|
# stay SDR), so a failure here warns loudly and exits 0 — it must never cost the host install or
|
|
# update it runs inside. The one hard rule is honesty at the seams: host.env points at the binary
|
|
# ONLY while `--version` proves it runs on SteamOS glass and carries the `+pfhdr` marker; on any
|
|
# failure both the binary and the host.env line are removed (a stale absolute override would
|
|
# otherwise break gamescope session spawning entirely, which is worse than SDR).
|
|
#
|
|
# The build clones gamescope fresh each run (submodules included). That costs bandwidth, but it
|
|
# only runs when the packaging/gamescope tree changed (pin bump, patch change — tracked by a
|
|
# content stamp) or the installed binary stopped working; a no-op re-run is milliseconds.
|
|
set -euo pipefail
|
|
|
|
log() { printf '\033[1;36m==>\033[0m %s\n' "$*"; }
|
|
ok() { printf '\033[1;32m ok\033[0m %s\n' "$*"; }
|
|
warn() { printf '\033[1;33m !!\033[0m %s\n' "$*" >&2; }
|
|
|
|
SRC="${PUNKTFUNK_SRC:-$HOME/punktfunk}"
|
|
BOX="${PUNKTFUNK_BOX:-pf2}"
|
|
GS_BIN="$HOME/.local/bin/punktfunk-gamescope"
|
|
STAMP="$HOME/.local/share/punktfunk/gamescope.stamp"
|
|
HOST_ENV="$HOME/.config/punktfunk/host.env"
|
|
PKGDIR="$SRC/packaging/gamescope"
|
|
|
|
# host.env may only name the binary while it verifiably works (see header). sed -i is fine: the
|
|
# file is ours (install.sh §3) and the line is one this script wrote.
|
|
unwire() {
|
|
[ -f "$HOST_ENV" ] || return 0
|
|
if grep -q '^PUNKTFUNK_GAMESCOPE_BIN=' "$HOST_ENV"; then
|
|
sed -i '/^# HDR gamescope built by scripts\/steamdeck/d;/^PUNKTFUNK_GAMESCOPE_BIN=/d' "$HOST_ENV"
|
|
warn "host.env: removed PUNKTFUNK_GAMESCOPE_BIN (no working punktfunk-gamescope) — sessions stream SDR"
|
|
fi
|
|
}
|
|
wire() {
|
|
[ -f "$HOST_ENV" ] || return 0 # install.sh runs this after §3 wrote host.env; by-hand runs may predate it
|
|
grep -q '^PUNKTFUNK_GAMESCOPE_BIN=' "$HOST_ENV" && return 0
|
|
printf '\n# HDR gamescope built by scripts/steamdeck/build-gamescope.sh (10-bit BT.2020 PQ capture;\n# rebuilt by update.sh; PUNKTFUNK_GAMESCOPE_HDR=0 forces SDR).\nPUNKTFUNK_GAMESCOPE_BIN=%s\n' "$GS_BIN" >> "$HOST_ENV"
|
|
ok "host.env: PUNKTFUNK_GAMESCOPE_BIN=$GS_BIN"
|
|
}
|
|
# The on-glass truth: the binary must RUN ON STEAMOS (not merely in the build container — this is
|
|
# the ABI seam the whole distrobox approach exists for) and carry the +pfhdr banner marker.
|
|
verifies() { [ -x "$GS_BIN" ] && "$GS_BIN" --version 2>&1 | head -1 | grep -q '+pfhdr'; }
|
|
|
|
[ -d "$PKGDIR/patches" ] || { warn "no $PKGDIR — skipping the HDR gamescope build"; exit 0; }
|
|
|
|
# Content stamp over the packaging tree: a pin bump or patch edit re-triggers the build; anything
|
|
# else makes this a fast no-op.
|
|
want_stamp="$(find "$PKGDIR" -type f | LC_ALL=C sort | xargs sha256sum | sha256sum | cut -d' ' -f1)"
|
|
if [ -f "$STAMP" ] && [ "$(cat "$STAMP")" = "$want_stamp" ] && verifies; then
|
|
ok "punktfunk-gamescope up to date ($("$GS_BIN" --version 2>&1 | head -1))"
|
|
wire
|
|
exit 0
|
|
fi
|
|
|
|
log "Building punktfunk-gamescope (HDR 10-bit capture; ~5-10 min, best-effort)"
|
|
# gamescope's build deps in the box (trixie names, mirroring packaging/gamescope/PKGBUILD — keep
|
|
# the two lists in step). Provisioned here, not in install.sh's main pass, so a dep problem can
|
|
# only ever cost this feature. glm/stb come in as meson wraps; wlroots/libliftoff/vkroots/
|
|
# libdisplay-info are vendored submodules — none of those need packages.
|
|
if ! distrobox enter "$BOX" -- bash -lc '
|
|
set -e
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
sudo apt-get update -qq
|
|
sudo apt-get install -y -qq --no-install-recommends \
|
|
meson ninja-build cmake glslang-tools \
|
|
libwayland-dev wayland-protocols libxkbcommon-dev \
|
|
libx11-dev libxcomposite-dev libxdamage-dev libxext-dev libxmu-dev \
|
|
libxrender-dev libxres-dev libxtst-dev libxxf86vm-dev libxcursor-dev \
|
|
libxcb-errors-dev libxcb-icccm4-dev libxcb-ewmh-dev \
|
|
libxcb1-dev libxcb-composite0-dev libxcb-render0-dev libxcb-xfixes0-dev \
|
|
libxcb-shm0-dev libxcb-res0-dev libxcb-present-dev libxcb-xinput-dev \
|
|
libxcb-randr0-dev libxcb-dri3-dev libxcb-shape0-dev \
|
|
libcap-dev libdrm-dev libinput-dev libudev-dev libseat-dev \
|
|
libvulkan-dev libglm-dev libpixman-1-dev libeis-dev \
|
|
libavif-dev libdecor-0-dev hwdata libluajit-5.1-dev \
|
|
libpipewire-0.3-dev libspa-0.2-dev libsdl2-dev \
|
|
xwayland liblcms2-dev >/dev/null
|
|
' ; then
|
|
warn "could not provision gamescope build deps in '$BOX' — sessions stay SDR (re-run update.sh to retry)"
|
|
exit 0
|
|
fi
|
|
if ! distrobox enter "$BOX" -- bash -lc "
|
|
set -e
|
|
bash '$PKGDIR/build-punktfunk-gamescope.sh' --prefix \"\$HOME/.local\" --no-setcap
|
|
"; then
|
|
warn "punktfunk-gamescope failed to build — sessions stay SDR (re-run update.sh to retry)"
|
|
unwire
|
|
exit 0
|
|
fi
|
|
|
|
if verifies; then
|
|
# CAP_SYS_NICE is gamescope's scheduling boost — worth it, never required. Filesystem caps
|
|
# can't be set from the rootless box, so it happens here on the SteamOS side.
|
|
if sudo -n true 2>/dev/null; then
|
|
sudo setcap 'CAP_SYS_NICE=eip' "$GS_BIN" 2>/dev/null \
|
|
&& ok "setcap CAP_SYS_NICE (frame-pacing boost)" \
|
|
|| warn "could not setcap CAP_SYS_NICE (gamescope still works, pacing slightly worse)"
|
|
fi
|
|
mkdir -p "$(dirname "$STAMP")"
|
|
printf '%s' "$want_stamp" > "$STAMP"
|
|
wire
|
|
ok "punktfunk-gamescope ready: $("$GS_BIN" --version 2>&1 | head -1)"
|
|
else
|
|
# Built in the box but does not run on SteamOS (an ABI/soname seam) or lacks the marker. A
|
|
# broken binary must not linger where PATH or host.env could resolve it.
|
|
warn "built binary failed its on-glass check on SteamOS — removing it; sessions stay SDR"
|
|
"$GS_BIN" --version 2>&1 | head -3 >&2 || true
|
|
rm -f "$GS_BIN" "$STAMP"
|
|
unwire
|
|
fi
|
|
exit 0
|