diff --git a/misc/build.func b/misc/build.func index fa17adbb..827c8e0f 100644 --- a/misc/build.func +++ b/misc/build.func @@ -1205,20 +1205,36 @@ EOF declare -A seen_devices VAAPI_DEVICES=() - for bypath in /dev/dri/by-path/*-render /dev/dri/renderD* /dev/dri/card*; do + VAAPI_DEVICES=() + seen_ids=() + + for bypath in /dev/dri/by-path/*-render /dev/dri/renderD*; do [[ -e "$bypath" ]] || continue - dev_target=$(readlink -f "$bypath" 2>/dev/null || echo "$bypath") - [[ -n "${seen_devices[$dev_target]}" ]] && continue - seen_devices["$dev_target"]=1 + dev_render=$(readlink -f "$bypath") || continue + id=$(basename "$dev_render") + [[ " ${seen_ids[*]} " == *" $id "* ]] && continue + seen_ids+=("$id") + + card="/dev/dri/card${id#renderD}" + combo_devices=("$dev_render") + [[ -e "$card" ]] && combo_devices+=("$card") pci_addr=$(basename "$bypath" | cut -d- -f1 --complement | sed 's/-render//' || true) pci_info=$(lspci -nn | grep "${pci_addr#0000:}" || true) name="${pci_info#*: }" [[ -z "$name" ]] && name="Unknown GPU ($pci_addr)" - label="$(basename "$dev_target") - $name" - VAAPI_DEVICES+=("$dev_target" "$label" "OFF") + label="$(basename "$dev_render")" + [[ -e "$card" ]] && label+=" + $(basename "$card")" + label+=" – $name" + + # Encode both devices with ":" separated, e.g.: /dev/dri/renderD128:/dev/dri/card0 + VAAPI_DEVICES+=("$( + IFS=: + echo "${combo_devices[*]}" + )" "$label" "OFF") done + [[ -e /dev/fb0 ]] && VAAPI_DEVICES+=("/dev/fb0" "fb0 - Framebuffer" "OFF") GID_VIDEO=$(getent group video | cut -d: -f3) @@ -1259,30 +1275,40 @@ such as 'intel-media-driver', 'libva2', or 'vainfo'." 15 74 fi SELECTED_DEVICES=$(whiptail --title "VAAPI Device Selection" \ - --checklist "Select VAAPI device(s) / GPU(s) to passthrough:" 20 72 10 \ + --checklist "Select VAAPI device(s) / GPU(s) to passthrough:" 20 100 6 \ "${VAAPI_DEVICES[@]}" 3>&1 1>&2 2>&3) + WHIPTAIL_EXIT=$? + if [[ "$WHIPTAIL_EXIT" -ne 0 ]]; then + exit_script + msg_error "VAAPI passthrough selection cancelled by user." + fi + if [[ -n "$SELECTED_DEVICES" ]]; then IDX=0 DID_MOUNT_DRI=0 for dev in $SELECTED_DEVICES; do dev=$(sed 's/"//g' <<<"$dev") - if [[ "$CT_TYPE" == "0" ]]; then - if [[ "$DID_MOUNT_DRI" -eq 0 && -d /dev/dri ]]; then - echo "lxc.mount.entry: /dev/dri /dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG" - DID_MOUNT_DRI=1 + IFS=":" read -ra devices <<<"$dev" + + for d in "${devices[@]}"; do + if [[ "$CT_TYPE" == "0" ]]; then + if [[ "$DID_MOUNT_DRI" -eq 0 && -d /dev/dri ]]; then + echo "lxc.mount.entry: /dev/dri /dev/dri none bind,optional,create=dir" >>"$LXC_CONFIG" + DID_MOUNT_DRI=1 + fi + if ! major_minor=$(stat -c '%t:%T' "$d" 2>/dev/null | awk -F: '{ printf "%d:%d", "0x"$1, "0x"$2 }'); then + msg_warn "Could not stat $d – skipping." + continue + fi + echo "lxc.cgroup2.devices.allow: c $major_minor rwm" >>"$LXC_CONFIG" + echo "lxc.mount.entry: $d $d none bind,optional,create=file" >>"$LXC_CONFIG" + else + GID=$([[ "$d" =~ render ]] && echo "$GID_RENDER" || echo "$GID_VIDEO") + echo "dev${IDX}: $d,gid=${GID}" >>"$LXC_CONFIG" + IDX=$((IDX + 1)) fi - if ! major_minor=$(stat -c '%t:%T' "$dev" 2>/dev/null | awk -F: '{ printf "%d:%d", "0x"$1, "0x"$2 }'); then - msg_warn "Could not stat $dev – skipping." - continue - fi - echo "lxc.cgroup2.devices.allow: c $major_minor rwm" >>"$LXC_CONFIG" - echo "lxc.mount.entry: $dev $dev none bind,optional,create=file" >>"$LXC_CONFIG" - else - GID=$([[ "$dev" =~ render ]] && echo "$GID_RENDER" || echo "$GID_VIDEO") - echo "dev${IDX}: $dev,gid=${GID}" >>"$LXC_CONFIG" - IDX=$((IDX + 1)) - fi + done done else msg_warn "No VAAPI devices selected – passthrough skipped."