Changes to the script.

This commit is contained in:
Raphaël Numbus
2026-07-24 12:16:03 +02:00
parent 3bc5b1c37c
commit b51b21a195
Regular → Executable
+208 -166
View File
@@ -9,204 +9,246 @@
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or # the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version. # (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 <https://www.gnu.org/licenses/>
# Avoid cryptic failure when running dash on this script # 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)" USER_ID="$(id -u)"
PCI_IDS_LOCATION="/run/user/${USER_ID}/gpu-detect" PCI_IDS_LOCATION="/run/user/${USER_ID}/gpu-detect"
declare -A args=( declare -A args=(
["brand"]="all" ["brand"]="all"
["hw_accel"]="true" ["hw_accel"]="true"
) )
PCI_IDS=()
show_help() {
gum style --border-foreground="030" --bold --border=normal --padding="0 2" "GPU detection tool for NixOS" 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 while [[ $# -gt 0 ]]; do
case "${1}" in case "${1}" in
--brand|-b) --brand|-b)
args["brand"]="${2}" if [[ -n "${2}" && ! "${2}" =~ ^- ]]; then
shift 2 args["brand"]="${2,,}"
shift 2
else
echo -e "${RED}Error: --brand requires an argument.${NC}"
exit 1
fi
;; ;;
--hw_accel|-hw) --hw_accel|-hw)
args["hw_accel"]="${2}" if [[ -n "${2}" && ! "${2}" =~ ^- ]]; then
shift 2 args["hw_accel"]="${2,,}"
shift 2
else
echo -e "${RED}Error: --hw_accel requires an argument.${NC}"
exit 1
fi
;; ;;
--help|-h|*) --help|-h)
echo "Usage: gpu-detect --brand=[all/amd/intel/nvidia] --hw_accel=[true/false] [PCIID]..." show_help
echo "" ;;
echo "For each GPU installed in your system, the program" -*)
echo "will provide you the needed NixOS configuration." echo -e "${RED}Unknown option ${1}${NC}"
exit 0 show_help
;;
*)
PCI_IDS+=("${1}")
shift
;; ;;
esac esac
done done
gpu_detect() { gum style --border-foreground="030" --bold --border=normal --padding="0 2" "GPU detection tool for NixOS"
# 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
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() { local EXTRA_PACKAGES=""
PCI_ID=${1} local HW_ACCEL_CONFIG=""
NVIDIA_VERSION="" if [[ "${args["hw_accel"]}" == "true" ]]; then
local NVIDIA_TEXT=""" if [[ "${NVIDIA_VERSION}" == "legacy_340" || "${NVIDIA_VERSION}" == "legacy_390" || "${NVIDIA_VERSION}" == "legacy_470" ]]; then
{ config, lib, pkgs, ... }: EXTRA_PACKAGES="libvdpau"
{ elif [[ "${NVIDIA_VERSION}" == "legacy_580" || "${NVIDIA_VERSION}" == "current" ]]; then
hardware.graphics = { EXTRA_PACKAGES="nvidia-vaapi-driver libvdpau"
enable = true; fi
extraPackages = with pkgs; [ ${EXTRA_PACKAGES} ]; HW_ACCEL_CONFIG="
}; hardware.graphics = {
services.xserver.videoDrivers = [ "nvidia" ]; enable = true;
hardware.nvidia = { extraPackages = with pkgs; [ ${EXTRA_PACKAGES} ];
modesetting.enable = true; };"
nvidiaSettings = true; fi
package = config.boot.kernelPackages.nvidiaPackages.${NVIDIA_VERSION};
# Unsupported options local DRIVER_INFO=""
powerManagement.enable = false; local NVIDIA_CONFIG=""
powerManagement.finegrained = false; local NIX_PACKAGE_VER="${NVIDIA_VERSION}"
open = false; if [[ "${NVIDIA_VERSION}" == "current" ]]; then
}; NIX_PACKAGE_VER="stable"
} fi
"""
local VERSIONS=("unsupported" "legacy_340" "legacy_390" "legacy_470" "legacy_580" "current")
for version in ${VERSIONS[@]}; do if [[ "${NVIDIA_VERSION}" == "current" ]]; then
if grep -q -i "${PCI_ID}" "${PCI_IDS_LOCATION}/nvidia/${version}.ids" 2>/dev/null; then DRIVER_INFO="An official stable NVIDIA driver release is available for your card."
NVIDIA_VERSION="${version}" NVIDIA_CONFIG="{ config, lib, pkgs, ... }:
break {${HW_ACCEL_CONFIG}
fi services.xserver.videoDrivers = [ \"nvidia\" ];
done hardware.nvidia = {
modesetting.enable = true;
nvidiaSettings = true;
open = true;
package = config.boot.kernelPackages.nvidiaPackages.${NIX_PACKAGE_VER};
if [[ -z "${NVIDIA_VERSION}" ]]; then # Advanced options, tweak if needed
echo "Uh oh. It seems that your card couldn't be detected." powerManagement.enable = false; # Experimental: Enable this if you have graphical corruption issues or application crashes after waking up from sleep.
echo "A newer driver may add support for your card later." powerManagement.finegrained = false; # Experimental: Turns off GPU when not in use
return 1 };
fi }"
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 # Unsupported options
echo "Good news! You have nothing to do, your card runs with the" powerManagement.enable = false;
echo "\"nouveau\" driver that is integrated in the kernel." powerManagement.finegrained = false;
echo "" open = false;
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." fi
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
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 0
exit $RET