Remove the amdgpu-name admission gate from Sigil and hardware tooling. Select exact render-node/GstVA factory pairs by device binding and encoder properties, add a real bounded H.264 smoke probe, cover Intel and cross-driver discovery, and update activation documentation.
- commit
- f6cc570a803c3d7469b1369609df1cc07f85b901
- parent
- 0db73cf2aa7233277ef168f1889ebefc341dcaf1
- author
- FelineStateMachine <dami.etoile@gmail.com>
| M | crates/ | 21 | +----------- |
| M | docs/ | 52 | +++++++++++++++++------------- |
| M | docs/ | 12 | +++--- |
| M | docs/ | 50 | +++++++++++++---------------- |
| M | scripts/ | 42 | ++++++++++++++++++++++-- |
| M | scripts/ | 35 | +++++++------------- |
| M | scripts/ | 28 | +++++++--------- |
| M | scripts/ | 24 | ++++++++++++++ |
@@ -26,7 +26,7 @@ pub(super) async fn preflight_gamescope_static(config: &HostConfig) -> Result<()
2626 if pipewire.encoder_backend == GamescopeEncoderBackend::ExternalGstLaunch {2727 validate_executable("gst_launch_path", &pipewire.gst_launch_path)?;2828 }29- validate_amd_render_node(&pipewire.vaapi_render_node)?;29+ validate_render_node(&pipewire.vaapi_render_node)?;3030 3131 let terminal_sink = match pipewire.encoder_backend {3232 GamescopeEncoderBackend::ExternalGstLaunch => "fdsink",@@ -187,7 +187,7 @@ pub(crate) async fn preflight_gstreamer_element(
187187 Ok(())188188 }189189 190-fn validate_amd_render_node(path: &std::path::Path) -> Result<()> {190+fn validate_render_node(path: &std::path::Path) -> Result<()> {191191 let metadata = fs::symlink_metadata(path)192192 .with_context(|| format!("inspecting VAAPI render node {}", path.display()))?;193193 @@ -206,23 +206,6 @@ fn validate_amd_render_node(path: &std::path::Path) -> Result<()> {
206206 path.display()207207 )208208 })?;209- 210- {211- let name = path212- .file_name()213- .context("VAAPI render node has no file name")?;214- let driver = fs::canonicalize(215- std::path::Path::new("/sys/class/drm")216- .join(name)217- .join("device/driver"),218- )219- .with_context(|| format!("resolving kernel driver for {}", path.display()))?;220- ensure!(221- driver.file_name().and_then(|name| name.to_str()) == Some("amdgpu"),222- "VAAPI render node {} is not backed by amdgpu",223- path.display()224- );225- }226209 Ok(())227210 }228211 @@ -1,4 +1,4 @@
1-# Fresh Bazzite AMD host engineering setup1+# Fresh Bazzite host engineering setup22 33 This document is the maintainer lab log and hardware-acceptance source. It44 intentionally contains historical machine names, checkout paths, evidence, and@@ -6,8 +6,10 @@ development workflows. A user activating an installed package should follow
66 the portable [Sigil host activation guide](sigil-host-activation.md) shipped in77 that package instead.88 9-This runbook takes a dedicated AMD x86_64 machine from a fresh Bazzite install10-to a remotely managed Sigil host. It also defines how `slate` is used as9+This runbook takes a dedicated x86_64 machine with VA-API H.264 encoding from a10+fresh Bazzite install to a remotely managed Sigil host. The proven reference11+machine uses AMD graphics, but host admission is based on encoder capability,12+not a kernel-driver name. It also defines how `slate` is used as1113 the temporary Linux stand-in while Steps 0–2 are being built.1214 1315 The dedicated Bazzite machine is the only target for Gamescope, PipeWire,@@ -20,7 +22,7 @@ changes on `slate`.
2022 | --- | --- | --- |2123 | Development Mac | Portal client and primary source tree | Client development, tests, evidence collection |2224 | `tank@slate` | Temporary Linux stand-in | Protocol tests, pure Rust host, synthetic H.264, iroh transport, reconnect tests |23-| Dedicated Bazzite AMD host | Final appliance | Everything above plus Gamescope, PipeWire, hardware H.264, audio, and `uinput` |25+| Dedicated Bazzite host | Final appliance | Everything above plus Gamescope, PipeWire, hardware H.264, audio, and `uinput` |2426 2527 Steps 0–2 do not require Gamescope. They use a synthetic encoded source so the2628 host boundary can be proven independently. The cutover to Gamescope starts at@@ -47,7 +49,7 @@ portal --dev-connect <host-node-id>
4749 The Gamescope source uses GStreamer's `pipewiresrc` and GstVA H.264 encoder,4850 because stock upstream FFmpeg does not expose a PipeWire video input device.4951 It resolves exactly one live node from configured PipeWire properties and50-fails closed if the node, encoder factory, AMD render node, or required52+fails closed if the node, encoder factory, render-node binding, or required5153 low-latency encoder properties do not match. This implementation still needs5254 the attached-display and headless appliance gates below before it is proven on5355 the target Bazzite image.@@ -348,9 +350,10 @@ Run this while a display is still attached:
348350 ./scripts/bazzite-inventory.sh --smoke | tee "$HOME/bazzite-smoke.txt"349351 ```350352 351-The script selects the first render node whose sysfs driver is `amdgpu`; it352-does not assume `renderD128`. The equivalent individual checks are shown below353-for recovery and review:353+The script selects the first accessible render node that completes a real354+one-frame VA-API H.264 encode; it does not assume a driver name or355+`renderD128`. The equivalent individual checks are shown below for recovery356+and review:354357 355358 ```bash356359 hostnamectl@@ -367,10 +370,14 @@ ls -l /dev/dri
367370 id368371 vulkaninfo --summary369372 render_node="$({370- for node in /sys/class/drm/renderD*; do371- test -e "$node/device/driver" || continue372- test "$(basename "$(readlink -f "$node/device/driver")")" = amdgpu || continue373- printf '/dev/dri/%s\n' "$(basename "$node")"373+ for node in /dev/dri/renderD*; do374+ test -c "$node" && test -r "$node" && test -w "$node" || continue375+ ffmpeg -hide_banner -loglevel error \376+ -vaapi_device "$node" \377+ -f lavfi -i color=size=128x128:rate=1 \378+ -vf 'format=nv12,hwupload' \379+ -c:v h264_vaapi -frames:v 1 -f null - >/dev/null 2>&1 || continue380+ printf '%s\n' "$node"374381 done375382 } | head -n 1)"376383 test -n "$render_node"@@ -391,9 +398,8 @@ ffmpeg -hide_banner -loglevel warning \
391398 392399 Required observations:393400 394-- The AMD GPU uses the `amdgpu` kernel driver.395401 - The gaming user can open a `/dev/dri/renderD*` render node.396-- Vulkan selects the intended AMD GPU.402+- Vulkan selects the intended gaming GPU.397403 - VA-API exposes H.264 encoding and completes the 600-frame smoke encode.398404 - FFmpeg exposes `libx264` for the bounded synthetic Steps 0–2 source.399405 - PipeWire and Gamescope are installed.@@ -1016,7 +1022,7 @@ journalctl --user -b --no-pager | grep -Ei 'gamescope|pipewire.*node'
10161022 Gamescope should publish a PipeWire stream with both `node.name=gamescope` and10171023 `media.class=Video/Source`. Select by those properties, not by numeric node ID,10181024 because node IDs change across boots. Inventory the exact executable paths,1019-AMD render node, and dynamically registered GstVA H.264 factories:1025+render-node candidates, and dynamically registered GstVA H.264 factories:10201026 10211027 ```bash10221028 pw_dump_path="$(readlink -f "$(command -v pw-dump)")"@@ -1035,10 +1041,9 @@ for node in /sys/class/drm/renderD*; do
10351041 "$(basename "$(readlink -f "$node/device/driver")")" \10361042 "$(basename "$(readlink -f "$node/device")")"10371043 done1038-render_node="<exact AMD render node chosen from the inventory>"1044+render_node="<exact encode-capable render node chosen from the inventory>"10391045 test -n "$render_node"10401046 test -r "$render_node" && test -w "$render_node"1041-test "$(basename "$(readlink -f "/sys/class/drm/$(basename "$render_node")/device/driver")")" = amdgpu10421047 10431048 gst-inspect-1.0 | awk '10441049 $2 ~ /^va(renderD[0-9]+)?h264(lp)?enc:$/ {@@ -1348,9 +1353,9 @@ of `/proc/<pid>/exe` and the Gamescope cgroup.
13481353 `config check` performs a live, bounded preflight. It requires exactly one13491354 matching PipeWire node, checks every configured executable and required13501355 GStreamer element, opens the configured render node read/write, proves its1351-kernel driver is `amdgpu`, verifies that the selected encoder reports the same1352-device plus all low-latency properties used by the pipeline, and—when audio is1353-configured—prints the exact resolved sink target:1356+exact GstVA factory is bound to that node, and verifies all low-latency1357+properties used by the pipeline. When audio is configured, it also prints the1358+exact resolved sink target:13541359 13551360 ```bash13561361 "$HOME/.local/libexec/sigil-spark/current/sigil" config check \@@ -1586,9 +1591,10 @@ the redeemed invitation. Both runs must pass, the Sigil PID must remain
15861591 unchanged, and the host log must contain one `Gamescope Xwayland pointer15871592 feedback reconnected` event per restart. The packaged hardware UAT performs15881593 this sequence after its fixed-mode session checks. That runner independently1589-enumerates `amdgpu` render nodes and matches the exact GstVA H.264 factory by1590-its inspected `device-path`; it never assumes `renderD128` is the AMD device or1591-that the matching factory is named `vah264enc`. If the panel's resolved native1594+enumerates accessible DRM render nodes and matches the exact GstVA H.2641595+factory by its inspected `device-path` and required CBR/CQP properties; it1596+never assumes a kernel driver, `renderD128`, or the generic `vah264enc` factory.1597+If the panel's resolved native15921598 mode is the same 1280x800 mode as the fixed performance leg, the native-config15931599 leg still runs and records that the two pixel sizes are identical instead of15941600 rejecting the host.@@ -48,7 +48,7 @@ host, copy the runner to that host, then execute there:
4848 ./run-bazzite-hardware-uat.sh UAT_ROOT FULL_COMMIT WORKFLOW_RUN_ID4949 ```5050 51-If more than one exact AMD render-node/factory pair satisfies the complete UAT51+If more than one exact render-node/factory pair satisfies the complete UAT5252 contract, discovery fails closed and prints the eligible pairs. Select one pair5353 explicitly and rerun:5454 @@ -59,13 +59,13 @@ explicitly and rerun:
5959 ```6060 6161 The two override options are inseparable, and the requested pair must pass the62-same device, driver, factory binding, property, CBR, and CQP checks as automatic62+same device, factory binding, property, CBR, and CQP checks as automatic6363 selection. The runner rejects reused output directories and concurrent hardware6464 runs.65-Before generating its isolated configs, it enumerates DRM render nodes through66-sysfs, considers only nodes backed by `amdgpu`, and matches each accessible node67-to the exact dynamically registered GstVA H.264 factory whose read-only68-`device-path` names that node. The chosen factory must advertise both CBR (for65+Before generating its isolated configs, it enumerates accessible DRM render66+nodes and matches each one to the exact dynamically registered GstVA H.26467+factory whose read-only `device-path` names that node. No kernel-driver name is68+required. The chosen factory must advertise both CBR (for6969 the in-process fixed/native legs) and CQP (for the external compatibility leg).7070 The gate therefore does not assume either `/dev/dri/renderD128` or the generic7171 `vah264enc` factory. The selected pair is recorded in `summary.env`.@@ -93,11 +93,12 @@ chmod 0600 "$identity"
9393 Never copy this seed to a client or rotate it during an upgrade. Portal pairs9494 to the host identity represented by this file.9595 96-## 3. Select the exact AMD render node and GstVA H.264 factory96+## 3. Select the exact VA-API render node and GstVA H.264 factory9797 9898 Sigil binds the encoder factory to its inspected read-only `device-path`; a9999 factory name alone is not enough on a multi-GPU machine. The following chooses100-automatically only when there is one usable AMD node/factory pair. Set100+automatically only when there is one usable capability-backed node/factory101+pair, independent of its kernel driver. Set101102 `RENDER_NODE` and `VA_ENCODER` explicitly before running it when the printed102103 inventory is intentionally ambiguous.103104 @@ -131,23 +132,12 @@ bounded_gst_inspect() {
131132 rm -f -- "$output_path"132133 }133134 134-mapfile -t amd_nodes < <(135- for sysfs_node in /sys/class/drm/renderD*; do136- test -e "$sysfs_node/device/driver" || continue137- test "$(basename "$(readlink -f "$sysfs_node/device/driver")")" = amdgpu \138- || continue139- node="/dev/dri/$(basename "$sysfs_node")"135+mapfile -t render_nodes < <(136+ for node in /dev/dri/renderD*; do140137 test -c "$node" && test -r "$node" && test -w "$node" && printf '%s\n' "$node"141138 done142139 )143-printf 'AMD render node: %s\n' "${amd_nodes[@]}"144-if test -n "${RENDER_NODE:-}"; then145- render_node="$RENDER_NODE"146-else147- test "${#amd_nodes[@]}" -eq 1148- render_node="${amd_nodes[0]}"149-fi150-printf '%s\n' "${amd_nodes[@]}" | grep -Fx "$render_node"140+printf 'accessible render node: %s\n' "${render_nodes[@]}"151141 152142 registry="$(bounded_gst_inspect)"153143 mapfile -t va_factories < <(@@ -155,21 +145,25 @@ mapfile -t va_factories < <(
155145 sub(/:$/, "", $2); print $2156146 }' <<<"$registry" | sort -u157147 )158-matching_factories=()159-for factory in "${va_factories[@]}"; do160- inspection="$(bounded_gst_inspect "$factory")" || continue161- grep -Fq "Default: \"$render_node\"" <<<"$inspection" || continue162- grep -Eq '\([0-9]+\): cbr([[:space:]]|$)' <<<"$inspection" || continue163- matching_factories+=("$factory")148+eligible_pairs=()149+for node in "${render_nodes[@]}"; do150+ for factory in "${va_factories[@]}"; do151+ inspection="$(bounded_gst_inspect "$factory")" || continue152+ grep -Fq "Default: \"$node\"" <<<"$inspection" || continue153+ grep -Eq '\([0-9]+\): cbr([[:space:]]|$)' <<<"$inspection" || continue154+ eligible_pairs+=("$node $factory")155+ done164156 done165-printf 'matching CBR GstVA factory: %s\n' "${matching_factories[@]}"166-if test -n "${VA_ENCODER:-}"; then167- va_encoder="$VA_ENCODER"157+printf 'eligible CBR GstVA pair: %s\n' "${eligible_pairs[@]}"158+if test -n "${RENDER_NODE:-}" || test -n "${VA_ENCODER:-}"; then159+ test -n "${RENDER_NODE:-}" && test -n "${VA_ENCODER:-}"160+ selected_pair="$RENDER_NODE $VA_ENCODER"161+ printf '%s\n' "${eligible_pairs[@]}" | grep -Fx "$selected_pair"168162 else169- test "${#matching_factories[@]}" -eq 1170- va_encoder="${matching_factories[0]}"163+ test "${#eligible_pairs[@]}" -eq 1164+ selected_pair="${eligible_pairs[0]}"171165 fi172-printf '%s\n' "${matching_factories[@]}" | grep -Fx "$va_encoder"166+read -r render_node va_encoder <<<"$selected_pair"173167 174168 printf 'export SIGIL_RENDER_NODE=%q\n' "$render_node"175169 printf 'export SIGIL_VA_ENCODER=%q\n' "$va_encoder"@@ -15,6 +15,42 @@ optional() {
1515 fi1616 }1717 18+probe_h264_vaapi_render_node() {19+ local ffmpeg_path="$1"20+ local candidate="$2"21+22+ "$ffmpeg_path" -hide_banner -loglevel error \23+ -vaapi_device "$candidate" \24+ -f lavfi -i color=size=128x128:rate=1 \25+ -vf 'format=nv12,hwupload' \26+ -c:v h264_vaapi -frames:v 1 -f null -27+}28+29+select_h264_vaapi_render_node() {30+ local device_root="${1:-/dev/dri}"31+ local require_character="${2:-true}"32+ local ffmpeg_path33+ local candidate34+35+ render_node=''36+ ffmpeg_path="$(command -v ffmpeg)" || return 137+ for candidate in "$device_root"/renderD*; do38+ [[ "$(basename "$candidate")" =~ ^renderD[0-9]+$ ]] || continue39+ [[ -e "$candidate" && ! -L "$candidate" && -r "$candidate" && -w "$candidate" ]] \40+ || continue41+ if [[ "$require_character" == true && ! -c "$candidate" ]]; then42+ continue43+ fi44+ if probe_h264_vaapi_render_node "$ffmpeg_path" "$candidate" \45+ >/dev/null 2>&146+ then47+ render_node="$candidate"48+ return 049+ fi50+ done51+ return 152+}53+1854 gstreamer_inventory() {1955 if ! command -v gst-inspect-1.0 >/dev/null 2>&1; then2056 echo 'gstreamer_inventory=unavailable'@@ -422,10 +458,8 @@ for sysfs_node in /sys/class/drm/renderD*; do
422458 device="$(basename "$(readlink -f "$sysfs_node/device")")"423459 printf 'render_node=/dev/dri/%s driver=%s device=%s\n' \424460 "$(basename "$sysfs_node")" "$driver" "$device"425- if [[ -z "$render_node" && "$driver" == amdgpu ]]; then426- render_node="/dev/dri/$(basename "$sysfs_node")"427- fi428461 done462+select_h264_vaapi_render_node /dev/dri true || true429463 optional lspci lspci -nnk430464 optional vulkaninfo vulkaninfo --summary431465 @@ -482,7 +516,7 @@ fi
482516 if [[ "$mode" == smoke ]]; then483517 section h264_smoke484518 if [[ -z "$render_node" ]]; then485- echo "AMD render node is required for --smoke" >&2519+ echo "an accessible VA-API H.264 encode-capable render node is required for --smoke" >&2486520 exit 1487521 fi488522 ffmpeg -hide_banner -loglevel warning \@@ -85,22 +85,18 @@ classify_native_uat_mode() {
8585 fi8686 }8787 88-select_amd_gstva_h264_encoder() {88+select_gstva_h264_encoder() {8989 local gst_inspect_path="$1"90- local sysfs_root="${2:-/sys/class/drm}"91- local device_root="${3:-/dev/dri}"92- local require_character="${4:-true}"93- local override_node="${5:-}"94- local override_factory="${6:-}"95- local timeout_path="${7:?timeout command is required}"96- local output_root="${8:?bounded inspection output directory is required}"90+ local device_root="${2:-/dev/dri}"91+ local require_character="${3:-true}"92+ local override_node="${4:-}"93+ local override_factory="${5:-}"94+ local timeout_path="${6:?timeout command is required}"95+ local output_root="${7:?bounded inspection output directory is required}"9796 local factory9897 local factories9998 local factory_output10099 local inspection101- local node_name102- local sysfs_node103- local driver104100 local candidate105101 local pair106102 local candidate_count=0@@ -121,13 +117,8 @@ select_amd_gstva_h264_encoder() {
121117 }122118 ' "$output_root/gst-inspect.registry" | sort -u)" || return 1123119 124- for sysfs_node in "$sysfs_root"/renderD*; do125- [[ -e "$sysfs_node/device/driver" ]] || continue126- node_name="$(basename "$sysfs_node")"127- [[ "$node_name" =~ ^renderD[0-9]+$ ]] || continue128- driver="$(basename "$(readlink -f "$sysfs_node/device/driver")")" || continue129- [[ "$driver" == amdgpu ]] || continue130- candidate="$device_root/$node_name"120+ for candidate in "$device_root"/renderD*; do121+ [[ "$(basename "$candidate")" =~ ^renderD[0-9]+$ ]] || continue131122 [[ -e "$candidate" && ! -L "$candidate" && -r "$candidate" && -w "$candidate" ]] \132123 || continue133124 if [[ "$require_character" == true && ! -c "$candidate" ]]; then@@ -430,17 +421,17 @@ timeout_command="$(command -v timeout)"
430421 ffmpeg="$(command -v ffmpeg)"431422 [[ -S "$XDG_RUNTIME_DIR/pipewire-0" ]]432423 selection_status=0433-select_amd_gstva_h264_encoder \434- "$gst_inspect" /sys/class/drm /dev/dri true \424+select_gstva_h264_encoder \425+ "$gst_inspect" /dev/dri true \435426 "$render_node_override" "$va_encoder_override" \436427 "$timeout_command" "$private" || selection_status=$?437428 if [[ "$selection_status" -ne 0 ]]; then438429 if [[ -n "$render_node_override" ]]; then439430 echo "the requested render-node and VA-encoder pair is not eligible for this UAT" >&2440431 elif [[ "$selection_status" -eq 2 ]]; then441- echo "multiple AMD GstVA H.264 encoder pairs are eligible; select one exact pair with --render-node and --va-encoder" >&2432+ echo "multiple GstVA H.264 encoder pairs are eligible; select one exact pair with --render-node and --va-encoder" >&2442433 else443- echo "no accessible AMD render node has a GstVA H.264 factory satisfying the CBR and CQP UAT contract" >&2434+ echo "no accessible render node has a GstVA H.264 factory satisfying the CBR and CQP UAT contract" >&2444435 fi445436 if [[ -n "$va_candidates" ]]; then446437 while IFS= read -r pair; do@@ -108,24 +108,21 @@ chmod 0755 "$bin/timeout"
108108 export SIGIL_TEST_FACTORY_FIXTURE="$factory_fixture"109109 110110 select_fixture() {111- select_amd_gstva_h264_encoder \112- "$bin/gst-inspect-1.0" "$sysfs_root" "$device_root" false \111+ select_gstva_h264_encoder \112+ "$bin/gst-inspect-1.0" "$device_root" false \113113 "${1:-}" "${2:-}" "$bin/timeout" "$fixture"114114 }115115 116116 reset_render_nodes117117 add_render_node renderD128 i915118-add_render_node renderD129 amdgpu119118 printf '%s\t%s\t%s\t%s\n' \120119 vah264enc "$device_root/renderD128" cqp,cbr complete \121- varenderD129h264lpenc "$device_root/renderD129" cqp complete \122- varenderD129h264enc "$device_root/renderD129" cqp,cbr complete \123120 >"$factory_fixture"124-select_fixture || fail 'a matching non-primary AMD encoder was not selected'125-[[ "$render_node" == "$device_root/renderD129" ]] || \126- fail 'the Intel renderD128 node was selected instead of the AMD node'127-[[ "$va_encoder" == varenderD129h264enc ]] || \128- fail 'the exact CBR+CQP per-device factory was not selected'121+select_fixture || fail 'an Intel GstVA H.264 encoder was rejected by driver name'122+[[ "$render_node" == "$device_root/renderD128" ]] || \123+ fail 'the capability-backed Intel render node was not selected'124+[[ "$va_encoder" == vah264enc ]] || \125+ fail 'the factory bound to the Intel render node was not selected'129126 130127 reset_render_nodes131128 add_render_node renderD130 amdgpu@@ -137,7 +134,7 @@ select_fixture || fail 'a generic factory backed by renderD130 was not selected'
137134 fail 'selection retained a renderD128 or per-device factory assumption'138135 139136 reset_render_nodes140-add_render_node renderD128 amdgpu137+add_render_node renderD128 i915141138 add_render_node renderD129 amdgpu142139 printf '%s\t%s\t%s\t%s\n' \143140 vah264enc "$device_root/renderD128" cqp,cbr complete \@@ -145,7 +142,8 @@ printf '%s\t%s\t%s\t%s\n' \
145142 >"$factory_fixture"146143 selection_status=0147144 select_fixture || selection_status=$?148-[[ "$selection_status" -eq 2 ]] || fail 'two viable AMD pairs were not ambiguous'145+[[ "$selection_status" -eq 2 ]] || \146+ fail 'two viable cross-driver pairs were not ambiguous'149147 [[ -z "$render_node" && -z "$va_encoder" ]] || \150148 fail 'ambiguous discovery retained a silent first selection'151149 grep -Fxq "$device_root/renderD128 vah264enc" <<<"$va_candidates" || \@@ -168,7 +166,7 @@ printf '%s\t%s\t%s\t%s\n' \
168166 vah264enc "$device_root/renderD129" cqp,cbr complete \169167 >"$factory_fixture"170168 if select_fixture; then171- fail 'a factory whose device-path mismatched the AMD node was accepted'169+ fail 'a factory whose device-path mismatched the render node was accepted'172170 fi173171 174172 for modes in cqp cbr; do@@ -222,8 +220,8 @@ if select_fixture; then
222220 fi223221 rm -f -- "$device_root/renderD130"224222 install -m 0600 /dev/null "$device_root/renderD130"225-if select_amd_gstva_h264_encoder \226- "$bin/gst-inspect-1.0" "$sysfs_root" "$device_root" true '' '' \223+if select_gstva_h264_encoder \224+ "$bin/gst-inspect-1.0" "$device_root" true '' '' \227225 "$bin/timeout" "$fixture"228226 then229227 fail 'a regular file was accepted as a production DRM character device'@@ -60,6 +60,19 @@ fi
6060 printf '1.26.11\n'6161 EOF6262 chmod 0755 "$temp_root/bin/pkg-config"63+cat >"$temp_root/bin/ffmpeg" <<'EOF'64+#!/usr/bin/env bash65+set -euo pipefail66+while [[ $# -gt 0 ]]; do67+ if [[ "$1" == -vaapi_device && $# -ge 2 ]]; then68+ [[ "$2" == "${SIGIL_TEST_VAAPI_NODE:?}" ]]69+ exit70+ fi71+ shift72+done73+exit 174+EOF75+chmod 0755 "$temp_root/bin/ffmpeg"6376 6477 PATH="$temp_root/bin:$PATH"6578 export PATH@@ -74,6 +87,17 @@ missing_output="$(SIGIL_TEST_APPSINK=missing gstreamer_inventory)"
7487 grep -qxF 'gstreamer_element=appsink status=missing' <<<"$missing_output" || \7588 fail 'appsink absence was not recorded'7689 90+install -d -m 0700 "$temp_root/dev/dri"91+install -m 0600 /dev/null "$temp_root/dev/dri/renderD128"92+install -m 0600 /dev/null "$temp_root/dev/dri/renderD129"93+SIGIL_TEST_VAAPI_NODE="$temp_root/dev/dri/renderD129"94+export SIGIL_TEST_VAAPI_NODE95+render_node=''96+select_h264_vaapi_render_node "$temp_root/dev/dri" false || \97+ fail 'a capability-backed non-AMD render node was not selected'98+[[ "$render_node" == "$SIGIL_TEST_VAAPI_NODE" ]] || \99+ fail 'render-node selection used enumeration order instead of the encode probe'100+77101 development_output="$(SIGIL_TEST_MISSING_MODULE=gstreamer-video-1.0 \78102 gstreamer_development_inventory)"79103 grep -qxF \