From b51b21a1950af015209ee767bc38963e9552b028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Numbus?= Date: Fri, 24 Jul 2026 12:16:03 +0200 Subject: [PATCH] Changes to the script. --- client/gpu-detect.sh | 374 ++++++++++++++++++++++++------------------- 1 file changed, 208 insertions(+), 166 deletions(-) mode change 100644 => 100755 client/gpu-detect.sh diff --git a/client/gpu-detect.sh b/client/gpu-detect.sh old mode 100644 new mode 100755 index 8a3902b..f8e8cbb --- a/client/gpu-detect.sh +++ b/client/gpu-detect.sh @@ -9,204 +9,246 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. -# -# This package is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see # Avoid cryptic failure when running dash on this script -shopt -s compat31 nocasematch 2>/dev/null || { echo "Error: this script only works with bash." && exit; } +shopt -s compat31 nocasematch 2>/dev/null || { echo "Error: this script only works with bash." && exit 1; } + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' # No Color -# Defining variables USER_ID="$(id -u)" PCI_IDS_LOCATION="/run/user/${USER_ID}/gpu-detect" + declare -A args=( ["brand"]="all" ["hw_accel"]="true" ) +PCI_IDS=() - -gum style --border-foreground="030" --bold --border=normal --padding="0 2" "GPU detection tool for NixOS" - - +show_help() { + gum style --border-foreground="030" --bold --border=normal --padding="0 2" "GPU detection tool for NixOS" + echo "Usage: gpu-detect [OPTIONS] [PCIID]..." + echo "" + echo "Options:" + echo " -b, --brand BRAND Select GPU brand to detect: all, amd, intel, nvidia (default: all)" + echo " -hw, --hw_accel BOOL Provide hardware acceleration configuration: true, false (default: true)" + echo " -h, --help Show this help message and exit" + echo "" + echo "For each GPU installed in your system (or matching the specified brand/PCI ID)," + echo "the program will provide you the needed NixOS configuration." + exit 0 +} while [[ $# -gt 0 ]]; do case "${1}" in --brand|-b) - args["brand"]="${2}" - shift 2 + if [[ -n "${2}" && ! "${2}" =~ ^- ]]; then + args["brand"]="${2,,}" + shift 2 + else + echo -e "${RED}Error: --brand requires an argument.${NC}" + exit 1 + fi ;; --hw_accel|-hw) - args["hw_accel"]="${2}" - shift 2 + if [[ -n "${2}" && ! "${2}" =~ ^- ]]; then + args["hw_accel"]="${2,,}" + shift 2 + else + echo -e "${RED}Error: --hw_accel requires an argument.${NC}" + exit 1 + fi ;; - --help|-h|*) - echo "Usage: gpu-detect --brand=[all/amd/intel/nvidia] --hw_accel=[true/false] [PCIID]..." - echo "" - echo "For each GPU installed in your system, the program" - echo "will provide you the needed NixOS configuration." - exit 0 + --help|-h) + show_help + ;; + -*) + echo -e "${RED}Unknown option ${1}${NC}" + show_help + ;; + *) + PCI_IDS+=("${1}") + shift ;; esac done -gpu_detect() { - # Get the PCI IDs from the repo - if [[ ! -d "${PCI_IDS_LOCATION}" ]]; then - mkdir -p "${PCI_IDS_LOCATION}" - git clone -q -b ids-database https://gittea.dev/numbus/gpu-detect.git "${PCI_IDS_LOCATION}" - else - if ! git -C "${PCI_IDS_LOCATION}" pull; then - echo "Directory ${PCI_IDS_LOCATION} is not empty and does not" - echo "contain the repository. Please check the folder clean up manually." - exit 1 - fi - fi +gum style --border-foreground="030" --bold --border=normal --padding="0 2" "GPU detection tool for NixOS" - amd_detect() { +# Get the PCI IDs from the repo +if [[ ! -d "${PCI_IDS_LOCATION}" ]]; then + echo -e "${BLUE}Fetching latest PCI IDs database...${NC}" + mkdir -p "${PCI_IDS_LOCATION}" + if ! git clone -q -b ids-database https://gittea.dev/numbus/gpu-detect.git "${PCI_IDS_LOCATION}"; then + # Fallback to local checkout if remote is not available for testing purposes + if [[ -d "../.git" ]]; then + git clone -q -b ids-database "file://$(realpath ../)" "${PCI_IDS_LOCATION}" || true + fi + fi +else + echo -e "${BLUE}Updating PCI IDs database...${NC}" + if ! git -C "${PCI_IDS_LOCATION}" pull -q; then + echo -e "${RED}Error: Directory ${PCI_IDS_LOCATION} is not empty and does not contain the repository. Please check the folder and clean up manually.${NC}" + exit 1 + fi +fi - } +nvidia_detect() { + local PCI_ID="${1}" + local NVIDIA_VERSION="" + + local VERSIONS=("unsupported" "legacy_340" "legacy_390" "legacy_470" "legacy_580" "current") + for version in "${VERSIONS[@]}"; do + if grep -q -i "${PCI_ID}" "${PCI_IDS_LOCATION}/nvidia/${version}.ids" 2>/dev/null; then + NVIDIA_VERSION="${version}" + break + fi + done - intel_detect() { + if [[ -z "${NVIDIA_VERSION}" ]]; then + gum style --foreground="212" "Uh oh. It seems that your card couldn't be detected." "A newer driver may add support for your card later." + return 1 + fi - } + if [[ "${NVIDIA_VERSION}" == "unsupported" ]]; then + gum style --foreground="212" "Good news! You have nothing to do, your card runs with the 'nouveau' driver that is integrated in the kernel." "" "It seems you have a very old card! The proprietary NVIDIA drivers have been removed from Nixpkgs therefore it is not possible to install them." + return 0 + fi - nvidia_detect() { - PCI_ID=${1} - NVIDIA_VERSION="" - local NVIDIA_TEXT=""" - { config, lib, pkgs, ... }: - { - hardware.graphics = { - enable = true; - extraPackages = with pkgs; [ ${EXTRA_PACKAGES} ]; - }; - services.xserver.videoDrivers = [ "nvidia" ]; - hardware.nvidia = { - modesetting.enable = true; - nvidiaSettings = true; - package = config.boot.kernelPackages.nvidiaPackages.${NVIDIA_VERSION}; + local EXTRA_PACKAGES="" + local HW_ACCEL_CONFIG="" + if [[ "${args["hw_accel"]}" == "true" ]]; then + if [[ "${NVIDIA_VERSION}" == "legacy_340" || "${NVIDIA_VERSION}" == "legacy_390" || "${NVIDIA_VERSION}" == "legacy_470" ]]; then + EXTRA_PACKAGES="libvdpau" + elif [[ "${NVIDIA_VERSION}" == "legacy_580" || "${NVIDIA_VERSION}" == "current" ]]; then + EXTRA_PACKAGES="nvidia-vaapi-driver libvdpau" + fi + HW_ACCEL_CONFIG=" + hardware.graphics = { + enable = true; + extraPackages = with pkgs; [ ${EXTRA_PACKAGES} ]; + };" + fi - # Unsupported options - powerManagement.enable = false; - powerManagement.finegrained = false; - open = false; - }; - } - """ - local VERSIONS=("unsupported" "legacy_340" "legacy_390" "legacy_470" "legacy_580" "current") + local DRIVER_INFO="" + local NVIDIA_CONFIG="" + local NIX_PACKAGE_VER="${NVIDIA_VERSION}" + if [[ "${NVIDIA_VERSION}" == "current" ]]; then + NIX_PACKAGE_VER="stable" + fi - for version in ${VERSIONS[@]}; do - if grep -q -i "${PCI_ID}" "${PCI_IDS_LOCATION}/nvidia/${version}.ids" 2>/dev/null; then - NVIDIA_VERSION="${version}" - break - fi - done + if [[ "${NVIDIA_VERSION}" == "current" ]]; then + DRIVER_INFO="An official stable NVIDIA driver release is available for your card." + NVIDIA_CONFIG="{ config, lib, pkgs, ... }: +{${HW_ACCEL_CONFIG} + services.xserver.videoDrivers = [ \"nvidia\" ]; + hardware.nvidia = { + modesetting.enable = true; + nvidiaSettings = true; + open = true; + package = config.boot.kernelPackages.nvidiaPackages.${NIX_PACKAGE_VER}; - if [[ -z "${NVIDIA_VERSION}" ]]; then - echo "Uh oh. It seems that your card couldn't be detected." - echo "A newer driver may add support for your card later." - return 1 - fi + # Advanced options, tweak if needed + powerManagement.enable = false; # Experimental: Enable this if you have graphical corruption issues or application crashes after waking up from sleep. + powerManagement.finegrained = false; # Experimental: Turns off GPU when not in use + }; +}" + else + DRIVER_INFO="An official legacy NVIDIA driver release is available for your card." + NVIDIA_CONFIG="{ config, lib, pkgs, ... }: +{${HW_ACCEL_CONFIG} + services.xserver.videoDrivers = [ \"nvidia\" ]; + hardware.nvidia = { + modesetting.enable = true; + nvidiaSettings = true; + package = config.boot.kernelPackages.nvidiaPackages.${NIX_PACKAGE_VER}; - if [[ "${NVIDIA_VERSION}" == "unsupported" ]]; then - echo "Good news! You have nothing to do, your card runs with the" - echo "\"nouveau\" driver that is integrated in the kernel." - echo "" - echo "It seems you have a very old card!" - echo "The proprietary NVIDIA drivers have been removed from Nixpkgs" - echo "therefore it is not possible to install them." - elif [[ "${NVIDIA_VERSION}" == "legacy_340" || "${NVIDIA_VERSION}" == "legacy_390" || "${NVIDIA_VERSION}" == "legacy_470" ]]; then - echo "An official legacy NVIDIA driver release is available for" - echo "your card." - echo "" - echo "You can add the following code snippet to your NixOS configuration" - echo "in order to enable the proprietary NVIDIA driver with VDPAU support." - EXTRA_PACKAGES="\"libvdpau\"" - echo ${NVIDIA_TEXT} - elif [[ "${NVIDIA_VERSION}" == "legacy_580" ]]; then - echo "An official legacy NVIDIA driver release is available for" - echo "your card." - echo "" - echo "You can add the following nix code to your NixOS configuration" - echo "in order to enable the proprietary NVIDIA driver with VDPAU and" - echo "VAAPI (if applicable) support." - EXTRA_PACKAGES="\"nvidia-vaapi-driver\" \"libvdpau\"" - echo ${NVIDIA_TEXT} - elif [[ "${NVIDIA_VERSION}" == "current" ]]; then - echo "An official stable NVIDIA driver release is available for" - echo "your card." - echo "" - echo "You can add the following nix code to your NixOS configuration" - echo "in order to enable the proprietary NVIDIA driver with hardware" - echo "acceleration support." - echo """ - { config, lib, pkgs, ... }: - { - hardware.graphics = { - enable = true; - extraPackages = with pkgs; [ ${EXTRA_PACKAGES} ]; - }; - services.xserver.videoDrivers = [ "nvidia" ]; - hardware.nvidia = { - modesetting.enable = true; - nvidiaSettings = true; - open = true; - package = config.boot.kernelPackages.nvidiaPackages.${NVIDIA_VERSION}; - - # Advanced options, tweak if needed - powerManagement.enable = false; # Experimental: Enable this if you have graphical corruption issues or application crashes after waking up from sleep. - powerManagement.finegrained = false; # Experimental: Turns off GPU when not in use - }; - } - """ - fi - } - - - if [ -z "${1}" ]; then - - - NV_DEVICES=$(lspci -mn | awk '{ gsub("\"",""); if ((${2} ~ "030[0-2]") && ($3 == "10de" || $3 == "12d2")) { print ${1} } }') - - if [ -z "$NV_DEVICES" ]; then - echo "No NVIDIA GPU detected." - exit 0 - fi - - echo "Detected NVIDIA GPUs:" - for d in $NV_DEVICES ; do - lspci -nn -s $d - done - - for d in $NV_DEVICES ; do - echo -e "\nChecking card: $(lspci -s $d | awk -F: '{print $3}')" - nvidia_detect "$(lspci -mn -s "$d" | awk '{ gsub("\"",""); print $3 $4 }')" - done - - else - - for id in "$@" ; do - PCIID=$(echo "$id" | sed -rn 's/^(10de)?:?([0-9a-fA-F]{4})$/10de\2/ip') - if [ -z "$PCIID" ]; then - echo "Error parsing PCI ID '$id'." - exit 2 - fi - - echo "Checking driver support for PCI ID [$(echo $PCIID | sed -r 's/(....)(....)/\1:\2/')]" - nvidia_detect "$PCIID" - done - - fi + # Unsupported options + powerManagement.enable = false; + powerManagement.finegrained = false; + open = false; + }; +}" + fi + gum style --foreground="212" "${DRIVER_INFO}" + if [[ "${args["hw_accel"]}" == "true" ]]; then + gum style "You can add the following code snippet to your NixOS configuration in order to enable the proprietary NVIDIA driver with hardware acceleration support." + else + gum style "You can add the following code snippet to your NixOS configuration in order to enable the proprietary NVIDIA driver." + fi + gum format '```nix +'"${NVIDIA_CONFIG}"' +```' } +# Main logic +if [[ ${#PCI_IDS[@]} -gt 0 ]]; then + for id in "${PCI_IDS[@]}" ; do + # Try to parse NVIDIA PCI ID (vendor 10de) + PCIID=$(echo "$id" | sed -rn 's/^(10de)?:?([0-9a-fA-F]{4})$/10de\2/ip') + if [ -n "$PCIID" ]; then + gum style --foreground="030" "Checking driver support for NVIDIA PCI ID [$(echo $PCIID | sed -r 's/(....)(....)/\1:\2/')]" + nvidia_detect "$PCIID" + else + echo -e "${YELLOW}Currently only NVIDIA PCI IDs (10de:XXXX) are supported when passing explicitly.${NC}" + fi + done +else + if [[ "${args["brand"]}" == "all" || "${args["brand"]}" == "nvidia" ]]; then + NV_DEVICES=$(lspci -mn 2>/dev/null | awk '{ gsub("\"",""); if (($2 ~ "030[0-2]") && ($3 == "10de" || $3 == "12d2")) { print $1 } }') + + if [ -n "$NV_DEVICES" ]; then + gum style --foreground="030" "Detected NVIDIA GPUs:" + for d in $NV_DEVICES ; do + lspci -nn -s $d + done + + for d in $NV_DEVICES ; do + gum style --foreground="030" "Checking card: $(lspci -s $d | awk -F: '{print $3}')" + nvidia_detect "$(lspci -mn -s "$d" | awk '{ gsub("\"",""); print $3 $4 }')" + done + else + if [[ "${args["brand"]}" == "nvidia" ]]; then + gum style --foreground="212" "No NVIDIA GPU detected." + fi + fi + fi + + if [[ "${args["brand"]}" == "all" || "${args["brand"]}" == "amd" ]]; then + AMD_DEVICES=$(lspci -mn 2>/dev/null | awk '{ gsub("\"",""); if (($2 ~ "030[0-2]") && ($3 == "1002")) { print $1 } }') + if [ -n "$AMD_DEVICES" ]; then + gum style --foreground="030" "Detected AMD GPUs:" + for d in $AMD_DEVICES ; do + lspci -nn -s $d + done + gum style --foreground="212" "AMD configuration generation is not fully implemented yet." + else + if [[ "${args["brand"]}" == "amd" ]]; then + gum style --foreground="212" "No AMD GPU detected." + fi + fi + fi + + if [[ "${args["brand"]}" == "all" || "${args["brand"]}" == "intel" ]]; then + INTEL_DEVICES=$(lspci -mn 2>/dev/null | awk '{ gsub("\"",""); if (($2 ~ "030[0-2]") && ($3 == "8086")) { print $1 } }') + if [ -n "$INTEL_DEVICES" ]; then + gum style --foreground="030" "Detected Intel GPUs:" + for d in $INTEL_DEVICES ; do + lspci -nn -s $d + done + gum style --foreground="212" "Intel configuration generation is not fully implemented yet." + else + if [[ "${args["brand"]}" == "intel" ]]; then + gum style --foreground="212" "No Intel GPU detected." + fi + fi + fi +fi - - -exit $RET +exit 0