mirror of
https://github.com/theupriser/steamify-cachyos.git
synced 2026-10-13 20:35:40 +02:00
feat: SteamOS conversion on NVIDIA with a patched gamescope (GBM scan-out)
Sync git.upriser.nl mirror / sync (push) Skipped
Sync git.upriser.nl mirror / sync (push) Skipped
The conversion is offered on supported NVIDIA cards again; it builds and installs steamify-gamescope-nvidia and sets gamescope_drm_gbm_scanout=1. It and Gaming on NVIDIA exclude each other. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KkpbsMw4rQyBsxDG6ebHK2
This commit is contained in:
1 parent
4d60dd227d
commit
127b8cf88b
9 files changed
+124
-14
No files matched your search
+8
-3
@@ -147,10 +147,15 @@ backend_apply() {
|
||||
for id in "${want[@]}"; do [[ "$id" == "$c" ]] && WANTED[$c]=1; done
|
||||
done
|
||||
# The same rules as the menu's toggles.
|
||||
# (Single user mode only needs the conversion where it is offered: not on NVIDIA PCs.)
|
||||
[[ "${WANTED[single]:-0}" == 1 ]] && component_available gaming && WANTED[gaming]=1
|
||||
# (Single user mode only needs the conversion where it is offered: not on NVIDIA PCs, where it works without it.)
|
||||
[[ "${WANTED[single]:-0}" == 1 ]] && component_available gaming && ! nvidia_present && WANTED[gaming]=1
|
||||
# On NVIDIA the conversion and "Gaming on NVIDIA" exclude each other: the one that is not on yet wins.
|
||||
if nvidia_present && [[ "${WANTED[gaming]:-0}" == 1 && "${WANTED[nvidia]:-0}" == 1 ]]; then
|
||||
if [[ "${CURRENT[gaming]:-0}" == 1 ]]; then WANTED[gaming]=0; WANTED[boot]=0; WANTED[silent]=0; WANTED[glyphs]=0
|
||||
else WANTED[nvidia]=0; WANTED[bigpicture]=0; WANTED[nvsilent]=0; fi
|
||||
fi
|
||||
if component_available gaming; then
|
||||
[[ "${WANTED[gaming]:-0}" == 0 ]] && { WANTED[single]=0; WANTED[boot]=0; }
|
||||
[[ "${WANTED[gaming]:-0}" == 0 ]] && { nvidia_present || WANTED[single]=0; WANTED[boot]=0; }
|
||||
else
|
||||
WANTED[boot]=0
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
#!/bin/bash
|
||||
# gamescope's own gaming mode on NVIDIA: a patched gamescope that allocates its scan-out buffers with GBM, which cures
|
||||
# the corrupted picture (https://github.com/ValveSoftware/gamescope/issues/2309). The patch and the build recipe live in
|
||||
# https://github.com/theupriser/steamify-gamescope-nvidia; the package `steamify-gamescope-nvidia` is built here, on the PC,
|
||||
# and replaces `gamescope` (it provides it). The patch is opt-in: gamescope reads `gamescope_drm_gbm_scanout=1` from its
|
||||
# environment, which is set for the gaming session (gamescope-session's environment file, and environment.d).
|
||||
# Used by the SteamOS conversion (`gaming_enable`/`gaming_disable`) on a supported NVIDIA card (`nvidia_supported`).
|
||||
# Sourced by steamify.sh; not meant to be run on its own.
|
||||
|
||||
GSN_PKG=steamify-gamescope-nvidia
|
||||
GSN_REPO=${GSN_REPO:-https://github.com/theupriser/steamify-gamescope-nvidia.git}
|
||||
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}"
|
||||
|
||||
gsn_package_installed() { pacman -Q "$GSN_PKG" >/dev/null 2>&1; }
|
||||
|
||||
gsn_env_set() { [[ -f "$GSN_ENV_D" ]] && grep -qsx "$GSN_ENV_LINE" "$GSN_SESSION_ENV"; }
|
||||
|
||||
gsn_status() { gsn_package_installed && gsn_env_set; }
|
||||
|
||||
gsn_install_package() {
|
||||
# Builds the package from the repo (makepkg runs as the user, never as root) and installs it. 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
|
||||
dir="$(mktemp -d)" || return 1
|
||||
if ! git clone --depth 1 "$GSN_REPO" "$dir/src"; then
|
||||
err "Couldn't download $GSN_REPO."
|
||||
rm -rf "$dir"; return 1
|
||||
fi
|
||||
if ! (cd "$dir/src" && 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"/src/"$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."
|
||||
rm -rf "$dir"; return 1
|
||||
fi
|
||||
rm -rf "$dir"
|
||||
ok "Patched gamescope installed."
|
||||
}
|
||||
|
||||
gsn_env_enable() {
|
||||
mkdir -p "$(dirname "$GSN_ENV_D")" "$(dirname "$GSN_SESSION_ENV")"
|
||||
echo "$GSN_ENV_LINE" > "$GSN_ENV_D"
|
||||
touch "$GSN_SESSION_ENV"
|
||||
grep -qsx "$GSN_ENV_LINE" "$GSN_SESSION_ENV" || echo "$GSN_ENV_LINE" >> "$GSN_SESSION_ENV"
|
||||
}
|
||||
|
||||
gsn_env_disable() {
|
||||
rm -f "$GSN_ENV_D"
|
||||
[[ -f "$GSN_SESSION_ENV" ]] && sed -i "/^${GSN_ENV_LINE}\$/d" "$GSN_SESSION_ENV"
|
||||
return 0
|
||||
}
|
||||
|
||||
gsn_enable() {
|
||||
# Only on a supported NVIDIA card; elsewhere the stock gamescope is right.
|
||||
nvidia_supported || return 0
|
||||
gsn_install_package || return 1
|
||||
gsn_env_enable
|
||||
ok "gamescope draws NVIDIA's picture through GBM (gamescope_drm_gbm_scanout=1) from the next gaming mode start."
|
||||
}
|
||||
|
||||
gsn_disable() {
|
||||
# The setting goes; the patched package stays, like the other packages (steam, gamescope-session-cachyos).
|
||||
gsn_env_disable
|
||||
}
|
||||
@@ -94,6 +94,8 @@ gaming_enable() {
|
||||
# LOGIN_MANAGER (sddm with single user, else plasmalogin) is set by the
|
||||
# menu. Re-running with the other value switches over cleanly.
|
||||
install_required_packages || return 1
|
||||
# NVIDIA: gamescope's picture is corrupted unless it is the patched one (no-op elsewhere).
|
||||
gsn_enable || return 1
|
||||
case "$LOGIN_MANAGER" in
|
||||
sddm)
|
||||
switch_to_sddm || return 1
|
||||
@@ -122,6 +124,7 @@ gaming_disable() {
|
||||
switch_to_plasmalogin
|
||||
remove_desktop_shortcut
|
||||
steam_disable
|
||||
gsn_disable
|
||||
krevert gaming
|
||||
os_name_disable
|
||||
ok "The PC boots to the normal login screen again (from the next boot)."
|
||||
|
||||
+15
-5
@@ -57,9 +57,10 @@ declare -A CURRENT WANTED
|
||||
|
||||
component_available() {
|
||||
case "$1" in
|
||||
# gamescope's own session is broken on NVIDIA: the conversion is replaced by "Gaming on NVIDIA" there (shown
|
||||
# anyway when it's already on, so it can be turned off).
|
||||
gaming|boot|silent|glyphs) ! nvidia_present || gaming_status ;;
|
||||
# gamescope's own session shows a corrupted picture on NVIDIA unless it is the patched one (lib/gamescope-nvidia.sh,
|
||||
# installed with the conversion on a supported card); "Gaming on NVIDIA" is the alternative there. Older NVIDIA
|
||||
# cards only get the alternative (the conversion is shown anyway when it's already on, so it can be turned off).
|
||||
gaming|boot|silent|glyphs) ! nvidia_present || gaming_status || nvidia_supported ;;
|
||||
nvidia) nvidia_available ;;
|
||||
bigpicture|nvsilent) bigpicture_available ;;
|
||||
machine|poweroff) machine_available ;;
|
||||
@@ -297,8 +298,8 @@ toggle_component() {
|
||||
WANTED[$c]=$(( 1 - WANTED[$c] ))
|
||||
# Single user mode only makes sense on top of the SteamOS conversion.
|
||||
# (On NVIDIA the conversion isn't offered: single user mode logs in by itself, see lib/single-user.sh.)
|
||||
if [[ "$c" == single && "${WANTED[single]}" == 1 ]] && component_available gaming; then WANTED[gaming]=1; fi
|
||||
if [[ "$c" == gaming && "${WANTED[gaming]}" == 0 ]]; then WANTED[single]=0; WANTED[boot]=0; fi
|
||||
if [[ "$c" == single && "${WANTED[single]}" == 1 ]] && component_available gaming && ! nvidia_present; then WANTED[gaming]=1; fi
|
||||
if [[ "$c" == gaming && "${WANTED[gaming]}" == 0 ]]; then nvidia_present || WANTED[single]=0; WANTED[boot]=0; fi
|
||||
# Where to boot to is part of the conversion, too.
|
||||
if [[ "$c" == boot && "${WANTED[boot]}" == 1 ]]; then WANTED[gaming]=1; fi
|
||||
# Big Picture is opt-out: ticked along with "Gaming on NVIDIA".
|
||||
@@ -310,6 +311,15 @@ toggle_component() {
|
||||
if [[ "$c" == gaming && "${WANTED[gaming]}" == 0 ]]; then WANTED[silent]=0; WANTED[glyphs]=0; fi
|
||||
if [[ "$c" == silent && "${WANTED[silent]}" == 1 ]]; then WANTED[gaming]=1; fi
|
||||
if [[ "$c" == glyphs && "${WANTED[glyphs]}" == 1 ]]; then WANTED[gaming]=1; fi
|
||||
# On NVIDIA the SteamOS conversion and "Gaming on NVIDIA" exclude each other (both would start Steam at login);
|
||||
# single user mode works with either.
|
||||
if nvidia_present; then
|
||||
if [[ "$c" == nvidia && "${WANTED[nvidia]}" == 1 ]]; then
|
||||
WANTED[gaming]=0; WANTED[boot]=0; WANTED[silent]=0; WANTED[glyphs]=0
|
||||
elif [[ "$c" =~ ^(gaming|boot|silent|glyphs)$ && "${WANTED[$c]}" == 1 && "${WANTED[gaming]}" == 1 ]]; then
|
||||
WANTED[nvidia]=0; WANTED[bigpicture]=0; WANTED[nvsilent]=0
|
||||
fi
|
||||
fi
|
||||
# The power-off fix is opt-out: ticked along with Steam Machine support.
|
||||
if [[ "$c" == machine ]]; then WANTED[poweroff]=${WANTED[machine]}; fi
|
||||
if [[ "$c" == poweroff && "${WANTED[poweroff]}" == 1 ]]; then WANTED[machine]=1; fi
|
||||
|
||||
+3
-3
@@ -37,9 +37,9 @@ nvidia_present() {
|
||||
return 1
|
||||
}
|
||||
|
||||
# Shown on NVIDIA PCs, unless the SteamOS conversion is already on there (it
|
||||
# has to be turned off first: both would start Steam at login).
|
||||
nvidia_available() { nvidia_present && ! gaming_status 2>/dev/null; }
|
||||
# Shown on NVIDIA PCs. It and the SteamOS conversion exclude each other (both
|
||||
# would start Steam at login): the menu unticks one when the other is ticked.
|
||||
nvidia_available() { nvidia_present; }
|
||||
bigpicture_available() { nvidia_available; }
|
||||
|
||||
nvidia_status() {
|
||||
|
||||
Reference in new issue
Block a user