diff --git a/README.md b/README.md index 55106bf..2af7c25 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ NVENC and NvFBC patches for Nvidia drivers ========================================== -![GitHub last commit](https://img.shields.io/github/last-commit/keylase/nvidia-patch.svg) ![Latest version](https://img.shields.io/badge/latest%20linux%20driver%20version-470.63.01-brightgreen.svg) +![GitHub last commit](https://img.shields.io/github/last-commit/keylase/nvidia-patch.svg) ![Latest version](https://img.shields.io/badge/latest%20linux%20driver%20version-470.74-brightgreen.svg) [NVENC patch](patch.sh) removes restriction on maximum number of simultaneous NVENC video encoding sessions imposed by Nvidia to consumer-grade GPUs. @@ -148,7 +148,9 @@ git clone https://ipfs.io/ipns/Qmed4r8yrBP162WK1ybd1DJWhLUi4t6mGuBoB9fLtjxR7u nv | 470.42.01 | YES | YES | [Driver link](https://international.download.nvidia.com/XFree86/Linux-x86_64/470.42.01/NVIDIA-Linux-x86_64-470.42.01.run) | | 470.57.02 | YES | YES | [Driver link](https://international.download.nvidia.com/XFree86/Linux-x86_64/470.57.02/NVIDIA-Linux-x86_64-470.57.02.run) | | 470.62.02 | YES | YES | | +| 470.62.05 | YES | YES | | | 470.63.01 | YES | YES | [Driver link](https://international.download.nvidia.com/XFree86/Linux-x86_64/470.63.01/NVIDIA-Linux-x86_64-470.63.01.run) | +| 470.74 | YES | YES | [Driver link](https://international.download.nvidia.com/XFree86/Linux-x86_64/470.74/NVIDIA-Linux-x86_64-470.74.run) | ## Synopsis @@ -156,7 +158,7 @@ git clone https://ipfs.io/ipns/Qmed4r8yrBP162WK1ybd1DJWhLUi4t6mGuBoB9fLtjxR7u nv # bash ./patch.sh -h SYNOPSIS - patch.sh [-s] [-r|-h|-c VERSION|-l] + patch.sh [-s] [-r|-h|-c VERSION|-l|-f] DESCRIPTION The patch for Nvidia drivers to remove NVENC session limit @@ -169,6 +171,7 @@ DESCRIPTION -l List supported driver versions -d VERSION Use VERSION driver version when looking for libraries instead of using nvidia-smi to detect it. + -f Enable support for Flatpak NVIDIA drivers. ``` @@ -176,7 +179,7 @@ DESCRIPTION # bash ./patch-fbc.sh -h SYNOPSIS - patch-fbc.sh [-s] [-r|-h|-c VERSION|-l] + patch-fbc.sh [-s] [-r|-h|-c VERSION|-l|-f] DESCRIPTION The patch for Nvidia drivers to allow FBC on consumer devices @@ -189,7 +192,7 @@ DESCRIPTION -l List supported driver versions -d VERSION Use VERSION driver version when looking for libraries instead of using nvidia-smi to detect it. - + -f Enable support for Flatpak NVIDIA drivers. ``` @@ -247,6 +250,22 @@ Essentially all you need to do during build is: `docker-entrypoint.sh` script does on-the-fly patching by means of manipulating dynamic linker to workaround read-only mount of Nvidia runtime. Finally it passes original docker command to shell, like if entrypoint was not restricted by `ENTRYPOINT` directive. So `docker run --runtime=nvidia -it mycontainer echo 123` will print `123`. Also it can be just invoked from your entrypoint script, if you have any. +## Flatpak support + +If you use a Flatpak app that uses NVENC/NvFBC (e.g. OBS Studio, Kdenlive), it's recommended that you patch the NVIDIA drivers for Flatpak as well. To do so, just pass the `-f` parameter to either `patch.sh` or `patch-fbc.sh`, like so: + +```bash +bash ./patch.sh -f +bash ./patch-fbc.sh -f +``` + +In case something goes wrong, you can restore the original Flatpak drivers by adding the `-r` paramater: + +``` +bash ./patch.sh -f -r +bash ./patch-fbc.sh -f -r +``` + ## Benchmarks * [Plex Media Server: nVidia Hardware Transcoding Calculator for Plex Estimates](https://www.elpamsoft.com/?p=Plex-Hardware-Transcoding) - useful benchmark of achieved simultaneous transcodes with various stream quality and hardware with patched drivers. diff --git a/patch-fbc.sh b/patch-fbc.sh index abe0c6c..518d751 100755 --- a/patch-fbc.sh +++ b/patch-fbc.sh @@ -7,10 +7,12 @@ set -euo pipefail ; # <- this semicolon and comment make options apply backup_path="/opt/nvidia/libnvidia-fbc-backup" silent_flag='' manual_driver_version='' +flatpak_flag='' +backup_suffix='' print_usage() { printf ' SYNOPSIS - patch-fbc.sh [-s] [-r|-h|-c VERSION|-l] + patch-fbc.sh [-s] [-r|-h|-c VERSION|-l|-f] DESCRIPTION The patch for Nvidia drivers to allow FBC on consumer devices @@ -23,14 +25,14 @@ DESCRIPTION -l List supported driver versions -d VERSION Use VERSION driver version when looking for libraries instead of using nvidia-smi to detect it. - + -f Enable support for Flatpak NVIDIA drivers. ' } # shellcheck disable=SC2209 opmode="patch" -while getopts 'rshc:ld:' flag; do +while getopts 'rshc:ld:f' flag; do case "${flag}" in r) opmode="${opmode}rollback" ;; s) silent_flag='true' ;; @@ -38,6 +40,7 @@ while getopts 'rshc:ld:' flag; do c) opmode="${opmode}checkversion" ; checked_version="$OPTARG" ;; l) opmode="${opmode}listversions" ;; d) manual_driver_version="$OPTARG" ;; + f) flatpak_flag='true' ;; *) echo "Incorrect option specified in command line" ; exit 2 ;; esac done @@ -46,6 +49,11 @@ if [[ $silent_flag ]]; then exec 1> /dev/null fi +if [[ $flatpak_flag ]]; then + backup_suffix='.flatpak' + echo "WARNING: Flatpak flag enabled (-f), modifying ONLY the Flatpak driver." +fi + declare -A patch_list=( ["435.27.08"]='s/\x85\xc0\x89\xc3\x0f\x85\x68\xfa\xff\xff/\x31\xc0\x89\xc3\x0f\x85\x68\xfa\xff\xff/' ["440.26"]='s/\x85\xc0\x89\xc3\x0f\x85\xa9\xfa\xff\xff/\x31\xc0\x89\xc3\x0f\x85\xa9\xfa\xff\xff/' @@ -118,7 +126,9 @@ declare -A patch_list=( ["470.42.01"]='s/\x83\xfe\x01\x73\x08\x48/\x83\xfe\x00\x72\x08\x48/' ["470.57.02"]='s/\x83\xfe\x01\x73\x08\x48/\x83\xfe\x00\x72\x08\x48/' ["470.62.02"]='s/\x83\xfe\x01\x73\x08\x48/\x83\xfe\x00\x72\x08\x48/' + ["470.62.05"]='s/\x83\xfe\x01\x73\x08\x48/\x83\xfe\x00\x72\x08\x48/' ["470.63.01"]='s/\x83\xfe\x01\x73\x08\x48/\x83\xfe\x00\x72\x08\x48/' + ["470.74"]='s/\x83\xfe\x01\x73\x08\x48/\x83\xfe\x00\x72\x08\x48/' ) declare -A object_list=( @@ -193,7 +203,9 @@ declare -A object_list=( ["470.42.01"]='libnvidia-fbc.so' ["470.57.02"]='libnvidia-fbc.so' ["470.62.02"]='libnvidia-fbc.so' + ["470.62.05"]='libnvidia-fbc.so' ["470.63.01"]='libnvidia-fbc.so' + ["470.74"]='libnvidia-fbc.so' ) check_version_supported () { @@ -201,6 +213,14 @@ check_version_supported () { [[ "${patch_list[$ver]+isset}" && "${object_list[$ver]+isset}" ]] } +get_flatpak_driver_path () { + # Flatpak's package versioning replaces '.' by '-' + version="$(echo "$1" | tr '.' '-')" + if path=$(flatpak info --show-location "org.freedesktop.Platform.GL.nvidia-${version}" 2>/dev/null); then + echo "$path/files/lib" + fi +} + get_supported_versions () { for drv in "${!patch_list[@]}"; do [[ "${object_list[$drv]+isset}" ]] && echo "$drv" @@ -244,6 +264,17 @@ patch_common () { patch="${patch_list[$driver_version]}" object="${object_list[$driver_version]}" + if [[ $flatpak_flag ]]; then + driver_dir=$(get_flatpak_driver_path "$driver_version") + if [ -z "$driver_dir" ]; then + echo "ERROR: Flatpak package for driver $driver_version does not appear to be installed." + echo "Try rebooting your computer and/or running 'flatpak update'." + exit 1 + fi + # return early because the code below is out of scope for the Flatpak driver + return 0 + fi + declare -a driver_locations=( '/usr/lib/x86_64-linux-gnu' '/usr/lib/x86_64-linux-gnu/nvidia/current/' @@ -265,10 +296,10 @@ patch_common () { rollback () { patch_common - if [[ -f "$backup_path/$object.$driver_version" ]]; then - cp -p "$backup_path/$object.$driver_version" \ + if [[ -f "$backup_path/$object.$driver_version$backup_suffix" ]]; then + cp -p "$backup_path/$object.$driver_version$backup_suffix" \ "$driver_dir/$object.$driver_version" - echo "Restore from backup $object.$driver_version" + echo "Restore from backup $object.$driver_version$backup_suffix" else echo "Backup not found. Try to patch first." exit 1 @@ -277,8 +308,8 @@ rollback () { patch () { patch_common - if [[ -f "$backup_path/$object.$driver_version" ]]; then - bkp_hash="$(sha1sum "$backup_path/$object.$driver_version" | cut -f1 -d\ )" + if [[ -f "$backup_path/$object.$driver_version$backup_suffix" ]]; then + bkp_hash="$(sha1sum "$backup_path/$object.$driver_version$backup_suffix" | cut -f1 -d\ )" drv_hash="$(sha1sum "$driver_dir/$object.$driver_version" | cut -f1 -d\ )" if [[ "$bkp_hash" != "$drv_hash" ]] ; then echo "Backup exists and driver file differ from backup. Skipping patch." @@ -288,10 +319,10 @@ patch () { echo "Attention! Backup not found. Copying current $object to backup." mkdir -p "$backup_path" cp -p "$driver_dir/$object.$driver_version" \ - "$backup_path/$object.$driver_version" + "$backup_path/$object.$driver_version$backup_suffix" fi - sha1sum "$backup_path/$object.$driver_version" - sed "$patch" "$backup_path/$object.$driver_version" > \ + sha1sum "$backup_path/$object.$driver_version$backup_suffix" + sed "$patch" "$backup_path/$object.$driver_version$backup_suffix" > \ "${PATCH_OUTPUT_DIR-$driver_dir}/$object.$driver_version" sha1sum "${PATCH_OUTPUT_DIR-$driver_dir}/$object.$driver_version" ldconfig diff --git a/patch.sh b/patch.sh index ea70063..e76992b 100755 --- a/patch.sh +++ b/patch.sh @@ -7,10 +7,12 @@ set -euo pipefail ; # <- this semicolon and comment make options apply backup_path="/opt/nvidia/libnvidia-encode-backup" silent_flag='' manual_driver_version='' +flatpak_flag='' +backup_suffix='' print_usage() { printf ' SYNOPSIS - patch.sh [-s] [-r|-h|-c VERSION|-l] + patch.sh [-s] [-r|-h|-c VERSION|-l|-f] DESCRIPTION The patch for Nvidia drivers to remove NVENC session limit @@ -23,13 +25,14 @@ DESCRIPTION -l List supported driver versions -d VERSION Use VERSION driver version when looking for libraries instead of using nvidia-smi to detect it. + -f Enable support for Flatpak NVIDIA drivers. ' } # shellcheck disable=SC2209 opmode="patch" -while getopts 'rshc:ld:' flag; do +while getopts 'rshc:ld:f' flag; do case "${flag}" in r) opmode="${opmode}rollback" ;; s) silent_flag='true' ;; @@ -37,6 +40,7 @@ while getopts 'rshc:ld:' flag; do c) opmode="${opmode}checkversion" ; checked_version="$OPTARG" ;; l) opmode="${opmode}listversions" ;; d) manual_driver_version="$OPTARG" ;; + f) flatpak_flag='true' ;; *) echo "Incorrect option specified in command line" ; exit 2 ;; esac done @@ -45,6 +49,11 @@ if [[ $silent_flag ]]; then exec 1> /dev/null fi +if [[ $flatpak_flag ]]; then + backup_suffix='.flatpak' + echo "WARNING: Flatpak flag enabled (-f), modifying ONLY the Flatpak driver." +fi + declare -A patch_list=( ["375.39"]='s/\x85\xC0\x89\xC5\x75\x18/\x29\xC0\x89\xC5\x90\x90/g' ["390.77"]='s/\x85\xC0\x89\xC5\x75\x18/\x29\xC0\x89\xC5\x90\x90/g' @@ -155,7 +164,9 @@ declare -A patch_list=( ["470.42.01"]='s/\xe8\x25\x1C\xff\xff\x85\xc0\x41\x89\xc4/\xe8\x25\x1C\xff\xff\x29\xc0\x41\x89\xc4/g' ["470.57.02"]='s/\xe8\x25\x1C\xff\xff\x85\xc0\x41\x89\xc4/\xe8\x25\x1C\xff\xff\x29\xc0\x41\x89\xc4/g' ["470.62.02"]='s/\xe8\x25\x1C\xff\xff\x85\xc0\x41\x89\xc4/\xe8\x25\x1C\xff\xff\x29\xc0\x41\x89\xc4/g' + ["470.62.05"]='s/\xe8\x25\x1C\xff\xff\x85\xc0\x41\x89\xc4/\xe8\x25\x1C\xff\xff\x29\xc0\x41\x89\xc4/g' ["470.63.01"]='s/\xe8\x25\x1C\xff\xff\x85\xc0\x41\x89\xc4/\xe8\x25\x1C\xff\xff\x29\xc0\x41\x89\xc4/g' + ["470.74"]='s/\xe8\x25\x1C\xff\xff\x85\xc0\x41\x89\xc4/\xe8\x25\x1C\xff\xff\x29\xc0\x41\x89\xc4/g' ) declare -A object_list=( @@ -266,7 +277,9 @@ declare -A object_list=( ["470.42.01"]='libnvidia-encode.so' ["470.57.02"]='libnvidia-encode.so' ["470.62.02"]='libnvidia-encode.so' + ["470.62.05"]='libnvidia-encode.so' ["470.63.01"]='libnvidia-encode.so' + ["470.74"]='libnvidia-encode.so' ) check_version_supported () { @@ -274,6 +287,14 @@ check_version_supported () { [[ "${patch_list[$ver]+isset}" && "${object_list[$ver]+isset}" ]] } +get_flatpak_driver_path () { + # Flatpak's package versioning replaces '.' by '-' + version="$(echo "$1" | tr '.' '-')" + if path=$(flatpak info --show-location "org.freedesktop.Platform.GL.nvidia-${version}" 2>/dev/null); then + echo "$path/files/lib" + fi +} + get_supported_versions () { for drv in "${!patch_list[@]}"; do [[ "${object_list[$drv]+isset}" ]] && echo "$drv" @@ -317,6 +338,17 @@ patch_common () { patch="${patch_list[$driver_version]}" object="${object_list[$driver_version]}" + if [[ $flatpak_flag ]]; then + driver_dir=$(get_flatpak_driver_path "$driver_version") + if [ -z "$driver_dir" ]; then + echo "ERROR: Flatpak package for driver $driver_version does not appear to be installed." + echo "Try rebooting your computer and/or running 'flatpak update'." + exit 1 + fi + # return early because the code below is out of scope for the Flatpak driver + return 0 + fi + declare -a driver_locations=( '/usr/lib/x86_64-linux-gnu' '/usr/lib/x86_64-linux-gnu/nvidia/current/' @@ -338,10 +370,10 @@ patch_common () { rollback () { patch_common - if [[ -f "$backup_path/$object.$driver_version" ]]; then - cp -p "$backup_path/$object.$driver_version" \ + if [[ -f "$backup_path/$object.$driver_version$backup_suffix" ]]; then + cp -p "$backup_path/$object.$driver_version$backup_suffix" \ "$driver_dir/$object.$driver_version" - echo "Restore from backup $object.$driver_version" + echo "Restore from backup $object.$driver_version$backup_suffix" else echo "Backup not found. Try to patch first." exit 1 @@ -350,8 +382,8 @@ rollback () { patch () { patch_common - if [[ -f "$backup_path/$object.$driver_version" ]]; then - bkp_hash="$(sha1sum "$backup_path/$object.$driver_version" | cut -f1 -d\ )" + if [[ -f "$backup_path/$object.$driver_version$backup_suffix" ]]; then + bkp_hash="$(sha1sum "$backup_path/$object.$driver_version$backup_suffix" | cut -f1 -d\ )" drv_hash="$(sha1sum "$driver_dir/$object.$driver_version" | cut -f1 -d\ )" if [[ "$bkp_hash" != "$drv_hash" ]] ; then echo "Backup exists and driver file differ from backup. Skipping patch." @@ -361,10 +393,10 @@ patch () { echo "Attention! Backup not found. Copying current $object to backup." mkdir -p "$backup_path" cp -p "$driver_dir/$object.$driver_version" \ - "$backup_path/$object.$driver_version" + "$backup_path/$object.$driver_version$backup_suffix" fi - sha1sum "$backup_path/$object.$driver_version" - sed "$patch" "$backup_path/$object.$driver_version" > \ + sha1sum "$backup_path/$object.$driver_version$backup_suffix" + sed "$patch" "$backup_path/$object.$driver_version$backup_suffix" > \ "${PATCH_OUTPUT_DIR-$driver_dir}/$object.$driver_version" sha1sum "${PATCH_OUTPUT_DIR-$driver_dir}/$object.$driver_version" ldconfig