#!/usr/bin/env bash # Description: # Select which GPU to use for rendering for Hyprland and Niri. # # envs exported: # HYPR_AQ_DRM_DEVICES - Colon-separated list of DRM device paths for Hyprland's aq_drm # BRIGHTNESSCTL_DEVICE - Device identifier for brightnessctl # Constants niri_config_file="$HOME/.config/niri/config/misc.kdl" prefer_order=(amd nvidia intel) # AMD -> Nvidia -> Intel # Get vendor and path of each GPU default_dri_path="$(find /dev/dri/card* 2>/dev/null | head -n 1)" [[ -z "$default_dri_path" ]] && default_dri_path="/dev/dri/card0" intel_path="" nvidia_path="" amd_path="" for link in /dev/dri/by-path/*-card; do [[ -e "$link" ]] || continue card="$(readlink -f "$link")" vfile="/sys/class/drm/$(basename "$card")/device/vendor" [[ -r "$vfile" ]] || continue vendor="$(cat "$vfile")" case "$vendor" in 0x10de) nvidia_path="$card" ;; 0x8086) intel_path="$card" ;; 0x1002) amd_path="$card" ;; esac done # Specify device for brightnessctl # Only tested on my laptop with Intel iGPU & Nvidia dGPU BRIGHTNESSCTL_DEVICE="auto" if [[ -n "$intel_path" ]]; then BRIGHTNESSCTL_DEVICE="intel_backlight" elif [[ -n "$nvidia_path" ]]; then BRIGHTNESSCTL_DEVICE="nvidia_0" fi export BRIGHTNESSCTL_DEVICE # AQ_DRM_DEVICES allows multiple entries separated by colon devices="" for who in "${prefer_order[@]}"; do case "$who" in nvidia) [[ -n "$nvidia_path" ]] && devices="${devices:+$devices:}$nvidia_path" ;; intel) [[ -n "$intel_path" ]] && devices="${devices:+$devices:}$intel_path" ;; amd) [[ -n "$amd_path" ]] && devices="${devices:+$devices:}$amd_path" ;; esac done HYPR_AQ_DRM_DEVICES="${devices:-$default_dri_path}" export HYPR_AQ_DRM_DEVICES # But niri only supports choosing one preferred render device primary_device="$default_dri_path" for who in "${prefer_order[@]}"; do case "$who" in nvidia) [[ -n "$nvidia_path" ]] && { primary_device="$nvidia_path"; break; } ;; intel) [[ -n "$intel_path" ]] && { primary_device="$intel_path"; break; } ;; amd) [[ -n "$amd_path" ]] && { primary_device="$amd_path"; break; } ;; esac done # Update niri config function update_niri_config() { local config_file="$1" local device_path="$2" [[ -f "$config_file" ]] || return if grep -qE '^\s*render-drm-device\s+"[^"]+"' "$config_file"; then local current current="$(grep -E '^\s*render-drm-device\s+"[^"]+"' "$config_file" | sed -E 's/^\s*render-drm-device\s+"([^"]+)".*/\1/')" [[ "$current" == "$device_path" ]] && return sed -i -E "s|^(\s*render-drm-device\s+)\"[^\"]+\"|\1\"$device_path\"|" "$config_file" else printf '\ndebug {\nrender-drm-device "%s"\n}\n' "$device_path" >> "$config_file" fi } update_niri_config "$niri_config_file" "$primary_device"