From 2e64fde7d5e682abf409f9dd82b63fd8195b4cdd Mon Sep 17 00:00:00 2001 From: rickpeters Date: Tue, 13 Oct 2026 18:47:29 +0200 Subject: [PATCH] feat: the patched gamescope comes from the pinned GitHub release (sha256), else the copy on the ISO, else a local build Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_01KkpbsMw4rQyBsxDG6ebHK2 --- .no-release-yet | 2 + CHANGELOG.md | 6 +-- lib/gamescope-nvidia.sh | 91 +++++++++++++++++++++++++++++++++-------- 3 files changed, 78 insertions(+), 21 deletions(-) create mode 100644 .no-release-yet diff --git a/.no-release-yet b/.no-release-yet new file mode 100644 index 0000000..eedb58b --- /dev/null +++ b/.no-release-yet @@ -0,0 +1,2 @@ +Not tested on hardware yet: the whole Steamify flow for the patched gamescope on NVIDIA (apply, reboot, session). +Delete this file when it was, after asking the user (AGENTS.md). diff --git a/CHANGELOG.md b/CHANGELOG.md index 89c443e..d1e372a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,11 +7,11 @@ one per merged pull request. ## 2.11.2 - 2026-10-13 -- **fix: HDMI-CEC on the Steam Machine no longer needs GitHub: when downloading Valve's CEC driver fails, Steamify uses the copy it carries (`patches/cros-ec-cec.c`), checked against the same pinned sha256** +- `124b424`, `f234c72` **fix: HDMI-CEC on the Steam Machine no longer needs GitHub: when downloading Valve's CEC driver fails, Steamify uses the copy it carries (`patches/cros-ec-cec.c`), checked against the same pinned sha256** -- **feat: the SteamOS conversion is offered on NVIDIA PCs again (GTX 16 / RTX 20 series or newer: Turing and later, the cards NVIDIA's open kernel driver supports): it builds and installs a patched gamescope from the recipe and patch Steamify carries (`patches/`, prepared in [steamify-gamescope-nvidia](https://github.com/theupriser/steamify-gamescope-nvidia); gamescope 3.16.31, so a Steamify release builds the version it was tested with) (GBM-allocated scan-out buffers, NVIDIA's corrupted gaming-mode picture, gamescope#2309; a few minutes to build) and sets `gamescope_drm_gbm_scanout=1` for the session (`lib/gamescope-nvidia.sh`). It replaces "Gaming on NVIDIA", which is not offered any more (the kernel parameters, early modules, suspend memory and the 32-bit libraries come with the conversion on a supported card; a PC that had "Gaming on NVIDIA" on has it turned off when the conversion is turned on). Tested on an RTX 5080 (driver 615.78.08): Steam's gaming UI is clean with it and shows artifacts without. The package is pinned to one gamescope release: updating it is not automatic yet** +- `127b8cf`, `2811ecc`, `f3cd053`, `4325d80`, `03f9e87`, `5b5181f`, `06ffc8b`, `4d60dd2`, `0ba94b2` **feat: the SteamOS conversion is offered on NVIDIA PCs again (GTX 16 / RTX 20 series or newer: Turing and later, the cards NVIDIA's open kernel driver supports): it builds and installs a patched gamescope from the recipe and patch Steamify carries (`patches/`, prepared in [steamify-gamescope-nvidia](https://github.com/theupriser/steamify-gamescope-nvidia); gamescope 3.16.31, so a Steamify release builds the version it was tested with) (GBM-allocated scan-out buffers, NVIDIA's corrupted gaming-mode picture, gamescope#2309; a few minutes to build) and sets `gamescope_drm_gbm_scanout=1` for the session (`lib/gamescope-nvidia.sh`). It replaces "Gaming on NVIDIA", which is not offered any more (the kernel parameters, early modules, suspend memory and the 32-bit libraries come with the conversion on a supported card; a PC that had "Gaming on NVIDIA" on has it turned off when the conversion is turned on). Tested on an RTX 5080 (driver 615.78.08): Steam's gaming UI is clean with it and shows artifacts without. The package is pinned to one gamescope release: updating it is not automatic yet** -- **feat: "Gaming on NVIDIA" also keeps video memory over suspend (`NVreg_PreserveVideoMemoryAllocations=1` in `/etc/modprobe.d/90-steamify-nvidia.conf`, the initramfs is rebuilt), enables `nvidia-suspend`/`nvidia-resume`/`nvidia-hibernate`, and installs `lib32-nvidia-utils` and `lib32-libxkbcommon` (32-bit games, the 32-bit MangoHud preload) on a supported card; off removes only what Steamify added. Untested on hardware yet** +- `ce4bc67` **feat: "Gaming on NVIDIA" also keeps video memory over suspend (`NVreg_PreserveVideoMemoryAllocations=1` in `/etc/modprobe.d/90-steamify-nvidia.conf`, the initramfs is rebuilt), enables `nvidia-suspend`/`nvidia-resume`/`nvidia-hibernate`, and installs `lib32-nvidia-utils` and `lib32-libxkbcommon` (32-bit games, the 32-bit MangoHud preload) on a supported card; off removes only what Steamify added. Untested on hardware yet** ## 2.11.1 - 2026-10-02 diff --git a/lib/gamescope-nvidia.sh b/lib/gamescope-nvidia.sh index dca71af..8a4e3c0 100644 --- a/lib/gamescope-nvidia.sh +++ b/lib/gamescope-nvidia.sh @@ -10,6 +10,14 @@ # Sourced by steamify.sh; not meant to be run on its own. GSN_PKG=steamify-gamescope-nvidia +# The package this Steamify release was tested with (the recipe in patches/ names the same version): built by CI in +# CachyOS's container and published as a release of steamify-gamescope-nvidia. A new pin: the release, its sha256, and +# patches/gamescope-nvidia.PKGBUILD's pkgver/pkgrel. +GSN_VERSION=3.16.31-1 +GSN_SHA256=9f20e5243866d1ddeb9ba0c6828bc7be1945f623f9a5d8094391f0df043002e1 +GSN_URL="${GSN_URL:-https://github.com/theupriser/steamify-gamescope-nvidia/releases/download/$GSN_VERSION}" +# Where the ISO leaves a copy of the same package, for installs without GitHub. +GSN_BACKUP_DIR="${GSN_BACKUP_DIR:-/usr/local/share/steamify/gamescope}" GSN_ENV_LINE='gamescope_drm_gbm_scanout=1' GSN_ENV_D="${GSN_ENV_D:-$HOME/.config/environment.d/99-steamify-gamescope-nvidia.conf}" GSN_SESSION_ENV="${GSN_SESSION_ENV:-$HOME/.config/gamescope-session/environment}" @@ -20,33 +28,80 @@ gsn_env_set() { [[ -f "$GSN_ENV_D" ]] && grep -qsx "$GSN_ENV_LINE" "$GSN_SESSION gsn_status() { gsn_package_installed && gsn_env_set; } -gsn_install_package() { - # Builds the package from the recipe and patch Steamify carries (patches/, so a Steamify release builds exactly the - # gamescope version it was tested with) and installs it. makepkg runs as the user, never as root, and downloads - # gamescope's sources (Valve's repository at the PKGBUILD's pkgver, and its submodules). The build needs a few minutes: - # gamescope compiles from source. --ask 4 lets pacman replace the stock gamescope it conflicts with. - gsn_package_installed && return 0 - info "Building the patched gamescope for NVIDIA (a few minutes)..." - sudo pacman -S --needed --noconfirm base-devel git || { err "Installing the build tools failed."; return 1; } - local dir pkg cache="${XDG_CACHE_HOME:-$HOME/.cache}/steamify" +gsn_package_current() { + # The pinned version is installed (a newer Steamify pins a newer one, which then installs over it). + [[ "$(pacman -Q "$GSN_PKG" 2>/dev/null | awk '{print $2}')" == "$GSN_VERSION" ]] +} + +gsn_sha_ok() { echo "$GSN_SHA256 $1" | sha256sum -c --quiet - >/dev/null 2>&1; } + +gsn_fetch_package() { + # The pinned, verified package, on stdout as a path: first from GitHub (built by CI in CachyOS's container), else the + # copy that came with the ISO. Both only count when their sha256 is the one pinned here: a Steamify release names + # exactly the package it was tested with, so an unchanged or swapped file is refused. + local cache="${XDG_CACHE_HOME:-$HOME/.cache}/steamify" file="$GSN_PKG-$GSN_VERSION-x86_64.pkg.tar.zst" backup + mkdir -p "$cache" || return 1 + if [[ -f "$cache/$file" ]] && gsn_sha_ok "$cache/$file"; then echo "$cache/$file"; return 0; fi + info "Downloading the patched gamescope (GitHub release $GSN_VERSION)..." >&2 + if curl -fsL --retry 2 --connect-timeout 15 --max-time 300 -o "$cache/$file.part" "$GSN_URL/$file" && + gsn_sha_ok "$cache/$file.part"; then + mv -f "$cache/$file.part" "$cache/$file" + echo "$cache/$file"; return 0 + fi + rm -f "$cache/$file.part" + warn "Downloading the patched gamescope failed (or its checksum didn't match)." >&2 + for backup in "$GSN_BACKUP_DIR/$file" "$cache/$file"; do + if [[ -f "$backup" ]] && gsn_sha_ok "$backup"; then + info "Using the copy that came with Steamify: $backup" >&2 + echo "$backup"; return 0 + fi + done + return 1 +} + +gsn_build_package() { + # Last resort: builds the package from the recipe and patch Steamify carries (patches/), as the user. It downloads + # gamescope's sources (Valve's repository at the PKGBUILD's pkgver, and its submodules) and compiles them: a few + # minutes. Prints the package's path. + local dir cache="${XDG_CACHE_HOME:-$HOME/.cache}/steamify" + info "Building the patched gamescope here instead (a few minutes)..." >&2 + sudo pacman -S --needed --noconfirm base-devel git >&2 || { err "Installing the build tools failed." >&2; return 1; } # On disk, not /tmp: the installer's chroot has a tmpfs there (RAM), and the build is 1-2 GB. mkdir -p "$cache" && dir="$(mktemp -d -p "$cache" gamescope-build.XXXXXX)" || return 1 patch_file gamescope-nvidia.PKGBUILD > "$dir/PKGBUILD" && patch_file gamescope-gbm-scanout.patch > "$dir/gamescope-gbm-scanout.patch" || { - err "Couldn't write the build files." + err "Couldn't write the build files." >&2 rm -rf "$dir"; return 1 } - if ! (cd "$dir" && makepkg -sf --noconfirm --nocheck); then - err "Building the patched gamescope failed (see above). The stock gamescope stays." - rm -rf "$dir"; return 1 - fi - pkg="$(ls "$dir"/"$GSN_PKG"-*.pkg.tar.* 2>/dev/null | grep -v -- '-debug-' | head -1)" - if [[ -z "$pkg" ]] || ! sudo pacman -U --noconfirm --ask 4 "$pkg"; then - err "Installing the patched gamescope failed. The stock gamescope stays." + if ! (cd "$dir" && makepkg -sf --noconfirm --nocheck >&2); then + err "Building the patched gamescope failed (see above)." >&2 rm -rf "$dir"; return 1 fi + # Moved out, so the build folder can go. + mv "$(ls "$dir"/"$GSN_PKG"-*.pkg.tar.* 2>/dev/null | grep -v -- '-debug-' | head -1)" "$cache/gamescope-local-build.pkg.tar.zst" || + { rm -rf "$dir"; return 1; } rm -rf "$dir" - ok "Patched gamescope installed." + echo "$cache/gamescope-local-build.pkg.tar.zst" +} + +gsn_install_package() { + # The patched gamescope, in this order, each step only when the one before failed: the pinned package from GitHub, the + # copy that came with the ISO, a build here. A package that downloaded fine but doesn't install (its libraries differ from + # this PC's) goes on to the build too. Nothing else changes before one of them is installed, so a failure leaves the PC as + # it was, with the stock gamescope. --ask 4 lets pacman replace the stock gamescope it conflicts with. + gsn_package_current && return 0 + local pkg + if pkg="$(gsn_fetch_package)" && sudo pacman -U --noconfirm --ask 4 "$pkg"; then + ok "Patched gamescope installed." + return 0 + fi + warn "The ready-made patched gamescope couldn't be installed." + if pkg="$(gsn_build_package)" && sudo pacman -U --noconfirm --ask 4 "$pkg"; then + ok "Patched gamescope built and installed." + return 0 + fi + err "The patched gamescope couldn't be installed. The stock gamescope stays." + return 1 } gsn_env_enable() {