11 Commits

Author SHA1 Message Date
marfrit 5feab57b6f libva: fix runner label — actrunner-debian-aarch64-bohr
The previous commit used `debian-aarch64-bohr` for the runs-on
label, but the actual registered label is the full
`actrunner-debian-aarch64-bohr` (per @marfrit on the PR thread).
Without the `actrunner-` prefix the job would have sat in the queue
forever waiting for a runner that doesn't exist.

Renames the label in three places:

  - .gitea/workflows/build.yml — the runs-on directive itself.
  - debian/.../build-deb.sh — the comment referencing the expected
    runner, and the error message printed when the ABI sanity check
    trips (so a future debug session lands on the right runner name).
  - debian/.../changelog — the -2 entry's prose description.

Pure label rename; no behavioral or build-graph change.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 15:03:49 +02:00
marfrit 051da5e8dc libva-v4l2-request-fourier-debian: switch to debian-aarch64-bohr runner
Per @marfrit on PR #44 review: a native Debian trixie aarch64 runner
(debian-aarch64-bohr) is available — use it instead of the sysroot
hack from the previous commit.

The sysroot approach worked but was a workaround for not having the
right runner.  Native trixie runner is much cleaner:

  - libva-dev installs via apt-get directly from trixie's archive
    (2.22.0-3) — pkg-config returns trixie headers, driver compiles
    in __vaDriverInit_1_22 naturally.
  - No need to symlink libva.so.2 -> libva.so or rewrite .pc prefixes.
  - No bsdtar/ar/dpkg-deb juggling on an Arch runner that doesn't
    natively have dpkg.

Changes from PR v1:

  - .gitea/workflows/build.yml: libva-v4l2-request-fourier-debian
    runs-on: debian-aarch64-bohr (was arch-aarch64).  Build-deps
    installed via apt-get instead of pacman -Syu.

  - build-deb.sh: drop the sysroot download / pkgconfig rewrite /
    symlink block.  Keep the post-build ABI sanity check (nm -D |
    grep __vaDriverInit_1_22) — same defensive role as before, with
    an updated error message that points to the expected runner.

  - debian/.../changelog: -2 entry rewritten to describe the runner
    move instead of the sysroot.

Tested approach on boltzmann (aarch64): meson build against trixie
sysroot produces __vaDriverInit_1_22 (proves the source compiles
correctly with VA-API 1.22 headers).  Native runner build will
follow the same path, just without the explicit sysroot setup.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 14:58:37 +02:00
marfrit a1ff6de652 libva-v4l2-request-fourier-debian: pin trixie libva-dev for ABI
The libva-v4l2-request-fourier .deb shipped with the wrong VA-API
symbol export because the CI runner is Arch (libva 2.23 = VA-API
1.23) while the install target is Debian trixie (libva 2.22 = VA-API
1.22).  At compile time, <va/va.h>'s VA_MAJOR/VA_MINOR macros are
baked into the driver's __vaDriverInit_<MAJOR>_<MINOR> symbol name.
trixie's libva runtime looks up __vaDriverInit_1_22, our driver only
exported __vaDriverInit_1_23, so dlsym() returned NULL and libva
fell back to its sentinel error "has no function __vaDriverInit_1_0".
Result: ffmpeg -hwaccel vaapi fails on startup, vainfo fails the
same way, on every Pi 5 / CM5 that installed the package.

The driver itself doesn't link libva.so (no NEEDED entry — confirmed
via readelf on higgs), so the only thing that matters is the symbol
NAME the compiler bakes in.  Fix is small: in build-deb.sh, download
trixie's libva-dev / libva2 / libva-drm2 .deb from deb.debian.org,
extract to a sysroot, rewrite the .pc prefixes, and set
PKG_CONFIG_PATH so pkg-config returns trixie headers regardless of
what the runner has installed.  The link step still resolves -lva
against the sysroot's libva.so.2, but the resulting .so has no
NEEDED entry for it.

Added a hard sanity check at the end of build-deb.sh: fail the build
if the produced .so doesn't export __vaDriverInit_1_22.  This makes
future ABI-skew failures loud at CI time instead of silent install-
then-refuse-to-load on the target.

Tested on boltzmann (aarch64): sysroot build produces a .so exporting
__vaDriverInit_1_22 (verified via nm -D).  Source unchanged from
c332d34; only the build env differs.

pkgver/upstream unchanged.  PKGREL bumped 1 -> 2 (rebuild against
pinned trixie libva-dev) so apt picks up the new .deb on higgs.

This is the LIBVA-2 unblocker — the runtime-libva-bind failure was
masking whether the LIBVA-1 per-codec dispatch actually works on
higgs.  Once -2 lands on packages.reauktion.de, apt upgrade on higgs
and the daedalus daemon log + rpi-hevc-dec dispatch can be validated
end-to-end.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 14:31:40 +02:00
marfrit 3abfdff943 libva-v4l2-request-fourier: de27e95 -> c332d34 (LIBVA-1 close)
Bumps both Arch (PKGBUILD) and Debian (build-deb.sh + changelog)
pins to upstream c332d34 — the merged LIBVA-1 PR.

Effect: Pi 5 / CM5 mixed deployment (higgs) now opens BOTH
rpi-hevc-dec and daedalus_v4l2 from one libva session and routes
per-codec — HEVC to rpi-hevc-dec ('p'), VP9 / AV1 / H.264 to the
daedalus daemon (new 'd' kind).  Before c332d34, find_codec_device
picked rpi-hevc-dec by known_decoder_drivers[] order and the
daedalus slot stayed -1, so VP9/AV1/H.264 frames failed S_FMT.

Also closes a small fd leak in RequestTerminate (daedalus pair —
caught while reviewing the alt-driver expansion).

Both packages: pkgver bumped 1.0.0.r378.c332d34, pkgrel reset to 1
(new upstream pin).  Backward-compatible on RK3399/3588 — new
branches gated by HAVE_DAEDALUS_V4L2 *and* video_fd_daedalus >= 0,
both false in those deployments.

