Changes to the script.
This commit is contained in:
Regular → Executable
+208
-166
@@ -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 <https://www.gnu.org/licenses/>
|
||||
|
||||
# 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
|
||||
|
||||
Reference in New Issue
Block a user