From 3df53e7e38470f5ebe4b5cec64221efcdac49802 Mon Sep 17 00:00:00 2001 From: Kristian Ollikainen <14197772+DatCaptainHorse@users.noreply.github.com> Date: Sun, 7 Jul 2024 12:43:58 +0300 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix(base):=20Device=20selection?= =?UTF-8?q?=20patch=20for=20gpu-screen-recorder=20(#93)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Adds new `-device` argument for gpu-screen-recorder which allows specifying a GPU to use (by `/dev/dri/cardN` path) This fixes an issue with multi-gpu systems when device such as `/dev/dri/card1` is passed through but gpu-screen-recorder will still try to access `/dev/dri/card0` for capturing and failing. Added relevant bits to `gpu_helpers.sh` to find the card path - I assume all modern modesetting drivers will have a `/drm/` path that tells the card number. If not, the script will fall back to gpu-screen-recorder's own method of finding the card. Edit: Forgot to mention patches are now copied to /tmp/ rather than /etc/ Co-authored-by: Kristian Ollikainen --- .patches/devicearg.patch | 23 +++++++++++++++++++++++ .scripts/entrypoint.sh | 12 +++++++++++- .scripts/gpu_helpers.sh | 34 ++++++++++++++++++++++++++++++++++ base.Dockerfile | 4 ++-- 4 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 .patches/devicearg.patch diff --git a/.patches/devicearg.patch b/.patches/devicearg.patch new file mode 100644 index 00000000..12fd803c --- /dev/null +++ b/.patches/devicearg.patch @@ -0,0 +1,23 @@ +diff --git a/src/main.cpp b/src/main.cpp +index 112a6ac..57bd9bf 100644 +--- a/src/main.cpp ++++ b/src/main.cpp +@@ -1906,6 +1906,7 @@ int main(int argc, char **argv) { + { "-gopm", Arg { {}, true, false } }, // deprecated, used keyint instead + { "-keyint", Arg { {}, true, false } }, + { "-encoder", Arg { {}, true, false } }, ++ { "-device", Arg { {}, true, false } }, + }; + + for(int i = 1; i < argc; i += 2) { +@@ -2226,6 +2227,10 @@ int main(int argc, char **argv) { + overclock = false; + } + ++ const char *dri_device = args["-device"].value(); ++ if (dri_device) ++ egl.dri_card_path = dri_device; ++ + egl.card_path[0] = '\0'; + if(wayland || egl.gpu_info.vendor != GSR_GPU_VENDOR_NVIDIA) { + // TODO: Allow specifying another card, and in other places diff --git a/.scripts/entrypoint.sh b/.scripts/entrypoint.sh index fedf9953..1204469e 100644 --- a/.scripts/entrypoint.sh +++ b/.scripts/entrypoint.sh @@ -115,6 +115,16 @@ selected_gpu_vendor=$(get_gpu_vendor "$selected_gpu") # Convert lshw gathered bus id into Xorg compatible one xorg_bus_id=$(get_gpu_bus_xorg "$selected_gpu") +# Get GPU card path if available +selected_gpu_card="" +gpu_screen_recorder_device_arg="" + +card_result=$(get_gpu_card "$selected_gpu") +if [[ $? -eq 0 && -n "$card_result" ]]; then + selected_gpu_card="$card_result" + gpu_screen_recorder_device_arg="-device $selected_gpu_card" +fi + # Check if the selected GPU is an NVIDIA GPU if [[ "${selected_gpu_vendor,,}" =~ "nvidia" ]]; then echo "Selected GPU is NVIDIA. Handling NVIDIA-specific configuration..." @@ -264,7 +274,7 @@ sudo chown nestri:nestri /usr/bin/gpu-screen-recorder if [[ -z "${SESSION_ID}" ]]; then echo "$(date +"[%Y-%m-%d %H:%M:%S]") No stream name was found, did you forget to set the env variable NAME?" && exit 1 else - /usr/bin/gpu-screen-recorder -v no -w screen -c flv -f "${REFRESH}" -a "$(pactl get-default-sink).monitor" | ffmpeg -hide_banner -v quiet -i pipe:0 -c copy -f mp4 -movflags empty_moov+frag_every_frame+separate_moof+omit_tfhd_offset - | /usr/bin/warp --name "${SESSION_ID}" https://fst.so:4443 & + /usr/bin/gpu-screen-recorder $gpu_screen_recorder_device_arg -v no -w screen -c flv -f "${REFRESH}" -a "$(pactl get-default-sink).monitor" | ffmpeg -hide_banner -v quiet -i pipe:0 -c copy -f mp4 -movflags empty_moov+frag_every_frame+separate_moof+omit_tfhd_offset - | /usr/bin/warp --name "${SESSION_ID}" https://fst.so:4443 & fi openbox-session & diff --git a/.scripts/gpu_helpers.sh b/.scripts/gpu_helpers.sh index eac2cf96..867fb502 100644 --- a/.scripts/gpu_helpers.sh +++ b/.scripts/gpu_helpers.sh @@ -4,6 +4,7 @@ declare -ga gpu_map declare -gA gpu_bus_map +declare -gA gpu_card_map declare -gA gpu_product_map declare -gA vendor_index_map declare -gA vendor_full_map @@ -22,6 +23,7 @@ get_gpu_info() { # Clear out previous data gpu_map=() gpu_bus_map=() + gpu_card_map=() gpu_product_map=() vendor_index_map=() vendor_full_map=() @@ -72,12 +74,19 @@ get_gpu_info() { local gpu_index="${vendor_index_map[$vendor]}" local gpu_key="$vendor:$gpu_index" + # Get /dev/dri/cardN of GPU + local gpu_card=$({ ls -1d /sys/bus/pci/devices/*${bus_info#pci@}/drm/*; } 2>&1 | grep card* | grep -oP '(?<=card)\d+') + # Store info in maps gpu_map+=("$gpu_key") gpu_bus_map["$gpu_key"]="$bus_info" gpu_product_map["$gpu_key"]="$product" vendor_full_map["$gpu_key"]="$vendor_full" + if [[ -n "$gpu_card" ]]; then + gpu_card_map["$gpu_key"]="$gpu_card" + fi + # Clear values for additional GPUs vendor="" product="" @@ -161,6 +170,12 @@ print_gpu_info() { echo " Vendor: ${vendor_full_map[$selected_gpu]}" echo " Product: ${gpu_product_map[$selected_gpu]}" echo " Bus: ${gpu_bus_map[$selected_gpu]}" + + # Check if card path was found + if [[ "${gpu_card_map[$selected_gpu]}" ]]; then + echo " Card: /dev/dri/card${gpu_card_map[$selected_gpu]}" + fi + echo } @@ -241,3 +256,22 @@ get_gpu_bus_xorg() { echo $(convert_bus_id_to_xorg "${gpu_bus_map[$selected_gpu]}") } + +get_gpu_card() { + if ! check_and_populate_gpus; then + return 1 + fi + + local selected_gpu + if ! selected_gpu=$(check_selected_gpu "$1"); then + return 1 + fi + + # Check if card path was found + if [[ -z "${gpu_card_map[$selected_gpu]}" ]]; then + echo "No card device found for GPU: $selected_gpu" >&2 + return 1 + fi + + echo "/dev/dri/card${gpu_card_map[$selected_gpu]}" +} diff --git a/base.Dockerfile b/base.Dockerfile index e5b6daf1..f23cf2bc 100644 --- a/base.Dockerfile +++ b/base.Dockerfile @@ -203,7 +203,7 @@ ENV \ # Disable VSYNC for NVIDIA GPUs __GL_SYNC_TO_VBLANK=0 -COPY .patches /etc/ +COPY .patches /tmp/ #Build and install gpu-screen-recorder RUN apt-get update -y \ @@ -259,7 +259,7 @@ RUN apt-get update -y \ && find . -maxdepth 1 -type f -name "*libnvrtc.so.*" -exec sh -c 'ln -snf $(basename {}) libnvrtc.so' \; \ && mkdir -p /usr/local/nvidia/lib && mv -f libnvrtc* /usr/local/nvidia/lib \ && git clone https://repo.dec05eba.com/gpu-screen-recorder && cd gpu-screen-recorder \ - && git apply /etc/connectcheckskip.patch \ + && git apply /tmp/connectcheckskip.patch && git apply /tmp/devicearg.patch \ && meson setup build \ && meson configure --prefix=/usr --buildtype=release -Dsystemd=true -Dstrip=true build \ && ninja -C build install