#!/usr/bin/env bash # Description: # Select which GPU to use for rendering by Hyprland and Niri. # # Envs exported: # HYPR_AQ_DRM_DEVICES - Colon-separated list of DRM device paths for Hyprland's AQ_DRM_DEVICES env # BRIGHTNESSCTL_DEVICE - Device identifier for brightnessctl # Constants niri_config_file="$HOME/.config/niri/config/misc.kdl" prefer_order=(nvidia intel) # Get vendor and path of each GPU default_card_path="$(find /dev/dri/card* 2>/dev/null | head -n 1)" default_render_path="$(find /dev/dri/renderD* 2>/dev/null | head -n 1)" [[ -z "$default_card_path" ]] && default_card_path="/dev/dri/card0" [[ -z "$default_render_path" ]] && default_render_path="/dev/dri/renderD128" intel_card_path="" nvidia_card_path="" amd_card_path="" intel_render_path="" nvidia_render_path="" amd_render_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_card_path="$card" ;; 0x8086) intel_card_path="$card" ;; 0x1002) amd_card_path="$card" ;; esac done for link in /dev/dri/by-path/*-render; do [[ -e "$link" ]] || continue render="$(readlink -f "$link")" vfile="/sys/class/drm/$(basename "$render")/device/vendor" [[ -r "$vfile" ]] || continue vendor="$(cat "$vfile")" case "$vendor" in 0x10de) nvidia_render_path="$render" ;; 0x8086) intel_render_path="$render" ;; 0x1002) amd_render_path="$render" ;; esac done # Specify device for brightnessctl # Only tested on my laptop with Intel iGPU & Nvidia dGPU BRIGHTNESSCTL_DEVICE="auto" if [[ -n "$intel_card_path" ]]; then BRIGHTNESSCTL_DEVICE="intel_backlight" elif [[ -n "$nvidia_card_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_card_path" ]] && devices="${devices:+$devices:}$nvidia_card_path" ;; intel) [[ -n "$intel_card_path" ]] && devices="${devices:+$devices:}$intel_card_path" ;; amd) [[ -n "$amd_card_path" ]] && devices="${devices:+$devices:}$amd_card_path" ;; esac done HYPR_AQ_DRM_DEVICES="${devices:-$default_card_path}" export HYPR_AQ_DRM_DEVICES # But niri only supports choosing one preferred render device primary_render_device="$default_render_path" for who in "${prefer_order[@]}"; do case "$who" in nvidia) [[ -n "$nvidia_render_path" ]] && { primary_render_device="$nvidia_render_path" break } ;; intel) [[ -n "$intel_render_path" ]] && { primary_render_device="$intel_render_path" break } ;; amd) [[ -n "$amd_render_path" ]] && { primary_render_device="$amd_render_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_render_device"