feat: VRAM booster with NVIDIA says what to do: update, switch to the open driver (chwd command), or not supported by the card

This commit is contained in:
theupriser committed 2026-09-27 16:31:39 +02:00
1 parent cde0188c3d
commit 8ec1632704
6 files changed
+76 -8

No files matched your search

+2 -1
View File
@@ -7,7 +7,8 @@ one per merged pull request.
## 2.5.0 - 2026-09-27 ## 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** - `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** - `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** - `479b70b` **feat: Everything in the home folder under steamify (state, scripts, icon), moved once from the old name**
+6
View File
@@ -267,6 +267,12 @@ cgroup controller (7.2); amdgpu and Intel's xe register their VRAM with it
(`drm/<pci>/vram`), NVIDIA's open kernel modules from driver 615 too (`drm/<pci>/vram`), NVIDIA's open kernel modules from driver 615 too
(`nvidia/<pci>/vidmem`); `dmemcg-booster` protects every region it lists, (`nvidia/<pci>/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 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 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=<file>` other (`WIZARD_VRAM_FAKE_NVIDIA=1` fakes the grey-out, `WIZARD_VRAM_CAPACITY=<file>`
reads the regions from a copy, for tests). Otherwise reads the regions from a copy, for tests). Otherwise
+5 -1
View File
@@ -54,7 +54,11 @@ backend_status() {
items+=",\"wanted\":$( [[ "${WANTED[$c]:-0}" == 1 ]] && echo true || echo false)" items+=",\"wanted\":$( [[ "${WANTED[$c]:-0}" == 1 ]] && echo true || echo false)"
items+=",\"update\":$(feature_outdated "$c" && echo true || echo false)" items+=",\"update\":$(feature_outdated "$c" && echo true || echo false)"
items+=",\"new\":$(feature_new "$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 done
local cec="" f local cec="" f
for f in /dev/cec*; do [[ -e "$f" ]] && cec+="${cec:+ }$(basename "$f")"; done for f in /dev/cec*; do [[ -e "$f" ]] && cec+="${cec:+ }$(basename "$f")"; done
+5 -2
View File
@@ -147,8 +147,11 @@ detect_components() {
launcher_repair && WANTED[launcher]=1 launcher_repair && WANTED[launcher]=1
# Shows the current and newest BIOS version. # Shows the current and newest BIOS version.
bios_available && { bios_lookup_newest; LABEL[bios]="$(bios_label)"; } bios_available && { bios_lookup_newest; LABEL[bios]="$(bios_label)"; }
# Greyed out with an NVIDIA card: say why. # Greyed out with an NVIDIA card: say why, and what to do.
component_available vram && ! vram_selectable && LABEL[vram]="VRAM booster: needs NVIDIA's open kernel modules (driver 615+)" 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). # First run: preselect the full SteamOS experience (never an action).
if [[ "$any" == false ]]; then if [[ "$any" == false ]]; then
for c in "${COMPONENTS[@]}"; do for c in "${COMPONENTS[@]}"; do
+54 -1
View File
@@ -18,7 +18,8 @@ VRAM_MIN_BYTES=$((2 * 1024 * 1024 * 1024))
VRAM_CAPACITY="${WIZARD_VRAM_CAPACITY:-/sys/fs/cgroup/dmem.capacity}" VRAM_CAPACITY="${WIZARD_VRAM_CAPACITY:-/sys/fs/cgroup/dmem.capacity}"
vram_supported() { 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 [[ -n "${WIZARD_VRAM_FAKE_NVIDIA:-}" ]] && return 1
# Only for a GPU with its own VRAM: an integrated GPU registers a small # 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. # carve-out too, but mostly uses system RAM, so there's little to boost.
@@ -39,6 +40,58 @@ vram_nvidia() {
return 1 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 <chwd profile>"
# (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 <case>: 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 <case>: 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 # 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 # 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). # can't be turned on. Hidden elsewhere (integrated graphics, older kernel).
+4 -3
View File
@@ -48,8 +48,8 @@ QtObject {
}) })
// Replaces the explanation of an option that can't be turned on here. // Replaces the explanation of an option that can't be turned on here.
readonly property var unsupported: ({ 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.", // The body comes from the backend (item.note): it depends on the driver.
changes: ["Nothing: needs NVIDIA's open kernel modules, driver 615 or newer"] } 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 // Per plan action: the review's chip [text, colour, background] and the
@@ -63,7 +63,8 @@ QtObject {
function of(item) { function of(item) {
var tx = items[item.id] || {}; 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; } function label(id, fallback) { return (items[id] || {}).label || fallback || id; }
} }