From 8ec1632704e0fd2563dc9800f158189c8c918cf9 Mon Sep 17 00:00:00 2001 From: rickpeters Date: Sun, 27 Sep 2026 16:31:39 +0200 Subject: [PATCH] feat: VRAM booster with NVIDIA says what to do: update, switch to the open driver (chwd command), or not supported by the card --- CHANGELOG.md | 3 ++- TECHNICAL.md | 6 +++++ lib/backend.sh | 6 ++++- lib/menu.sh | 7 ++++-- lib/vram-booster.sh | 55 ++++++++++++++++++++++++++++++++++++++++++++- ui/qml/Texts.qml | 7 +++--- 6 files changed, 76 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97ed8e8..00b8e58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,8 @@ one per merged pull request. ## 2.5.0 - 2026-09-27 -- **docs: VRAM booster works with NVIDIA's open kernel modules (driver 615+); only the closed driver is greyed out** +- **feat: VRAM booster with NVIDIA says what to do: update, switch to the open driver (chwd command), or not supported by the card** +- `57995bc` **docs: VRAM booster works with NVIDIA's open kernel modules (driver 615+); only the closed driver is greyed out** - `d57e8d8` **docs: AGENTS.md and changelog for the vidmem detection** - `5a34633` **feat: VRAM booster also for drivers that name their region vidmem (or numbered), NVIDIA included once its driver registers it** - `479b70b` **feat: Everything in the home folder under steamify (state, scripts, icon), moved once from the old name** diff --git a/TECHNICAL.md b/TECHNICAL.md index 4c65136..f08a416 100644 --- a/TECHNICAL.md +++ b/TECHNICAL.md @@ -267,6 +267,12 @@ cgroup controller (7.2); amdgpu and Intel's xe register their VRAM with it (`drm//vram`), NVIDIA's open kernel modules from driver 615 too (`nvidia//vidmem`); `dmemcg-booster` protects every region it lists, whatever its name. NVIDIA's closed modules don't: with such a card the option is shown greyed +out with what to do (`vram_nvidia_case`): open modules older than 615 -> +update; the closed driver on a card the open one supports (not in chwd's +legacy lists `/var/lib/chwd/ids/nvidia-{580,470,390}.ids`) -> the `chwd` +commands to switch, never switched by Steamify itself (a failed switch +means a black screen, and it can't be tested here); a legacy card or +nouveau -> not supported. Shown greyed out, with why, until its driver lists a region: then it's offered like any other (`WIZARD_VRAM_FAKE_NVIDIA=1` fakes the grey-out, `WIZARD_VRAM_CAPACITY=` reads the regions from a copy, for tests). Otherwise diff --git a/lib/backend.sh b/lib/backend.sh index 4418317..37af7fe 100644 --- a/lib/backend.sh +++ b/lib/backend.sh @@ -54,7 +54,11 @@ backend_status() { items+=",\"wanted\":$( [[ "${WANTED[$c]:-0}" == 1 ]] && echo true || echo false)" items+=",\"update\":$(feature_outdated "$c" && echo true || echo false)" items+=",\"new\":$(feature_new "$c" && echo true || echo false)" - items+=",\"selectable\":$(component_selectable "$c" && echo true || echo false)}" + items+=",\"selectable\":$(component_selectable "$c" && echo true || echo false)" + # Why it can't be turned on, for the app's explanation. + [[ "$c" == vram && -n "${VRAM_NVIDIA_CASE:-}" ]] && + items+=",\"note\":$(json_str "$(vram_nvidia_note "$VRAM_NVIDIA_CASE")")" + items+="}" done local cec="" f for f in /dev/cec*; do [[ -e "$f" ]] && cec+="${cec:+ }$(basename "$f")"; done diff --git a/lib/menu.sh b/lib/menu.sh index 6e18688..0a235be 100644 --- a/lib/menu.sh +++ b/lib/menu.sh @@ -147,8 +147,11 @@ detect_components() { launcher_repair && WANTED[launcher]=1 # Shows the current and newest BIOS version. bios_available && { bios_lookup_newest; LABEL[bios]="$(bios_label)"; } - # Greyed out with an NVIDIA card: say why. - component_available vram && ! vram_selectable && LABEL[vram]="VRAM booster: needs NVIDIA's open kernel modules (driver 615+)" + # Greyed out with an NVIDIA card: say why, and what to do. + if component_available vram && ! vram_selectable; then + VRAM_NVIDIA_CASE="$(vram_nvidia_case)" + LABEL[vram]="VRAM booster: $(vram_nvidia_hint "$VRAM_NVIDIA_CASE")" + fi # First run: preselect the full SteamOS experience (never an action). if [[ "$any" == false ]]; then for c in "${COMPONENTS[@]}"; do diff --git a/lib/vram-booster.sh b/lib/vram-booster.sh index f6ed63e..8dce31d 100644 --- a/lib/vram-booster.sh +++ b/lib/vram-booster.sh @@ -18,7 +18,8 @@ VRAM_MIN_BYTES=$((2 * 1024 * 1024 * 1024)) VRAM_CAPACITY="${WIZARD_VRAM_CAPACITY:-/sys/fs/cgroup/dmem.capacity}" vram_supported() { - # WIZARD_VRAM_FAKE_NVIDIA=1 (tests): as with an NVIDIA card. + # WIZARD_VRAM_FAKE_NVIDIA (tests): as with an NVIDIA card whose driver + # doesn't register its VRAM; see vram_nvidia_case. [[ -n "${WIZARD_VRAM_FAKE_NVIDIA:-}" ]] && return 1 # Only for a GPU with its own VRAM: an integrated GPU registers a small # carve-out too, but mostly uses system RAM, so there's little to boost. @@ -39,6 +40,58 @@ vram_nvidia() { return 1 } +# chwd's lists of NVIDIA cards that need a closed legacy branch (580xx, +# 470xx, 390xx); every other NVIDIA card runs the open kernel modules. +VRAM_CHWD_IDS=/var/lib/chwd/ids + +vram_nvidia_case() { + # Why an NVIDIA card's VRAM isn't registered, so the menu can say what to + # do: "update" (open modules older than 615), "switch " + # (closed driver on a card the open one supports), "legacy" (card only + # runs a closed legacy branch), "nouveau" (no NVIDIA module). + # WIZARD_VRAM_FAKE_NVIDIA=1 fakes "switch nvidia-dkms-580xx", or name a case. + local fake="${WIZARD_VRAM_FAKE_NVIDIA:-}" license d id p + if [[ -n "$fake" ]]; then + [[ "$fake" == 1 ]] && fake="switch nvidia-dkms-580xx" + echo "$fake"; return + fi + license="$(modinfo -F license nvidia 2>/dev/null)" + case "$license" in + "Dual MIT/GPL") echo update; return ;; + "") echo nouveau; return ;; + esac + for d in /sys/bus/pci/devices/*; do + [[ "$(cat "$d/vendor" 2>/dev/null)" == 0x10de && "$(cat "$d/class" 2>/dev/null)" == 0x03* ]] || continue + id="$(cat "$d/device")"; id="${id#0x}" + grep -qwi "$id" "$VRAM_CHWD_IDS"/nvidia-*.ids 2>/dev/null && { echo legacy; return; } + done + for p in 580xx 470xx 390xx; do + pacman -Q "nvidia-$p-dkms" >/dev/null 2>&1 && { echo "switch nvidia-dkms-$p"; return; } + done + echo switch +} + +vram_nvidia_hint() { + # vram_nvidia_hint : the short reason (terminal menu, the app's row). + case "$1" in + update) echo "update NVIDIA's driver to 615 or newer (sudo pacman -Syu)" ;; + switch*) echo "needs NVIDIA's open driver, which your card supports" ;; + legacy) echo "your NVIDIA card's driver doesn't support it (older than RTX 20)" ;; + *) echo "the nouveau driver doesn't support it yet" ;; + esac +} + +vram_nvidia_note() { + # vram_nvidia_note : the full explanation, with what to do. + local profile="${1#switch}"; profile="${profile# }" + case "$1" in + update) echo "NVIDIA's open driver tells Linux how its video memory is used from version 615 on; yours is older ($(cat /sys/module/nvidia/version 2>/dev/null || echo unknown)). Update your system (sudo pacman -Syu), restart, and it's available here." ;; + switch*) echo "Your card also runs NVIDIA's open driver, the one CachyOS installs by default, and only that one tells Linux how its video memory is used. You're using NVIDIA's closed driver. Switch in a terminal with: ${profile:+sudo chwd -r $profile && }sudo chwd -i nvidia-open-dkms, then restart: it's available here after that. Steamify doesn't switch it for you: if something goes wrong, the screen stays black after the restart." ;; + legacy) echo "Your NVIDIA card is older than the RTX 20 series and only runs NVIDIA's closed driver, which doesn't tell Linux how its video memory is used. Newer NVIDIA cards (RTX 20 series and up), and AMD and Intel graphics cards, support it." ;; + *) echo "The open-source nouveau driver doesn't tell Linux how its video memory is used yet (a patch is on its way into the kernel). NVIDIA's own open driver does, from version 615 on (sudo chwd -a installs the right one)." ;; + esac +} + # Shown where it works, and greyed out with an NVIDIA card whose driver # doesn't register its VRAM with the kernel (yet): so it's clear why it # can't be turned on. Hidden elsewhere (integrated graphics, older kernel). diff --git a/ui/qml/Texts.qml b/ui/qml/Texts.qml index 363f083..e0f2005 100644 --- a/ui/qml/Texts.qml +++ b/ui/qml/Texts.qml @@ -48,8 +48,8 @@ QtObject { }) // Replaces the explanation of an option that can't be turned on here. readonly property var unsupported: ({ - vram: { body: "Not available with the NVIDIA driver you're using: it doesn't tell Linux how its video memory is used, so there's nothing to steer. NVIDIA's open kernel modules do, from driver 615 on (nvidia-open, CachyOS's default for RTX 20 series and newer); with those it's available here.", - changes: ["Nothing: needs NVIDIA's open kernel modules, driver 615 or newer"] } + // The body comes from the backend (item.note): it depends on the driver. + vram: { changes: ["Nothing until then: it can't steer video memory Linux doesn't know about"] } }) // Per plan action: the review's chip [text, colour, background] and the @@ -63,7 +63,8 @@ QtObject { function of(item) { var tx = items[item.id] || {}; - return item.selectable === false && unsupported[item.id] ? Object.assign({}, tx, unsupported[item.id]) : tx; + if (item.selectable !== false || !unsupported[item.id]) return tx; + return Object.assign({}, tx, unsupported[item.id], item.note ? { body: item.note } : {}); } function label(id, fallback) { return (items[id] || {}).label || fallback || id; } }