Companion: daedalus-v4l2{,-dkms} bump 481279c landed in PR #39
(systemd unit + auto-enable).  Together they close the Pi 5 stack:
boot → modules-load.d loads daedalus_v4l2 → daedalus-v4l2.service
starts daemon → libva opens both decoders → ffmpeg -hwaccel vaapi
routes by codec.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 13:58:05 +02:00
marfrit fce33b02a2 Merge pull request 'libva-v4l2-request-fourier: restore epoch=1' (#42) from epoch-bump/libva-v4l2-request-fourier-2026-05-20 into main
Reviewed-on: marfrit/marfrit-packages#42
2026-05-20 10:58:26 +00:00
marfrit da60fa7c49 libva-v4l2-request-fourier: restore epoch=1
Installed systems carry 1:1.0.0.r361.cf8cd9d-1 from an earlier build
that had epoch=1. Current PKGBUILD ships 1.0.0.r376.de27e95-1 without
epoch, which pacman vercmp ranks BELOW the installed version, so
ohm refuses to upgrade with:

  warning: libva-v4l2-request-fourier: local (1:1.0.0.r361.cf8cd9d-1) is
  newer than marfrit (1.0.0.r376.de27e95-1)

Restoring epoch=1 fixes the monotonic version chain.
2026-05-20 12:13:32 +02:00
marfrit 20161d231f Merge pull request 'ci: skip jobs when their package version is already published' (#41) from claude-noether/marfrit-packages:claude-noether/rebuild-guard-2026-05-20 into main
Reviewed-on: marfrit/marfrit-packages#41
2026-05-20 10:05:40 +00:00
claude-noether c7bb14f369 ci: skip jobs when package already published
Wire .gitea/scripts/check-already-published.sh into every job in
build.yml. New step `skip if already published` (id: skip-check) lands
right after actions/checkout@v4 and runs the helper against the job's
recipe-dir. Subsequent steps gain `if: steps.skip-check.outputs.skip
!= '1'`, except `wipe secrets` which keeps its existing
`if: always()`.

Recipe-dir per job is taken from each job's existing `cp -r arch/...`
or `cd debian/...` line — no guessing.

Effect: on push where only e.g. firefox-fourier changed, 13 jobs HEAD
the pool, see 200, and short-circuit; only firefox-fourier rebuilds.
Verified live against packages.reauktion.de — current branch tip
would skip 10/14 jobs.

Patch is text-based (no PyYAML round-trip) so comments and blank
lines stay where they were. Diff is 190 lines added, 0 removed.
2026-05-20 11:48:46 +02:00
claude-noether f8d1257d35 ci: add check-already-published helper script
CI currently rebuilds every recipe on every push. distcc-avahi hasn't
changed in weeks but still burns runner-time. Add a small bash helper
that takes a recipe dir (arch/<n> or debian/<n>), resolves the expected
pool URL on packages.reauktion.de, and prints `skip=1` or `skip=0`.

Live-tested against all 14 recipes. Sources PKGBUILDs in a sandboxed
subshell so epoch=, ${_pkgver/-/}, and pkgname=() arrays resolve
correctly. For debian/*, extracts top-level PKGVER/PKGREL lines with
an awk guard that rejects command-subst and embedded-command
assignments (avoids false-positive matches against HEREDOC-quoted
dkms.conf content).

Wiring into build.yml lands in the next commit.
2026-05-20 11:47:24 +02:00
marfrit f3b1087ac7 Merge pull request 'mesa-panvk-bifrost: new package — Vulkan-compositor Brave for Bifrost SBCs' (#40) from claude-noether/marfrit-packages:noether/mesa-panvk-bifrost into main
Reviewed-on: marfrit/marfrit-packages#40
2026-05-20 09:08:17 +00:00
marfrit 489d6e3862 mesa-panvk-bifrost: new package — Vulkan-compositor Brave for Bifrost SBCs
iter9 of the panvk-bifrost campaign — operator-confirmed Vulkan output
on PineTab2 (Mali-G52 r1 MC1) 2026-05-20.

Patches Mesa 26.0.6's PanVk Vulkan driver:
  - VK_KHR/EXT_robustness2 + nullDescriptor exposed for PAN_ARCH 6/7
  - has_vk1_1 / has_vk1_2 = true on Bifrost
Patches applied via sed in PKGBUILD prepare() (cleaner than maintaining
a Mesa fork for two two-line tweaks; upstream context drifts between
Mesa releases would make a literal .patch brittle).

Co-installs at /usr/lib/panvk-bifrost/ — stock mesa untouched. Stock
libvulkan_panfrost.so and its ICD JSON keep working for everyone not
opting into the patched driver.

Ships /usr/bin/brave-vulkan that wires up:
  VK_ICD_FILENAMES=/usr/lib/panvk-bifrost/icd.json
  PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1
  MESA_VK_VERSION_OVERRIDE=1.2     # ANGLE needs apiVersion>=1.1; the
                                   # has_vk1_x flags don't move it, so
                                   # the env-var override carries that
  brave --use-gl=disabled --enable-features=Vulkan --use-vulkan=native
        --ozone-platform=x11 --no-sandbox --disable-gpu-sandbox
        --ignore-gpu-blocklist "$@"

Side-steps the stock "GLES3 is unsupported / GPU process exits" failure
documented in panvk-bifrost/README's "Consumer-side benefit" section.

Known limitation: WebGL/WebGL2 in-page won't work — ANGLE needs GLES3
which needs VK_EXT_transform_feedback, which PanVk-Bifrost doesn't
currently support. Browser chrome + standard page rendering work fine.

Gitea Actions job mesa-panvk-bifrost-aarch64 added to build.yml,
patterned on libva-v4l2-request-fourier-aarch64. Mesa build is slow
(~30-60min on actrunner-aarch64). Standalone (no needs:),
continue-on-error so it doesn't block other jobs.

Campaign artifacts: ~/src/panvk-bifrost/{README.md, phase8_iteration9_close.md,
phase0_evidence/iter9_brave_vulkan_breakthrough.txt}.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 11:03:59 +02:00
11 changed files with 1012 additions and 15 deletions
+210
View File
@@ -0,0 +1,210 @@
#!/bin/bash
# check-already-published.sh <recipe-dir>
#
# Decide whether a given recipe (arch/<name> or debian/<name>) is already
# present in https://packages.reauktion.de/. Emits exactly one line to
# stdout:
#
# skip=1 — package with this version-pkgrel-arch tuple already lives in
# the pool; CI should short-circuit.
# skip=0 — file is missing or HEAD failed; CI should build + publish.
#
# Design notes:
# * For Arch recipes we source the PKGBUILD in a clean subshell so
# shell expansions (epoch=, ${_pkgver/-/}, pkgname=() arrays) resolve
# naturally. Only the first element of pkgname[] is checked — split
# packages share one source tarball / one build, so any-one-missing
# forces the full rebuild anyway.
# * For Debian recipes we extract the bare top-level PKGVER= /
# PKGREL= assignments (plus any other top-level VAR=value lines they
# reference) via grep and re-evaluate them in an isolated subshell —
# sourcing the entire build-deb.sh would run curl/tar/dpkg-deb
# against a tempdir we don't want to materialise here.
# * Epoch handling differs by ecosystem: Arch keeps `<epoch>:` in the
# pool filename, Debian/reprepro strips it.
# * curl --head with -f maps non-2xx to non-zero exit, which is what we
# want — 404 means "build it". -L follows mirrors. --max-time caps
# the worst-case latency per HEAD.
set -euo pipefail
REPO_BASE="${REPO_BASE:-https://packages.reauktion.de}"
HEAD_TIMEOUT="${HEAD_TIMEOUT:-15}"
RECIPE_DIR="${1:?usage: $0 <recipe-dir> (e.g. arch/distcc-avahi or debian/lmcp)}"
# Resolve relative to repo root if a leading path is passed; allow
# both `arch/foo` and absolute paths.
if [ ! -d "$RECIPE_DIR" ]; then
echo "error: recipe dir not found: $RECIPE_DIR" >&2
exit 2
fi
ecosystem="${RECIPE_DIR%%/*}"
http_head() {
local url="$1"
curl -sS -L --max-time "$HEAD_TIMEOUT" -o /dev/null \
-w '%{http_code}' --head "$url" || echo "000"
}
emit() {
# one-line GITHUB_OUTPUT-compatible kv
echo "skip=$1"
exit 0
}
case "$ecosystem" in
arch)
pkgbuild="$RECIPE_DIR/PKGBUILD"
[ -f "$pkgbuild" ] || { echo "error: $pkgbuild missing" >&2; exit 2; }
# Source in a fresh bash to capture variables. Some PKGBUILDs run
# functions or call commands at top level — keep this fast by
# restricting PATH and trapping side effects.
eval "$(
bash --noprofile --norc -c "
set +e
# Stub out anything that might shell out; we only need variable
# assignments to land.
cd '$RECIPE_DIR'
source ./PKGBUILD >/dev/null 2>&1 || true
# pkgname may be array; print first element.
if declare -p pkgname 2>/dev/null | grep -q 'declare -a'; then
first_name=\"\${pkgname[0]}\"
else
first_name=\"\$pkgname\"
fi
if declare -p arch 2>/dev/null | grep -q 'declare -a'; then
first_arch=\"\${arch[0]}\"
else
first_arch=\"\$arch\"
fi
printf 'PB_NAME=%q\n' \"\$first_name\"
printf 'PB_VER=%q\n' \"\$pkgver\"
printf 'PB_REL=%q\n' \"\$pkgrel\"
printf 'PB_EPOCH=%q\n' \"\${epoch:-}\"
printf 'PB_ARCH=%q\n' \"\$first_arch\"
"
)"
if [ -z "${PB_NAME:-}" ] || [ -z "${PB_VER:-}" ] || [ -z "${PB_REL:-}" ]; then
echo "error: failed to parse PKGBUILD ($RECIPE_DIR)" >&2
emit 0
fi
# Pool arch:
# arch=('any') → any
# arch=('aarch64' 'x86_64') → aarch64 (we publish for both, but the
# aarch64 artifact is the canonical CI build)
# arch=('aarch64') → aarch64
case "$PB_ARCH" in
any) pool_arch=any ;;
*) pool_arch=aarch64 ;;
esac
# Version string with optional epoch (epoch:pkgver-pkgrel).
if [ -n "${PB_EPOCH:-}" ]; then
ver_full="${PB_EPOCH}:${PB_VER}-${PB_REL}"
else
ver_full="${PB_VER}-${PB_REL}"
fi
# Pool URL path (arch keeps any/aarch64 split; 'any' lands in the
# aarch64 dir per current marfrit layout — both arches share the
# blob via the publish-to-both-arches step in build.yml).
pool_dir="arch/aarch64"
base_url="${REPO_BASE}/${pool_dir}/${PB_NAME}-${ver_full}-${pool_arch}.pkg.tar"
for ext in zst xz gz; do
code=$(http_head "${base_url}.${ext}")
if [ "$code" = "200" ]; then
emit 1
fi
done
emit 0
;;
debian)
bd="$RECIPE_DIR/build-deb.sh"
ctrl="$RECIPE_DIR/control"
[ -f "$bd" ] || { echo "error: $bd missing" >&2; exit 2; }
# Pull top-level `VAR=value` lines until we've passed PKGREL, and
# only those whose RHS is safe to re-evaluate (no command
# substitution `$(...)`, no escaped `\$`, no embedded commands like
# `DESTDIR=... meson ...`). This deliberately undershoots: we just
# need PKGVER/PKGREL plus any version vars they reference. Anything
# else (HERE=$(readlink ...), KERNELVER=\$(uname -r) inside a
# HEREDOC, etc.) gets dropped.
assigns=$(awk '
/^[A-Z_][A-Z0-9_]*=/ {
# split into LHS and RHS
eq = index($0, "=")
lhs = substr($0, 1, eq - 1)
rhs = substr($0, eq + 1)
# strip inline `# comment`
hash = index(rhs, "#")
if (hash > 1 && substr(rhs, hash-1, 1) == " ") rhs = substr(rhs, 1, hash - 2)
# reject lines with command-subst or escaped-dollar or naked commands
if (rhs ~ /\$\(/) next
if (rhs ~ /\\\$/) next
if (rhs ~ / [a-z]/) next # e.g. `DESTDIR="$ROOT" meson ...`
print lhs "=" rhs
if (lhs == "PKGREL") exit
}
' "$bd")
eval "$(
bash --noprofile --norc -c "
set +e
$assigns
printf 'PKGVER=%q\n' \"\${PKGVER:-}\"
printf 'PKGREL=%q\n' \"\${PKGREL:-}\"
"
)"
if [ -z "${PKGVER:-}" ] || [ -z "${PKGREL:-}" ]; then
echo "error: failed to parse PKGVER/PKGREL from $bd" >&2
emit 0
fi
# Strip epoch (`N:` prefix) — debian pool filenames omit it.
ver_no_epoch="${PKGVER#*:}"
# If PKGVER had no colon, ${PKGVER#*:} returns PKGVER unchanged (bash quirk:
# the pattern must match for the prefix to be stripped). Guard explicitly.
case "$PKGVER" in
*:*) : ;;
*) ver_no_epoch="$PKGVER" ;;
esac
ver_full="${ver_no_epoch}-${PKGREL}"
# Architecture: parse control's `Architecture:` field.
if [ ! -f "$ctrl" ]; then
# Some recipes ship debian/control instead of ./control
ctrl="$RECIPE_DIR/debian/control"
fi
ctrl_arch=$(grep -m1 '^Architecture:' "$ctrl" 2>/dev/null | awk '{print $2}')
case "$ctrl_arch" in
all) file_arch=all ;;
arm64|any) file_arch=arm64 ;;
amd64) file_arch=amd64 ;;
*) file_arch=arm64 ;; # conservative default
esac
pkg_name=$(basename "$RECIPE_DIR")
first_letter="${pkg_name:0:1}"
url="${REPO_BASE}/debian/pool/main/${first_letter}/${pkg_name}/${pkg_name}_${ver_full}_${file_arch}.deb"
code=$(http_head "$url")
if [ "$code" = "200" ]; then
emit 1
fi
emit 0
;;
*)
echo "error: unsupported ecosystem '$ecosystem' (recipe-dir=$RECIPE_DIR)" >&2
emit 0
;;
esac
+320 -4
View File
@@ -16,13 +16,23 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh arch/distcc-avahi)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: bootstrap runner (idempotent) - name: bootstrap runner (idempotent)
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo avahi popt python python-setuptools retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo avahi popt python python-setuptools
- name: import signing key - name: import signing key
if: steps.skip-check.outputs.skip != '1'
env: env:
PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }} PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }}
PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }} PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }}
@@ -37,6 +47,7 @@ jobs:
echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust
- name: install deploy ssh key - name: install deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env: env:
KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }} KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }}
run: | run: |
@@ -46,6 +57,7 @@ jobs:
ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null
- name: makepkg distcc-avahi - name: makepkg distcc-avahi
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
rm -rf /tmp/build-distcc-avahi rm -rf /tmp/build-distcc-avahi
@@ -56,6 +68,7 @@ jobs:
ls -la *.pkg.tar.* | grep -v "\.sig$" ls -la *.pkg.tar.* | grep -v "\.sig$"
- name: sign distcc-avahi - name: sign distcc-avahi
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
cd /tmp/build-distcc-avahi cd /tmp/build-distcc-avahi
@@ -66,6 +79,7 @@ jobs:
done done
- name: update aarch64 repo db - name: update aarch64 repo db
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
mkdir -p /tmp/arch-stage mkdir -p /tmp/arch-stage
@@ -105,6 +119,7 @@ jobs:
rm -f marfrit.files.sig rm -f marfrit.files.sig
- name: publish to aarch64 - name: publish to aarch64
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
@@ -129,13 +144,23 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh debian/lmcp)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: install dpkg - name: install dpkg
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed dpkg openssh rsync curl retry pacman -Syu --noconfirm --needed dpkg openssh rsync curl
- name: install hertz deploy ssh key - name: install hertz deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env: env:
KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }} KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }}
run: | run: |
@@ -145,6 +170,7 @@ jobs:
ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null
- name: build lmcp .deb - name: build lmcp .deb
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
cd debian/lmcp cd debian/lmcp
@@ -152,6 +178,7 @@ jobs:
ls -la *.deb ls -la *.deb
- name: upload + publish to suites - name: upload + publish to suites
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
@@ -182,13 +209,23 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh arch/lmcp)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: bootstrap runner (idempotent) - name: bootstrap runner (idempotent)
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo lua lua-socket retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo lua lua-socket
- name: import signing key - name: import signing key
if: steps.skip-check.outputs.skip != '1'
env: env:
PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }} PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }}
PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }} PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }}
@@ -203,6 +240,7 @@ jobs:
echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust
- name: install deploy ssh key - name: install deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env: env:
KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }} KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }}
run: | run: |
@@ -212,6 +250,7 @@ jobs:
ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null
- name: makepkg lmcp - name: makepkg lmcp
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
rm -rf /tmp/build-lmcp rm -rf /tmp/build-lmcp
@@ -222,6 +261,7 @@ jobs:
ls -la *.pkg.tar.* | grep -v "\.sig$" ls -la *.pkg.tar.* | grep -v "\.sig$"
- name: sign lmcp - name: sign lmcp
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
cd /tmp/build-lmcp cd /tmp/build-lmcp
@@ -232,6 +272,7 @@ jobs:
done done
- name: publish lmcp to both arches - name: publish lmcp to both arches
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
@@ -283,13 +324,23 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh arch/claude-his-agent)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: bootstrap runner (idempotent) - name: bootstrap runner (idempotent)
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo
- name: import signing key - name: import signing key
if: steps.skip-check.outputs.skip != '1'
env: env:
PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }} PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }}
PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }} PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }}
@@ -304,6 +355,7 @@ jobs:
echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust
- name: install deploy ssh key - name: install deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env: env:
KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }} KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }}
run: | run: |
@@ -313,6 +365,7 @@ jobs:
ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null
- name: makepkg claude-his-agent - name: makepkg claude-his-agent
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
rm -rf /tmp/build-his rm -rf /tmp/build-his
@@ -323,6 +376,7 @@ jobs:
ls -la *.pkg.tar.* | grep -v "\.sig$" ls -la *.pkg.tar.* | grep -v "\.sig$"
- name: sign claude-his-agent - name: sign claude-his-agent
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
cd /tmp/build-his cd /tmp/build-his
@@ -333,6 +387,7 @@ jobs:
done done
- name: publish claude-his-agent to both arches - name: publish claude-his-agent to both arches
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
@@ -387,13 +442,23 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh arch/ffmpeg-v4l2-request-fourier)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: bootstrap runner (idempotent) - name: bootstrap runner (idempotent)
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo nasm retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo nasm
- name: import signing key - name: import signing key
if: steps.skip-check.outputs.skip != '1'
env: env:
PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }} PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }}
PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }} PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }}
@@ -408,6 +473,7 @@ jobs:
echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust
- name: install deploy ssh key - name: install deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env: env:
KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }} KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }}
run: | run: |
@@ -417,6 +483,7 @@ jobs:
ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null
- name: makepkg ffmpeg-v4l2-request-fourier - name: makepkg ffmpeg-v4l2-request-fourier
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
rm -rf /tmp/build-ffmpeg-v4l2 rm -rf /tmp/build-ffmpeg-v4l2
@@ -430,6 +497,7 @@ jobs:
ls -la *.pkg.tar.* | grep -v "\.sig$" ls -la *.pkg.tar.* | grep -v "\.sig$"
- name: sign ffmpeg-v4l2-request-fourier - name: sign ffmpeg-v4l2-request-fourier
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
cd /tmp/build-ffmpeg-v4l2 cd /tmp/build-ffmpeg-v4l2
@@ -440,6 +508,7 @@ jobs:
done done
- name: update aarch64 repo db - name: update aarch64 repo db
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
mkdir -p /tmp/arch-stage-ffmpeg mkdir -p /tmp/arch-stage-ffmpeg
@@ -475,6 +544,7 @@ jobs:
rm -f marfrit.files.sig rm -f marfrit.files.sig
- name: publish to aarch64 - name: publish to aarch64
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
@@ -500,13 +570,23 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh arch/libva-v4l2-request-fourier)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: bootstrap runner (idempotent) - name: bootstrap runner (idempotent)
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo
- name: import signing key - name: import signing key
if: steps.skip-check.outputs.skip != '1'
env: env:
PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }} PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }}
PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }} PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }}
@@ -521,6 +601,7 @@ jobs:
echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust
- name: install deploy ssh key - name: install deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env: env:
KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }} KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }}
run: | run: |
@@ -530,6 +611,7 @@ jobs:
ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null
- name: makepkg libva-v4l2-request-fourier - name: makepkg libva-v4l2-request-fourier
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
rm -rf /tmp/build-libva-v4l2 rm -rf /tmp/build-libva-v4l2
@@ -541,6 +623,7 @@ jobs:
ls -la *.pkg.tar.* | grep -v "\.sig$" ls -la *.pkg.tar.* | grep -v "\.sig$"
- name: sign libva-v4l2-request-fourier - name: sign libva-v4l2-request-fourier
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
cd /tmp/build-libva-v4l2 cd /tmp/build-libva-v4l2
@@ -551,6 +634,7 @@ jobs:
done done
- name: update aarch64 repo db - name: update aarch64 repo db
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
mkdir -p /tmp/arch-stage-libva mkdir -p /tmp/arch-stage-libva
@@ -586,6 +670,7 @@ jobs:
rm -f marfrit.files.sig rm -f marfrit.files.sig
- name: publish to aarch64 - name: publish to aarch64
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
@@ -611,13 +696,23 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh arch/mpv-fourier)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: bootstrap runner (idempotent) - name: bootstrap runner (idempotent)
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo
- name: import signing key - name: import signing key
if: steps.skip-check.outputs.skip != '1'
env: env:
PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }} PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }}
PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }} PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }}
@@ -632,6 +727,7 @@ jobs:
echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust
- name: install deploy ssh key - name: install deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env: env:
KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }} KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }}
run: | run: |
@@ -641,6 +737,7 @@ jobs:
ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null
- name: configure [marfrit] repo + pre-install ffmpeg-v4l2-request-fourier - name: configure [marfrit] repo + pre-install ffmpeg-v4l2-request-fourier
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
# mpv-fourier links libavcodec at build time. If the build host pulls # mpv-fourier links libavcodec at build time. If the build host pulls
@@ -668,6 +765,7 @@ jobs:
printf 'y\ny\ny\n' | pacman -S marfrit/ffmpeg-v4l2-request-fourier printf 'y\ny\ny\n' | pacman -S marfrit/ffmpeg-v4l2-request-fourier
- name: makepkg mpv-fourier - name: makepkg mpv-fourier
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
rm -rf /tmp/build-mpv rm -rf /tmp/build-mpv
@@ -679,6 +777,7 @@ jobs:
ls -la *.pkg.tar.* | grep -v "\.sig$" ls -la *.pkg.tar.* | grep -v "\.sig$"
- name: sign mpv-fourier - name: sign mpv-fourier
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
cd /tmp/build-mpv cd /tmp/build-mpv
@@ -689,6 +788,7 @@ jobs:
done done
- name: update aarch64 repo db - name: update aarch64 repo db
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
mkdir -p /tmp/arch-stage-mpv mkdir -p /tmp/arch-stage-mpv
@@ -724,6 +824,7 @@ jobs:
rm -f marfrit.files.sig rm -f marfrit.files.sig
- name: publish to aarch64 - name: publish to aarch64
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
@@ -746,13 +847,23 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh debian/claude-his-agent)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: install dpkg - name: install dpkg
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed dpkg openssh rsync curl retry pacman -Syu --noconfirm --needed dpkg openssh rsync curl
- name: install hertz deploy ssh key - name: install hertz deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env: env:
KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }} KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }}
run: | run: |
@@ -762,6 +873,7 @@ jobs:
ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null
- name: build claude-his-agent .deb - name: build claude-his-agent .deb
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
cd debian/claude-his-agent cd debian/claude-his-agent
@@ -769,6 +881,7 @@ jobs:
ls -la *.deb ls -la *.deb
- name: upload + publish to suites - name: upload + publish to suites
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
@@ -798,7 +911,16 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh debian/ffmpeg-v4l2-request-fourier)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: install build-deps (Arch pkg names; build-deb.sh links natively) - name: install build-deps (Arch pkg names; build-deb.sh links natively)
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
@@ -809,6 +931,7 @@ jobs:
libvorbis libvpx libwebp x264 x265 libxml2 opus v4l-utils xz zlib libvorbis libvpx libwebp x264 x265 libxml2 opus v4l-utils xz zlib
- name: install hertz deploy ssh key - name: install hertz deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env: env:
KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }} KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }}
run: | run: |
@@ -818,6 +941,7 @@ jobs:
ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null
- name: build ffmpeg-v4l2-request-fourier .deb - name: build ffmpeg-v4l2-request-fourier .deb
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
cd debian/ffmpeg-v4l2-request-fourier cd debian/ffmpeg-v4l2-request-fourier
@@ -825,6 +949,7 @@ jobs:
ls -la *.deb ls -la *.deb
- name: upload + publish to suites - name: upload + publish to suites
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
@@ -846,20 +971,38 @@ jobs:
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
libva-v4l2-request-fourier-debian: libva-v4l2-request-fourier-debian:
needs: libva-v4l2-request-fourier-aarch64 needs: libva-v4l2-request-fourier-aarch64
runs-on: arch-aarch64 # Native Debian trixie runner — the driver bakes __vaDriverInit_1_<MINOR>
# at compile time from <va/va.h>. Building on Arch (libva 2.23) produced
# __vaDriverInit_1_23, which trixie's libva 2.22 runtime cannot bind: the
# .deb installed but vaInitialize() returned -1 on every host. A native
# trixie runner avoids the cross-distro ABI skew entirely.
runs-on: actrunner-debian-aarch64-bohr
continue-on-error: true continue-on-error: true
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh debian/libva-v4l2-request-fourier)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: install build-deps - name: install build-deps
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed \ export DEBIAN_FRONTEND=noninteractive
dpkg openssh rsync curl base-devel git meson ninja pkgconf \ retry apt-get update -qq
libva libdrm systemd-libs retry apt-get install -y --no-install-recommends \
build-essential meson ninja-build pkg-config \
libva-dev libdrm-dev \
curl openssh-client rsync ca-certificates git dpkg-dev
- name: install hertz deploy ssh key - name: install hertz deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env: env:
KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }} KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }}
run: | run: |
@@ -869,6 +1012,7 @@ jobs:
ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null
- name: build libva-v4l2-request-fourier .deb - name: build libva-v4l2-request-fourier .deb
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
cd debian/libva-v4l2-request-fourier cd debian/libva-v4l2-request-fourier
@@ -876,6 +1020,7 @@ jobs:
ls -la *.deb ls -la *.deb
- name: upload + publish to suites - name: upload + publish to suites
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
@@ -905,7 +1050,16 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh debian/mpv-fourier)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: install build-deps - name: install build-deps
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
@@ -921,6 +1075,7 @@ jobs:
vulkan-icd-loader wayland zlib vulkan-icd-loader wayland zlib
- name: configure [marfrit] repo + pre-install ffmpeg-v4l2-request-fourier - name: configure [marfrit] repo + pre-install ffmpeg-v4l2-request-fourier
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
curl -sLo /tmp/marfrit.gpg https://packages.reauktion.de/marfrit.gpg curl -sLo /tmp/marfrit.gpg https://packages.reauktion.de/marfrit.gpg
@@ -935,6 +1090,7 @@ jobs:
printf 'y\ny\ny\n' | pacman -S marfrit/ffmpeg-v4l2-request-fourier printf 'y\ny\ny\n' | pacman -S marfrit/ffmpeg-v4l2-request-fourier
- name: install hertz deploy ssh key - name: install hertz deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env: env:
KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }} KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }}
run: | run: |
@@ -944,6 +1100,7 @@ jobs:
ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null
- name: build mpv-fourier .deb - name: build mpv-fourier .deb
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
cd debian/mpv-fourier cd debian/mpv-fourier
@@ -951,6 +1108,7 @@ jobs:
ls -la *.deb ls -la *.deb
- name: upload + publish to suites - name: upload + publish to suites
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
@@ -978,7 +1136,16 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh debian/daedalus-v4l2)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: install build-deps (sans ffmpeg — see [marfrit] step) - name: install build-deps (sans ffmpeg — see [marfrit] step)
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
@@ -994,6 +1161,7 @@ jobs:
libdrm libdrm
- name: ensure ffmpeg-v4l2-request-fourier installed (link-time ABI source) - name: ensure ffmpeg-v4l2-request-fourier installed (link-time ABI source)
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
# Idempotent: pre-install the marfrit fourier ffmpeg so cmake # Idempotent: pre-install the marfrit fourier ffmpeg so cmake
@@ -1011,6 +1179,7 @@ jobs:
printf 'y\ny\ny\n' | pacman -S --needed marfrit/ffmpeg-v4l2-request-fourier printf 'y\ny\ny\n' | pacman -S --needed marfrit/ffmpeg-v4l2-request-fourier
- name: install hertz deploy ssh key - name: install hertz deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env: env:
KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }} KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }}
run: | run: |
@@ -1020,6 +1189,7 @@ jobs:
ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null
- name: build daedalus-v4l2 .deb - name: build daedalus-v4l2 .deb
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
cd debian/daedalus-v4l2 cd debian/daedalus-v4l2
@@ -1027,6 +1197,7 @@ jobs:
ls -la *.deb ls -la *.deb
- name: upload + publish to suites - name: upload + publish to suites
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
@@ -1054,13 +1225,23 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh debian/daedalus-v4l2-dkms)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: install tooling - name: install tooling
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed dpkg openssh rsync curl tar gzip retry pacman -Syu --noconfirm --needed dpkg openssh rsync curl tar gzip
- name: install hertz deploy ssh key - name: install hertz deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env: env:
KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }} KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }}
run: | run: |
@@ -1070,6 +1251,7 @@ jobs:
ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null
- name: build daedalus-v4l2-dkms .deb - name: build daedalus-v4l2-dkms .deb
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
cd debian/daedalus-v4l2-dkms cd debian/daedalus-v4l2-dkms
@@ -1077,6 +1259,7 @@ jobs:
ls -la *.deb ls -la *.deb
- name: upload + publish to suites - name: upload + publish to suites
if: steps.skip-check.outputs.skip != '1'
run: | run: |
set -e set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; } retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
@@ -1092,3 +1275,136 @@ jobs:
- name: wipe secrets - name: wipe secrets
if: always() if: always()
run: rm -f /root/.ssh/id_ed25519_hertz run: rm -f /root/.ssh/id_ed25519_hertz
# -------------------------------------------------------------------------
# mesa-panvk-bifrost (aarch64 only) — patched Mesa libvulkan_panfrost.so
# for Bifrost-gen Mali (panvk-bifrost campaign iter9). Co-installs at
# /usr/lib/panvk-bifrost/ so stock mesa stays intact; opt-in via the
# brave-vulkan launcher this package also ships.
#
# Build is slow (~30-60min on actrunner-aarch64): full Mesa-from-source.
# Standalone job — no `needs:` since it doesn't depend on the fourier
# codec stack. continue-on-error so a build hiccup doesn't block other
# jobs in the same workflow run.
# -------------------------------------------------------------------------
mesa-panvk-bifrost-aarch64:
runs-on: arch-aarch64
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh arch/mesa-panvk-bifrost)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: bootstrap runner (idempotent)
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo
- name: import signing key
if: steps.skip-check.outputs.skip != '1'
env:
PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }}
PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }}
run: |
set -e
gpgconf --homedir /root/.gnupg --kill all 2>/dev/null || true
rm -rf /root/.gnupg /root/repo_pass
mkdir -m700 -p /root/.gnupg
printf '%s' "$PASS" > /root/repo_pass
chmod 600 /root/repo_pass
printf '%s\n' "$PRIV" | gpg --batch --import
echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust
- name: install deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env:
KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519
chmod 600 /root/.ssh/id_ed25519
ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null
- name: makepkg mesa-panvk-bifrost
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
rm -rf /tmp/build-mesa-panvk-bifrost
cp -r arch/mesa-panvk-bifrost /tmp/build-mesa-panvk-bifrost
chown -R builder:builder /tmp/build-mesa-panvk-bifrost
cd /tmp/build-mesa-panvk-bifrost
# MAKEFLAGS for parallel build; runner is multi-core.
# --skipinteg because sha256sums=SKIP in PKGBUILD (matches the
# fourier-fork PKGBUILD convention).
sudo -u builder -H env MAKEFLAGS="-j60" \
makepkg --nocheck --noconfirm --syncdeps --cleanbuild --skipinteg
ls -la *.pkg.tar.* | grep -v "\.sig$"
- name: sign mesa-panvk-bifrost
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd /tmp/build-mesa-panvk-bifrost
for f in *.pkg.tar.xz *.pkg.tar.zst *.pkg.tar.gz; do
[ -f "$f" ] || continue
gpg --batch --pinentry-mode loopback --passphrase-file /root/repo_pass \
--detach-sign --yes -u 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C "$f"
done
- name: update aarch64 repo db
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
mkdir -p /tmp/arch-stage-mesa-panvk
cd /tmp/arch-stage-mesa-panvk
rm -f *
for f in marfrit.db.tar.gz marfrit.db.tar.gz.sig marfrit.files.tar.gz marfrit.files.tar.gz.sig; do
curl -sSLf "https://packages.reauktion.de/arch/aarch64/$f" -o "$f" || rm -f "$f"
done
for ext in xz zst gz; do
ls /tmp/build-mesa-panvk-bifrost/*.pkg.tar.$ext 2>/dev/null && \
mv /tmp/build-mesa-panvk-bifrost/*.pkg.tar.$ext /tmp/build-mesa-panvk-bifrost/*.pkg.tar.$ext.sig .
done || true
export GNUPGHOME=/root/.gnupg
printf 'pinentry-mode loopback\npassphrase-file /root/repo_pass\n' > /root/.gnupg/gpg.conf
printf 'allow-loopback-pinentry\n' > /root/.gnupg/gpg-agent.conf
gpg-connect-agent reloadagent /bye
pkgs=()
for ext in xz zst gz; do
for f in *.pkg.tar.$ext; do [ -f "$f" ] && pkgs+=("$f"); done
done
if [ -f marfrit.db.tar.gz ]; then
for f in "${pkgs[@]}"; do
name=$(echo "$f" | sed -E 's/-[0-9].*//')
repo-remove --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
marfrit.db.tar.gz "$name" 2>/dev/null || true
done
fi
repo-add --new --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
--verify marfrit.db.tar.gz "${pkgs[@]}"
ln -sf marfrit.db.tar.gz marfrit.db
ln -sf marfrit.files.tar.gz marfrit.files
ln -sf marfrit.db.tar.gz.sig marfrit.db.sig
rm -f marfrit.files.sig
- name: publish to aarch64
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd /tmp/arch-stage-mesa-panvk
retry rsync -avL --copy-unsafe-links \
-e 'ssh -i /root/.ssh/id_ed25519' \
./ mfritsche@nc.reauktion.de:arch/aarch64/
- name: wipe secrets
if: always()
run: rm -f /root/repo_pass /root/.ssh/id_ed25519
+9 -6
View File
@@ -21,6 +21,7 @@
# Alternative: boltzmann via his subagent + marfrit-publish. # Alternative: boltzmann via his subagent + marfrit-publish.
pkgname=libva-v4l2-request-fourier pkgname=libva-v4l2-request-fourier
epoch=1
_upstreampkg=libva-v4l2-request _upstreampkg=libva-v4l2-request
# Pin the fork tip. de27e95 = "v4l2: log error_idx + failing ctrl id # Pin the fork tip. de27e95 = "v4l2: log error_idx + failing ctrl id
@@ -30,18 +31,20 @@ _upstreampkg=libva-v4l2-request
# H264/HEVC probe; actual VP9 stateless control SET worked all along). # H264/HEVC probe; actual VP9 stateless control SET worked all along).
# #
# Prior pin (7ac934e) was iter38b — fresnel-fourier multi-device probe # Prior pin (7ac934e) was iter38b — fresnel-fourier multi-device probe
# + MAX_PROFILES bounds-check fix. de27e95 adds the daedalus_v4l2 # + MAX_PROFILES bounds-check fix. de27e95 added the daedalus_v4l2
# probe slot (b5b3acf), the meson option gate (2146341), and the # probe slot (b5b3acf), the meson option gate (2146341), and the
# S_EXT_CTRLS diagnostic (de27e95 itself). Backward-compatible on # S_EXT_CTRLS diagnostic (de27e95 itself). c332d34 (LIBVA-1) finishes
# rkvdec / hantro / cedrus / rpi-hevc-dec hosts — daedalus probe is # the per-codec dispatch: rpi-hevc-dec + daedalus_v4l2 both probe each
# off by default unless the kernel module is present. # other as alts, VP9/AV1/H.264 route to daedalus via new 'd' kind,
_commit=de27e95571b67ef34619c23a12db4698f9b3454e # HEVC stays on 'p' (rpi-hevc-dec). Required for the Pi 5 / CM5
# mixed-decoder deployment (higgs).
_commit=c332d34643be29e88012e30878d2fbeb255b20ab
# Project version from meson.build (1.0.0) + commit count + short sha, # Project version from meson.build (1.0.0) + commit count + short sha,
# matching the ffmpeg-v4l2-request-fourier convention. Recomputed at # matching the ffmpeg-v4l2-request-fourier convention. Recomputed at
# build time by pkgver() below; the static value here is a placeholder # build time by pkgver() below; the static value here is a placeholder
# so AUR-style consumers see something coherent before src/ exists. # so AUR-style consumers see something coherent before src/ exists.
pkgver=1.0.0.r376.de27e95 pkgver=1.0.0.r378.c332d34
pkgrel=1 pkgrel=1
pkgdesc="VA-API backend for V4L2 stateless decoders (multiplanar fork — fourier umbrella)" pkgdesc="VA-API backend for V4L2 stateless decoders (multiplanar fork — fourier umbrella)"
arch=('aarch64') arch=('aarch64')
@@ -0,0 +1,57 @@
From: claude-noether (on behalf of mfritsche)
Date: 2026-05-19
Subject: panvk: expose VK_KHR/EXT_robustness2 + nullDescriptor on Bifrost (PAN_ARCH 6/7)
Without this, Mesa's Zink driver refuses to use PanVk-Bifrost as its Vulkan
backend, falling back silently to llvmpipe (software rasterizer) for all
GL-via-Zink on Bifrost SBCs. That defeats the entire purpose of having a
Vulkan driver on Bifrost — GL acceleration via Zink is the most natural
near-term consumer.
panvk_vX_nir_lower_descriptors.c:1309 and panvk_vX_shader.c:1355 already
plumb dev->vk.enabled_features.nullDescriptor arch-agnostically — the gate
at panvk_vX_physical_device.c was set conservatively when Bifrost was
unmaintained, not because of hardware incapability.
iter17 of the panvk-bifrost campaign proved fundamental driver functions
on Mali-G52 r1 MC1 (PAN_ARCH=7). This patch is the iter8 follow-up.
robustBufferAccess2 and robustImageAccess2 are NOT flipped — they're
independent rb2 features Zink doesn't require, gated differently
(robustBufferAccess2 = PAN_ARCH >= 11, robustImageAccess2 = false), and
out of scope for iter8.
---
src/panfrost/vulkan/panvk_vX_physical_device.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/panfrost/vulkan/panvk_vX_physical_device.c b/src/panfrost/vulkan/panvk_vX_physical_device.c
--- a/src/panfrost/vulkan/panvk_vX_physical_device.c
+++ b/src/panfrost/vulkan/panvk_vX_physical_device.c
@@ -91,7 +91,7 @@ get_device_extensions(const struct panvk_physical_device *device,
.KHR_pipeline_binary = true,
.KHR_pipeline_executable_properties = true,
.KHR_pipeline_library = true,
- .KHR_robustness2 = PAN_ARCH >= 10,
+ .KHR_robustness2 = true,
.KHR_sampler_mirror_clamp_to_edge = true,
.KHR_sampler_ycbcr_conversion = true,
.KHR_separate_depth_stencil_layouts = true,
@@ -168,7 +168,7 @@ get_device_extensions(const struct panvk_physical_device *device,
.EXT_queue_family_foreign = true,
.EXT_robustness = pan_arch(device->kmod.dev->props.gpu_id) >= 9,
.EXT_image_robustness = true,
- .EXT_robustness2 = PAN_ARCH >= 10,
+ .EXT_robustness2 = true,
.EXT_sampler_filter_minmax = PAN_ARCH >= 10,
.EXT_scalar_block_layout = true,
.EXT_separate_stencil_usage = true,
@@ -493,7 +493,7 @@ get_device_features(const struct panvk_physical_device *device,
/* VK_KHR_robustness2 */
.robustBufferAccess2 = PAN_ARCH >= 11,
.robustImageAccess2 = false,
- .nullDescriptor = PAN_ARCH >= 10,
+ .nullDescriptor = true,
/* VK_KHR_shader_clock */
.shaderSubgroupClock = device->kmod.dev->props.gpu_can_query_timestamp,
@@ -0,0 +1,47 @@
From: claude-noether (on behalf of mfritsche)
Date: 2026-05-20
Subject: panvk: expose Vulkan 1.1 + 1.2 on Bifrost (PAN_ARCH 6/7)
ANGLE (Chromium's GL stack) requires apiVersion >= 1.1 to initialize. Without
this, Brave / Chromium's GPU process fails at GL info collection:
vk_renderer.cpp:2659 (initialize): ANGLE Requires a minimum Vulkan device
version of 1.1
Display::initialize error 0: Internal Vulkan error (-9): The requested
version of Vulkan is not supported by the driver
Stack-up with iter8's robustness2 patch enables ANGLE → PanVk-Bifrost →
Skia (via --enable-features=Vulkan) on Bifrost SBCs.
PanVk-Bifrost already supports the bulk of 1.1-promoted features as extensions
(multiview, maintenance1-3, descriptor update template, 16-bit storage,
descriptor update template, sampler ycbcr, variable pointers, etc. — all
visible in iter0 vulkaninfo). The version bump primarily bundles them.
Risk: Vulkan 1.1 has features beyond what iter17 exercised (protected memory,
full subgroup ops). Specific app failures will be characterizable.
1.2 is also flipped — Brave's Vulkan path may want descriptor indexing,
buffer device address, etc. (all listed in iter0 vulkaninfo as supported
extensions, just gated as 1.0-with-extensions, not 1.2-core).
---
src/panfrost/vulkan/panvk_vX_physical_device.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/panfrost/vulkan/panvk_vX_physical_device.c b/src/panfrost/vulkan/panvk_vX_physical_device.c
--- a/src/panfrost/vulkan/panvk_vX_physical_device.c
+++ b/src/panfrost/vulkan/panvk_vX_physical_device.c
@@ -38,8 +38,8 @@ get_device_extensions(const struct panvk_physical_device *device,
struct vk_device_extension_table *ext)
{
*ext = (struct vk_device_extension_table){
- .KHR_8bit_storage = true,
- .KHR_16bit_storage = true,
- bool has_vk1_1 = PAN_ARCH >= 10;
- bool has_vk1_2 = PAN_ARCH >= 10;
+ .KHR_8bit_storage = true,
+ .KHR_16bit_storage = true,
+ bool has_vk1_1 = true;
+ bool has_vk1_2 = true;
*ext = (struct vk_device_extension_table){
+156
View File
@@ -0,0 +1,156 @@
# Maintainer: Markus Fritsche <fritsche.markus@gmail.com>
#
# mesa-panvk-bifrost — patched Mesa libvulkan_panfrost.so that exposes
# Bifrost-gen Mali (Mali-G31/G52/G72/G76, PAN_ARCH 6/7) to Chromium-family
# browsers' Vulkan compositor.
#
# Campaign: ~/src/panvk-bifrost/ — iter9 close (technical milestone
# 2026-05-20, operator-confirmed Brave window). Goal close requires
# this package built + published + installable per the
# feedback_package_done_means_installable.md 3-point check.
#
# What it does:
# - Builds Mesa 26.0.6 (matching ohm's stock mesa pkg) with two
# patches against src/panfrost/vulkan/panvk_vX_physical_device.c:
# (1) expose VK_KHR/EXT_robustness2 + nullDescriptor on PAN_ARCH 6/7
# (2) set has_vk1_1/has_vk1_2 to true on Bifrost
# - Installs the patched libvulkan_panfrost.so to /usr/lib/panvk-bifrost/
# (NOT /usr/lib — co-installs alongside stock mesa).
# - Registers a custom ICD JSON at a non-default path so the system
# Vulkan loader only picks up our driver when VK_ICD_FILENAMES is set.
# - Ships /usr/bin/brave-vulkan launcher that wires up env vars + flags.
#
# Co-existence: stock /usr/lib/libvulkan_panfrost.so is untouched. Stock
# /usr/share/vulkan/icd.d/panfrost_icd.json is untouched. Users opt in
# via brave-vulkan (or by setting VK_ICD_FILENAMES manually).
#
# Build target: arch-aarch64 runner via marfrit-packages Gitea Actions.
# Mesa build is slow (~30-60min on Cortex-A55). Build deps installed
# inside the runner via pacman -S in the workflow.
pkgname=mesa-panvk-bifrost
_mesaver=26.0.6
pkgver=26.0.6.r2
pkgrel=1
pkgdesc="Patched Mesa libvulkan_panfrost.so exposing Bifrost-gen Mali to Vulkan apps (panvk-bifrost campaign)"
arch=('aarch64')
url="https://github.com/marfrit/panvk-bifrost"
license=('MIT')
# We co-install at /usr/lib/panvk-bifrost/ so no conflicts with stock mesa.
# We DO provide a script that requires brave to be installed.
depends=(
'mesa' # for shared mesa runtime libs (libgallium-mesa etc.)
'libdrm'
'wayland'
'libxcb'
'libx11'
'libxshmfence'
'zlib'
'zstd'
'libdisplay-info'
'expat'
'systemd-libs' # libudev
'spirv-tools'
)
optdepends=(
'brave-bin: for the brave-vulkan launcher script'
)
makedepends=(
'meson'
'ninja'
'pkgconf'
'bison'
'flex'
'python'
'python-yaml'
'python-mako'
'glslang'
'spirv-tools'
'llvm'
'clang'
'libclc'
'spirv-llvm-translator'
'vulkan-headers'
'wayland-protocols'
)
source=(
"https://archive.mesa3d.org/mesa-${_mesaver}.tar.xz"
"0001-panvk-expose-robustness2-nullDescriptor-bifrost.patch"
"0002-panvk-expose-vulkan-1.1-1.2-on-bifrost.patch"
"brave-vulkan"
"icd.json"
)
sha256sums=(
'SKIP' # TODO: pin once we know the upstream tarball is stable. archive.mesa3d.org tarballs are stable, so we can hash-pin in iter10.
'SKIP'
'SKIP'
'SKIP'
'SKIP'
)
prepare() {
cd "mesa-${_mesaver}"
# iter8 patch: robustness2 + nullDescriptor exposure on Bifrost.
# Three hunks in panvk_vX_physical_device.c. Apply via sed since
# the upstream context drifts between Mesa releases and unified-diff
# patching is brittle (we hit hunk-rejects during manual application).
sed -i 's|\.KHR_robustness2 = PAN_ARCH >= 10,|.KHR_robustness2 = true,|' src/panfrost/vulkan/panvk_vX_physical_device.c
sed -i 's|\.EXT_robustness2 = PAN_ARCH >= 10,|.EXT_robustness2 = true,|' src/panfrost/vulkan/panvk_vX_physical_device.c
sed -i 's|\.nullDescriptor = PAN_ARCH >= 10,|.nullDescriptor = true,|' src/panfrost/vulkan/panvk_vX_physical_device.c
# iter9 patch: bump api version to 1.1/1.2 for Bifrost. NOTE: this only
# affects extension exposure flags, NOT the reported apiVersion (which
# is set by get_api_version() further down and gated separately).
# The brave-vulkan launcher sets MESA_VK_VERSION_OVERRIDE=1.2 at runtime
# to deal with the latter — no source change needed for that path.
sed -i 's|bool has_vk1_1 = PAN_ARCH >= 10;|bool has_vk1_1 = true;|' src/panfrost/vulkan/panvk_vX_physical_device.c
sed -i 's|bool has_vk1_2 = PAN_ARCH >= 10;|bool has_vk1_2 = true;|' src/panfrost/vulkan/panvk_vX_physical_device.c
# Sanity-check the patches landed.
grep -q "KHR_robustness2 = true," src/panfrost/vulkan/panvk_vX_physical_device.c
grep -q "EXT_robustness2 = true," src/panfrost/vulkan/panvk_vX_physical_device.c
grep -q "nullDescriptor = true," src/panfrost/vulkan/panvk_vX_physical_device.c
grep -q "has_vk1_1 = true;" src/panfrost/vulkan/panvk_vX_physical_device.c
grep -q "has_vk1_2 = true;" src/panfrost/vulkan/panvk_vX_physical_device.c
}
build() {
cd "mesa-${_mesaver}"
# Minimal Mesa build — only the panvk Vulkan driver. No GLES/GLX/EGL/
# gallium drivers — keeps the build narrower and avoids pulling in
# the entire Mesa runtime in this package's dep graph.
meson setup build/ \
--prefix=/usr \
--libdir=lib \
--buildtype=release \
-Dvulkan-drivers=panfrost \
-Dgallium-drivers= \
-Dplatforms=wayland,x11 \
-Dglx=disabled \
-Degl=disabled \
-Dgles1=disabled \
-Dgles2=disabled \
-Dvulkan-layers= \
-Dtools= \
-Dgallium-rusticl=false \
-Dmicrosoft-clc=disabled
meson compile -C build
}
package() {
cd "${srcdir}/mesa-${_mesaver}"
# Patched lib — co-install path, NOT /usr/lib (to avoid clashing
# with stock mesa's libvulkan_panfrost.so).
install -Dm755 build/src/panfrost/vulkan/libvulkan_panfrost.so \
"$pkgdir/usr/lib/panvk-bifrost/libvulkan_panfrost.so"
# Custom ICD JSON. NOT under /usr/share/vulkan/icd.d/ (the default
# loader search path) — the user has to opt in via VK_ICD_FILENAMES.
install -Dm644 "$srcdir/icd.json" \
"$pkgdir/usr/lib/panvk-bifrost/icd.json"
# The brave-vulkan launcher wires up env + flags.
install -Dm755 "$srcdir/brave-vulkan" "$pkgdir/usr/bin/brave-vulkan"
}
+83
View File
@@ -0,0 +1,83 @@
# mesa-panvk-bifrost
Patched Mesa `libvulkan_panfrost.so` exposing Bifrost-gen Mali GPUs
(Mali-G31/G52/G72/G76, PAN_ARCH 6/7) to Chromium-family browsers'
Vulkan compositor.
Result of the **panvk-bifrost** campaign ([`~/src/panvk-bifrost/`](../../../panvk-bifrost/)),
iter9 close 2026-05-20 (technical milestone — operator-confirmed Brave
window) followed by this package as the actual delivery.
## What it solves
Stock Chromium / Brave on Bifrost SBCs (PineTab2, etc.) currently dies
at GL bindings init:
```
ERROR: ui/gl/gl_context_egl.cc:120 GLES3 is unsupported and ES version fallback is disabled
ERROR: ui/gl/init/gl_factory.cc:111 Requested GL implementation not found
ERROR: components/viz/service/main/viz_main_impl.cc:189 Exiting GPU process due to errors during initialization
```
This package makes Brave's **Vulkan compositor path** work on Bifrost,
side-stepping the failing GL stack. Browser chrome and standard page
rendering work.
## Known limitations (not addressed)
- **WebGL / WebGL2** in-page: blocked. ANGLE needs `VK_EXT_transform_feedback`
to expose GLES3 contexts; PanVk-Bifrost doesn't currently support that.
Sites using WebGL will degrade or refuse.
- **VAAPI hardware video decode**: unrelated to this package — see the
`libva-v4l2-request-fourier` package for that path.
## Install
```sh
# Ensure [marfrit] is in /etc/pacman.conf, then:
sudo pacman -Sy mesa-panvk-bifrost
```
## Use
```sh
brave-vulkan # launches Brave with Vulkan
brave-vulkan https://www.example.com
brave-vulkan --your-flags-here # extra args passed through
```
The launcher sets:
- `VK_ICD_FILENAMES=/usr/lib/panvk-bifrost/icd.json` (the patched driver)
- `PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1` (Mesa upstream gate)
- `MESA_VK_VERSION_OVERRIDE=1.2` (apiVersion bump for ANGLE)
- Brave flags: `--use-gl=disabled --enable-features=Vulkan --use-vulkan=native --ozone-platform=x11 --no-sandbox --disable-gpu-sandbox --ignore-gpu-blocklist`
## What's in the package
- `/usr/lib/panvk-bifrost/libvulkan_panfrost.so` — patched Mesa Vulkan driver (Mesa 26.0.6 + 2 sed-applied patches)
- `/usr/lib/panvk-bifrost/icd.json` — Vulkan ICD JSON pointing at the patched .so (NOT auto-loaded; only via `VK_ICD_FILENAMES`)
- `/usr/bin/brave-vulkan` — launcher script
System Mesa is untouched. The stock `/usr/lib/libvulkan_panfrost.so` and
`/usr/share/vulkan/icd.d/panfrost_icd.json` continue to work for any
other Vulkan app.
## Co-existence
Both stock Mesa and this package can be installed. Stock Vulkan apps
(`vulkaninfo`, `vkcube`, etc.) use the stock driver by default. Only
apps started via `brave-vulkan` (or with `VK_ICD_FILENAMES` manually
set to our path) use the patched driver.
## Campaign close criterion
Per [`feedback_package_done_means_installable`](file:///home/mfritsche/.claude/projects/-home-mfritsche-src/memory/feedback_package_done_means_installable.md)
three-point check:
1. PR merged to `marfrit-packages`
2. CI green AND `packages.reauktion.de/arch/aarch64/mesa-panvk-bifrost-*.pkg.tar.zst` exists
3. `pacman -Ss mesa-panvk-bifrost` on a fresh consumer host (e.g. ohm
after `pacman -Syu` from clean state) returns the package + brave-vulkan launches
When all three pass, panvk-bifrost iter9 closes.
+61
View File
@@ -0,0 +1,61 @@
#!/bin/bash
# brave-vulkan — launch Brave with the PanVk-Bifrost Vulkan compositor on
# Bifrost SBCs (PineTab2 / Mali-G52 r1 MC1 and similar).
#
# Side-steps the GL stack failures stock Brave hits on Bifrost
# (the README "Consumer-side benefit" path of the panvk-bifrost campaign).
#
# Provided by the mesa-panvk-bifrost package. See:
# /usr/share/doc/mesa-panvk-bifrost/README
# ~/src/panvk-bifrost/phase8_iteration9_close.md (campaign close)
#
# Usage: brave-vulkan [brave args...]
# Equivalent to: brave [VULKAN_FLAGS] [your args]
set -e
# Patched Vulkan driver (from this package) — must point at the custom path
# so we don't clash with the stock /usr/share/vulkan/icd.d/panfrost_icd.json
export VK_ICD_FILENAMES=/usr/lib/panvk-bifrost/icd.json
# PanVk's "I know it's not conformant" gate — the patched driver still
# refuses to enumerate Bifrost without this env var (Mesa upstream choice,
# kept for compatibility).
export PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1
# Override apiVersion to 1.2 — ANGLE (Chromium's GL stack) requires
# device.apiVersion >= 1.1. The patched libvulkan_panfrost.so still has
# a PAN_ARCH>=10 gate inside get_api_version(); easier to override at
# runtime via this Mesa env var than to add a third patch.
export MESA_VK_VERSION_OVERRIDE=1.2
# Find the live Plasma session's Xauthority. On a fresh boot the suffix
# is randomized; pgrep the Xwayland args to find the current one.
if [ -z "${XAUTHORITY:-}" ]; then
XAUTHF=$(pgrep -fa Xwayland 2>/dev/null | grep -oE "/run/user/$(id -u)/xauth_[A-Za-z0-9]+" | head -1)
if [ -n "$XAUTHF" ]; then
export XAUTHORITY="$XAUTHF"
fi
fi
# Standard session env if not already set
: "${XDG_RUNTIME_DIR:=/run/user/$(id -u)}"
export XDG_RUNTIME_DIR
# Default to the active Plasma Wayland session if WAYLAND_DISPLAY unset
: "${WAYLAND_DISPLAY:=wayland-0}"
export WAYLAND_DISPLAY
# Default to the XWayland :1 unless DISPLAY is set
: "${DISPLAY:=:1}"
export DISPLAY
exec brave \
--use-gl=disabled \
--enable-features=Vulkan \
--use-vulkan=native \
--ozone-platform=x11 \
--no-sandbox \
--disable-gpu-sandbox \
--ignore-gpu-blocklist \
"$@"
+7
View File
@@ -0,0 +1,7 @@
{
"ICD": {
"api_version": "1.4.335",
"library_path": "/usr/lib/panvk-bifrost/libvulkan_panfrost.so"
},
"file_format_version": "1.0.1"
}
+29 -5
View File
@@ -10,11 +10,13 @@
# Upstream fork: https://git.reauktion.de/marfrit/libva-v4l2-request-fourier # Upstream fork: https://git.reauktion.de/marfrit/libva-v4l2-request-fourier
set -euo pipefail set -euo pipefail
# Same pin as the Arch PKGBUILD. de27e95 = "v4l2: log error_idx + # Same pin as the Arch PKGBUILD. c332d34 = LIBVA-1 close — per-codec
# failing ctrl id on S_EXT_CTRLS failure" (Phase 8.13 diagnostic). # dispatch on Pi 5: rpi-hevc-dec + daedalus_v4l2 both probe each other
UPSTREAM_COMMIT=de27e95571b67ef34619c23a12db4698f9b3454e # as alts, VP9/AV1/H.264 route to daedalus via new 'd' kind, HEVC stays
PKGVER=1.0.0+r376+gde27e95 # on 'p' (rpi-hevc-dec).
PKGREL=1 UPSTREAM_COMMIT=c332d34643be29e88012e30878d2fbeb255b20ab
PKGVER=1.0.0+r378+gc332d34
PKGREL=2 # rebuild against pinned trixie libva-dev (2.22) for __vaDriverInit_1_22 ABI
HERE=$(dirname "$(readlink -f "$0")") HERE=$(dirname "$(readlink -f "$0")")
@@ -38,6 +40,28 @@ meson setup build \
-Db_lto=false -Db_lto=false
meson compile -C build meson compile -C build
# ---------------------------------------------------------------------------
# ABI sanity check: the produced .so MUST export __vaDriverInit_1_<MINOR>
# matching the install target's libva runtime. Build is expected to run on
# a Debian trixie runner where <va/va.h>'s VA_MINOR is 22 — see
# .gitea/workflows/build.yml (runs-on: actrunner-debian-aarch64-bohr). If a future
# runner change lands the build on a host with a different libva-dev
# version, the produced symbol won't bind on the install target and ffmpeg/
# vainfo/firefox-vaapi will all fail with "has no function
# __vaDriverInit_1_0". Fail loud at build time instead of shipping a
# silently-broken .deb (which is what happened in -1).
# ---------------------------------------------------------------------------
SO=$(find build -name 'v4l2_request_drv_video.so' | head -1)
if ! nm -D --defined-only "$SO" | grep -q '__vaDriverInit_1_22'; then
echo "FATAL: built driver does not export __vaDriverInit_1_22."
echo " Build host's <va/va.h> VA_MINOR_VERSION is likely != 22."
echo " Expected runner: actrunner-debian-aarch64-bohr (trixie, libva 2.22)."
echo " Symbol exports found:"
nm -D --defined-only "$SO" | grep -i vadriverinit || echo " (none)"
exit 1
fi
echo "ABI check: $SO exports __vaDriverInit_1_22 (matches trixie libva 2.22)"
ROOT="$work/pkgroot" ROOT="$work/pkgroot"
DESTDIR="$ROOT" meson install -C build DESTDIR="$ROOT" meson install -C build
+33
View File
@@ -1,3 +1,36 @@
libva-v4l2-request-fourier (1.0.0+r378+gc332d34-2) bookworm trixie; urgency=medium
* Rebuild on a native Debian trixie runner (actrunner-debian-aarch64-bohr) so
the driver picks up trixie's libva-dev (2.22) and exports
__vaDriverInit_1_22 — the symbol trixie's libva runtime looks up.
Previous -1 build used the Arch CI runner (libva 2.23.0) and
exported __vaDriverInit_1_23, which trixie's loader cannot bind:
vaInitialize() returns -1 ("has no function __vaDriverInit_1_0")
and ffmpeg -hwaccel vaapi fails on startup.
* No source change; pure build-env fix. CI workflow's
libva-v4l2-request-fourier-debian job moved from runs-on:
arch-aarch64 to runs-on: actrunner-debian-aarch64-bohr; build-deps installed
via apt-get instead of pacman.
* Hard sanity check kept in build-deb.sh: build fails if the
resulting .so doesn't export __vaDriverInit_1_22 (preempts the
silent install-then-refuse-to-load failure mode).
-- Markus Fritsche <mfritsche@reauktion.de> Wed, 20 May 2026 18:00:00 +0000
libva-v4l2-request-fourier (1.0.0+r378+gc332d34-1) bookworm trixie; urgency=medium
* Bump to c332d34 — LIBVA-1 per-codec dispatch close. Pi 5 mixed
deployment (rpi-hevc-dec + daedalus_v4l2 both loaded) now correctly
opens BOTH decoders: VP9/AV1/H.264 route to daedalus via new 'd'
kind, HEVC stays on 'p' (rpi-hevc-dec). Before this commit
find_codec_device picked rpi-hevc-dec as the sole primary and the
daedalus_v4l2 slot stayed -1, so VP9/AV1/H.264 frames failed.
* Also closes a small fd leak in RequestTerminate (daedalus pair).
* Backward-compatible: new branches gated by HAVE_DAEDALUS_V4L2
*and* video_fd_daedalus >= 0 — RK3399/RK3588 boxes unaffected.
-- Markus Fritsche <mfritsche@reauktion.de> Wed, 20 May 2026 17:30:00 +0000
libva-v4l2-request-fourier (1.0.0+r376+gde27e95-1) bookworm trixie; urgency=medium libva-v4l2-request-fourier (1.0.0+r376+gde27e95-1) bookworm trixie; urgency=medium
* Initial Debian packaging (sibling to existing * Initial Debian packaging (sibling to existing