🐜 fix(runner): Improve NVIDIA driver handling, switch to gamescope (#279)

## Description
- Made it so failed NVIDIA driver install won't quit entrypoint script
if other GPU vendors are present (fixes mixed GPU cases).
- Switch to gamescope as compositor, with optional SYS_NICE cap handling
for higher priority.
- Use mangohud preset 2 for stats, which is more compact.
- Fixes to nestri-server lspci regex, to deal with AMD naming scheme.
- Added missing radeon vulkan driver packages.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
	- Added support for additional AMD Vulkan drivers.
- Integrated Steam launch directly within the gamescope compositor for a
streamlined startup.

- **Bug Fixes**
- Improved GPU driver fallback handling to ensure smoother operation on
systems without NVIDIA GPUs.
	- Enhanced PCI device parsing for more accurate GPU detection.

- **Chores**
- Updated environment configuration to use X11 session type and set
MangoHud preset.
- Removed unused packages and legacy compositor/resolution management
logic.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: DatCaptainHorse <DatCaptainHorse@users.noreply.github.com>
This commit is contained in:
Kristian Ollikainen
2025-05-17 04:19:00 +03:00
committed by GitHub
parent 80deb82d25
commit baf178afc5
5 changed files with 64 additions and 93 deletions

View File

@@ -132,9 +132,11 @@ RUN sed -i \
# Core system components # Core system components
RUN --mount=type=cache,target=/var/cache/pacman/pkg \ RUN --mount=type=cache,target=/var/cache/pacman/pkg \
pacman -Sy --needed --noconfirm \ pacman -Sy --needed --noconfirm \
vulkan-intel lib32-vulkan-intel vpl-gpu-rt mesa \ vulkan-intel lib32-vulkan-intel vpl-gpu-rt \
vulkan-radeon lib32-vulkan-radeon \
mesa \
steam steam-native-runtime gtk3 lib32-gtk3 \ steam steam-native-runtime gtk3 lib32-gtk3 \
sudo xorg-xwayland seatd libinput labwc wlr-randr gamescope mangohud \ sudo xorg-xwayland seatd libinput gamescope mangohud \
libssh2 curl wget \ libssh2 curl wget \
pipewire pipewire-pulse pipewire-alsa wireplumber \ pipewire pipewire-pulse pipewire-alsa wireplumber \
noto-fonts-cjk supervisor jq chwd lshw pacman-contrib && \ noto-fonts-cjk supervisor jq chwd lshw pacman-contrib && \

View File

@@ -141,26 +141,60 @@ main() {
if [[ -z "$nvidia_driver_version" ]]; then if [[ -z "$nvidia_driver_version" ]]; then
log "Error: Failed to determine NVIDIA driver version." log "Error: Failed to determine NVIDIA driver version."
exit 1 # Check for other GPU vendors before exiting
if [[ -n "${vendor_devices[amd]:-}" || -n "${vendor_devices[intel]:-}" ]]; then
log "Other GPUs (AMD or Intel) detected, continuing without NVIDIA driver."
else
log "No other GPUs detected, exiting due to NVIDIA driver version failure."
exit 1
fi
else
log "Detected NVIDIA driver version: $nvidia_driver_version"
# Set up cache and get installer
setup_cache
local arch=$(uname -m)
local filename="NVIDIA-Linux-${arch}-${nvidia_driver_version}.run"
cd "$NVIDIA_INSTALLER_DIR" || {
log "Error: Failed to change to $NVIDIA_INSTALLER_DIR."
exit 1
}
get_nvidia_installer "$nvidia_driver_version" "$arch" || {
# Check for other GPU vendors before exiting
if [[ -n "${vendor_devices[amd]:-}" || -n "${vendor_devices[intel]:-}" ]]; then
log "Other GPUs (AMD or Intel) detected, continuing without NVIDIA driver."
else
log "No other GPUs detected, exiting due to NVIDIA installer failure."
exit 1
fi
}
# Install driver
install_nvidia_driver "$filename" || {
# Check for other GPU vendors before exiting
if [[ -n "${vendor_devices[amd]:-}" || -n "${vendor_devices[intel]:-}" ]]; then
log "Other GPUs (AMD or Intel) detected, continuing without NVIDIA driver."
else
log "No other GPUs detected, exiting due to NVIDIA driver installation failure."
exit 1
fi
}
fi fi
log "Detected NVIDIA driver version: $nvidia_driver_version"
# Set up cache and get installer
setup_cache
local arch=$(uname -m)
local filename="NVIDIA-Linux-${arch}-${nvidia_driver_version}.run"
cd "$NVIDIA_INSTALLER_DIR" || {
log "Error: Failed to change to $NVIDIA_INSTALLER_DIR."
exit 1
}
get_nvidia_installer "$nvidia_driver_version" "$arch" || exit 1
# Install driver
install_nvidia_driver "$filename" || exit 1
else else
log "No NVIDIA GPU detected, skipping driver fix." log "No NVIDIA GPU detected, skipping driver fix."
fi fi
# Make sure gamescope has CAP_SYS_NICE capabilities if available
log "Checking for CAP_SYS_NICE availability..."
if capsh --print | grep -q "Current:.*cap_sys_nice"; then
log "Giving gamescope compositor CAP_SYS_NICE permissions..."
setcap 'CAP_SYS_NICE+eip' /usr/bin/gamescope 2>/dev/null || {
log "Warning: Failed to set CAP_SYS_NICE on gamescope, continuing without it..."
}
else
log "Skipping CAP_SYS_NICE for gamescope, capability not available..."
fi
# Switch to nestri user # Switch to nestri user
log "Switching to nestri user for application startup..." log "Switching to nestri user for application startup..."
if [[ ! -x /etc/nestri/entrypoint_nestri.sh ]]; then if [[ ! -x /etc/nestri/entrypoint_nestri.sh ]]; then

View File

@@ -85,39 +85,21 @@ start_nestri_server() {
restart_chain restart_chain
} }
# Starts compositor (labwc) # Starts compositor (gamescope) with Steam
start_compositor() { start_compositor() {
kill_if_running "${COMPOSITOR_PID:-}" "compositor" kill_if_running "${COMPOSITOR_PID:-}" "compositor"
log "Pre-configuring compositor..." log "Starting compositor with Steam..."
mkdir -p "${HOME}/.config/labwc/"
cat > ~/.config/labwc/rc.xml << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<labwc_config>
<keyboard><default/></keyboard>
<mouse><default/>
<context name="Root">
<mousebind button="Left" action="Press"/>
<mousebind button="Right" action="Press"/>
<mousebind button="Middle" action="Press"/>
</context>
</mouse>
</labwc_config>
EOF
echo '<?xml version="1.0" encoding="UTF-8"?><openbox_menu></openbox_menu>' > ~/.config/labwc/menu.xml
log "Starting compositor..."
rm -rf /tmp/.X11-unix && mkdir -p /tmp/.X11-unix && chown nestri:nestri /tmp/.X11-unix rm -rf /tmp/.X11-unix && mkdir -p /tmp/.X11-unix && chown nestri:nestri /tmp/.X11-unix
WAYLAND_DISPLAY=wayland-1 WLR_BACKENDS=wayland labwc & WAYLAND_DISPLAY=wayland-1 gamescope --backend wayland -g -f -e --rt --mangoapp -W "${WIDTH}" -H "${HEIGHT}" -- steam-native -tenfoot -cef-force-gpu &
COMPOSITOR_PID=$! COMPOSITOR_PID=$!
log "Waiting for compositor to initialize..." log "Waiting for compositor to initialize..."
COMPOSITOR_SOCKET="${XDG_RUNTIME_DIR}/wayland-0" COMPOSITOR_SOCKET="${XDG_RUNTIME_DIR}/gamescope-0"
for ((i=1; i<=15; i++)); do for ((i=1; i<=15; i++)); do
if [[ -e "$COMPOSITOR_SOCKET" ]]; then if [[ -e "$COMPOSITOR_SOCKET" ]]; then
log "Compositor initialized, wayland-0 ready." log "Compositor initialized, gamescope-0 ready."
sleep 2 sleep 2
start_wlr_randr
return return
fi fi
sleep 1 sleep 1
@@ -128,46 +110,6 @@ EOF
start_compositor start_compositor
} }
# Configures resolution with wlr-randr
start_wlr_randr() {
log "Configuring resolution with wlr-randr..."
OUTPUT_NAME=$(WAYLAND_DISPLAY=wayland-0 wlr-randr --json | jq -r '.[] | select(.enabled == true) | .name' | head -n 1)
if [[ -z "$OUTPUT_NAME" ]]; then
log "Error: No enabled outputs detected."
exit 1
fi
local WLR_RETRIES=0
while ! WAYLAND_DISPLAY=wayland-0 wlr-randr --output "$OUTPUT_NAME" --custom-mode "$RESOLUTION"; do
log "Error: Failed to configure wlr-randr. Retrying..."
((WLR_RETRIES++))
if [[ "$WLR_RETRIES" -ge "$MAX_RETRIES" ]]; then
log "Error: Max retries reached for wlr-randr."
exit 1
fi
sleep 2
done
log "wlr-randr configuration successful."
sleep 2
}
# Starts Steam
start_steam() {
kill_if_running "${STEAM_PID:-}" "Steam"
log "Starting Steam with -tenfoot..."
steam-native -tenfoot &
STEAM_PID=$!
sleep 2
if ! kill -0 "$STEAM_PID" 2>/dev/null; then
log "Error: Steam failed to start."
return 1
fi
log "Steam started successfully."
return 0
}
# Increments retry counter # Increments retry counter
increment_retry() { increment_retry() {
local component="$1" local component="$1"
@@ -190,7 +132,6 @@ cleanup() {
log "Terminating processes..." log "Terminating processes..."
kill_if_running "${NESTRI_PID:-}" "nestri-server" kill_if_running "${NESTRI_PID:-}" "nestri-server"
kill_if_running "${COMPOSITOR_PID:-}" "compositor" kill_if_running "${COMPOSITOR_PID:-}" "compositor"
kill_if_running "${STEAM_PID:-}" "Steam"
exit 0 exit 0
} }
@@ -205,18 +146,11 @@ main_loop() {
log "nestri-server died." log "nestri-server died."
increment_retry "nestri-server" increment_retry "nestri-server"
restart_chain restart_chain
start_steam || increment_retry "Steam"
# Check compositor # Check compositor
elif [[ -n "${COMPOSITOR_PID:-}" ]] && ! kill -0 "${COMPOSITOR_PID}" 2>/dev/null; then elif [[ -n "${COMPOSITOR_PID:-}" ]] && ! kill -0 "${COMPOSITOR_PID}" 2>/dev/null; then
log "compositor died." log "compositor died."
increment_retry "compositor" increment_retry "compositor"
start_compositor start_compositor
start_steam || increment_retry "Steam"
# Check Steam
elif [[ -n "${STEAM_PID:-}" ]] && ! kill -0 "${STEAM_PID}" 2>/dev/null; then
log "Steam died."
increment_retry "Steam"
start_steam || increment_retry "Steam"
fi fi
done done
} }
@@ -224,9 +158,8 @@ main_loop() {
main() { main() {
chown_user_directory chown_user_directory
load_envs load_envs
#parse_resolution "${RESOLUTION:-1920x1080}" || exit 1 # Not used currently parse_resolution "${RESOLUTION:-1920x1080}" || exit 1
restart_chain restart_chain
start_steam || increment_retry "Steam"
main_loop main_loop
} }

View File

@@ -2,13 +2,15 @@
set -euo pipefail set -euo pipefail
export XDG_RUNTIME_DIR=/run/user/${UID}/ export XDG_RUNTIME_DIR=/run/user/${UID}/
export WAYLAND_DISPLAY=wayland-0 export XDG_SESSION_TYPE=x11
export XDG_SESSION_TYPE=wayland
export DISPLAY=:0 export DISPLAY=:0
export $(dbus-launch) export $(dbus-launch)
# Causes some setups to break # Causes some setups to break
export PROTON_NO_FSYNC=1 export PROTON_NO_FSYNC=1
# Sleeker Mangohud preset :)
export MANGOHUD_CONFIG=preset=2
# Our preferred prefix # Our preferred prefix
export WINEPREFIX=/home/${USER}/.nestripfx/ export WINEPREFIX=/home/${USER}/.nestripfx/

View File

@@ -84,7 +84,7 @@ pub fn get_gpus() -> Vec<GPUInfo> {
fn parse_pci_device(line: &str) -> Option<(String, String, String, String)> { fn parse_pci_device(line: &str) -> Option<(String, String, String, String)> {
let re = Regex::new( let re = Regex::new(
r#"^(?P<pci_addr>\S+)\s+"[^\[]*\[(?P<class_id>[0-9a-f]{4})\].*?"\s+"[^\[]*\[(?P<vendor_id>[0-9a-f]{4})\].*?"\s+"(?P<device_name>[^"]+?)""#, r#"^(?P<pci_addr>\S+)\s+"[^\[]*\[(?P<class_id>[0-9a-f]{4})\].*?"\s+"[^"]*?\[(?P<vendor_id>[0-9a-f]{4})\][^"]*?"\s+"(?P<device_name>[^"]+?)""#,
).unwrap(); ).unwrap();
let caps = re.captures(line)?; let caps = re.captures(line)?;