forked from marfrit/marfrit-packages
Compare commits
69 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9bf97fdb49 | |||
| a536e20218 | |||
| a1dba5f630 | |||
| 88a65cb6d0 | |||
| e641d679d3 | |||
| 877238bd1b | |||
| 27617e4cb0 | |||
| a2daab1b28 | |||
| 9146e83710 | |||
| abf8fb3077 | |||
| 1414dfeac2 | |||
| 41c1e0b6b9 | |||
| c9a4b82f2c | |||
| 736b6da176 | |||
| 34972ae9c1 | |||
| a9f1b833b9 | |||
| 83e8eca56d | |||
| 1c8c186681 | |||
| a0be2dcc9f | |||
| eb89f12c3e | |||
| ce2fff1a4f | |||
| 9301894997 | |||
| f21c1ff80a | |||
| e15b887d8d | |||
| b69db65037 | |||
| adcc824bf7 | |||
| 7213b23861 | |||
| 2cd3acd680 | |||
| 22ac3c9845 | |||
| 3275d06728 | |||
| 33b91cf7dc | |||
| a640633ea7 | |||
| 5f21a71770 | |||
| de3c2c6744 | |||
| e7e79e5a76 | |||
| 130a259c69 | |||
| 9580f33cb6 | |||
| eab66cfab8 | |||
| d2cecbcd05 | |||
| 2028eccc3c | |||
| 70c8c2b417 | |||
| 793187ff9e | |||
| 42bf6b1633 | |||
| 40719efc43 | |||
| e540384f50 | |||
| 9ca97374c8 | |||
| 902e855d92 | |||
| 64269d69ee | |||
| e976c88016 | |||
| 29cc145d44 | |||
| b16a3f1a77 | |||
| c2018413aa | |||
| 243e05ca5e | |||
| a29fe71666 | |||
| b0ffd4d74f | |||
| ab60acd9f4 | |||
| 6a417fcc9d | |||
| 1c77b05f68 | |||
| 051da5e8dc | |||
| a1ff6de652 | |||
| b471847b1c | |||
| 3abfdff943 | |||
| fce33b02a2 | |||
| da60fa7c49 | |||
| 20161d231f | |||
| c7bb14f369 | |||
| f8d1257d35 | |||
| f3b1087ac7 | |||
| 2299d7a02f |
Executable
+230
@@ -0,0 +1,230 @@
|
|||||||
|
#!/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")
|
||||||
|
|
||||||
|
# Compare against the canonical Packages index (what apt actually
|
||||||
|
# consults). reprepro refuses lower-version uploads, so checking
|
||||||
|
# only an exact source-pkgrel URL produces an endless-rebuild trap
|
||||||
|
# whenever source PKGREL has rolled back below pool head. We skip
|
||||||
|
# if pools published version >= source version-tuple.
|
||||||
|
source_full="${ver_full}"
|
||||||
|
if [ -n "${PKGVER#*:}" ] && [ "${PKGVER}" != "${PKGVER#*:}" ]; then
|
||||||
|
# PKGVER had an epoch — keep it for dpkg --compare-versions.
|
||||||
|
source_full="${PKGVER}-${PKGREL}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Determine suite: most recipes publish to both bookworm and trixie;
|
||||||
|
# checking trixie is sufficient (changelogs share Distribution).
|
||||||
|
suite="trixie"
|
||||||
|
pkg_arch_label="$file_arch"
|
||||||
|
[ "$file_arch" = "all" ] && pkg_arch_label="all"
|
||||||
|
packages_url="${REPO_BASE}/debian/dists/${suite}/main/binary-arm64/Packages"
|
||||||
|
[ "$file_arch" = "amd64" ] && packages_url="${REPO_BASE}/debian/dists/${suite}/main/binary-amd64/Packages"
|
||||||
|
|
||||||
|
pool_ver=$(set +o pipefail; curl -sS --max-time "$HEAD_TIMEOUT" "$packages_url" 2>/dev/null | awk -v p="$pkg_name" '$1=="Package:" && $2==p {found=1; next} found && $1=="Version:" {print $2; exit}')
|
||||||
|
|
||||||
|
if [ -n "$pool_ver" ] && command -v dpkg >/dev/null && dpkg --compare-versions "$pool_ver" ge "$source_full"; then
|
||||||
|
echo "pool has $pool_ver >= source $source_full" >&2
|
||||||
|
emit 1
|
||||||
|
fi
|
||||||
|
echo "pool has $pool_ver, source wants $source_full — build" >&2
|
||||||
|
emit 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "error: unsupported ecosystem '$ecosystem' (recipe-dir=$RECIPE_DIR)" >&2
|
||||||
|
emit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
+276
-66
@@ -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; }
|
||||||
@@ -793,22 +906,42 @@ jobs:
|
|||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
ffmpeg-v4l2-request-debian:
|
ffmpeg-v4l2-request-debian:
|
||||||
needs: ffmpeg-v4l2-request-aarch64
|
needs: ffmpeg-v4l2-request-aarch64
|
||||||
runs-on: arch-aarch64
|
runs-on: debian-aarch64
|
||||||
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/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; }
|
||||||
retry pacman -Syu --noconfirm --needed \
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
dpkg openssh rsync curl base-devel git nasm yasm \
|
retry apt-get update -qq
|
||||||
linux-api-headers mesa alsa-lib bzip2 fontconfig fribidi gmp \
|
# Debian build-deps for the FFmpeg fourier-fork build. These
|
||||||
gnutls lame libass dav1d libdrm freetype2 libpulse libva \
|
# map 1:1 to the previous Arch list; libav*-dev intentionally
|
||||||
libvorbis libvpx libwebp x264 x265 libxml2 opus v4l-utils xz zlib
|
# absent (we are FFmpeg itself, providing those libs).
|
||||||
|
retry apt-get install -y --no-install-recommends \
|
||||||
|
build-essential cmake ninja-build git pkg-config nasm yasm \
|
||||||
|
linux-libc-dev libgl1-mesa-dev libasound2-dev libbz2-dev \
|
||||||
|
libfontconfig-dev libfribidi-dev libgmp-dev libgnutls28-dev \
|
||||||
|
libmp3lame-dev libass-dev libdav1d-dev libdrm-dev \
|
||||||
|
libfreetype-dev libpulse-dev libva-dev libvorbis-dev libvpx-dev \
|
||||||
|
libwebp-dev libx264-dev libx265-dev libxml2-dev libopus-dev \
|
||||||
|
libvulkan-dev glslang-tools \
|
||||||
|
v4l-utils liblzma-dev zlib1g-dev \
|
||||||
|
curl ca-certificates openssh-client rsync 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: |
|
||||||
@@ -818,6 +951,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 +959,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 +981,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: debian-aarch64
|
||||||
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 +1022,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 +1030,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; }
|
||||||
@@ -900,41 +1055,51 @@ jobs:
|
|||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
mpv-fourier-debian:
|
mpv-fourier-debian:
|
||||||
needs: mpv-fourier-aarch64
|
needs: mpv-fourier-aarch64
|
||||||
runs-on: arch-aarch64
|
runs-on: debian-aarch64
|
||||||
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/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; }
|
||||||
retry pacman -Syu --noconfirm --needed \
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
dpkg openssh rsync curl base-devel git meson ninja python-docutils \
|
retry apt-get update -qq
|
||||||
ladspa wayland-protocols vulkan-headers \
|
# Debian libav*-dev is ABI-compatible with the fourier ffmpeg
|
||||||
alsa-lib desktop-file-utils glibc hicolor-icon-theme jack lcms2 \
|
# fork at the header level; mpv link-binds against system
|
||||||
libarchive libass libbluray libcdio libcdio-paranoia libdisplay-info \
|
# libav at build time, runtime dlopen picks up the fourier
|
||||||
libdrm libdvdnav libdvdread libegl libgl libglvnd libjpeg-turbo \
|
# libs if installed. The previous [marfrit] pre-install of
|
||||||
libplacebo libpulse libsixel libva libvdpau libx11 libxext \
|
# ffmpeg-v4l2-request-fourier under pacman is unnecessary
|
||||||
libxkbcommon libxpresent libxrandr libxss libxv luajit mesa mujs \
|
# under apt: stock Debian libav*-dev provides the trixie
|
||||||
libpipewire rubberband sdl2 openal uchardet vapoursynth \
|
# ABI mpv-fourier's binary will encounter.
|
||||||
vulkan-icd-loader wayland zlib
|
retry apt-get install -y --no-install-recommends \
|
||||||
|
build-essential git meson ninja-build pkg-config python3-docutils \
|
||||||
- name: configure [marfrit] repo + pre-install ffmpeg-v4l2-request-fourier
|
ladspa-sdk wayland-protocols libvulkan-dev libwayland-dev \
|
||||||
run: |
|
libasound2-dev desktop-file-utils libc6-dev hicolor-icon-theme \
|
||||||
set -e
|
libjack-jackd2-dev liblcms2-dev libarchive-dev libass-dev \
|
||||||
curl -sLo /tmp/marfrit.gpg https://packages.reauktion.de/marfrit.gpg
|
libbluray-dev libcdio-dev libcdio-paranoia-dev libdisplay-info-dev \
|
||||||
pacman-key --add /tmp/marfrit.gpg
|
libdrm-dev libdvdnav-dev libdvdread-dev libegl-dev libgl-dev \
|
||||||
pacman-key --lsign-key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C
|
libglvnd-dev libjpeg-dev libplacebo-dev libpulse-dev libsixel-dev \
|
||||||
rm -f /tmp/marfrit.gpg
|
libva-dev libvdpau-dev libx11-dev libxext-dev libxkbcommon-dev \
|
||||||
if ! grep -q '^\[marfrit\]' /etc/pacman.conf; then
|
libxpresent-dev libxrandr-dev libxss-dev libxv-dev libluajit-5.1-dev \
|
||||||
printf '\n[marfrit]\nServer = https://packages.reauktion.de/arch/$arch\nSigLevel = Required\n' >> /etc/pacman.conf
|
libmujs-dev libpipewire-0.3-dev librubberband-dev libsdl2-dev \
|
||||||
fi
|
libopenal-dev libuchardet-dev libvapoursynth-dev liblzma-dev \
|
||||||
pacman -Sy --noconfirm
|
libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev \
|
||||||
rm -f /var/cache/pacman/pkg/ffmpeg-v4l2-request-fourier-*-aarch64.pkg.tar.*
|
zlib1g-dev \
|
||||||
printf 'y\ny\ny\n' | pacman -S marfrit/ffmpeg-v4l2-request-fourier
|
curl ca-certificates openssh-client rsync 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: |
|
||||||
@@ -944,6 +1109,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 +1117,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; }
|
||||||
@@ -973,44 +1140,55 @@ jobs:
|
|||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
daedalus-v4l2-debian:
|
daedalus-v4l2-debian:
|
||||||
needs: claude-his-debian
|
needs: claude-his-debian
|
||||||
runs-on: arch-aarch64
|
runs-on: debian-aarch64
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: install build-deps (sans ffmpeg — see [marfrit] step)
|
- 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
|
||||||
|
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; }
|
||||||
# Do NOT pull stock 'ffmpeg' here: the arch-aarch64 runner has
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
# ffmpeg-v4l2-request-fourier pre-installed from the mpv-aarch64
|
retry apt-get update -qq
|
||||||
# job (configured via [marfrit]), and pacman -S ffmpeg would
|
# FFmpeg headers + sonames the daemon dlopens. As of
|
||||||
# conflict on the libav* drop-in. Daedalus build only needs
|
# daedalus-v4l2 PR #16 (commit 514da29), the daemon targets
|
||||||
# libavcodec/libavformat headers, which the fourier package
|
# the Kwiboo fork's libavcodec.so.62 / libavformat.so.62 /
|
||||||
# already supplies. Keep cmake/ninja/pkgconf/libdrm here; the
|
# libavutil.so.60 at /opt/fourier — so the build needs
|
||||||
# ffmpeg-dev equivalent comes via the next step.
|
# /opt/fourier/include and /opt/fourier/lib/pkgconfig.
|
||||||
retry pacman -Syu --noconfirm --needed \
|
# ffmpeg-v4l2-request-fourier provides both (plus the
|
||||||
dpkg openssh rsync curl base-devel git cmake ninja pkgconf \
|
# runtime libs the .deb will dlopen on the target host;
|
||||||
libdrm
|
# we install it as a build-dep here and the dpkg-shlibdeps
|
||||||
|
# step pulls it into the daemon .deb's Depends automatically).
|
||||||
- name: ensure ffmpeg-v4l2-request-fourier installed (link-time ABI source)
|
# Debian-stock libav*-dev removed — would conflict on
|
||||||
run: |
|
# /usr/include/libavcodec/avcodec.h vs /opt/fourier's copy.
|
||||||
set -e
|
#
|
||||||
# Idempotent: pre-install the marfrit fourier ffmpeg so cmake
|
# libvulkan-dev + glslang-tools: needed by the in-build
|
||||||
# finds libavcodec / libavformat / libavutil headers + .so's.
|
# daedalus-fourier fetch (build-deb.sh fetches the sibling
|
||||||
# Mirrors mpv-fourier-debian's [marfrit] step.
|
# library, cmake-builds it into a temp prefix, then the
|
||||||
curl -sLo /tmp/marfrit.gpg https://packages.reauktion.de/marfrit.gpg
|
# daedalus daemon static-links against it via pkg-config).
|
||||||
pacman-key --add /tmp/marfrit.gpg
|
# Without these, daedalus-fourier's find_package(Vulkan)
|
||||||
pacman-key --lsign-key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C
|
# and glslangValidator find_program both fail at configure
|
||||||
rm -f /tmp/marfrit.gpg
|
# time. See marfrit/daedalus-fourier PR #1 +
|
||||||
if ! grep -q '^\[marfrit\]' /etc/pacman.conf; then
|
# reauktion/daedalus-v4l2 PR #13.
|
||||||
printf '\n[marfrit]\nServer = https://packages.reauktion.de/arch/$arch\nSigLevel = Required\n' >> /etc/pacman.conf
|
retry apt-get install -y --no-install-recommends \
|
||||||
fi
|
build-essential cmake ninja-build pkg-config git \
|
||||||
pacman -Sy --noconfirm
|
ffmpeg-v4l2-request-fourier libdrm-dev \
|
||||||
rm -f /var/cache/pacman/pkg/ffmpeg-v4l2-request-fourier-*-aarch64.pkg.tar.*
|
libvulkan-dev glslang-tools \
|
||||||
printf 'y\ny\ny\n' | pacman -S --needed marfrit/ffmpeg-v4l2-request-fourier
|
linux-libc-dev \
|
||||||
|
curl ca-certificates openssh-client rsync 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: |
|
||||||
@@ -1020,6 +1198,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 +1206,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; }
|
||||||
@@ -1049,18 +1229,31 @@ jobs:
|
|||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
daedalus-v4l2-dkms-debian:
|
daedalus-v4l2-dkms-debian:
|
||||||
needs: daedalus-v4l2-debian
|
needs: daedalus-v4l2-debian
|
||||||
runs-on: arch-aarch64
|
runs-on: debian-aarch64
|
||||||
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/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
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
retry apt-get update -qq
|
||||||
|
retry apt-get install -y --no-install-recommends \
|
||||||
|
dpkg-dev openssh-client rsync curl ca-certificates 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 +1263,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 +1271,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; }
|
||||||
@@ -1110,13 +1305,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/mesa-panvk-bifrost)
|
||||||
|
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 }}
|
||||||
@@ -1131,6 +1336,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: |
|
||||||
@@ -1140,6 +1346,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 mesa-panvk-bifrost
|
- name: makepkg mesa-panvk-bifrost
|
||||||
|
if: steps.skip-check.outputs.skip != '1'
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -e
|
||||||
rm -rf /tmp/build-mesa-panvk-bifrost
|
rm -rf /tmp/build-mesa-panvk-bifrost
|
||||||
@@ -1154,6 +1361,7 @@ jobs:
|
|||||||
ls -la *.pkg.tar.* | grep -v "\.sig$"
|
ls -la *.pkg.tar.* | grep -v "\.sig$"
|
||||||
|
|
||||||
- name: sign mesa-panvk-bifrost
|
- name: sign mesa-panvk-bifrost
|
||||||
|
if: steps.skip-check.outputs.skip != '1'
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -e
|
||||||
cd /tmp/build-mesa-panvk-bifrost
|
cd /tmp/build-mesa-panvk-bifrost
|
||||||
@@ -1164,6 +1372,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-mesa-panvk
|
mkdir -p /tmp/arch-stage-mesa-panvk
|
||||||
@@ -1199,6 +1408,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; }
|
||||||
|
|||||||
@@ -18,10 +18,15 @@ _module=daedalus_v4l2
|
|||||||
|
|
||||||
# Same pin as arch/daedalus-v4l2 — keep kernel module + daemon
|
# Same pin as arch/daedalus-v4l2 — keep kernel module + daemon
|
||||||
# bit-versioned together so the chardev wire protocol stays in sync.
|
# bit-versioned together so the chardev wire protocol stays in sync.
|
||||||
_commit=481279c9bffd19e32c8f3299897e9b63fc5a24aa
|
# 5d8b436 reverts PRs #7 + #8 (parking design that broke libva's
|
||||||
|
# 1:1 contract — see daedalus-v4l2#9 + #10). Tree is
|
||||||
|
# content-equivalent to f0d4186 plus PR #4 (cosmetic menu ctrls).
|
||||||
|
# PROTO_VERSION drops 1 → 0; lock-step install with
|
||||||
|
# daedalus-v4l2 0.1.0.r33.5d8b436 REQUIRED.
|
||||||
|
_commit=5d8b4369e58ab947d1c56b1f718293c57c6065b5
|
||||||
|
|
||||||
pkgver=0.1.0.r18.481279c
|
pkgver=0.1.0.r33.5d8b436
|
||||||
pkgrel=1 # reset for new upstream pin (481279c — Phase 8.13 close)
|
pkgrel=1 # reset for new upstream pin (5d8b436 — revert parking design)
|
||||||
pkgdesc="V4L2 stateless decoder shim kernel module (DKMS) — Pi 5 / CM5"
|
pkgdesc="V4L2 stateless decoder shim kernel module (DKMS) — Pi 5 / CM5"
|
||||||
arch=('any')
|
arch=('any')
|
||||||
url="https://git.reauktion.de/reauktion/daedalus-v4l2"
|
url="https://git.reauktion.de/reauktion/daedalus-v4l2"
|
||||||
|
|||||||
@@ -16,17 +16,19 @@
|
|||||||
pkgname=daedalus-v4l2
|
pkgname=daedalus-v4l2
|
||||||
_upstreampkg=daedalus-v4l2
|
_upstreampkg=daedalus-v4l2
|
||||||
|
|
||||||
# Pin the daedalus-v4l2 tip. 481279c = "Phase 8.13: byte-exact end-to-
|
# 6e6dfa1 = picks up daedalus-v4l2 PR #16 — daemon now dlopens
|
||||||
# end via libva (consumer target hit)" — first commit where the full
|
# the Kwiboo fourier fork's libavcodec.so.62 / libavformat.so.62 /
|
||||||
# ffmpeg -hwaccel vaapi → libva → /dev/video0 → daemon path lands a
|
# libavutil.so.60 at /opt/fourier instead of Debian-stock soname
|
||||||
# pixel-correct decoded frame back in ffmpeg. Promote to a later pin
|
# 61/61/59. First step on the daedalus-fourier substitution arc
|
||||||
# only after a future phase closes cleanly.
|
# (daedalus-v4l2#11). Daemon still needs daedalus-fourier at
|
||||||
_commit=481279c9bffd19e32c8f3299897e9b63fc5a24aa
|
# build time (Arch packaging for that is a follow-up; Debian side
|
||||||
|
# fetches inline via build-deb.sh).
|
||||||
|
_commit=6e6dfa144da7bc7fa8be50c8da91d7d1c6132a2c
|
||||||
|
|
||||||
# 0.1.0 (pre-1.0) + commit count + short sha. Bump the .Y on each
|
# 0.1.0 (pre-1.0) + commit count + short sha. Bump the .Y on each
|
||||||
# Phase 8.x close. pkgver() recomputes at build time.
|
# Phase 8.x close. pkgver() recomputes at build time.
|
||||||
pkgver=0.1.0.r18.481279c
|
pkgver=0.1.0.r41.6e6dfa1
|
||||||
pkgrel=1 # reset for new upstream pin (481279c — Phase 8.13 close)
|
pkgrel=1 # reset for new upstream pin (6e6dfa1 — soname 62 via /opt/fourier)
|
||||||
pkgdesc="Userspace daemon for the daedalus-v4l2 V4L2 stateless decoder shim (VP9/AV1/H.264 on Pi 5 / CM5)"
|
pkgdesc="Userspace daemon for the daedalus-v4l2 V4L2 stateless decoder shim (VP9/AV1/H.264 on Pi 5 / CM5)"
|
||||||
arch=('aarch64')
|
arch=('aarch64')
|
||||||
url="https://git.reauktion.de/reauktion/daedalus-v4l2"
|
url="https://git.reauktion.de/reauktion/daedalus-v4l2"
|
||||||
@@ -34,7 +36,7 @@ license=('BSD-2-Clause' 'GPL-2.0-or-later')
|
|||||||
# Daemon dlopens libavformat.so.61 / libavcodec.so.61 / libavutil.so.59
|
# Daemon dlopens libavformat.so.61 / libavcodec.so.61 / libavutil.so.59
|
||||||
# at runtime (Option γ — see daemon/src/ffmpeg_loader.h). ffmpeg
|
# at runtime (Option γ — see daemon/src/ffmpeg_loader.h). ffmpeg
|
||||||
# provides those; we don't link them.
|
# provides those; we don't link them.
|
||||||
depends=('ffmpeg' 'libdrm')
|
depends=('ffmpeg-v4l2-request-fourier' 'libdrm')
|
||||||
# Headers from libav*-dev needed at compile time for type-safe function
|
# Headers from libav*-dev needed at compile time for type-safe function
|
||||||
# pointer signatures; pkg-config locates them.
|
# pointer signatures; pkg-config locates them.
|
||||||
makedepends=('cmake' 'ninja' 'pkgconf' 'git' 'ffmpeg')
|
makedepends=('cmake' 'ninja' 'pkgconf' 'git' 'ffmpeg')
|
||||||
|
|||||||
@@ -0,0 +1,137 @@
|
|||||||
|
From f760c0541586f43334c02611fcb4c212c08ad576 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Markus Fritsche <mfritsche@reauktion.de>
|
||||||
|
Date: Thu, 21 May 2026 21:40:22 +0200
|
||||||
|
Subject: [PATCH] avcodec/aarch64/h264dsp: route H.264 4x4 IDCT through
|
||||||
|
daedalus-fourier
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
H264DSPContext.idct_add (called per 4x4 block from the intra-4x4
|
||||||
|
decode path in h264_mb.c) now dispatches through
|
||||||
|
daedalus_recipe_dispatch_h264_idct4 instead of ff_h264_idct_add_neon.
|
||||||
|
|
||||||
|
The recipe layer picks the substrate; for cycle 6 (H.264 IDCT 4x4)
|
||||||
|
the recipe is CPU NEON, so this is effectively a NEON-to-NEON
|
||||||
|
substitution with one extra dispatch call and recipe-table lookup.
|
||||||
|
Provides the first end-to-end exercise of the daedalus-fourier
|
||||||
|
kernel pack inside the libavcodec.so decode hot path; follow-up
|
||||||
|
patches wire IDCT 8x8, luma-v deblock, and qpel mc20.
|
||||||
|
|
||||||
|
The library context is process-global, lazily initialised under
|
||||||
|
pthread_once on first call. We pick the no-QPU constructor because
|
||||||
|
libavcodec.so is loaded into arbitrary host processes
|
||||||
|
(firefox-fourier, mpv-fourier, daedalus_v4l2_daemon, ...) and we
|
||||||
|
cannot assume the host has a usable Vulkan instance. Higher cycles
|
||||||
|
(deblock luma-v, MC) that benefit from the QPU will provision their
|
||||||
|
own recipe-selected context once that path is wired.
|
||||||
|
|
||||||
|
Bulk paths (idct_add16, idct_add16intra, idct_add8 — used for
|
||||||
|
non-intra4x4 macroblocks) remain on the stock NEON .S implementations
|
||||||
|
and will be batched through daedalus_recipe_dispatch_h264_idct4 with
|
||||||
|
n_blocks>1 in a follow-up.
|
||||||
|
|
||||||
|
Bit-exact against ff_h264_idct_add_neon (daedalus-fourier cycle 6
|
||||||
|
green; see marfrit/daedalus-fourier/CYCLE_LOGS.md).
|
||||||
|
|
||||||
|
Refs reauktion/daedalus-v4l2#11 — substitution arc step 2.
|
||||||
|
---
|
||||||
|
libavcodec/aarch64/Makefile | 3 +-
|
||||||
|
libavcodec/aarch64/h264_idct_daedalus.c | 49 +++++++++++++++++++++++
|
||||||
|
libavcodec/aarch64/h264dsp_init_aarch64.c | 3 +-
|
||||||
|
3 files changed, 53 insertions(+), 2 deletions(-)
|
||||||
|
create mode 100644 libavcodec/aarch64/h264_idct_daedalus.c
|
||||||
|
|
||||||
|
diff --git a/libavcodec/aarch64/Makefile b/libavcodec/aarch64/Makefile
|
||||||
|
index 41ab025..7b95fb1 100644
|
||||||
|
--- a/libavcodec/aarch64/Makefile
|
||||||
|
+++ b/libavcodec/aarch64/Makefile
|
||||||
|
@@ -3,7 +3,8 @@ OBJS-$(CONFIG_AC3DSP) += aarch64/ac3dsp_init_aarch64.o
|
||||||
|
OBJS-$(CONFIG_FDCTDSP) += aarch64/fdctdsp_init_aarch64.o
|
||||||
|
OBJS-$(CONFIG_FMTCONVERT) += aarch64/fmtconvert_init.o
|
||||||
|
OBJS-$(CONFIG_H264CHROMA) += aarch64/h264chroma_init_aarch64.o
|
||||||
|
-OBJS-$(CONFIG_H264DSP) += aarch64/h264dsp_init_aarch64.o
|
||||||
|
+OBJS-$(CONFIG_H264DSP) += aarch64/h264dsp_init_aarch64.o \
|
||||||
|
+ aarch64/h264_idct_daedalus.o
|
||||||
|
OBJS-$(CONFIG_HUFFYUVDSP) += aarch64/huffyuvdsp_init_aarch64.o
|
||||||
|
OBJS-$(CONFIG_H264PRED) += aarch64/h264pred_init.o
|
||||||
|
OBJS-$(CONFIG_H264QPEL) += aarch64/h264qpel_init_aarch64.o
|
||||||
|
diff --git a/libavcodec/aarch64/h264_idct_daedalus.c b/libavcodec/aarch64/h264_idct_daedalus.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..538d223
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/libavcodec/aarch64/h264_idct_daedalus.c
|
||||||
|
@@ -0,0 +1,49 @@
|
||||||
|
+/*
|
||||||
|
+ * H.264 4x4 IDCT + add — daedalus-fourier substitution shim.
|
||||||
|
+ *
|
||||||
|
+ * Routes H264DSPContext.idct_add through
|
||||||
|
+ * daedalus_recipe_dispatch_h264_idct4 instead of ff_h264_idct_add_neon.
|
||||||
|
+ * The recipe layer picks the substrate (CPU NEON by default for
|
||||||
|
+ * cycle 6; future cycles may dispatch to V3D opportunistically).
|
||||||
|
+ *
|
||||||
|
+ * FFmpeg's 4x4 block memory layout matches daedalus's column-major
|
||||||
|
+ * convention: block[r + 4*c] = coefficient at (row r, col c). Both
|
||||||
|
+ * sides destructively zero the block after the transform.
|
||||||
|
+ *
|
||||||
|
+ * The library context is process-global and lazily initialised under
|
||||||
|
+ * pthread_once. We pick the no-QPU constructor here because
|
||||||
|
+ * libavcodec.so is loaded into arbitrary host processes
|
||||||
|
+ * (firefox-fourier, mpv-fourier, daedalus_v4l2_daemon, ...) and we
|
||||||
|
+ * cannot assume the host has a usable Vulkan instance. Higher cycles
|
||||||
|
+ * (deblock, MC) that benefit from the QPU initialise their own
|
||||||
|
+ * recipe-selected context once that path is wired.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <pthread.h>
|
||||||
|
+#include <stddef.h>
|
||||||
|
+#include <stdint.h>
|
||||||
|
+
|
||||||
|
+#include <daedalus.h>
|
||||||
|
+
|
||||||
|
+#include "libavutil/attributes.h"
|
||||||
|
+#include "libavcodec/h264dsp.h"
|
||||||
|
+
|
||||||
|
+static daedalus_ctx *g_dctx;
|
||||||
|
+static pthread_once_t g_dctx_once = PTHREAD_ONCE_INIT;
|
||||||
|
+
|
||||||
|
+static void daedalus_ctx_init_once(void)
|
||||||
|
+{
|
||||||
|
+ g_dctx = daedalus_ctx_create_no_qpu();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void ff_h264_idct_add_daedalus(uint8_t *dst, int16_t *block, int stride);
|
||||||
|
+
|
||||||
|
+void ff_h264_idct_add_daedalus(uint8_t *dst, int16_t *block, int stride)
|
||||||
|
+{
|
||||||
|
+ static const daedalus_h264_block_meta meta = { .dst_off = 0 };
|
||||||
|
+
|
||||||
|
+ pthread_once(&g_dctx_once, daedalus_ctx_init_once);
|
||||||
|
+
|
||||||
|
+ daedalus_recipe_dispatch_h264_idct4(g_dctx, dst, (size_t)stride,
|
||||||
|
+ block, 1, &meta);
|
||||||
|
+}
|
||||||
|
diff --git a/libavcodec/aarch64/h264dsp_init_aarch64.c b/libavcodec/aarch64/h264dsp_init_aarch64.c
|
||||||
|
index c684574..b993df2 100644
|
||||||
|
--- a/libavcodec/aarch64/h264dsp_init_aarch64.c
|
||||||
|
+++ b/libavcodec/aarch64/h264dsp_init_aarch64.c
|
||||||
|
@@ -66,6 +66,7 @@ void ff_biweight_h264_pixels_4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride
|
||||||
|
int weights, int offset);
|
||||||
|
|
||||||
|
void ff_h264_idct_add_neon(uint8_t *dst, int16_t *block, int stride);
|
||||||
|
+void ff_h264_idct_add_daedalus(uint8_t *dst, int16_t *block, int stride);
|
||||||
|
void ff_h264_idct_dc_add_neon(uint8_t *dst, int16_t *block, int stride);
|
||||||
|
void ff_h264_idct_add16_neon(uint8_t *dst, const int *block_offset,
|
||||||
|
int16_t *block, int stride,
|
||||||
|
@@ -139,7 +140,7 @@ av_cold void ff_h264dsp_init_aarch64(H264DSPContext *c, const int bit_depth,
|
||||||
|
c->biweight_pixels_tab[1] = ff_biweight_h264_pixels_8_neon;
|
||||||
|
c->biweight_pixels_tab[2] = ff_biweight_h264_pixels_4_neon;
|
||||||
|
|
||||||
|
- c->idct_add = ff_h264_idct_add_neon;
|
||||||
|
+ c->idct_add = ff_h264_idct_add_daedalus;
|
||||||
|
c->idct_dc_add = ff_h264_idct_dc_add_neon;
|
||||||
|
c->idct_add16 = ff_h264_idct_add16_neon;
|
||||||
|
c->idct_add16intra = ff_h264_idct_add16intra_neon;
|
||||||
|
--
|
||||||
|
2.47.3
|
||||||
|
|
||||||
@@ -24,8 +24,13 @@ _srcname=FFmpeg
|
|||||||
_version='8.1'
|
_version='8.1'
|
||||||
_commit='b57fbbe50c9b2656fad86a1a7eeabfd2b2a50935' # v4l2-request-n8.1 tip 2026-04-24
|
_commit='b57fbbe50c9b2656fad86a1a7eeabfd2b2a50935' # v4l2-request-n8.1 tip 2026-04-24
|
||||||
pkgver=8.1.r123329.b57fbbe
|
pkgver=8.1.r123329.b57fbbe
|
||||||
pkgrel=5
|
pkgrel=6 # pkgrel=6 — H.264 IDCT 4x4 daedalus-fourier substitution (2026-05-21)
|
||||||
epoch=2
|
epoch=2
|
||||||
|
|
||||||
|
# daedalus-fourier pin — first kernel substitution in libavcodec
|
||||||
|
# (cycle 6 H.264 IDCT 4x4). Same SHA as the daedalus-v4l2 daemon's
|
||||||
|
# inline build; lockstep with that until the public API rolls.
|
||||||
|
_daedalus_fourier_commit='d87239d8172307d9a1b93c95cbed116d175b85cc'
|
||||||
pkgdesc='FFmpeg with V4L2 Request API hwaccel (Rockchip / Allwinner stateless decode)'
|
pkgdesc='FFmpeg with V4L2 Request API hwaccel (Rockchip / Allwinner stateless decode)'
|
||||||
arch=('aarch64')
|
arch=('aarch64')
|
||||||
url='https://github.com/Kwiboo/FFmpeg'
|
url='https://github.com/Kwiboo/FFmpeg'
|
||||||
@@ -34,6 +39,7 @@ depends=(
|
|||||||
alsa-lib
|
alsa-lib
|
||||||
bzip2
|
bzip2
|
||||||
fontconfig
|
fontconfig
|
||||||
|
vulkan-icd-loader
|
||||||
fribidi
|
fribidi
|
||||||
gmp
|
gmp
|
||||||
gnutls
|
gnutls
|
||||||
@@ -59,10 +65,13 @@ depends=(
|
|||||||
zlib
|
zlib
|
||||||
)
|
)
|
||||||
makedepends=(
|
makedepends=(
|
||||||
|
cmake
|
||||||
git
|
git
|
||||||
linux-api-headers
|
linux-api-headers
|
||||||
mesa
|
mesa
|
||||||
nasm
|
nasm
|
||||||
|
ninja
|
||||||
|
vulkan-headers
|
||||||
)
|
)
|
||||||
provides=(
|
provides=(
|
||||||
libavcodec.so
|
libavcodec.so
|
||||||
@@ -78,9 +87,11 @@ provides=(
|
|||||||
conflicts=(ffmpeg)
|
conflicts=(ffmpeg)
|
||||||
replaces=(ffmpeg ffmpeg-v4l2-request-git)
|
replaces=(ffmpeg ffmpeg-v4l2-request-git)
|
||||||
source=("git+https://github.com/Kwiboo/FFmpeg.git#commit=${_commit}"
|
source=("git+https://github.com/Kwiboo/FFmpeg.git#commit=${_commit}"
|
||||||
|
"daedalus-fourier-${_daedalus_fourier_commit}.tar.gz::https://git.reauktion.de/marfrit/daedalus-fourier/archive/${_daedalus_fourier_commit}.tar.gz"
|
||||||
'0001-libudev-bypass-fallback.patch'
|
'0001-libudev-bypass-fallback.patch'
|
||||||
'0002-nv15-to-p010-unpack.patch')
|
'0002-nv15-to-p010-unpack.patch'
|
||||||
sha256sums=('SKIP' 'SKIP' 'SKIP')
|
'0003-h264-idct4-daedalus-fourier.patch')
|
||||||
|
sha256sums=('SKIP' 'SKIP' 'SKIP' 'SKIP' 'SKIP')
|
||||||
|
|
||||||
pkgver() {
|
pkgver() {
|
||||||
cd "${_srcname}"
|
cd "${_srcname}"
|
||||||
@@ -93,9 +104,25 @@ prepare() {
|
|||||||
cd "${_srcname}"
|
cd "${_srcname}"
|
||||||
patch -Np1 -i "${srcdir}/0001-libudev-bypass-fallback.patch"
|
patch -Np1 -i "${srcdir}/0001-libudev-bypass-fallback.patch"
|
||||||
patch -Np1 -i "${srcdir}/0002-nv15-to-p010-unpack.patch"
|
patch -Np1 -i "${srcdir}/0002-nv15-to-p010-unpack.patch"
|
||||||
|
patch -Np1 -i "${srcdir}/0003-h264-idct4-daedalus-fourier.patch"
|
||||||
}
|
}
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
|
# --- daedalus-fourier: build static .a with PIC, install to a
|
||||||
|
# per-build prefix; libavcodec.so links it into the shared object so
|
||||||
|
# H264DSPContext.idct_add (and follow-up kernels) dispatch through
|
||||||
|
# the daedalus recipe layer instead of the in-tree NEON .S code. ---
|
||||||
|
local _fourier_prefix="${srcdir}/fourier-prefix"
|
||||||
|
mkdir -p "${_fourier_prefix}"
|
||||||
|
pushd "${srcdir}"/daedalus-fourier >/dev/null
|
||||||
|
cmake -B build -G Ninja \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
|
||||||
|
-DCMAKE_INSTALL_PREFIX="${_fourier_prefix}"
|
||||||
|
cmake --build build --target daedalus_core
|
||||||
|
cmake --install build
|
||||||
|
popd >/dev/null
|
||||||
|
|
||||||
cd "${_srcname}"
|
cd "${_srcname}"
|
||||||
|
|
||||||
# FFmpeg's configure resolves the compiler via `which` and bakes the
|
# FFmpeg's configure resolves the compiler via `which` and bakes the
|
||||||
@@ -147,6 +174,9 @@ build() {
|
|||||||
--enable-libx265 \
|
--enable-libx265 \
|
||||||
--enable-libwebp \
|
--enable-libwebp \
|
||||||
\
|
\
|
||||||
|
--extra-cflags="-I${_fourier_prefix}/include" \
|
||||||
|
--extra-ldflags="-L${_fourier_prefix}/lib" \
|
||||||
|
--extra-libs="-ldaedalus_core -lvulkan -lpthread" \
|
||||||
--host-cflags='-fPIC'
|
--host-cflags='-fPIC'
|
||||||
|
|
||||||
make
|
make
|
||||||
|
|||||||
@@ -18,27 +18,30 @@ This patch adds a sibling init path, `InitV4L2RequestDecoder`, that:
|
|||||||
* looks up the codec via two complementary mechanisms libavcodec
|
* looks up the codec via two complementary mechanisms libavcodec
|
||||||
uses for v4l2_request:
|
uses for v4l2_request:
|
||||||
- **named codec** (`h264_v4l2request`, `vp8_v4l2request`, etc.):
|
- **named codec** (`h264_v4l2request`, `vp8_v4l2request`, etc.):
|
||||||
the legacy AVCodec-per-hwaccel registration. ALARM, Debian,
|
the legacy AVCodec-per-hwaccel registration.
|
||||||
and most distros building with --enable-v4l2-request expose
|
- **generic codec + hw_configs walk**: the modern hwaccel
|
||||||
this (avcodec_find_decoder_by_name lookup).
|
registration. Accepts EITHER AV_HWDEVICE_TYPE_DRM (legacy
|
||||||
- **generic codec + AV_HWDEVICE_TYPE_DRM** in `hw_configs`:
|
ffmpeg-v4l2-request-fork output prior to FFmpeg 7.1) OR
|
||||||
the modern hwaccel registration on some upstream-only ffmpeg
|
AV_HWDEVICE_TYPE_V4L2REQUEST (FFmpeg 7.1+ dedicated enum,
|
||||||
builds.
|
value 13 on Kwiboo's no-AMF tree, 14 on upstream-AMF tree).
|
||||||
|
Mozilla's bundled libavutil headers may not have the V4L2REQUEST
|
||||||
|
enumerator, so the test is on the integer value via `(int)cast`.
|
||||||
Probes named-codec first (explicit, portable) and falls back to
|
Probes named-codec first (explicit, portable) and falls back to
|
||||||
walking the generic codec's `hw_configs` for the DRM device type;
|
walking the generic codec's `hw_configs` for either device type;
|
||||||
* creates an `AV_HWDEVICE_TYPE_DRM` hwdevice context bound to
|
* creates an hwdevice context bound to `/dev/dri/renderD128`. Uses
|
||||||
`/dev/dri/renderD128` via the new `av_hwdevice_ctx_create` wrapper
|
integer 13 (V4L2REQUEST as defined by Kwiboo's v4l2-request-n7.1.3
|
||||||
(patch 2/4) and attaches it to the codec context;
|
tree, what our libavcodec61-fourier emits) cast to enum
|
||||||
|
AVHWDeviceType for the av_hwdevice_ctx_create call;
|
||||||
* reuses the existing `ChooseV4L2PixelFormat` get-format callback
|
* reuses the existing `ChooseV4L2PixelFormat` get-format callback
|
||||||
(already returns `AV_PIX_FMT_DRM_PRIME`) and the existing
|
(already returns `AV_PIX_FMT_DRM_PRIME`) and the existing
|
||||||
`apply_cropping = 0` constraint.
|
`apply_cropping = 0` constraint.
|
||||||
|
|
||||||
`InitV4L2RequestDecoder` is invoked **before** `InitV4L2Decoder` in
|
`InitV4L2RequestDecoder` is invoked **before** `InitV4L2Decoder` in
|
||||||
`InitHWDecoderIfAllowed`. On Rockchip mainline it succeeds via either
|
`InitHWDecoderIfAllowed`. On Rockchip mainline it succeeds via either
|
||||||
mechanism (ALARM uses the named codec). On Pi4 / Mediatek /
|
mechanism. On Pi4 / Mediatek / vendor-MPP-stateful boards neither
|
||||||
vendor-MPP-stateful boards neither mechanism is registered for the
|
mechanism is registered for the codec, the function bails out, and the
|
||||||
codec, the function bails out, and the existing stateful
|
existing stateful `InitV4L2Decoder` runs as before. No regression of
|
||||||
`InitV4L2Decoder` runs as before. No regression of stateful boards.
|
stateful boards.
|
||||||
|
|
||||||
`mDRMDeviceContext` is unconditionally `av_buffer_unref`'d in
|
`mDRMDeviceContext` is unconditionally `av_buffer_unref`'d in
|
||||||
`ProcessShutdown` (no-op when null). Gated behind
|
`ProcessShutdown` (no-op when null). Gated behind
|
||||||
@@ -46,9 +49,8 @@ codec, the function bails out, and the existing stateful
|
|||||||
|
|
||||||
Bug 1969297.
|
Bug 1969297.
|
||||||
|
|
||||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h
|
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h 2026-05-21 04:57:59.570946601 +0000
|
||||||
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h 2026-03-18 19:22:14.000000000 +0000
|
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h 2026-05-21 04:57:59.876488776 +0000
|
||||||
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h 2026-04-27 20:43:39.347992674 +0000
|
|
||||||
@@ -225,7 +225,12 @@
|
@@ -225,7 +225,12 @@
|
||||||
bool IsLinuxHDR() const;
|
bool IsLinuxHDR() const;
|
||||||
MediaResult InitVAAPIDecoder();
|
MediaResult InitVAAPIDecoder();
|
||||||
@@ -73,9 +75,8 @@ diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h b/dom/media/platfor
|
|||||||
// If video overlay is used we want to upload SW decoded frames to
|
// If video overlay is used we want to upload SW decoded frames to
|
||||||
// DMABuf and present it as a external texture to rendering pipeline.
|
// DMABuf and present it as a external texture to rendering pipeline.
|
||||||
bool mUploadSWDecodeToDMABuf = false;
|
bool mUploadSWDecodeToDMABuf = false;
|
||||||
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
|
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp 2026-05-21 04:57:59.566685221 +0000
|
||||||
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp 2026-04-27 16:09:10.000000000 +0200
|
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp 2026-05-21 04:58:00.136004159 +0000
|
||||||
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp 2026-04-29 00:10:00.098884335 +0200
|
|
||||||
@@ -403,6 +403,129 @@
|
@@ -403,6 +403,129 @@
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@@ -90,7 +91,7 @@ diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platf
|
|||||||
+ }
|
+ }
|
||||||
+ const char* drmDevice = "/dev/dri/renderD128";
|
+ const char* drmDevice = "/dev/dri/renderD128";
|
||||||
+ if (mLib->av_hwdevice_ctx_create(&mDRMDeviceContext,
|
+ if (mLib->av_hwdevice_ctx_create(&mDRMDeviceContext,
|
||||||
+ AV_HWDEVICE_TYPE_DRM, drmDevice,
|
+ (enum AVHWDeviceType)13, drmDevice,
|
||||||
+ nullptr, 0) < 0) {
|
+ nullptr, 0) < 0) {
|
||||||
+ FFMPEG_LOG(" av_hwdevice_ctx_create(DRM, %s) failed", drmDevice);
|
+ FFMPEG_LOG(" av_hwdevice_ctx_create(DRM, %s) failed", drmDevice);
|
||||||
+ return false;
|
+ return false;
|
||||||
@@ -143,7 +144,7 @@ diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platf
|
|||||||
+ for (int i = 0;; i++) {
|
+ for (int i = 0;; i++) {
|
||||||
+ const AVCodecHWConfig* cfg = mLib->avcodec_get_hw_config(generic, i);
|
+ const AVCodecHWConfig* cfg = mLib->avcodec_get_hw_config(generic, i);
|
||||||
+ if (!cfg) break;
|
+ if (!cfg) break;
|
||||||
+ if (cfg->device_type == AV_HWDEVICE_TYPE_DRM) {
|
+ if (cfg->device_type == AV_HWDEVICE_TYPE_DRM || (int)cfg->device_type == 13 || (int)cfg->device_type == 14) {
|
||||||
+ codec = generic;
|
+ codec = generic;
|
||||||
+ FFMPEG_LOG(" using generic codec %s with DRM hwaccel", codec->name);
|
+ FFMPEG_LOG(" using generic codec %s with DRM hwaccel", codec->name);
|
||||||
+ break;
|
+ break;
|
||||||
|
|||||||
@@ -21,27 +21,32 @@
|
|||||||
# 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. c454618 = PR #16 merge "picture, request_pool:
|
||||||
# on S_EXT_CTRLS failure" — Phase 8.13 diagnostic that surfaced the
|
# transparent OUTPUT-pool resize on bitstream overrun (#15)" —
|
||||||
# real root cause of the libva→daedalus_v4l2 request-completion
|
# follow-up root-cause fix to #13/#14. On a mid-stream bitstream-
|
||||||
# timeout (turned out the EINVAL libva was logging was a harmless
|
# budget overrun (typical cause: SPS-driven resolution upshift in an
|
||||||
# H264/HEVC probe; actual VP9 stateless control SET worked all along).
|
# adaptive-bitrate stream), codec_store_buffer now snapshots the in-
|
||||||
|
# flight surface's accumulated bytes, releases its OUTPUT pool slot,
|
||||||
|
# calls request_pool_resize (STREAMOFF → REQBUFS(0) → S_FMT with
|
||||||
|
# 2×sizeimage hint, capped at 1 GiB, page-aligned → CREATE_BUFS →
|
||||||
|
# mmap → media_request_alloc → STREAMON), re-acquires a slot, re-
|
||||||
|
# mirrors the surface's source_{data,size,request_fd}, restores the
|
||||||
|
# bytes, and continues. The frame survives instead of being dropped
|
||||||
|
# back to libavcodec for surface recreation. CAPTURE side untouched
|
||||||
|
# (per-queue V4L2 streaming independence).
|
||||||
#
|
#
|
||||||
# Prior pin (7ac934e) was iter38b — fresnel-fourier multi-device probe
|
# Prior pin (2860d75) = PR #14 merge — codec_store_buffer bounds-
|
||||||
# + MAX_PROFILES bounds-check fix. de27e95 adds the daedalus_v4l2
|
# check floor (#13).
|
||||||
# probe slot (b5b3acf), the meson option gate (2146341), and the
|
_commit=c454618ae11addce2e17b560f4deeacbed067d98
|
||||||
# S_EXT_CTRLS diagnostic (de27e95 itself). Backward-compatible on
|
|
||||||
# rkvdec / hantro / cedrus / rpi-hevc-dec hosts — daedalus probe is
|
|
||||||
# off by default unless the kernel module is present.
|
|
||||||
_commit=de27e95571b67ef34619c23a12db4698f9b3454e
|
|
||||||
|
|
||||||
# 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.r390.c454618
|
||||||
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')
|
||||||
|
|||||||
+3291
-6248
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
pkgbase=linux-pinetab2-danctnix-besser
|
pkgbase=linux-pinetab2-danctnix-besser
|
||||||
pkgver=7.0.danctnix1
|
pkgver=7.0.danctnix1
|
||||||
pkgrel=6
|
pkgrel=5
|
||||||
pkgdesc='PineTab2 (BESser bes2600 driver patchset, kernel-agent managed)'
|
pkgdesc='PineTab2 (BESser bes2600 driver patchset, kernel-agent managed)'
|
||||||
_srcname=linux-pinetab2
|
_srcname=linux-pinetab2
|
||||||
_srctag=v${pkgver%.*}-${pkgver##*.}
|
_srctag=v${pkgver%.*}-${pkgver##*.}
|
||||||
@@ -68,7 +68,7 @@ b2sums=('3d9795083c8938f80f480de0d10bfd9c525640e59d5c7f22983de3f12ee42c84c31be90
|
|||||||
'SKIP'
|
'SKIP'
|
||||||
'71fe98221e802b315e54b4b10d3e8c8f376695a36bae3541d876e5776a37f3fa33c8f8dfa6e51fcbd6f5396add02e5166634165f2351836a0ea0453c172fe56c'
|
'71fe98221e802b315e54b4b10d3e8c8f376695a36bae3541d876e5776a37f3fa33c8f8dfa6e51fcbd6f5396add02e5166634165f2351836a0ea0453c172fe56c'
|
||||||
'SKIP'
|
'SKIP'
|
||||||
'eb179c03f35a4dbaec2e40036f0033ef04985bb6b14ab22419d68e5caaa5874f2ad14e158f7c5b05added97f60fecde8fb8b7f2a6ced33e031e37352fe776ca6'
|
'50397711a6a3ba522283685a9e7397aeed6663f353f7cba214d4bb88bc98516065b2fca9a36ce13c52644617879f69f39c5305e86db5d9fb25c4dae5434eb9c4'
|
||||||
'656a998ab40cb85ee4c00f087b071a91632a6c091da2c84b0f74236b51d2dea6e9db6886625f80ad81dc249d8494ec47cd79d6dd9ea4f5e44f3cde857f861e10')
|
'656a998ab40cb85ee4c00f087b071a91632a6c091da2c84b0f74236b51d2dea6e9db6886625f80ad81dc249d8494ec47cd79d6dd9ea4f5e44f3cde857f861e10')
|
||||||
|
|
||||||
export KBUILD_BUILD_HOST=archlinux
|
export KBUILD_BUILD_HOST=archlinux
|
||||||
|
|||||||
@@ -4,174 +4,34 @@ baseline:
|
|||||||
upstream_compat: linux-7.0
|
upstream_compat: linux-7.0
|
||||||
url: https://codeberg.org/DanctNIX/linux-pinetab2
|
url: https://codeberg.org/DanctNIX/linux-pinetab2
|
||||||
cumulative:
|
cumulative:
|
||||||
b2sum: eb179c03f35a4dbaec2e40036f0033ef04985bb6b14ab22419d68e5caaa5874f2ad14e158f7c5b05added97f60fecde8fb8b7f2a6ced33e031e37352fe776ca6
|
b2sum: 50397711a6a3ba522283685a9e7397aeed6663f353f7cba214d4bb88bc98516065b2fca9a36ce13c52644617879f69f39c5305e86db5d9fb25c4dae5434eb9c4
|
||||||
path: cumulative.patch
|
path: cumulative.patch
|
||||||
size: 279554
|
size: 162716
|
||||||
generated_at: '2026-05-19T13:05:46.476359+00:00'
|
generated_at: '2026-05-18T17:16:06.455474+00:00'
|
||||||
host: ohm
|
host: ohm
|
||||||
ka_promote_version: 1
|
ka_promote_version: 1
|
||||||
manifest:
|
manifest:
|
||||||
path: fleet/ohm.yaml
|
path: fleet/ohm.yaml
|
||||||
sha256: 9ac04ddd3170418b7b2d2cf7b31ac225a31ed19be4f03e8477bf28b585bae257
|
sha256: da59ac2c965e5ad9c5004a115b10a37abf47ed3ecc8b7f5ab426470d2ee7b442
|
||||||
resolved_patches:
|
resolved_patches:
|
||||||
- apply_order: 1
|
- apply_order: 1
|
||||||
from_series: true
|
from_series: true
|
||||||
include: driver/bes2600/factory-series/0001-bes2600-use-request_firmware-for-factory.txt-read.patch
|
include: driver/bes2600/cumulative-c5x-danctnix/0001-bes2600-besser-cumulative-series.patch
|
||||||
sha256: a1bc2d13b258709fa37c9ff428dfdc0659464b436470fa2ec69b07edf7592f6f
|
sha256: e477a170567487fef84fe13be5b0a1f0498247ff1f201000d0085a2e49ff9026
|
||||||
size: 5456
|
size: 148149
|
||||||
- apply_order: 2
|
- apply_order: 2
|
||||||
from_series: true
|
from_series: true
|
||||||
include: driver/bes2600/factory-series/0002-bes2600-default-STANDARD_FACTORY_EFUSE_FLAG-off-for-PineTab2.patch
|
include: driver/bes2600/scan-filter-5ghz-danctnix/0001-bes2600-filter-5ghz-scan-and-allow-single-channel.patch
|
||||||
sha256: 577d7024ce0b342c4381365872fc29e75a93427ad61223907fead8b829b5a86c
|
|
||||||
size: 3499
|
|
||||||
- apply_order: 3
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/factory-thread-dev/0001-bes2600-thread-struct-device-through-factory-request_firmware.patch
|
|
||||||
sha256: e3fac725e6addc11147341836600c2c5cd0116abba960f34ba50bb8094581c75
|
|
||||||
size: 4406
|
|
||||||
- apply_order: 4
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/pm-gate-on-handshake/0001-bes2600-gate-device-LP-mode-entry-on-successful-handshake.patch
|
|
||||||
sha256: 9842c0dd66f59fe28898041ba5a816be56965b0665f202410cd461c3e6565474
|
|
||||||
size: 3914
|
|
||||||
- apply_order: 5
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/remove-chardev-user-interface/0001-bes2600-remove-userspace-dev-bes2600-character-device-interface.patch
|
|
||||||
sha256: c67d340ae5923aada613ea9c5133e3efa3aeb7986749f4bf3619d1752a1b61fb
|
|
||||||
size: 22445
|
|
||||||
- apply_order: 6
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/enable-testmode/0001-bes2600-enable-CONFIG_BES2600_TESTMODE-by-default-fix-bitrot.patch
|
|
||||||
sha256: 5dee74e8753d332fd380882994ea43aa907d1ff97466b0c48aedf38d4076e446
|
|
||||||
size: 6152
|
|
||||||
- apply_order: 7
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/tx-sdio-dma-oob-danctnix/0001-bes2600-bounce-SDIO-TX-buffers-to-avoid-DMA-OOB-read.patch
|
|
||||||
sha256: 0dce2fe35450b8376c2d2a7c007119f28c888c1c30b489a67841039caedeebfc
|
|
||||||
size: 4544
|
|
||||||
- apply_order: 8
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/factory-drop-kernel-write-danctnix/0001-bes2600-drop-kernel_write-persistence-from-factory-cali-save.patch
|
|
||||||
sha256: a7995b38e210af16b73d284a58ab39b8aecac36ff4a671af3d894b1983f961b3
|
|
||||||
size: 5704
|
|
||||||
- apply_order: 9
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/drop-dpd-file-paths-danctnix/0001-bes2600-drop-BES2600_WRITE_DPD_TO_FILE-kernel-file-paths.patch
|
|
||||||
sha256: 0cd8780c245c97c65e4845e42d712c6256a0449658641aea18e4c7d400f63e41
|
|
||||||
size: 9661
|
|
||||||
- apply_order: 10
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/drop-orphan-file-io-danctnix/0001-bes2600-drop-orphan-DATA_DUMP_OBSERVE-and-access_file-IO.patch
|
|
||||||
sha256: fd8c297223e6a985c2898f919ae1ab27eb56ab44f09f44d84d75eb35a187527b
|
|
||||||
size: 5327
|
|
||||||
- apply_order: 11
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/pm-timeout-silence-danctnix/0001-bes2600-demote-wait-pm-ind-timeout-from-bes_err-to-bes_devel.patch
|
|
||||||
sha256: 3a4fd3255facbcef0419e0e0332cb980316529aa5c225b35bcfd244a42736667
|
|
||||||
size: 2332
|
|
||||||
- apply_order: 12
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/scan-defer-on-reject-danctnix/0001-bes2600-defer-scan-and-soften-WARN-on-firmware-reject.patch
|
|
||||||
sha256: 55e16c176bc147c371a20f57b3a57da38c719d3b42417e88f9de243e10102d35
|
|
||||||
size: 8393
|
|
||||||
- apply_order: 13
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/scan-defer-backoff-tune-danctnix/0001-bes2600-widen-scan-defer-backoff-30s-and-decay-on-quiet.patch
|
|
||||||
sha256: 70a5b25baaf41c8090701b069c30cbad378883d828bdd06e4eb560a35bc077f1
|
|
||||||
size: 4924
|
|
||||||
- apply_order: 14
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/lmac-recover-via-mmc-hw-reset-danctnix/0001-bes2600-recover-wedged-firmware-via-mmc_hw_reset-on-link-break.patch
|
|
||||||
sha256: 3decf33c9684b3aba64004d5ad97ae3d54e1d6dc176d0b0ae539036c65e6dc6c
|
|
||||||
size: 10604
|
|
||||||
- apply_order: 15
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/lmac-recover-via-mmc-hw-reset-danctnix/0002-bes2600-handle-multi-function-SDIO-cards-in-mmc_hw_reset-bus_reset.patch
|
|
||||||
sha256: a1acfcc401afc699a9c3676b6df2ec0f092e78826a32616268f90b509d538e33
|
|
||||||
size: 3321
|
|
||||||
- apply_order: 16
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/pm-state-resync-danctnix/0001-bes2600-gate-PM-indication-completion-on-pending-request-and-track-state.patch
|
|
||||||
sha256: 049cf3ff9c01fdd10ff73bd18497e14ef0cd8fd1a65486ba86fbc6c1935a5f8e
|
|
||||||
size: 10269
|
|
||||||
- apply_order: 17
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/pm-wake-consume-state-danctnix/0001-bes2600-short-circuit-wake-handshake-when-chip-confirmed-ACTIVE.patch
|
|
||||||
sha256: c9d19a73816f4c82b418dcd18008176bbb0c49fd4138be53cad45ae142224112
|
|
||||||
size: 8100
|
|
||||||
- apply_order: 18
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/pm-detect-firmware-unsupported-danctnix/0001-bes2600-self-detect-firmware-does-not-honor-PSM-skip-cycle.patch
|
|
||||||
sha256: 196dc9d51ffea268718a290d434b6237fb60119f10c2b050a58724c8a775c7a8
|
|
||||||
size: 9041
|
|
||||||
- apply_order: 19
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/decrypt-storm-fast-recover-danctnix/0001-bes2600-pre-empt-AP-deauth-6-mac80211-reassoc-on-decrypt-fail-storm.patch
|
|
||||||
sha256: b57ed316005f402c95ccae8ab24ac761bdf34162d73f108f5790af8f8ad2d1fe
|
|
||||||
size: 9249
|
|
||||||
- apply_order: 20
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/connection-loss-fast-recover-danctnix/0001-bes2600-bus_reset-on-connection-loss-storm-to-dodge-assoc-comeback-blackhole.patch
|
|
||||||
sha256: cd1eaff97c3f08c58e7b1588e19a12200e8bb2a1f39afe554284f1d818610a67
|
|
||||||
size: 12184
|
|
||||||
- apply_order: 21
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/cw1200-fix-backports-danctnix/0001-bes2600-replace-atomic_add-with-atomic_inc-cw1200-backport.patch
|
|
||||||
sha256: 3876c9e512f556c7f2e8d4cfaba1d7df2945ee48af8edfab5f8d09d9de9adf23
|
|
||||||
size: 3080
|
|
||||||
- apply_order: 22
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/cw1200-fix-backports-danctnix/0002-bes2600-fix-missing-destroy_workqueue-on-error-in-init_common.patch
|
|
||||||
sha256: 2b82ecb127748349780404479205b952337c244e715278e6d40471c6ecad7602
|
|
||||||
size: 2230
|
|
||||||
- apply_order: 23
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/cw1200-fix-backports-danctnix/0003-bes2600-fix-concurrency-UAF-in-bes2600_hw_scan-and-sched_scan.patch
|
|
||||||
sha256: 4c1850ad003ddcac543d3d61edd15c18ccd0cc601367cf4c6dd31e1fbb39ab16
|
|
||||||
size: 4476
|
|
||||||
- apply_order: 24
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/sdio-rx-no-relay-danctnix/0001-bes2600-drop-sdio_rx_work-relay-IRQ-bh-direct-no-relay-architecture.patch
|
|
||||||
sha256: f1182150c5893f2497f942900b34c9c4aeb8d5901d9786ae2753dcce38ed6c78
|
|
||||||
size: 19313
|
|
||||||
- apply_order: 25
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/license-spdx-restore-attribution-danctnix/0001-bes2600-Patch-G-restore-SPDX-identifiers-ST-Ericsson-attribution.patch
|
|
||||||
sha256: 91dadab0b58f8b8ad2dca80fd04796d478ecb83ce94a1e4b6e97ef8634d97ef1
|
|
||||||
size: 41521
|
|
||||||
- apply_order: 26
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/ba-lock-atomic-danctnix/0001-bes2600-Patch-D-atomicize-ba_lock-counters-drop-the-spinlock.patch
|
|
||||||
sha256: a5d4ed2bf545458a756e65670c7eed31997bd0be9262344a10313bee31ea4963
|
|
||||||
size: 11987
|
|
||||||
- apply_order: 27
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/ps-state-lock-skip-pm-disabled-danctnix/0001-bes2600-Patch-E-skip-ps_state_lock-when-PSM-known-disabled.patch
|
|
||||||
sha256: 18040a563b37cc95c558703f01bfbf6b7fa23a52f2f4f0f8f1254ad4fa0fe0d6
|
|
||||||
size: 3396
|
|
||||||
- apply_order: 28
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/rx-list-batch-delivery-danctnix/0001-bes2600-Patch-C2-replace-ieee80211_rx_irqsafe-with-ieee80211_rx_ni.patch
|
|
||||||
sha256: ffeffd085a9d052c126a717b845d50120ea302e76c12e53c0c3c891291cababf
|
|
||||||
size: 8377
|
|
||||||
- apply_order: 29
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/bh-c-fossil-cleanup-danctnix/0001-bes2600-Patch-H-bh.c-hygiene-cleanup-drop-fossil-blocks-dead-stubs.patch
|
|
||||||
sha256: 8fb0c799e3a8ee5ad7bfb647fceaf370c6a1a5f24d8621776fd07bf18a976f81
|
|
||||||
size: 21082
|
|
||||||
- apply_order: 30
|
|
||||||
from_series: true
|
|
||||||
include: driver/bes2600/scan-filter-5ghz-danctnix/0001-bes2600-filter-5-GHz-scans-at-the-driver-boundary.patch
|
|
||||||
sha256: 31e67569e00daead0784214aced1e077d3270cf1407baa0b330d474e17ec3931
|
sha256: 31e67569e00daead0784214aced1e077d3270cf1407baa0b330d474e17ec3931
|
||||||
size: 7735
|
size: 7735
|
||||||
- apply_order: 31
|
- apply_order: 3
|
||||||
from_series: true
|
from_series: true
|
||||||
include: arch/arm64/scs-arm-neon-build-fix/0001-arm64-xor-neon-ffixed-x18-build-fix.patch
|
include: arch/arm64/xor-neon-ffixed-x18-scs-build-fix-danctnix/0001-arm64-xor-neon-ffixed-x18-build-fix.patch
|
||||||
sha256: 105e32edc54743d8107c4dcd846833ae97d2df5f918aebc9fe3e67d6f23249cc
|
sha256: a49c50f0ebffc499970c24908b832c3e61c96ed87de35b3a82178eff587f94f1
|
||||||
size: 1562
|
size: 1574
|
||||||
- apply_order: 32
|
- apply_order: 4
|
||||||
from_series: true
|
from_series: true
|
||||||
include: driver/bes2600/queue-pending-record-lock-bh-danctnix/0001-bes2600-take-pending-record-lock-with-bh.patch
|
include: driver/bes2600/queue-pending-record-lock-bh-danctnix/0001-bes2600-take-pending-record-lock-with-bh.patch
|
||||||
sha256: e0894371c43f750590e1704ae3c77b27b6910548afa4a5b61ebc4d9919580ca2
|
sha256: 089862e5f6da5783ed0db979144e4fa07cff7f743809a0bebd715c75a3bb8eb5
|
||||||
size: 5270
|
size: 5258
|
||||||
schema_version: 1
|
schema_version: 1
|
||||||
|
|||||||
@@ -0,0 +1,328 @@
|
|||||||
|
--- a/src/panfrost/vulkan/panvk_shader.h 2026-04-29 22:19:00.000000000 +0200
|
||||||
|
+++ b/src/panfrost/vulkan/panvk_shader.h 2026-05-20 18:52:53.312698258 +0200
|
||||||
|
@@ -150,6 +150,10 @@
|
||||||
|
struct {
|
||||||
|
#if PAN_ARCH < 9
|
||||||
|
int32_t raw_vertex_offset;
|
||||||
|
+ uint32_t num_vertices; /* iter13: XFB needs per-draw vertex count */
|
||||||
|
+ /* aligned_u64 attribute below inserts the 4-byte alignment gap
|
||||||
|
+ * after num_vertices automatically — no explicit pad needed. */
|
||||||
|
+ aligned_u64 xfb_address[4]; /* iter13: 4 transform feedback buffer base addresses */
|
||||||
|
#endif
|
||||||
|
int32_t first_vertex;
|
||||||
|
int32_t base_instance;
|
||||||
|
--- a/src/panfrost/vulkan/panvk_vX_physical_device.c 2026-05-20 19:09:29.711145446 +0200
|
||||||
|
+++ b/src/panfrost/vulkan/panvk_vX_physical_device.c 2026-05-20 18:52:54.832720445 +0200
|
||||||
|
@@ -169,6 +169,7 @@
|
||||||
|
.EXT_provoking_vertex = true,
|
||||||
|
.EXT_queue_family_foreign = true,
|
||||||
|
.EXT_robustness2 = true,
|
||||||
|
+ .EXT_transform_feedback = PAN_ARCH < 9, /* iter13: JM-class only for now */
|
||||||
|
.EXT_sampler_filter_minmax = PAN_ARCH >= 10,
|
||||||
|
.EXT_scalar_block_layout = true,
|
||||||
|
.EXT_separate_stencil_usage = true,
|
||||||
|
@@ -495,6 +496,10 @@
|
||||||
|
.robustImageAccess2 = false,
|
||||||
|
.nullDescriptor = true,
|
||||||
|
|
||||||
|
+ /* VK_EXT_transform_feedback (iter13) */
|
||||||
|
+ .transformFeedback = PAN_ARCH < 9,
|
||||||
|
+ .geometryStreams = false,
|
||||||
|
+
|
||||||
|
/* VK_KHR_shader_clock */
|
||||||
|
.shaderSubgroupClock = device->kmod.dev->props.gpu_can_query_timestamp,
|
||||||
|
.shaderDeviceClock = device->kmod.dev->props.timestamp_device_coherent,
|
||||||
|
@@ -1020,6 +1025,18 @@
|
||||||
|
.robustStorageBufferAccessSizeAlignment = 1,
|
||||||
|
.robustUniformBufferAccessSizeAlignment = 1,
|
||||||
|
|
||||||
|
+ /* VK_EXT_transform_feedback (iter13) */
|
||||||
|
+ .maxTransformFeedbackStreams = 1,
|
||||||
|
+ .maxTransformFeedbackBuffers = 4,
|
||||||
|
+ .maxTransformFeedbackBufferSize = UINT32_MAX,
|
||||||
|
+ .maxTransformFeedbackStreamDataSize = 512,
|
||||||
|
+ .maxTransformFeedbackBufferDataSize = 512,
|
||||||
|
+ .maxTransformFeedbackBufferDataStride = 2048,
|
||||||
|
+ .transformFeedbackQueries = false,
|
||||||
|
+ .transformFeedbackStreamsLinesTriangles = false,
|
||||||
|
+ .transformFeedbackRasterizationStreamSelect = false,
|
||||||
|
+ .transformFeedbackDraw = false,
|
||||||
|
+
|
||||||
|
/* VK_EXT_shader_object */
|
||||||
|
/* We do not currently support VK_EXT_shader_object but this is used
|
||||||
|
* internally by vk_shader
|
||||||
|
--- a/src/panfrost/vulkan/panvk_vX_shader.c 2026-04-29 22:19:00.000000000 +0200
|
||||||
|
+++ b/src/panfrost/vulkan/panvk_vX_shader.c 2026-05-20 18:52:56.556745611 +0200
|
||||||
|
@@ -21,6 +21,7 @@
|
||||||
|
#include "panvk_physical_device.h"
|
||||||
|
#include "panvk_sampler.h"
|
||||||
|
#include "panvk_shader.h"
|
||||||
|
+#include "pan_nir.h" /* iter13: pan_nir_lower_xfb */
|
||||||
|
|
||||||
|
#include "spirv/nir_spirv.h"
|
||||||
|
#include "util/memstream.h"
|
||||||
|
@@ -100,6 +101,20 @@
|
||||||
|
case nir_intrinsic_load_raw_vertex_offset_pan:
|
||||||
|
val = load_sysval(b, graphics, bit_size, vs.raw_vertex_offset);
|
||||||
|
break;
|
||||||
|
+ case nir_intrinsic_load_num_vertices: /* iter13: XFB index calc */
|
||||||
|
+ val = load_sysval(b, graphics, bit_size, vs.num_vertices);
|
||||||
|
+ break;
|
||||||
|
+ case nir_intrinsic_load_xfb_address: { /* iter13: XFB buffer N base address */
|
||||||
|
+ unsigned idx = nir_intrinsic_base(intr);
|
||||||
|
+ switch (idx) {
|
||||||
|
+ case 0: val = load_sysval(b, graphics, bit_size, vs.xfb_address[0]); break;
|
||||||
|
+ case 1: val = load_sysval(b, graphics, bit_size, vs.xfb_address[1]); break;
|
||||||
|
+ case 2: val = load_sysval(b, graphics, bit_size, vs.xfb_address[2]); break;
|
||||||
|
+ case 3: val = load_sysval(b, graphics, bit_size, vs.xfb_address[3]); break;
|
||||||
|
+ default: return false;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
case nir_intrinsic_load_layer_id:
|
||||||
|
assert(b->shader->info.stage == MESA_SHADER_FRAGMENT);
|
||||||
|
val = load_sysval(b, graphics, bit_size, layer_id);
|
||||||
|
@@ -457,6 +472,7 @@
|
||||||
|
core_max_id);
|
||||||
|
|
||||||
|
pan_preprocess_nir(nir, pdev->kmod.dev->props.gpu_id);
|
||||||
|
+
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -870,6 +886,18 @@
|
||||||
|
nir_var_shader_in | nir_var_shader_out, UINT32_MAX);
|
||||||
|
NIR_PASS(_, nir, nir_lower_io, nir_var_shader_in | nir_var_shader_out,
|
||||||
|
glsl_type_size, nir_lower_io_use_interpolated_input_intrinsics);
|
||||||
|
+
|
||||||
|
+#if PAN_ARCH < 9
|
||||||
|
+ /* iter13: VK_EXT_transform_feedback — runs AFTER nir_lower_io so that
|
||||||
|
+ * shader outputs are now store_output intrinsics that pan_nir_lower_xfb
|
||||||
|
+ * can rewrite to nir_store_global+nir_load_xfb_address. */
|
||||||
|
+ if (nir->info.stage == MESA_SHADER_VERTEX &&
|
||||||
|
+ nir->info.has_transform_feedback_varyings) {
|
||||||
|
+ NIR_PASS(_, nir, nir_opt_constant_folding);
|
||||||
|
+ NIR_PASS(_, nir, nir_io_add_intrinsic_xfb_info);
|
||||||
|
+ NIR_PASS(_, nir, pan_nir_lower_xfb);
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static VkResult
|
||||||
|
@@ -1288,6 +1316,9 @@
|
||||||
|
.view_mask = (state && state->rp) ? state->rp->view_mask : 0,
|
||||||
|
.robust2_modes = robust2_modes,
|
||||||
|
.robust_descriptors = dev->vk.enabled_features.nullDescriptor,
|
||||||
|
+ /* iter13: XFB shaders must disable IDVS (matches Panfrost-Gallium). */
|
||||||
|
+ .no_idvs = (info->stage == MESA_SHADER_VERTEX) &&
|
||||||
|
+ info->nir->info.has_transform_feedback_varyings,
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (info->stage) {
|
||||||
|
--- a/src/panfrost/vulkan/panvk_cmd_draw.h 2026-04-29 22:19:00.000000000 +0200
|
||||||
|
+++ b/src/panfrost/vulkan/panvk_cmd_draw.h 2026-05-20 18:52:57.748763011 +0200
|
||||||
|
@@ -135,6 +135,19 @@
|
||||||
|
struct panvk_graphics_sysvals sysvals;
|
||||||
|
|
||||||
|
#if PAN_ARCH < 9
|
||||||
|
+ /* iter13: VK_EXT_transform_feedback state (JM-class only for now). */
|
||||||
|
+ struct {
|
||||||
|
+ bool active;
|
||||||
|
+ uint32_t buffer_count;
|
||||||
|
+ struct {
|
||||||
|
+ uint64_t addr;
|
||||||
|
+ uint64_t offset;
|
||||||
|
+ uint64_t size;
|
||||||
|
+ } buffers[4];
|
||||||
|
+ } xfb;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#if PAN_ARCH < 9
|
||||||
|
struct panvk_shader_link link;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
--- a/src/panfrost/vulkan/panvk_vX_cmd_draw.c 2026-04-29 22:19:00.000000000 +0200
|
||||||
|
+++ b/src/panfrost/vulkan/panvk_vX_cmd_draw.c 2026-05-20 19:10:23.031919662 +0200
|
||||||
|
@@ -10,6 +10,7 @@
|
||||||
|
#include "panvk_entrypoints.h"
|
||||||
|
|
||||||
|
#include "pan_desc.h"
|
||||||
|
+#include "pan_compiler.h" /* PAN_SHADER_OOB_ADDRESS */
|
||||||
|
#include "pan_util.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -722,6 +723,35 @@
|
||||||
|
set_gfx_sysval(cmdbuf, dirty_sysvals, vs.raw_vertex_offset,
|
||||||
|
info->vertex.raw_offset);
|
||||||
|
set_gfx_sysval(cmdbuf, dirty_sysvals, layer_id, info->layer_id);
|
||||||
|
+
|
||||||
|
+ /* iter13: VK_EXT_transform_feedback sysvals — always set (per draw),
|
||||||
|
+ * reflect bound XFB state. set_gfx_sysval is a no-op if value unchanged. */
|
||||||
|
+ set_gfx_sysval(cmdbuf, dirty_sysvals, vs.num_vertices, info->vertex.count);
|
||||||
|
+ {
|
||||||
|
+ const struct panvk_cmd_graphics_state *_gfx = &cmdbuf->state.gfx;
|
||||||
|
+ /* iter13: default each XFB buffer address to PAN_SHADER_OOB_ADDRESS
|
||||||
|
+ * (= 1<<63). This is the Panfrost-Gallium memory-sink idiom — the
|
||||||
|
+ * Bifrost MMU silently discards stores to this address, so a pipeline
|
||||||
|
+ * with XFB outputs used in a non-XFB draw (or in an XFB draw with
|
||||||
|
+ * fewer bound buffers than the shader declares) is safe instead of
|
||||||
|
+ * faulting. See gallium/drivers/panfrost/pan_cmdstream.c PAN_SYSVAL_XFB. */
|
||||||
|
+ uint64_t _xa0 = PAN_SHADER_OOB_ADDRESS, _xa1 = PAN_SHADER_OOB_ADDRESS,
|
||||||
|
+ _xa2 = PAN_SHADER_OOB_ADDRESS, _xa3 = PAN_SHADER_OOB_ADDRESS;
|
||||||
|
+ if (_gfx->xfb.active) {
|
||||||
|
+ if (_gfx->xfb.buffer_count > 0 && _gfx->xfb.buffers[0].addr)
|
||||||
|
+ _xa0 = _gfx->xfb.buffers[0].addr + _gfx->xfb.buffers[0].offset;
|
||||||
|
+ if (_gfx->xfb.buffer_count > 1 && _gfx->xfb.buffers[1].addr)
|
||||||
|
+ _xa1 = _gfx->xfb.buffers[1].addr + _gfx->xfb.buffers[1].offset;
|
||||||
|
+ if (_gfx->xfb.buffer_count > 2 && _gfx->xfb.buffers[2].addr)
|
||||||
|
+ _xa2 = _gfx->xfb.buffers[2].addr + _gfx->xfb.buffers[2].offset;
|
||||||
|
+ if (_gfx->xfb.buffer_count > 3 && _gfx->xfb.buffers[3].addr)
|
||||||
|
+ _xa3 = _gfx->xfb.buffers[3].addr + _gfx->xfb.buffers[3].offset;
|
||||||
|
+ }
|
||||||
|
+ set_gfx_sysval(cmdbuf, dirty_sysvals, vs.xfb_address[0], _xa0);
|
||||||
|
+ set_gfx_sysval(cmdbuf, dirty_sysvals, vs.xfb_address[1], _xa1);
|
||||||
|
+ set_gfx_sysval(cmdbuf, dirty_sysvals, vs.xfb_address[2], _xa2);
|
||||||
|
+ set_gfx_sysval(cmdbuf, dirty_sysvals, vs.xfb_address[3], _xa3);
|
||||||
|
+ }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (dyn_gfx_state_dirty(cmdbuf, CB_BLEND_CONSTANTS)) {
|
||||||
|
--- a/src/panfrost/vulkan/meson.build 2026-04-29 22:19:00.000000000 +0200
|
||||||
|
+++ b/src/panfrost/vulkan/meson.build 2026-05-20 18:53:04.484861338 +0200
|
||||||
|
@@ -73,6 +73,7 @@
|
||||||
|
jm_inc_dir = ['jm']
|
||||||
|
jm_files = [
|
||||||
|
'jm/panvk_vX_bind_queue.c',
|
||||||
|
+ 'jm/panvk_vX_cmd_xfb.c', # iter13
|
||||||
|
'jm/panvk_vX_cmd_buffer.c',
|
||||||
|
'jm/panvk_vX_cmd_dispatch.c',
|
||||||
|
'jm/panvk_vX_cmd_draw.c',
|
||||||
|
--- a/src/panfrost/vulkan/jm/panvk_vX_cmd_buffer.c 2026-04-29 22:19:00.000000000 +0200
|
||||||
|
+++ b/src/panfrost/vulkan/jm/panvk_vX_cmd_buffer.c 2026-05-20 19:10:26.163965149 +0200
|
||||||
|
@@ -473,5 +473,12 @@
|
||||||
|
|
||||||
|
vk_command_buffer_begin(&cmdbuf->vk, pBeginInfo);
|
||||||
|
|
||||||
|
+#if PAN_ARCH < 9
|
||||||
|
+ /* iter13: clear XFB state on Begin so a reused command buffer does not
|
||||||
|
+ * inherit stale xfb.buffer_count / xfb.active / xfb.buffers[] from a
|
||||||
|
+ * prior recording. */
|
||||||
|
+ memset(&cmdbuf->state.gfx.xfb, 0, sizeof(cmdbuf->state.gfx.xfb));
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
return VK_SUCCESS;
|
||||||
|
}
|
||||||
|
--- a/src/panfrost/vulkan/jm/panvk_vX_cmd_xfb.c 2026-05-18 12:50:53.067999996 +0200
|
||||||
|
+++ b/src/panfrost/vulkan/jm/panvk_vX_cmd_xfb.c 2026-05-20 19:10:27.175979847 +0200
|
||||||
|
@@ -0,0 +1,111 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright © 2026 mfritsche / claude-noether
|
||||||
|
+ * SPDX-License-Identifier: MIT
|
||||||
|
+ *
|
||||||
|
+ * iter13: VK_EXT_transform_feedback command handlers for the JM
|
||||||
|
+ * architecture path (Bifrost v6/v7 + Valhall-JM v9).
|
||||||
|
+ *
|
||||||
|
+ * The runtime contract:
|
||||||
|
+ * - vkCmdBindTransformFeedbackBuffersEXT: stash (gpu_addr, offset, size)
|
||||||
|
+ * for each slot into cmdbuf->state.gfx.xfb.buffers[].
|
||||||
|
+ * - vkCmdBeginTransformFeedbackEXT: set cmdbuf->state.gfx.xfb.active = true.
|
||||||
|
+ * Mark sysvals dirty so the next draw re-emits vs.xfb_address[].
|
||||||
|
+ * - vkCmdEndTransformFeedbackEXT: set active = false.
|
||||||
|
+ *
|
||||||
|
+ * Counter buffers (firstCounterBuffer/counterBufferCount/pCounterBuffers/
|
||||||
|
+ * pCounterBufferOffsets) are accepted by API but ignored — v1 doesn't
|
||||||
|
+ * support pause/resume. transformFeedbackDraw is advertised as false.
|
||||||
|
+ *
|
||||||
|
+ * Per-draw integration: jm/panvk_vX_cmd_draw.c reads cmdbuf->state.gfx.xfb
|
||||||
|
+ * and populates vs.xfb_address[i] for shader use. The pan_nir_lower_xfb
|
||||||
|
+ * pass in panvk_vX_shader.c emits nir_load_xfb_address(i) which lowers
|
||||||
|
+ * (via panvk_vX_shader.c sysval handler) to a load from the per-draw
|
||||||
|
+ * sysval push area.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "vk_log.h"
|
||||||
|
+#include "util/log.h"
|
||||||
|
+
|
||||||
|
+#include "panvk_cmd_buffer.h"
|
||||||
|
+#include "panvk_cmd_draw.h"
|
||||||
|
+#include "panvk_buffer.h"
|
||||||
|
+#include "panvk_entrypoints.h"
|
||||||
|
+
|
||||||
|
+VKAPI_ATTR void VKAPI_CALL
|
||||||
|
+panvk_per_arch(CmdBindTransformFeedbackBuffersEXT)(
|
||||||
|
+ VkCommandBuffer commandBuffer,
|
||||||
|
+ uint32_t firstBinding,
|
||||||
|
+ uint32_t bindingCount,
|
||||||
|
+ const VkBuffer *pBuffers,
|
||||||
|
+ const VkDeviceSize *pOffsets,
|
||||||
|
+ const VkDeviceSize *pSizes)
|
||||||
|
+{
|
||||||
|
+ VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
|
||||||
|
+ struct panvk_cmd_graphics_state *gfx = &cmdbuf->state.gfx;
|
||||||
|
+
|
||||||
|
+ for (uint32_t i = 0; i < bindingCount; i++) {
|
||||||
|
+ uint32_t slot = firstBinding + i;
|
||||||
|
+ if (slot >= 4)
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ VK_FROM_HANDLE(panvk_buffer, buf, pBuffers[i]);
|
||||||
|
+ gfx->xfb.buffers[slot].addr = panvk_buffer_gpu_ptr(buf, 0);
|
||||||
|
+ gfx->xfb.buffers[slot].offset = pOffsets[i];
|
||||||
|
+ gfx->xfb.buffers[slot].size =
|
||||||
|
+ (pSizes != NULL && pSizes[i] != VK_WHOLE_SIZE)
|
||||||
|
+ ? pSizes[i]
|
||||||
|
+ : (buf->vk.size - pOffsets[i]);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (firstBinding + bindingCount > gfx->xfb.buffer_count)
|
||||||
|
+ gfx->xfb.buffer_count = firstBinding + bindingCount;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+VKAPI_ATTR void VKAPI_CALL
|
||||||
|
+panvk_per_arch(CmdBeginTransformFeedbackEXT)(
|
||||||
|
+ VkCommandBuffer commandBuffer,
|
||||||
|
+ uint32_t firstCounterBuffer,
|
||||||
|
+ uint32_t counterBufferCount,
|
||||||
|
+ const VkBuffer *pCounterBuffers,
|
||||||
|
+ const VkDeviceSize *pCounterBufferOffsets)
|
||||||
|
+{
|
||||||
|
+ VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
|
||||||
|
+ struct panvk_cmd_graphics_state *gfx = &cmdbuf->state.gfx;
|
||||||
|
+
|
||||||
|
+ /* Counter buffers ignored in v1 — see VkPhysicalDeviceTransformFeedback
|
||||||
|
+ * PropertiesEXT.transformFeedbackDraw = false in panvk_vX_physical_device.c.
|
||||||
|
+ * App is spec-compliant if it does not pass counter buffers (which our
|
||||||
|
+ * features advertisement allows), but warn loudly if it does so we do not
|
||||||
|
+ * silently produce wrong capture state. */
|
||||||
|
+ (void)firstCounterBuffer;
|
||||||
|
+ (void)pCounterBufferOffsets;
|
||||||
|
+ if (counterBufferCount > 0 && pCounterBuffers != NULL) {
|
||||||
|
+ mesa_logw("panvk: CmdBeginTransformFeedbackEXT: counter buffers not "
|
||||||
|
+ "implemented (transformFeedbackDraw=false); XFB resume will "
|
||||||
|
+ "restart at buffer offset 0");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ gfx->xfb.active = true;
|
||||||
|
+ /* Per-draw set_gfx_sysval picks up the change automatically — no
|
||||||
|
+ * explicit dirty marking required (set_gfx_sysval uses memcmp +
|
||||||
|
+ * BITSET to detect state diffs and re-emit sysvals). */
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+VKAPI_ATTR void VKAPI_CALL
|
||||||
|
+panvk_per_arch(CmdEndTransformFeedbackEXT)(
|
||||||
|
+ VkCommandBuffer commandBuffer,
|
||||||
|
+ uint32_t firstCounterBuffer,
|
||||||
|
+ uint32_t counterBufferCount,
|
||||||
|
+ const VkBuffer *pCounterBuffers,
|
||||||
|
+ const VkDeviceSize *pCounterBufferOffsets)
|
||||||
|
+{
|
||||||
|
+ VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
|
||||||
|
+ struct panvk_cmd_graphics_state *gfx = &cmdbuf->state.gfx;
|
||||||
|
+
|
||||||
|
+ (void)firstCounterBuffer;
|
||||||
|
+ (void)counterBufferCount;
|
||||||
|
+ (void)pCounterBuffers;
|
||||||
|
+ (void)pCounterBufferOffsets;
|
||||||
|
+
|
||||||
|
+ gfx->xfb.active = false;
|
||||||
|
+}
|
||||||
@@ -0,0 +1,629 @@
|
|||||||
|
diff -urN a/src/panfrost/vulkan/meson.build b/src/panfrost/vulkan/meson.build
|
||||||
|
--- a/src/panfrost/vulkan/meson.build 2026-05-21 14:04:02.529474145 +0200
|
||||||
|
+++ b/src/panfrost/vulkan/meson.build 2026-05-21 14:04:04.106755486 +0200
|
||||||
|
@@ -123,6 +123,7 @@
|
||||||
|
'panvk_vX_nir_lower_input_attachment_loads.c',
|
||||||
|
'panvk_vX_sampler.c',
|
||||||
|
'panvk_vX_shader.c',
|
||||||
|
+ 'panvk_vX_xfb_lower.c',
|
||||||
|
sha1_h,
|
||||||
|
]
|
||||||
|
|
||||||
|
diff -urN a/src/panfrost/vulkan/panvk_shader.h b/src/panfrost/vulkan/panvk_shader.h
|
||||||
|
--- a/src/panfrost/vulkan/panvk_shader.h 2026-05-21 14:04:02.525251986 +0200
|
||||||
|
+++ b/src/panfrost/vulkan/panvk_shader.h 2026-05-21 14:04:04.084251800 +0200
|
||||||
|
@@ -154,6 +154,8 @@
|
||||||
|
/* aligned_u64 attribute below inserts the 4-byte alignment gap
|
||||||
|
* after num_vertices automatically — no explicit pad needed. */
|
||||||
|
aligned_u64 xfb_address[4]; /* iter13: 4 transform feedback buffer base addresses */
|
||||||
|
+ uint32_t xfb_topology; /* iter17: panvk_xfb_topology enum value */
|
||||||
|
+ uint32_t xfb_output_count; /* iter17: per-instance output verts after decomp */
|
||||||
|
#endif
|
||||||
|
int32_t first_vertex;
|
||||||
|
int32_t base_instance;
|
||||||
|
@@ -569,4 +571,76 @@
|
||||||
|
struct pan_compute_dim local_size, const void *bin_ptr, size_t bin_size,
|
||||||
|
struct panvk_shader **shader_out);
|
||||||
|
|
||||||
|
+
|
||||||
|
+#if PAN_ARCH < 9
|
||||||
|
+/* iter17: encoding for vs.xfb_topology sysval. Maps VkPrimitiveTopology values
|
||||||
|
+ * we need to distinguish at shader runtime for XFB capture. LIST topologies
|
||||||
|
+ * use the iter13 single-store fast path; non-LIST need per-vertex decomposition. */
|
||||||
|
+enum panvk_xfb_topology {
|
||||||
|
+ PANVK_XFB_TOPO_LIST = 0,
|
||||||
|
+ PANVK_XFB_TOPO_LINE_STRIP = 1,
|
||||||
|
+ PANVK_XFB_TOPO_TRI_STRIP = 2,
|
||||||
|
+ PANVK_XFB_TOPO_TRI_FAN = 3,
|
||||||
|
+ PANVK_XFB_TOPO_LINE_LIST_ADJ = 4,
|
||||||
|
+ PANVK_XFB_TOPO_LINE_STRIP_ADJ = 5,
|
||||||
|
+ PANVK_XFB_TOPO_TRI_LIST_ADJ = 6,
|
||||||
|
+ PANVK_XFB_TOPO_TRI_STRIP_ADJ = 7,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+#include "panvk_macros.h"
|
||||||
|
+struct nir_shader;
|
||||||
|
+bool panvk_per_arch(nir_lower_xfb)(struct nir_shader *nir);
|
||||||
|
+
|
||||||
|
+/* Map VkPrimitiveTopology to panvk_xfb_topology enum (driver-side helper). */
|
||||||
|
+static inline uint32_t
|
||||||
|
+panvk_vk_topology_to_xfb_enum(VkPrimitiveTopology topo)
|
||||||
|
+{
|
||||||
|
+ switch (topo) {
|
||||||
|
+ case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
|
||||||
|
+ return PANVK_XFB_TOPO_LINE_STRIP;
|
||||||
|
+ case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
|
||||||
|
+ return PANVK_XFB_TOPO_TRI_STRIP;
|
||||||
|
+ case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
|
||||||
|
+ return PANVK_XFB_TOPO_TRI_FAN;
|
||||||
|
+ case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
|
||||||
|
+ return PANVK_XFB_TOPO_LINE_LIST_ADJ;
|
||||||
|
+ case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
|
||||||
|
+ return PANVK_XFB_TOPO_LINE_STRIP_ADJ;
|
||||||
|
+ case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
|
||||||
|
+ return PANVK_XFB_TOPO_TRI_LIST_ADJ;
|
||||||
|
+ case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
|
||||||
|
+ return PANVK_XFB_TOPO_TRI_STRIP_ADJ;
|
||||||
|
+ case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
|
||||||
|
+ case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
|
||||||
|
+ case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
|
||||||
|
+ default:
|
||||||
|
+ return PANVK_XFB_TOPO_LIST;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Compute the per-instance output vertex count for a given (topology, input count). */
|
||||||
|
+static inline uint32_t
|
||||||
|
+panvk_xfb_output_count(VkPrimitiveTopology topo, uint32_t input_count)
|
||||||
|
+{
|
||||||
|
+ switch (topo) {
|
||||||
|
+ case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
|
||||||
|
+ return input_count >= 1 ? 2u * (input_count - 1u) : 0u;
|
||||||
|
+ case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
|
||||||
|
+ case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
|
||||||
|
+ return input_count >= 2 ? 3u * (input_count - 2u) : 0u;
|
||||||
|
+ case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
|
||||||
|
+ return (input_count / 4u) * 2u;
|
||||||
|
+ case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
|
||||||
|
+ return input_count >= 3 ? 2u * (input_count - 3u) : 0u;
|
||||||
|
+ case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
|
||||||
|
+ return (input_count / 6u) * 3u;
|
||||||
|
+ case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
|
||||||
|
+ return input_count >= 6 ? 3u * (input_count / 2u - 2u) : 0u;
|
||||||
|
+ default:
|
||||||
|
+ return input_count; /* LIST topologies: 1:1 mapping */
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+
|
||||||
|
#endif
|
||||||
|
diff -urN a/src/panfrost/vulkan/panvk_vX_cmd_draw.c b/src/panfrost/vulkan/panvk_vX_cmd_draw.c
|
||||||
|
--- a/src/panfrost/vulkan/panvk_vX_cmd_draw.c 2026-05-21 14:04:02.528576354 +0200
|
||||||
|
+++ b/src/panfrost/vulkan/panvk_vX_cmd_draw.c 2026-05-21 14:04:04.091357598 +0200
|
||||||
|
@@ -727,6 +727,20 @@
|
||||||
|
/* iter13: VK_EXT_transform_feedback sysvals — always set (per draw),
|
||||||
|
* reflect bound XFB state. set_gfx_sysval is a no-op if value unchanged. */
|
||||||
|
set_gfx_sysval(cmdbuf, dirty_sysvals, vs.num_vertices, info->vertex.count);
|
||||||
|
+
|
||||||
|
+ /* iter17: XFB primitive-decomposition sysvals.
|
||||||
|
+ * xfb_topology = enum value for the current bound topology.
|
||||||
|
+ * xfb_output_count = per-instance output vertex count after decomposition.
|
||||||
|
+ * For LIST topologies, output_count == input vertex count and the shader
|
||||||
|
+ * takes the iter13 single-store fast path. */
|
||||||
|
+ {
|
||||||
|
+ VkPrimitiveTopology vk_topo =
|
||||||
|
+ cmdbuf->vk.dynamic_graphics_state.ia.primitive_topology;
|
||||||
|
+ uint32_t topo_enum = panvk_vk_topology_to_xfb_enum(vk_topo);
|
||||||
|
+ uint32_t out_count = panvk_xfb_output_count(vk_topo, info->vertex.count);
|
||||||
|
+ set_gfx_sysval(cmdbuf, dirty_sysvals, vs.xfb_topology, topo_enum);
|
||||||
|
+ set_gfx_sysval(cmdbuf, dirty_sysvals, vs.xfb_output_count, out_count);
|
||||||
|
+ }
|
||||||
|
{
|
||||||
|
const struct panvk_cmd_graphics_state *_gfx = &cmdbuf->state.gfx;
|
||||||
|
/* iter13: default each XFB buffer address to PAN_SHADER_OOB_ADDRESS
|
||||||
|
diff -urN a/src/panfrost/vulkan/panvk_vX_shader.c b/src/panfrost/vulkan/panvk_vX_shader.c
|
||||||
|
--- a/src/panfrost/vulkan/panvk_vX_shader.c 2026-05-21 14:04:02.527576494 +0200
|
||||||
|
+++ b/src/panfrost/vulkan/panvk_vX_shader.c 2026-05-21 14:04:04.098356619 +0200
|
||||||
|
@@ -895,7 +895,10 @@
|
||||||
|
nir->info.has_transform_feedback_varyings) {
|
||||||
|
NIR_PASS(_, nir, nir_opt_constant_folding);
|
||||||
|
NIR_PASS(_, nir, nir_io_add_intrinsic_xfb_info);
|
||||||
|
- NIR_PASS(_, nir, pan_nir_lower_xfb);
|
||||||
|
+ /* iter17: panvk-specific replacement for pan_nir_lower_xfb that handles
|
||||||
|
+ * primitive decomposition for non-LIST topologies. Single-store LIST
|
||||||
|
+ * fast path matches iter13 behavior. */
|
||||||
|
+ NIR_PASS(_, nir, panvk_per_arch(nir_lower_xfb));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
diff -urN a/src/panfrost/vulkan/panvk_vX_xfb_lower.c b/src/panfrost/vulkan/panvk_vX_xfb_lower.c
|
||||||
|
--- a/src/panfrost/vulkan/panvk_vX_xfb_lower.c 1970-01-01 01:00:00.000000000 +0100
|
||||||
|
+++ b/src/panfrost/vulkan/panvk_vX_xfb_lower.c 2026-05-21 14:04:04.115354242 +0200
|
||||||
|
@@ -0,0 +1,486 @@
|
||||||
|
+/*
|
||||||
|
+ * Copyright © 2026 mfritsche / claude-noether
|
||||||
|
+ * SPDX-License-Identifier: MIT
|
||||||
|
+ *
|
||||||
|
+ * iter17: panvk-specific replacement for pan_nir_lower_xfb that handles
|
||||||
|
+ * primitive decomposition for transform_feedback on non-LIST topologies
|
||||||
|
+ * (TRIANGLE_STRIP/FAN, LINE_STRIP, *_WITH_ADJACENCY).
|
||||||
|
+ *
|
||||||
|
+ * Approach: emit a topology dispatch at the start of each store_output
|
||||||
|
+ * lowering. The shader reads vs.xfb_topology sysval at runtime and branches
|
||||||
|
+ * into per-topology emission logic. For each affected topology, the lowered
|
||||||
|
+ * code emits guarded conditional stores — one per primitive this vertex
|
||||||
|
+ * contributes to, computing the output buffer position via primitive index
|
||||||
|
+ * and slot within the decomposed primitive.
|
||||||
|
+ *
|
||||||
|
+ * For LIST topologies (POINT/LINE/TRIANGLE LIST), takes a fast path that
|
||||||
|
+ * matches iter13's single-store behavior.
|
||||||
|
+ *
|
||||||
|
+ * For TRIANGLE_FAN, the central vertex (v=0) contributes to ALL primitives
|
||||||
|
+ * as slot 2 — handled via a NIR loop bounded by num_vertices.
|
||||||
|
+ *
|
||||||
|
+ * See ~/src/panvk-bifrost/iter17/phase{0,1,2}_*.md for full design context.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "panvk_macros.h"
|
||||||
|
+
|
||||||
|
+#if PAN_ARCH < 9
|
||||||
|
+
|
||||||
|
+#include "panvk_shader.h"
|
||||||
|
+
|
||||||
|
+#include "compiler/nir/nir_builder.h"
|
||||||
|
+#include "pan_nir.h"
|
||||||
|
+
|
||||||
|
+#include <vulkan/vulkan_core.h>
|
||||||
|
+
|
||||||
|
+/* ----- Address arithmetic ----- */
|
||||||
|
+
|
||||||
|
+static nir_def *
|
||||||
|
+xfb_store_addr(nir_builder *b, nir_def *buf, nir_def *out_idx,
|
||||||
|
+ uint16_t stride, uint16_t offset_bytes)
|
||||||
|
+{
|
||||||
|
+ nir_def *byte_off = nir_iadd_imm(b,
|
||||||
|
+ nir_imul_imm(b, out_idx, stride), offset_bytes);
|
||||||
|
+ return nir_iadd(b, buf, nir_u2u64(b, byte_off));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+emit_list_store(nir_builder *b, nir_def *buf, nir_def *output_count,
|
||||||
|
+ nir_def *instance_id, nir_def *raw_vid, nir_def *value,
|
||||||
|
+ uint16_t stride, uint16_t offset_bytes)
|
||||||
|
+{
|
||||||
|
+ nir_def *out_idx = nir_iadd(b,
|
||||||
|
+ nir_imul(b, instance_id, output_count), raw_vid);
|
||||||
|
+ nir_def *addr = xfb_store_addr(b, buf, out_idx, stride, offset_bytes);
|
||||||
|
+ nir_store_global(b, value, addr);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+emit_prim_store(nir_builder *b, nir_def *buf, nir_def *output_count,
|
||||||
|
+ nir_def *instance_id, nir_def *eligible,
|
||||||
|
+ nir_def *prim_idx, nir_def *slot,
|
||||||
|
+ uint32_t verts_per_prim,
|
||||||
|
+ nir_def *value, uint16_t stride, uint16_t offset_bytes)
|
||||||
|
+{
|
||||||
|
+ nir_push_if(b, eligible);
|
||||||
|
+ {
|
||||||
|
+ nir_def *out_idx = nir_iadd(b,
|
||||||
|
+ nir_imul(b, instance_id, output_count),
|
||||||
|
+ nir_iadd(b, nir_imul_imm(b, prim_idx, verts_per_prim), slot));
|
||||||
|
+ nir_def *addr = xfb_store_addr(b, buf, out_idx, stride, offset_bytes);
|
||||||
|
+ nir_store_global(b, value, addr);
|
||||||
|
+ }
|
||||||
|
+ nir_pop_if(b, NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* ----- Per-topology emission ----- */
|
||||||
|
+
|
||||||
|
+/* TRIANGLE_STRIP: vertex v contributes to prims v, v-1, v-2 (per eligibility). */
|
||||||
|
+static void
|
||||||
|
+emit_tri_strip(nir_builder *b, nir_def *v, nir_def *N,
|
||||||
|
+ nir_def *buf, nir_def *output_count, nir_def *instance_id,
|
||||||
|
+ nir_def *value, uint16_t stride, uint16_t offset_bytes)
|
||||||
|
+{
|
||||||
|
+ nir_def *Nm2 = nir_iadd_imm(b, N, -2);
|
||||||
|
+ nir_def *Nm1 = nir_iadd_imm(b, N, -1);
|
||||||
|
+
|
||||||
|
+ /* Prim v, slot 0: v < N-2 */
|
||||||
|
+ emit_prim_store(b, buf, output_count, instance_id,
|
||||||
|
+ nir_ult(b, v, Nm2),
|
||||||
|
+ v, nir_imm_int(b, 0), 3, value, stride, offset_bytes);
|
||||||
|
+
|
||||||
|
+ /* Prim v-1, slot = 1 if prim even else 2: 1 <= v < N-1 */
|
||||||
|
+ {
|
||||||
|
+ nir_def *prim = nir_iadd_imm(b, v, -1);
|
||||||
|
+ nir_def *parity = nir_iand_imm(b, prim, 1u);
|
||||||
|
+ nir_def *slot = nir_iadd_imm(b, parity, 1);
|
||||||
|
+ nir_def *eligible = nir_iand(b,
|
||||||
|
+ nir_uge(b, v, nir_imm_int(b, 1)),
|
||||||
|
+ nir_ult(b, v, Nm1));
|
||||||
|
+ emit_prim_store(b, buf, output_count, instance_id, eligible,
|
||||||
|
+ prim, slot, 3, value, stride, offset_bytes);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Prim v-2, slot = 2 if prim even else 1: 2 <= v < N */
|
||||||
|
+ {
|
||||||
|
+ nir_def *prim = nir_iadd_imm(b, v, -2);
|
||||||
|
+ nir_def *parity = nir_iand_imm(b, prim, 1u);
|
||||||
|
+ nir_def *slot = nir_isub(b, nir_imm_int(b, 2), parity);
|
||||||
|
+ nir_def *eligible = nir_iand(b,
|
||||||
|
+ nir_uge(b, v, nir_imm_int(b, 2)),
|
||||||
|
+ nir_ult(b, v, N));
|
||||||
|
+ emit_prim_store(b, buf, output_count, instance_id, eligible,
|
||||||
|
+ prim, slot, 3, value, stride, offset_bytes);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* LINE_STRIP: vertex v contributes to prim v slot 0 + prim v-1 slot 1. */
|
||||||
|
+static void
|
||||||
|
+emit_line_strip(nir_builder *b, nir_def *v, nir_def *N,
|
||||||
|
+ nir_def *buf, nir_def *output_count, nir_def *instance_id,
|
||||||
|
+ nir_def *value, uint16_t stride, uint16_t offset_bytes)
|
||||||
|
+{
|
||||||
|
+ nir_def *Nm1 = nir_iadd_imm(b, N, -1);
|
||||||
|
+
|
||||||
|
+ /* Prim v, slot 0: v < N-1 */
|
||||||
|
+ emit_prim_store(b, buf, output_count, instance_id,
|
||||||
|
+ nir_ult(b, v, Nm1),
|
||||||
|
+ v, nir_imm_int(b, 0), 2, value, stride, offset_bytes);
|
||||||
|
+
|
||||||
|
+ /* Prim v-1, slot 1: 1 <= v < N */
|
||||||
|
+ {
|
||||||
|
+ nir_def *prim = nir_iadd_imm(b, v, -1);
|
||||||
|
+ nir_def *eligible = nir_iand(b,
|
||||||
|
+ nir_uge(b, v, nir_imm_int(b, 1)),
|
||||||
|
+ nir_ult(b, v, N));
|
||||||
|
+ emit_prim_store(b, buf, output_count, instance_id, eligible,
|
||||||
|
+ prim, nir_imm_int(b, 1), 2, value, stride, offset_bytes);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* TRIANGLE_FAN: prim p emits {p+1, p+2, 0}.
|
||||||
|
+ * vertex v=0: contributes to ALL prims as slot 2 (loop required)
|
||||||
|
+ * vertex v>=1: contributes to prim v-1 as slot 0 (if 1 <= v <= N-2)
|
||||||
|
+ * vertex v>=2: contributes to prim v-2 as slot 1 (if 2 <= v <= N-1)
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+emit_tri_fan(nir_builder *b, nir_def *v, nir_def *N,
|
||||||
|
+ nir_def *buf, nir_def *output_count, nir_def *instance_id,
|
||||||
|
+ nir_def *value, uint16_t stride, uint16_t offset_bytes)
|
||||||
|
+{
|
||||||
|
+ nir_def *Nm1 = nir_iadd_imm(b, N, -1);
|
||||||
|
+ nir_def *Nm2 = nir_iadd_imm(b, N, -2);
|
||||||
|
+
|
||||||
|
+ /* Prim v-1, slot 0: 1 <= v < N-1 */
|
||||||
|
+ {
|
||||||
|
+ nir_def *prim = nir_iadd_imm(b, v, -1);
|
||||||
|
+ nir_def *eligible = nir_iand(b,
|
||||||
|
+ nir_uge(b, v, nir_imm_int(b, 1)),
|
||||||
|
+ nir_ult(b, v, Nm1));
|
||||||
|
+ emit_prim_store(b, buf, output_count, instance_id, eligible,
|
||||||
|
+ prim, nir_imm_int(b, 0), 3, value, stride, offset_bytes);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Prim v-2, slot 1: 2 <= v < N */
|
||||||
|
+ {
|
||||||
|
+ nir_def *prim = nir_iadd_imm(b, v, -2);
|
||||||
|
+ nir_def *eligible = nir_iand(b,
|
||||||
|
+ nir_uge(b, v, nir_imm_int(b, 2)),
|
||||||
|
+ nir_ult(b, v, N));
|
||||||
|
+ emit_prim_store(b, buf, output_count, instance_id, eligible,
|
||||||
|
+ prim, nir_imm_int(b, 1), 3, value, stride, offset_bytes);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Central vertex (v == 0): loop over all prims, write to slot 2. */
|
||||||
|
+ nir_push_if(b, nir_ieq_imm(b, v, 0));
|
||||||
|
+ {
|
||||||
|
+ nir_variable *p_var = nir_local_variable_create(b->impl,
|
||||||
|
+ glsl_uint_type(), "fan_p");
|
||||||
|
+ nir_store_var(b, p_var, nir_imm_int(b, 0), 0x1);
|
||||||
|
+ nir_push_loop(b);
|
||||||
|
+ {
|
||||||
|
+ nir_def *p = nir_load_var(b, p_var);
|
||||||
|
+ nir_push_if(b, nir_uge(b, p, Nm2));
|
||||||
|
+ {
|
||||||
|
+ nir_jump(b, nir_jump_break);
|
||||||
|
+ }
|
||||||
|
+ nir_pop_if(b, NULL);
|
||||||
|
+
|
||||||
|
+ nir_def *out_idx = nir_iadd(b,
|
||||||
|
+ nir_imul(b, instance_id, output_count),
|
||||||
|
+ nir_iadd_imm(b, nir_imul_imm(b, p, 3), 2));
|
||||||
|
+ nir_def *addr = xfb_store_addr(b, buf, out_idx, stride, offset_bytes);
|
||||||
|
+ nir_store_global(b, value, addr);
|
||||||
|
+
|
||||||
|
+ nir_store_var(b, p_var, nir_iadd_imm(b, p, 1), 0x1);
|
||||||
|
+ }
|
||||||
|
+ nir_pop_loop(b, NULL);
|
||||||
|
+ }
|
||||||
|
+ nir_pop_if(b, NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* LINE_LIST_WITH_ADJACENCY: 4-vertex groups [4i..4i+3]; output {4i+1, 4i+2}.
|
||||||
|
+ * v contributes if v%4 == 1: prim v/4 slot 0
|
||||||
|
+ * v contributes if v%4 == 2: prim v/4 slot 1
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+emit_line_list_adj(nir_builder *b, nir_def *v, nir_def *N,
|
||||||
|
+ nir_def *buf, nir_def *output_count, nir_def *instance_id,
|
||||||
|
+ nir_def *value, uint16_t stride, uint16_t offset_bytes)
|
||||||
|
+{
|
||||||
|
+ (void)N; /* eligibility is mod-based, not range-based */
|
||||||
|
+ nir_def *vmod4 = nir_iand_imm(b, v, 3u);
|
||||||
|
+ nir_def *prim = nir_ushr_imm(b, v, 2); /* v / 4 */
|
||||||
|
+
|
||||||
|
+ emit_prim_store(b, buf, output_count, instance_id,
|
||||||
|
+ nir_ieq_imm(b, vmod4, 1),
|
||||||
|
+ prim, nir_imm_int(b, 0), 2, value, stride, offset_bytes);
|
||||||
|
+
|
||||||
|
+ emit_prim_store(b, buf, output_count, instance_id,
|
||||||
|
+ nir_ieq_imm(b, vmod4, 2),
|
||||||
|
+ prim, nir_imm_int(b, 1), 2, value, stride, offset_bytes);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* LINE_STRIP_WITH_ADJACENCY: prim p emits {p+1, p+2}.
|
||||||
|
+ * v contributes to prim v-1 slot 0 (1 <= v <= N-2)
|
||||||
|
+ * v contributes to prim v-2 slot 1 (2 <= v <= N-1)
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+emit_line_strip_adj(nir_builder *b, nir_def *v, nir_def *N,
|
||||||
|
+ nir_def *buf, nir_def *output_count, nir_def *instance_id,
|
||||||
|
+ nir_def *value, uint16_t stride, uint16_t offset_bytes)
|
||||||
|
+{
|
||||||
|
+ nir_def *Nm1 = nir_iadd_imm(b, N, -1);
|
||||||
|
+ nir_def *Nm2 = nir_iadd_imm(b, N, -2);
|
||||||
|
+
|
||||||
|
+ /* Prim v-1, slot 0: 1 <= v <= N-2 ⇔ v >= 1 AND v <= N-2 ⇔ v >= 1 AND v < N-1 */
|
||||||
|
+ {
|
||||||
|
+ nir_def *prim = nir_iadd_imm(b, v, -1);
|
||||||
|
+ nir_def *eligible = nir_iand(b,
|
||||||
|
+ nir_uge(b, v, nir_imm_int(b, 1)),
|
||||||
|
+ nir_ult(b, v, Nm1));
|
||||||
|
+ (void)Nm2;
|
||||||
|
+ emit_prim_store(b, buf, output_count, instance_id, eligible,
|
||||||
|
+ prim, nir_imm_int(b, 0), 2, value, stride, offset_bytes);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Prim v-2, slot 1: 2 <= v <= N-1 ⇔ v >= 2 AND v < N */
|
||||||
|
+ {
|
||||||
|
+ nir_def *prim = nir_iadd_imm(b, v, -2);
|
||||||
|
+ nir_def *eligible = nir_iand(b,
|
||||||
|
+ nir_uge(b, v, nir_imm_int(b, 2)),
|
||||||
|
+ nir_ult(b, v, N));
|
||||||
|
+ emit_prim_store(b, buf, output_count, instance_id, eligible,
|
||||||
|
+ prim, nir_imm_int(b, 1), 2, value, stride, offset_bytes);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* TRIANGLE_LIST_WITH_ADJACENCY: 6-vertex groups; output {6i, 6i+2, 6i+4}.
|
||||||
|
+ * v contributes if v%6 == 0: prim v/6 slot 0
|
||||||
|
+ * v contributes if v%6 == 2: prim v/6 slot 1
|
||||||
|
+ * v contributes if v%6 == 4: prim v/6 slot 2
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+emit_tri_list_adj(nir_builder *b, nir_def *v, nir_def *N,
|
||||||
|
+ nir_def *buf, nir_def *output_count, nir_def *instance_id,
|
||||||
|
+ nir_def *value, uint16_t stride, uint16_t offset_bytes)
|
||||||
|
+{
|
||||||
|
+ (void)N;
|
||||||
|
+ nir_def *vmod6 = nir_umod_imm(b, v, 6);
|
||||||
|
+ nir_def *prim = nir_udiv_imm(b, v, 6);
|
||||||
|
+
|
||||||
|
+ for (uint32_t slot = 0; slot < 3; slot++) {
|
||||||
|
+ emit_prim_store(b, buf, output_count, instance_id,
|
||||||
|
+ nir_ieq_imm(b, vmod6, slot * 2),
|
||||||
|
+ prim, nir_imm_int(b, slot), 3, value, stride, offset_bytes);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* TRIANGLE_STRIP_WITH_ADJACENCY: prim i emits:
|
||||||
|
+ * even i: {2i, 2i+2, 2i+4} (slots 0, 1, 2 ← input indices 2i, 2i+2, 2i+4)
|
||||||
|
+ * odd i: {2i, 2i+4, 2i+2} (slots 0, 1, 2 ← input indices 2i, 2i+4, 2i+2)
|
||||||
|
+ *
|
||||||
|
+ * Only EVEN input vertices contribute (since all output indices are 2*something).
|
||||||
|
+ * For even input v:
|
||||||
|
+ * prim v/2 slot 0 (always, if v/2 < N/2-2)
|
||||||
|
+ * prim (v-2)/2 slot 1 if (v-2)/2 even, slot 2 if odd (when v >= 2)
|
||||||
|
+ * prim (v-4)/2 slot 2 if (v-4)/2 even, slot 1 if odd (when v >= 4)
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+emit_tri_strip_adj(nir_builder *b, nir_def *v, nir_def *N,
|
||||||
|
+ nir_def *buf, nir_def *output_count, nir_def *instance_id,
|
||||||
|
+ nir_def *value, uint16_t stride, uint16_t offset_bytes)
|
||||||
|
+{
|
||||||
|
+ /* Bail for odd input vertices — they never contribute. */
|
||||||
|
+ nir_def *v_is_even = nir_ieq_imm(b, nir_iand_imm(b, v, 1u), 0);
|
||||||
|
+ nir_push_if(b, v_is_even);
|
||||||
|
+ {
|
||||||
|
+ nir_def *N_half = nir_ushr_imm(b, N, 1);
|
||||||
|
+ nir_def *max_prim = nir_iadd_imm(b, N_half, -2); /* N/2 - 2 */
|
||||||
|
+ nir_def *v_half = nir_ushr_imm(b, v, 1);
|
||||||
|
+
|
||||||
|
+ /* Prim v/2 slot 0: v/2 < N/2 - 2 */
|
||||||
|
+ emit_prim_store(b, buf, output_count, instance_id,
|
||||||
|
+ nir_ult(b, v_half, max_prim),
|
||||||
|
+ v_half, nir_imm_int(b, 0), 3, value, stride, offset_bytes);
|
||||||
|
+
|
||||||
|
+ /* Prim (v-2)/2 = v/2 - 1: v >= 2 AND prim < N/2-2 */
|
||||||
|
+ {
|
||||||
|
+ nir_def *prim = nir_iadd_imm(b, v_half, -1);
|
||||||
|
+ nir_def *parity = nir_iand_imm(b, prim, 1u);
|
||||||
|
+ nir_def *slot = nir_iadd_imm(b, parity, 1); /* even→1, odd→2 */
|
||||||
|
+ nir_def *eligible = nir_iand(b,
|
||||||
|
+ nir_uge(b, v, nir_imm_int(b, 2)),
|
||||||
|
+ nir_ult(b, prim, max_prim));
|
||||||
|
+ emit_prim_store(b, buf, output_count, instance_id, eligible,
|
||||||
|
+ prim, slot, 3, value, stride, offset_bytes);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Prim (v-4)/2 = v/2 - 2: v >= 4 AND prim < N/2-2 */
|
||||||
|
+ {
|
||||||
|
+ nir_def *prim = nir_iadd_imm(b, v_half, -2);
|
||||||
|
+ nir_def *parity = nir_iand_imm(b, prim, 1u);
|
||||||
|
+ nir_def *slot = nir_isub(b, nir_imm_int(b, 2), parity); /* even→2, odd→1 */
|
||||||
|
+ nir_def *eligible = nir_iand(b,
|
||||||
|
+ nir_uge(b, v, nir_imm_int(b, 4)),
|
||||||
|
+ nir_ult(b, prim, max_prim));
|
||||||
|
+ emit_prim_store(b, buf, output_count, instance_id, eligible,
|
||||||
|
+ prim, slot, 3, value, stride, offset_bytes);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ nir_pop_if(b, NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* ----- Main lowering: per store_output XFB channel ----- */
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+lower_xfb_output_iter17(nir_builder *b, nir_intrinsic_instr *intr,
|
||||||
|
+ unsigned channel_idx, unsigned num_components,
|
||||||
|
+ unsigned buffer, unsigned offset_words)
|
||||||
|
+{
|
||||||
|
+ assert(buffer < MAX_XFB_BUFFERS);
|
||||||
|
+ assert(nir_intrinsic_component(intr) == 0);
|
||||||
|
+
|
||||||
|
+ uint16_t stride = b->shader->info.xfb_stride[buffer] * 4;
|
||||||
|
+ assert(stride != 0);
|
||||||
|
+ uint16_t offset_bytes = offset_words * 4;
|
||||||
|
+
|
||||||
|
+ BITSET_SET(b->shader->info.system_values_read, SYSTEM_VALUE_VERTEX_ID_ZERO_BASE);
|
||||||
|
+ BITSET_SET(b->shader->info.system_values_read, SYSTEM_VALUE_INSTANCE_ID);
|
||||||
|
+
|
||||||
|
+ nir_def *topology = load_sysval(b, graphics, 32, vs.xfb_topology);
|
||||||
|
+ nir_def *out_count = load_sysval(b, graphics, 32, vs.xfb_output_count);
|
||||||
|
+ nir_def *N = nir_load_num_vertices(b);
|
||||||
|
+ nir_def *v = nir_load_raw_vertex_id_pan(b);
|
||||||
|
+ nir_def *instance = nir_load_instance_id(b);
|
||||||
|
+ nir_def *buf = nir_load_xfb_address(b, 64, .base = buffer);
|
||||||
|
+
|
||||||
|
+ nir_def *src = intr->src[0].ssa;
|
||||||
|
+ nir_component_mask_t mask = nir_component_mask(num_components);
|
||||||
|
+ nir_def *value = nir_channels(b, src, mask << channel_idx);
|
||||||
|
+
|
||||||
|
+ /* Topology dispatch ladder. LIST first (fast path). */
|
||||||
|
+ nir_push_if(b, nir_ieq_imm(b, topology, PANVK_XFB_TOPO_LIST));
|
||||||
|
+ {
|
||||||
|
+ emit_list_store(b, buf, out_count, instance, v, value,
|
||||||
|
+ stride, offset_bytes);
|
||||||
|
+ }
|
||||||
|
+ nir_push_else(b, NULL);
|
||||||
|
+ {
|
||||||
|
+ /* iter17 Janet Finding 3: gate all non-LIST emission on
|
||||||
|
+ * output_count > 0. For degenerate input counts (N < min required
|
||||||
|
+ * for the topology), output_count is 0 and we must emit NO stores
|
||||||
|
+ * — otherwise N-2 / N-3 / etc. arithmetic underflows in the
|
||||||
|
+ * eligibility predicates and we falsely fire stores. */
|
||||||
|
+ nir_push_if(b, nir_ult(b, nir_imm_int(b, 0), out_count));
|
||||||
|
+ {
|
||||||
|
+ nir_push_if(b, nir_ieq_imm(b, topology, PANVK_XFB_TOPO_TRI_STRIP));
|
||||||
|
+ {
|
||||||
|
+ emit_tri_strip(b, v, N, buf, out_count, instance, value,
|
||||||
|
+ stride, offset_bytes);
|
||||||
|
+ }
|
||||||
|
+ nir_push_else(b, NULL);
|
||||||
|
+ {
|
||||||
|
+ nir_push_if(b, nir_ieq_imm(b, topology, PANVK_XFB_TOPO_LINE_STRIP));
|
||||||
|
+ {
|
||||||
|
+ emit_line_strip(b, v, N, buf, out_count, instance, value,
|
||||||
|
+ stride, offset_bytes);
|
||||||
|
+ }
|
||||||
|
+ nir_push_else(b, NULL);
|
||||||
|
+ {
|
||||||
|
+ nir_push_if(b, nir_ieq_imm(b, topology, PANVK_XFB_TOPO_TRI_FAN));
|
||||||
|
+ {
|
||||||
|
+ emit_tri_fan(b, v, N, buf, out_count, instance, value,
|
||||||
|
+ stride, offset_bytes);
|
||||||
|
+ }
|
||||||
|
+ nir_push_else(b, NULL);
|
||||||
|
+ {
|
||||||
|
+ nir_push_if(b, nir_ieq_imm(b, topology, PANVK_XFB_TOPO_LINE_LIST_ADJ));
|
||||||
|
+ {
|
||||||
|
+ emit_line_list_adj(b, v, N, buf, out_count, instance, value,
|
||||||
|
+ stride, offset_bytes);
|
||||||
|
+ }
|
||||||
|
+ nir_push_else(b, NULL);
|
||||||
|
+ {
|
||||||
|
+ nir_push_if(b, nir_ieq_imm(b, topology, PANVK_XFB_TOPO_LINE_STRIP_ADJ));
|
||||||
|
+ {
|
||||||
|
+ emit_line_strip_adj(b, v, N, buf, out_count, instance, value,
|
||||||
|
+ stride, offset_bytes);
|
||||||
|
+ }
|
||||||
|
+ nir_push_else(b, NULL);
|
||||||
|
+ {
|
||||||
|
+ nir_push_if(b, nir_ieq_imm(b, topology, PANVK_XFB_TOPO_TRI_LIST_ADJ));
|
||||||
|
+ {
|
||||||
|
+ emit_tri_list_adj(b, v, N, buf, out_count, instance, value,
|
||||||
|
+ stride, offset_bytes);
|
||||||
|
+ }
|
||||||
|
+ nir_push_else(b, NULL);
|
||||||
|
+ {
|
||||||
|
+ /* TRI_STRIP_ADJ — last case */
|
||||||
|
+ emit_tri_strip_adj(b, v, N, buf, out_count, instance, value,
|
||||||
|
+ stride, offset_bytes);
|
||||||
|
+ }
|
||||||
|
+ nir_pop_if(b, NULL);
|
||||||
|
+ }
|
||||||
|
+ nir_pop_if(b, NULL);
|
||||||
|
+ }
|
||||||
|
+ nir_pop_if(b, NULL);
|
||||||
|
+ }
|
||||||
|
+ nir_pop_if(b, NULL);
|
||||||
|
+ }
|
||||||
|
+ nir_pop_if(b, NULL);
|
||||||
|
+ }
|
||||||
|
+ nir_pop_if(b, NULL);
|
||||||
|
+ }
|
||||||
|
+ nir_pop_if(b, NULL); /* Janet Finding 3: close output_count > 0 guard */
|
||||||
|
+ }
|
||||||
|
+ nir_pop_if(b, NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Mirror of pan_nir_lower_xfb's lower_xfb: load_vertex_id rewrite +
|
||||||
|
+ * dispatch store_output through our topology-aware emission. */
|
||||||
|
+static bool
|
||||||
|
+lower_xfb_iter17(nir_builder *b, nir_intrinsic_instr *intr,
|
||||||
|
+ UNUSED void *data)
|
||||||
|
+{
|
||||||
|
+ if (intr->intrinsic == nir_intrinsic_load_vertex_id) {
|
||||||
|
+ b->cursor = nir_instr_remove(&intr->instr);
|
||||||
|
+ nir_def *repl = nir_iadd(b, nir_load_raw_vertex_id_pan(b),
|
||||||
|
+ nir_load_raw_vertex_offset_pan(b));
|
||||||
|
+ nir_def_rewrite_uses(&intr->def, repl);
|
||||||
|
+ return true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (intr->intrinsic != nir_intrinsic_store_output)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ bool progress = false;
|
||||||
|
+ b->cursor = nir_before_instr(&intr->instr);
|
||||||
|
+
|
||||||
|
+ /* io_xfb has only out[0,1]; the other 2 channels are in io_xfb2.
|
||||||
|
+ * Outer loop selects which annotation; inner picks which channel. */
|
||||||
|
+ for (unsigned i = 0; i < 2; ++i) {
|
||||||
|
+ nir_io_xfb xfb = i ? nir_intrinsic_io_xfb2(intr)
|
||||||
|
+ : nir_intrinsic_io_xfb(intr);
|
||||||
|
+ for (unsigned j = 0; j < 2; ++j) {
|
||||||
|
+ if (!xfb.out[j].num_components)
|
||||||
|
+ continue;
|
||||||
|
+ lower_xfb_output_iter17(b, intr, i * 2 + j, xfb.out[j].num_components,
|
||||||
|
+ xfb.out[j].buffer, xfb.out[j].offset);
|
||||||
|
+ progress = true;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (progress)
|
||||||
|
+ nir_instr_remove(&intr->instr);
|
||||||
|
+ return progress;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+bool
|
||||||
|
+panvk_per_arch(nir_lower_xfb)(nir_shader *nir)
|
||||||
|
+{
|
||||||
|
+ return nir_shader_intrinsics_pass(
|
||||||
|
+ nir, lower_xfb_iter17, nir_metadata_control_flow, NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif /* PAN_ARCH < 9 */
|
||||||
@@ -30,8 +30,8 @@
|
|||||||
|
|
||||||
pkgname=mesa-panvk-bifrost
|
pkgname=mesa-panvk-bifrost
|
||||||
_mesaver=26.0.6
|
_mesaver=26.0.6
|
||||||
pkgver=26.0.6.r2
|
pkgver=26.0.6.r4
|
||||||
pkgrel=2
|
pkgrel=1
|
||||||
pkgdesc="Patched Mesa libvulkan_panfrost.so exposing Bifrost-gen Mali to Vulkan apps (panvk-bifrost campaign)"
|
pkgdesc="Patched Mesa libvulkan_panfrost.so exposing Bifrost-gen Mali to Vulkan apps (panvk-bifrost campaign)"
|
||||||
arch=('aarch64')
|
arch=('aarch64')
|
||||||
url="https://github.com/marfrit/panvk-bifrost"
|
url="https://github.com/marfrit/panvk-bifrost"
|
||||||
@@ -79,11 +79,15 @@ source=(
|
|||||||
"https://archive.mesa3d.org/mesa-${_mesaver}.tar.xz"
|
"https://archive.mesa3d.org/mesa-${_mesaver}.tar.xz"
|
||||||
"0001-panvk-expose-robustness2-nullDescriptor-bifrost.patch"
|
"0001-panvk-expose-robustness2-nullDescriptor-bifrost.patch"
|
||||||
"0002-panvk-expose-vulkan-1.1-1.2-on-bifrost.patch"
|
"0002-panvk-expose-vulkan-1.1-1.2-on-bifrost.patch"
|
||||||
|
"0003-panvk-bifrost-vk-ext-transform-feedback.patch"
|
||||||
|
"0004-panvk-bifrost-xfb-primitive-decomposition.patch"
|
||||||
"brave-vulkan"
|
"brave-vulkan"
|
||||||
"icd.json"
|
"icd.json"
|
||||||
)
|
)
|
||||||
sha256sums=(
|
sha256sums=(
|
||||||
'1d3c3b8a8363b8cc354175bb4a684ad8b035211cc1d6fa17aeb9b9623c513f89' # mesa-26.0.6.tar.xz from archive.mesa3d.org, pinned 2026-05-20 (iter10)
|
'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'
|
||||||
'SKIP'
|
'SKIP'
|
||||||
'SKIP'
|
'SKIP'
|
||||||
@@ -107,12 +111,36 @@ prepare() {
|
|||||||
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_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
|
sed -i 's|bool has_vk1_2 = PAN_ARCH >= 10;|bool has_vk1_2 = true;|' src/panfrost/vulkan/panvk_vX_physical_device.c
|
||||||
|
|
||||||
|
# iter13: VK_EXT_transform_feedback implementation for Bifrost (PAN_ARCH<9).
|
||||||
|
# Applied as a real unified-diff patch — the change is too large for sed.
|
||||||
|
# Phase-doc context: ~/src/panvk-bifrost/phase{4,5,6}_iter13_close.md.
|
||||||
|
# Unlocks ANGLE-Vulkan → GLES3 → WebGL2 / WebGPU on Brave (chrome://gpu
|
||||||
|
# reports "Hardware accelerated" across the board for the affected paths).
|
||||||
|
patch -p1 < "${srcdir}/0003-panvk-bifrost-vk-ext-transform-feedback.patch"
|
||||||
|
|
||||||
|
# iter17: XFB primitive decomposition for non-LIST topologies (TRI_STRIP,
|
||||||
|
# TRI_FAN, LINE_STRIP, *_WITH_ADJACENCY). Replacement panvk-specific
|
||||||
|
# NIR pass (panvk_per_arch(nir_lower_xfb)) substituted for upstream
|
||||||
|
# pan_nir_lower_xfb. Closes the 162 dEQP-VK winding_* failures from
|
||||||
|
# iter15 (958 P / 81 F / 0 Crash on full XFB CTS — remaining 81 fails
|
||||||
|
# are by-design resume_* tests, transformFeedbackDraw=false).
|
||||||
|
# Phase-doc context: ~/src/panvk-bifrost/iter17/phase{0,1,2,4,5,6,8}_*.md.
|
||||||
|
patch -p1 < "${srcdir}/0004-panvk-bifrost-xfb-primitive-decomposition.patch"
|
||||||
|
|
||||||
# Sanity-check the patches landed.
|
# Sanity-check the patches landed.
|
||||||
grep -q "KHR_robustness2 = true," src/panfrost/vulkan/panvk_vX_physical_device.c
|
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 "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 "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_1 = true;" src/panfrost/vulkan/panvk_vX_physical_device.c
|
||||||
grep -q "has_vk1_2 = true;" src/panfrost/vulkan/panvk_vX_physical_device.c
|
grep -q "has_vk1_2 = true;" src/panfrost/vulkan/panvk_vX_physical_device.c
|
||||||
|
# iter13 sanity:
|
||||||
|
grep -q "EXT_transform_feedback = PAN_ARCH < 9," src/panfrost/vulkan/panvk_vX_physical_device.c
|
||||||
|
test -f src/panfrost/vulkan/jm/panvk_vX_cmd_xfb.c
|
||||||
|
# iter17 sanity: pan_nir_lower_xfb call site has been replaced; new file present.
|
||||||
|
grep -q "panvk_per_arch(nir_lower_xfb)" src/panfrost/vulkan/panvk_vX_shader.c
|
||||||
|
grep -q "xfb_topology" src/panfrost/vulkan/panvk_shader.h
|
||||||
|
grep -q "panvk_xfb_topology" src/panfrost/vulkan/panvk_shader.h
|
||||||
|
test -f src/panfrost/vulkan/panvk_vX_xfb_lower.c
|
||||||
}
|
}
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
@@ -142,24 +170,15 @@ package() {
|
|||||||
cd "${srcdir}/mesa-${_mesaver}"
|
cd "${srcdir}/mesa-${_mesaver}"
|
||||||
|
|
||||||
# Patched lib — co-install path, NOT /usr/lib (to avoid clashing
|
# Patched lib — co-install path, NOT /usr/lib (to avoid clashing
|
||||||
# with stock mesa's libvulkan_panfrost.so binary).
|
# with stock mesa's libvulkan_panfrost.so).
|
||||||
install -Dm755 build/src/panfrost/vulkan/libvulkan_panfrost.so \
|
install -Dm755 build/src/panfrost/vulkan/libvulkan_panfrost.so \
|
||||||
"$pkgdir/usr/lib/panvk-bifrost/libvulkan_panfrost.so"
|
"$pkgdir/usr/lib/panvk-bifrost/libvulkan_panfrost.so"
|
||||||
|
|
||||||
# ICD JSON at the standard Vulkan loader search path. The '00-'
|
# Custom ICD JSON. NOT under /usr/share/vulkan/icd.d/ (the default
|
||||||
# filename prefix gives optical priority but is NOT spec-backed —
|
# loader search path) — the user has to opt in via VK_ICD_FILENAMES.
|
||||||
# Vulkan loader readdir-order is implementation-defined per Khronos
|
|
||||||
# LoaderDriverInterface. The brave-vulkan wrapper sets
|
|
||||||
# VK_LOADER_DRIVERS_SELECT='00-panvk-bifrost*' to make the selection
|
|
||||||
# deterministic across filesystems. This avoids the VK_ICD_FILENAMES
|
|
||||||
# full-path override (whose GPU-sandbox survival is fragile) while
|
|
||||||
# still letting the loader work normally. iter10 result + Phase 5
|
|
||||||
# hardening.
|
|
||||||
install -Dm644 "$srcdir/icd.json" \
|
install -Dm644 "$srcdir/icd.json" \
|
||||||
"$pkgdir/usr/share/vulkan/icd.d/00-panvk-bifrost.json"
|
"$pkgdir/usr/lib/panvk-bifrost/icd.json"
|
||||||
|
|
||||||
# The brave-vulkan launcher wires up env + flags. iter10: no longer
|
# The brave-vulkan launcher wires up env + flags.
|
||||||
# sets VK_ICD_FILENAMES, no longer passes --no-sandbox /
|
|
||||||
# --disable-gpu-sandbox.
|
|
||||||
install -Dm755 "$srcdir/brave-vulkan" "$pkgdir/usr/bin/brave-vulkan"
|
install -Dm755 "$srcdir/brave-vulkan" "$pkgdir/usr/bin/brave-vulkan"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,23 +48,20 @@ brave-vulkan --your-flags-here # extra args passed through
|
|||||||
|
|
||||||
The launcher sets:
|
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)
|
- `PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1` (Mesa upstream gate)
|
||||||
- `MESA_VK_VERSION_OVERRIDE=1.2` (apiVersion bump for ANGLE)
|
- `MESA_VK_VERSION_OVERRIDE=1.2` (apiVersion bump for ANGLE)
|
||||||
- Brave flags: `--use-gl=disabled --enable-features=Vulkan --use-vulkan=native --ozone-platform=x11 --ignore-gpu-blocklist`
|
- Brave flags: `--use-gl=disabled --enable-features=Vulkan --use-vulkan=native --ozone-platform=x11 --no-sandbox --disable-gpu-sandbox --ignore-gpu-blocklist`
|
||||||
|
|
||||||
iter10 dropped `VK_ICD_FILENAMES` (ICD now at `/usr/share/vulkan/icd.d/00-panvk-bifrost.json` so the Vulkan loader auto-picks it, pinned deterministically via `VK_LOADER_DRIVERS_SELECT='00-panvk-bifrost*'`) and `--no-sandbox` / `--disable-gpu-sandbox` (env vars survive the GPU sandbox boundary without bypass).
|
|
||||||
|
|
||||||
## What's in the package
|
## 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/libvulkan_panfrost.so` — patched Mesa Vulkan driver (Mesa 26.0.6 + 2 sed-applied patches)
|
||||||
- `/usr/share/vulkan/icd.d/00-panvk-bifrost.json` — Vulkan ICD JSON pointing at the patched .so (Vulkan loader picks it deterministically via `VK_LOADER_DRIVERS_SELECT='00-panvk-bifrost*'` set by the launcher)
|
- `/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
|
- `/usr/bin/brave-vulkan` — launcher script
|
||||||
|
|
||||||
System Mesa's binary `/usr/lib/libvulkan_panfrost.so` is untouched. The
|
System Mesa is untouched. The stock `/usr/lib/libvulkan_panfrost.so` and
|
||||||
stock `panfrost_icd.json` is also untouched and continues to enumerate
|
`/usr/share/vulkan/icd.d/panfrost_icd.json` continue to work for any
|
||||||
the same Mali-G52 device — apps see both drivers in
|
other Vulkan app.
|
||||||
`vkEnumeratePhysicalDevices` and pick by index (ANGLE picks first, which
|
|
||||||
becomes ours by alphabetical priority).
|
|
||||||
|
|
||||||
## Co-existence
|
## Co-existence
|
||||||
|
|
||||||
|
|||||||
@@ -7,35 +7,26 @@
|
|||||||
#
|
#
|
||||||
# Provided by the mesa-panvk-bifrost package. See:
|
# Provided by the mesa-panvk-bifrost package. See:
|
||||||
# /usr/share/doc/mesa-panvk-bifrost/README
|
# /usr/share/doc/mesa-panvk-bifrost/README
|
||||||
# ~/src/panvk-bifrost/phase8_iteration{9,10}_close.md
|
# ~/src/panvk-bifrost/phase8_iteration9_close.md (campaign close)
|
||||||
#
|
#
|
||||||
# Usage: brave-vulkan [brave args...]
|
# Usage: brave-vulkan [brave args...]
|
||||||
# Equivalent to: brave [VULKAN_FLAGS] [your args]
|
# Equivalent to: brave [VULKAN_FLAGS] [your args]
|
||||||
#
|
|
||||||
# iter10 changes vs iter9:
|
|
||||||
# - dropped VK_ICD_FILENAMES env (ICD now at /usr/share/vulkan/icd.d/
|
|
||||||
# with '00-' prefix so the Vulkan loader auto-picks ours first)
|
|
||||||
# - dropped --no-sandbox / --disable-gpu-sandbox (env vars survive the
|
|
||||||
# GPU sandbox boundary, no bypass needed)
|
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Pin the Vulkan ICD selection to our package's ICD. The Vulkan loader's
|
# Patched Vulkan driver (from this package) — must point at the custom path
|
||||||
# readdir-order in /usr/share/vulkan/icd.d/ is implementation-defined
|
# so we don't clash with the stock /usr/share/vulkan/icd.d/panfrost_icd.json
|
||||||
# per Khronos LoaderDriverInterface — the '00-' filename prefix is NOT
|
export VK_ICD_FILENAMES=/usr/lib/panvk-bifrost/icd.json
|
||||||
# spec-backed. VK_LOADER_DRIVERS_SELECT short-circuits the directory
|
|
||||||
# enumeration and picks our ICD deterministically. (Phase 5 review
|
|
||||||
# hardening, iter10.)
|
|
||||||
export VK_LOADER_DRIVERS_SELECT='00-panvk-bifrost*'
|
|
||||||
|
|
||||||
# PanVk's "I know it's not conformant" gate — the patched driver still
|
# PanVk's "I know it's not conformant" gate — the patched driver still
|
||||||
# refuses to enumerate Bifrost without this env var (upstream Mesa choice
|
# refuses to enumerate Bifrost without this env var (Mesa upstream choice,
|
||||||
# for v6/v7, kept for compatibility).
|
# kept for compatibility).
|
||||||
export PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1
|
export PAN_I_WANT_A_BROKEN_VULKAN_DRIVER=1
|
||||||
|
|
||||||
# Override apiVersion to 1.2 — ANGLE (Chromium's GL stack) requires
|
# Override apiVersion to 1.2 — ANGLE (Chromium's GL stack) requires
|
||||||
# device.apiVersion >= 1.1. Source patches don't move get_api_version()'s
|
# device.apiVersion >= 1.1. The patched libvulkan_panfrost.so still has
|
||||||
# PAN_ARCH>=10 hardcode; the env var override does.
|
# 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
|
export MESA_VK_VERSION_OVERRIDE=1.2
|
||||||
|
|
||||||
# Find the live Plasma session's Xauthority. On a fresh boot the suffix
|
# Find the live Plasma session's Xauthority. On a fresh boot the suffix
|
||||||
@@ -64,5 +55,7 @@ exec brave \
|
|||||||
--enable-features=Vulkan \
|
--enable-features=Vulkan \
|
||||||
--use-vulkan=native \
|
--use-vulkan=native \
|
||||||
--ozone-platform=x11 \
|
--ozone-platform=x11 \
|
||||||
|
--no-sandbox \
|
||||||
|
--disable-gpu-sandbox \
|
||||||
--ignore-gpu-blocklist \
|
--ignore-gpu-blocklist \
|
||||||
"$@"
|
"$@"
|
||||||
|
|||||||
Vendored
+1
-1
@@ -16,7 +16,7 @@ work=$(mktemp -d)
|
|||||||
trap "rm -rf $work" EXIT
|
trap "rm -rf $work" EXIT
|
||||||
|
|
||||||
cd "$work"
|
cd "$work"
|
||||||
curl -sSLfo his.tar.gz \
|
curl --connect-timeout 10 --max-time 600 --retry 3 --retry-delay 5 -sSLfo his.tar.gz \
|
||||||
"https://git.reauktion.de/marfrit/claude-his-agent/archive/v${PKGVER}.tar.gz"
|
"https://git.reauktion.de/marfrit/claude-his-agent/archive/v${PKGVER}.tar.gz"
|
||||||
echo "$HIS_TARBALL_SHA256 his.tar.gz" | sha256sum -c
|
echo "$HIS_TARBALL_SHA256 his.tar.gz" | sha256sum -c
|
||||||
tar xzf his.tar.gz
|
tar xzf his.tar.gz
|
||||||
|
|||||||
+50
-24
@@ -14,9 +14,9 @@
|
|||||||
# Sibling userspace package: ../daedalus-v4l2/build-deb.sh
|
# Sibling userspace package: ../daedalus-v4l2/build-deb.sh
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
UPSTREAM_COMMIT=481279c9bffd19e32c8f3299897e9b63fc5a24aa
|
UPSTREAM_COMMIT=5d8b4369e58ab947d1c56b1f718293c57c6065b5
|
||||||
PKGVER=0.1.0+r18+g481279c
|
PKGVER=0.1.0+r33+g5d8b436
|
||||||
PKGREL=1 # reset for new upstream pin (481279c — Phase 8.13 close)
|
PKGREL=1 # reset for new upstream pin (5d8b436 — revert parking design); still carries the #64 multi-kernel postinst fix
|
||||||
MODULE_NAME=daedalus_v4l2
|
MODULE_NAME=daedalus_v4l2
|
||||||
|
|
||||||
HERE=$(dirname "$(readlink -f "$0")")
|
HERE=$(dirname "$(readlink -f "$0")")
|
||||||
@@ -28,7 +28,7 @@ work=$(mktemp -d)
|
|||||||
trap "rm -rf $work" EXIT
|
trap "rm -rf $work" EXIT
|
||||||
|
|
||||||
cd "$work"
|
cd "$work"
|
||||||
curl -sSLfo daedalus-v4l2.tar.gz \
|
curl --connect-timeout 10 --max-time 600 --retry 3 --retry-delay 5 -sSLfo daedalus-v4l2.tar.gz \
|
||||||
"https://git.reauktion.de/reauktion/daedalus-v4l2/archive/${UPSTREAM_COMMIT}.tar.gz"
|
"https://git.reauktion.de/reauktion/daedalus-v4l2/archive/${UPSTREAM_COMMIT}.tar.gz"
|
||||||
tar xzf daedalus-v4l2.tar.gz
|
tar xzf daedalus-v4l2.tar.gz
|
||||||
SRCDIR=daedalus-v4l2
|
SRCDIR=daedalus-v4l2
|
||||||
@@ -78,7 +78,6 @@ set -e
|
|||||||
|
|
||||||
NAME=${MODULE_NAME}
|
NAME=${MODULE_NAME}
|
||||||
VERSION=${PKGVER}
|
VERSION=${PKGVER}
|
||||||
KERNELVER=\$(uname -r)
|
|
||||||
|
|
||||||
# Yellow + bold ANSI for the warning so it stands out in apt's
|
# Yellow + bold ANSI for the warning so it stands out in apt's
|
||||||
# stream of "Setting up" lines. Disable colour on non-TTY.
|
# stream of "Setting up" lines. Disable colour on non-TTY.
|
||||||
@@ -101,29 +100,56 @@ if [ "\$1" = "configure" ]; then
|
|||||||
|
|
||||||
dkms add "\$NAME/\$VERSION" 2>/dev/null || true
|
dkms add "\$NAME/\$VERSION" 2>/dev/null || true
|
||||||
|
|
||||||
# Don't let autoinstall failure mask the actual problem behind '|| true'.
|
# Enumerate every kernel whose headers are actually present
|
||||||
# Run it, capture the result, then verify post-condition.
|
# (/lib/modules/<kver>/build resolves to a directory). We iterate
|
||||||
autoinstall_rc=0
|
# all of them — not just \$(uname -r) — so that installing this
|
||||||
dkms autoinstall "\$NAME/\$VERSION" || autoinstall_rc=\$?
|
# package after a kernel update covers the newly-installed kernel
|
||||||
|
# too, and so that a later kernel-headers install for a previously
|
||||||
|
# uncovered version gets picked up on dpkg-reconfigure. Without
|
||||||
|
# this, autoinstall (which targets only the running kernel) leaves
|
||||||
|
# /dev/daedalus-v4l2 absent after a kernel switch + reboot
|
||||||
|
# (marfrit/marfrit-packages#64).
|
||||||
|
kvers=''
|
||||||
|
for d in /lib/modules/*/build; do
|
||||||
|
[ -d "\$d" ] || continue
|
||||||
|
k=\$(basename "\$(dirname "\$d")")
|
||||||
|
kvers="\$kvers \$k"
|
||||||
|
done
|
||||||
|
|
||||||
# Verify the module actually built + installed for the running kernel.
|
if [ -z "\$kvers" ]; then
|
||||||
status=\$(dkms status -m "\$NAME" -v "\$VERSION" -k "\$KERNELVER" 2>/dev/null || true)
|
|
||||||
if ! printf '%s\\n' "\$status" | grep -q -E 'installed|loaded'; then
|
|
||||||
warn ""
|
warn ""
|
||||||
warn "DKMS build did NOT land for kernel \$KERNELVER."
|
warn "No kernels with headers found under /lib/modules/*/build."
|
||||||
warn " dkms status -m \$NAME -v \$VERSION -k \$KERNELVER:"
|
warn "Install kernel headers (e.g. linux-headers-rpi-2712 on Pi OS)"
|
||||||
warn " \$(printf '%s' "\$status" | head -1)"
|
warn "then finish with:"
|
||||||
warn ""
|
|
||||||
warn "Most likely cause: kernel headers package is missing."
|
|
||||||
warn " Raspberry Pi OS / Pi 5: apt install linux-headers-rpi-2712"
|
|
||||||
warn " Debian generic: apt install linux-headers-\$KERNELVER"
|
|
||||||
warn ""
|
|
||||||
warn "After installing headers, finish the install with:"
|
|
||||||
warn " sudo dkms autoinstall \$NAME/\$VERSION"
|
warn " sudo dkms autoinstall \$NAME/\$VERSION"
|
||||||
warn " sudo modprobe daedalus_v4l2"
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
failed=''
|
||||||
|
for k in \$kvers; do
|
||||||
|
dkms autoinstall -k "\$k" "\$NAME/\$VERSION" >/dev/null 2>&1 || true
|
||||||
|
s=\$(dkms status -m "\$NAME" -v "\$VERSION" -k "\$k" 2>/dev/null || true)
|
||||||
|
if ! printf '%s\\n' "\$s" | grep -q -E 'installed|loaded'; then
|
||||||
|
failed="\$failed \$k"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "\$failed" ]; then
|
||||||
warn ""
|
warn ""
|
||||||
warn "Until then daedalus_v4l2 will NOT be loadable and the"
|
warn "DKMS build did NOT land for kernel(s):\$failed"
|
||||||
warn "userspace daedalus-v4l2 daemon will have nothing to talk to."
|
warn ""
|
||||||
|
warn "Most likely cause: kernel headers missing for those versions."
|
||||||
|
warn " Raspberry Pi OS / Pi 5: apt install linux-headers-rpi-2712"
|
||||||
|
warn " Debian generic: apt install linux-headers-<version>"
|
||||||
|
warn ""
|
||||||
|
warn "After installing headers, finish with:"
|
||||||
|
for k in \$failed; do
|
||||||
|
warn " sudo dkms autoinstall -k \$k \$NAME/\$VERSION"
|
||||||
|
done
|
||||||
|
warn " sudo modprobe daedalus_v4l2 (after booting that kernel)"
|
||||||
|
warn ""
|
||||||
|
warn "Until then daedalus_v4l2 will NOT be loadable on those kernels"
|
||||||
|
warn "and the userspace daedalus-v4l2 daemon will have nothing to talk to."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
+110
@@ -1,3 +1,113 @@
|
|||||||
|
daedalus-v4l2-dkms (0.1.0+r33+g5d8b436-1) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
|
* Bump to 5d8b436 — reverts daedalus-v4l2 PRs #7 + #8. Kernel
|
||||||
|
module returns to the pre-#7 buf_done_and_job_finish completion
|
||||||
|
model: no src/dst lifecycle decoupling, no parked dst_bufs, no
|
||||||
|
1:1-contract violation against libva-v4l2-request-fourier
|
||||||
|
(closes daedalus-v4l2#9 + #10 as won't-fix at this layer; proper
|
||||||
|
fix tracked at daedalus-v4l2#11).
|
||||||
|
* Wire-protocol drops 1 → 0; lock-step install with daedalus-v4l2
|
||||||
|
0.1.0+r33+g5d8b436 REQUIRED.
|
||||||
|
* Carries forward the #64 multi-kernel postinst fix.
|
||||||
|
|
||||||
|
-- Markus Fritsche <mfritsche@reauktion.de> Thu, 21 May 2026 14:50:00 +0000
|
||||||
|
|
||||||
|
daedalus-v4l2-dkms (0.1.0+r30+g6ffe92b-1) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
|
* Bump to 6ffe92b — fixes the kernel panic regression introduced
|
||||||
|
by 79256dc's split-completion design (closes daedalus-v4l2#8).
|
||||||
|
`device_run` now removes both src + dst from `m2m_ctx`'s
|
||||||
|
rdy_queue at pickup time, not at `buf_done` time. Without
|
||||||
|
this, after `SRC_CONSUMED`'s `job_finish` released the m2m
|
||||||
|
scheduler, the NEXT `device_run` saw the still-queued parked
|
||||||
|
dst_buf and paired it with a fresh src — two inflight entries
|
||||||
|
referencing the same vb2_buffer, the later `HAS_PIXELS`
|
||||||
|
triggered list_del on an already-detached list_head, smashing
|
||||||
|
the rdy_queue → hard reboot on Pi CM5 during `mpv vaapi-copy`
|
||||||
|
playback of 720p H.264 (2026-05-21).
|
||||||
|
* Wire protocol unchanged — DAEDALUS_PROTO_VERSION stays at 1.
|
||||||
|
Daemon (userspace daedalus-v4l2 package) need NOT bump in
|
||||||
|
lockstep with this DKMS update; the existing
|
||||||
|
daedalus-v4l2 0.1.0+r28+g79256dc is wire-compatible with
|
||||||
|
daedalus-v4l2-dkms 0.1.0+r30+g6ffe92b.
|
||||||
|
* Carries forward the #64 multi-kernel postinst fix.
|
||||||
|
|
||||||
|
-- Markus Fritsche <mfritsche@reauktion.de> Thu, 21 May 2026 14:00:00 +0000
|
||||||
|
|
||||||
|
daedalus-v4l2-dkms (0.1.0+r28+g79256dc-1) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
|
* Bump to 79256dc — H.264 B-frame display reorder fix (closes
|
||||||
|
daedalus-v4l2#6). libavcodec's H.264 decoder reorders output to
|
||||||
|
display order before returning from avcodec_receive_frame; the
|
||||||
|
daemon was binding each REQ_DECODE's pixels to the cookie of the
|
||||||
|
bitstream that triggered the receive_frame call, not the cookie
|
||||||
|
of the bitstream that actually produced the picture. For B-frame
|
||||||
|
sequences this paired cookie N's CAPTURE buffer with cookie N-2's
|
||||||
|
pixels and silently lost intermediate frames — visible as
|
||||||
|
"2 1 4 3 6 5" frame pairing in mpv / Firefox on Pi CM5.
|
||||||
|
* Wire-protocol bump (DAEDALUS_PROTO_VERSION 0 → 1): REQ_DECODE
|
||||||
|
gains __u64 src_pts; RESP_FRAME gains __u32 flags +
|
||||||
|
__u64 output_src_pts. Kernel + daemon must install atomically
|
||||||
|
(this package + daedalus-v4l2 0.1.0+r28+g79256dc).
|
||||||
|
* Carries forward the #64 multi-kernel postinst fix from -2:
|
||||||
|
autoinstall for every /lib/modules/*/build that resolves to real
|
||||||
|
headers, not just $(uname -r).
|
||||||
|
* Closes #64.
|
||||||
|
|
||||||
|
-- Markus Fritsche <mfritsche@reauktion.de> Thu, 21 May 2026 12:00:00 +0000
|
||||||
|
|
||||||
|
daedalus-v4l2-dkms (0.1.0+r24+gf0d4186-2) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
|
* postinst: autoinstall for every installed kernel with headers, not
|
||||||
|
just the running one. Previously `dkms autoinstall $NAME/$VERSION`
|
||||||
|
built only against `$(uname -r)`, so installing the package on
|
||||||
|
kernel A and then rebooting into a separately-installed kernel B
|
||||||
|
left /lib/modules/B/updates/dkms/ empty — /dev/daedalus-v4l2 absent,
|
||||||
|
daedalus daemon nothing to talk to, browser/VAAPI silently falling
|
||||||
|
back to software with no obvious diagnostic. Now we enumerate every
|
||||||
|
/lib/modules/*/build that resolves to a real directory and run
|
||||||
|
`dkms autoinstall -k <kver>` for each, reporting per-kernel failure
|
||||||
|
only when headers are missing. Closes #64.
|
||||||
|
|
||||||
|
-- Markus Fritsche <mfritsche@reauktion.de> Thu, 21 May 2026 09:30:00 +0000
|
||||||
|
|
||||||
|
daedalus-v4l2-dkms (0.1.0+r24+gf0d4186-1) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
|
* Bump to f0d4186 — per-ctx vb2 lock fix. daedalus_queue_init now
|
||||||
|
uses ctx->vb_mutex instead of ctx->dev->m2m_lock for each
|
||||||
|
vb2_queue's lock, unblocking Firefox's multi-process VAAPI
|
||||||
|
clients (they were colliding on the device-wide mutex and one
|
||||||
|
would EBUSY-fail S_FMT while another was mid-streamon).
|
||||||
|
|
||||||
|
-- Markus Fritsche <mfritsche@reauktion.de> Wed, 20 May 2026 23:00:00 +0000
|
||||||
|
|
||||||
|
daedalus-v4l2-dkms (0.1.0+r22+g462aa4b-1) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
|
* Bump to 462aa4b — kernel device_run() now calls
|
||||||
|
v4l2_ctrl_request_setup() before reading the H.264 stateless
|
||||||
|
control values from the bound media_request, so the values
|
||||||
|
daedalus ships to the userspace daemon match what the V4L2
|
||||||
|
client (libva-v4l2-request-fourier) actually set. Closes the
|
||||||
|
libva→kernel control-binding gap that was causing decoded
|
||||||
|
frames to come back as best-effort zero garbage from libavcodec.
|
||||||
|
* Wire-ABI lockstep with daedalus-v4l2 0.1.0+r22+g462aa4b.
|
||||||
|
|
||||||
|
-- Markus Fritsche <mfritsche@reauktion.de> Wed, 20 May 2026 22:00:00 +0000
|
||||||
|
|
||||||
|
daedalus-v4l2-dkms (0.1.0+r20+g3dd0eb0-1) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
|
* Bump to 3dd0eb0 — DAEMON-PPS kernel-side changes. device_run()
|
||||||
|
now reads the V4L2 H.264 stateless control values from the bound
|
||||||
|
media_request and ships them to the daemon inside REQ_DECODE
|
||||||
|
via the new struct daedalus_h264_meta block (gated on
|
||||||
|
DAEDALUS_REQ_FLAG_H264_META). Required for H.264 decode to
|
||||||
|
work via the libva-v4l2-request -> daedalus daemon path; daemon
|
||||||
|
synthesises AnnexB SPS+PPS NAL units from the structs.
|
||||||
|
* Wire-ABI lockstep with daedalus-v4l2 0.1.0+r20+g3dd0eb0 — install
|
||||||
|
both packages together.
|
||||||
|
|
||||||
|
-- Markus Fritsche <mfritsche@reauktion.de> Wed, 20 May 2026 21:00:00 +0000
|
||||||
|
|
||||||
daedalus-v4l2-dkms (0.1.0+r18+g481279c-1) bookworm trixie; urgency=medium
|
daedalus-v4l2-dkms (0.1.0+r18+g481279c-1) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
* Bump to 481279c in lockstep with the userspace daedalus-v4l2
|
* Bump to 481279c in lockstep with the userspace daedalus-v4l2
|
||||||
|
|||||||
Vendored
+42
-9
@@ -11,13 +11,23 @@
|
|||||||
# Upstream repo: https://git.reauktion.de/reauktion/daedalus-v4l2
|
# Upstream repo: https://git.reauktion.de/reauktion/daedalus-v4l2
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# Same pin as the Arch PKGBUILD. 481279c = "Phase 8.13: byte-exact
|
# 6e6dfa1 = picks up daedalus-v4l2 PR #16 — daemon now dlopens
|
||||||
# end-to-end via libva (consumer target hit)" — first commit where the
|
# the Kwiboo fourier fork's libavcodec.so.62 / libavformat.so.62 /
|
||||||
# full ffmpeg -hwaccel vaapi → libva → /dev/video0 → daemon path lands
|
# libavutil.so.60 at /opt/fourier instead of Debian-stock soname
|
||||||
# a pixel-correct decoded frame back in ffmpeg.
|
# 61/61/59. First step on the daedalus-fourier substitution arc
|
||||||
UPSTREAM_COMMIT=481279c9bffd19e32c8f3299897e9b63fc5a24aa
|
# (daedalus-v4l2#11): routes the daemon through the libavcodec
|
||||||
PKGVER=0.1.0+r18+g481279c
|
# source tree we own in marfrit-packages. Headers + .pc files
|
||||||
PKGREL=1 # reset for new upstream pin (481279c — Phase 8.13 close)
|
# come from ffmpeg-v4l2-request-fourier (installed by the CI
|
||||||
|
# workflow before this script runs; see PKG_CONFIG_PATH below).
|
||||||
|
UPSTREAM_COMMIT=6e6dfa144da7bc7fa8be50c8da91d7d1c6132a2c
|
||||||
|
PKGVER=0.1.0+r41+g6e6dfa1
|
||||||
|
PKGREL=1 # reset for new upstream pin (6e6dfa1 — soname 62 via /opt/fourier)
|
||||||
|
|
||||||
|
# daedalus-fourier pin. d87239d = marfrit/daedalus-fourier PR #1 merge
|
||||||
|
# (install rules + pkg-config, enables this consumer to find_package
|
||||||
|
# + link). Bump in lockstep with the upstream daemon when daedalus-
|
||||||
|
# fourier's API or installed shaders are changed by a new consumer.
|
||||||
|
DAEDALUS_FOURIER_COMMIT=d87239d8172307d9a1b93c95cbed116d175b85cc
|
||||||
|
|
||||||
HERE=$(dirname "$(readlink -f "$0")")
|
HERE=$(dirname "$(readlink -f "$0")")
|
||||||
|
|
||||||
@@ -27,14 +37,37 @@ export SOURCE_DATE_EPOCH=1779231600
|
|||||||
work=$(mktemp -d)
|
work=$(mktemp -d)
|
||||||
trap "rm -rf $work" EXIT
|
trap "rm -rf $work" EXIT
|
||||||
|
|
||||||
|
# --- daedalus-fourier: fetch + build + install to per-build prefix ---
|
||||||
|
#
|
||||||
|
# Static-linked into the daemon, so the temp prefix is only for the
|
||||||
|
# duration of this build script. Requires libvulkan-dev + glslang-tools
|
||||||
|
# on the runner (already needed for the daedalus-fourier benches).
|
||||||
|
FOURIER_PREFIX=$work/fourier-prefix
|
||||||
|
mkdir -p "$FOURIER_PREFIX"
|
||||||
|
|
||||||
cd "$work"
|
cd "$work"
|
||||||
curl -sSLfo daedalus-v4l2.tar.gz \
|
curl --connect-timeout 10 --max-time 600 --retry 3 --retry-delay 5 -sSLfo daedalus-fourier.tar.gz \
|
||||||
|
"https://git.reauktion.de/marfrit/daedalus-fourier/archive/${DAEDALUS_FOURIER_COMMIT}.tar.gz"
|
||||||
|
tar xzf daedalus-fourier.tar.gz
|
||||||
|
cd daedalus-fourier
|
||||||
|
cmake -B build -G Ninja \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DCMAKE_INSTALL_PREFIX="$FOURIER_PREFIX"
|
||||||
|
cmake --build build --target daedalus_core
|
||||||
|
cmake --install build
|
||||||
|
|
||||||
|
# --- daedalus-v4l2: fetch + build daemon against installed daedalus-fourier ---
|
||||||
|
|
||||||
|
cd "$work"
|
||||||
|
curl --connect-timeout 10 --max-time 600 --retry 3 --retry-delay 5 -sSLfo daedalus-v4l2.tar.gz \
|
||||||
"https://git.reauktion.de/reauktion/daedalus-v4l2/archive/${UPSTREAM_COMMIT}.tar.gz"
|
"https://git.reauktion.de/reauktion/daedalus-v4l2/archive/${UPSTREAM_COMMIT}.tar.gz"
|
||||||
tar xzf daedalus-v4l2.tar.gz
|
tar xzf daedalus-v4l2.tar.gz
|
||||||
SRCDIR=daedalus-v4l2
|
SRCDIR=daedalus-v4l2
|
||||||
|
|
||||||
# Build daemon (CMake)
|
# Build daemon (CMake) — point pkg-config at the daedalus-fourier
|
||||||
|
# temp prefix so pkg_check_modules(DAEDALUS_FOURIER …) resolves to it.
|
||||||
cd "$SRCDIR/daemon"
|
cd "$SRCDIR/daemon"
|
||||||
|
PKG_CONFIG_PATH="$FOURIER_PREFIX/lib/pkgconfig:/opt/fourier/lib/pkgconfig" \
|
||||||
cmake -B build -G Ninja \
|
cmake -B build -G Ninja \
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
-DCMAKE_INSTALL_PREFIX=/usr
|
-DCMAKE_INSTALL_PREFIX=/usr
|
||||||
|
|||||||
+169
@@ -1,3 +1,172 @@
|
|||||||
|
daedalus-v4l2 (0.1.0+r41+g6e6dfa1-1) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
|
* Bump to 6e6dfa1 — daedalus-v4l2 PR #16. Daemon dlopens Kwiboo
|
||||||
|
fourier fork's libavcodec.so.62 / libavformat.so.62 /
|
||||||
|
libavutil.so.60 at /opt/fourier instead of Debian-stock
|
||||||
|
soname 61/61/59. First step on the daedalus-fourier
|
||||||
|
substitution arc (daedalus-v4l2#11): the next PR series
|
||||||
|
layers daedalus_recipe_dispatch_h264_* substitution patches
|
||||||
|
into ffmpeg-v4l2-request-fourier's H264DSPContext NEON init,
|
||||||
|
reaching the daemon's production decode path.
|
||||||
|
* Build: PKG_CONFIG_PATH now includes /opt/fourier/lib/pkgconfig
|
||||||
|
so daemon's pkg_check_modules picks up the Kwiboo .pc files.
|
||||||
|
* CI workflow build-deps: libavcodec-dev / libavformat-dev /
|
||||||
|
libavutil-dev (Debian stock 7.1.3) → ffmpeg-v4l2-request-fourier
|
||||||
|
(provides /opt/fourier/include + .pc files).
|
||||||
|
* Wire protocol unchanged. No daedalus-v4l2-dkms bump.
|
||||||
|
|
||||||
|
-- Markus Fritsche <mfritsche@reauktion.de> Thu, 21 May 2026 21:30:00 +0000
|
||||||
|
|
||||||
|
daedalus-v4l2 (0.1.0+r39+g3bc0da1-1) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
|
* Bump to 3bc0da1 — picks up daedalus-v4l2 PR #15. Per-frame
|
||||||
|
`decoder: OK ...` log line gains `decode_us=N` (libavcodec
|
||||||
|
send_packet + receive_frame wall-clock cost in microseconds).
|
||||||
|
New `decoder stats` summary line every 60 decoded frames with
|
||||||
|
codec, fps, avg decode_us, MBs/s throughput, B/MB bitrate.
|
||||||
|
* Pure observability — no decode-path behaviour change.
|
||||||
|
Establishes baseline metrics for the substitution work in
|
||||||
|
daedalus-v4l2#11 step 2 (replacing libavcodec primitives with
|
||||||
|
daedalus-fourier kernels one cycle at a time).
|
||||||
|
* On Pi CM5 / bbb 720p H.264 baseline: ~4 ms decode_us / 24 fps
|
||||||
|
/ 90 K MBs/s — workload is well under 1 % of any single
|
||||||
|
daedalus-fourier kernel's NEON ceiling.
|
||||||
|
* Wire protocol unchanged. No daedalus-v4l2-dkms bump needed.
|
||||||
|
|
||||||
|
-- Markus Fritsche <mfritsche@reauktion.de> Thu, 21 May 2026 18:30:00 +0000
|
||||||
|
|
||||||
|
daedalus-v4l2 (0.1.0+r37+g77e14e5-1) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
|
* Bump to 77e14e5 — picks up daedalus-v4l2 PRs #12 + #13.
|
||||||
|
* #12 (LOW_DELAY half-measure): the daemon now sets
|
||||||
|
AV_CODEC_FLAG_LOW_DELAY on the H.264 AVCodecContext so libavcodec
|
||||||
|
emits frames in decode order ~99% of the time (a few stragglers
|
||||||
|
at GOP boundaries when the stream's SPS num_reorder_frames
|
||||||
|
overrides the flag). Visible improvement vs the 2-1-4-3
|
||||||
|
pair-swap on Firefox YouTube + mpv playback; not a permanent
|
||||||
|
fix (see #11 for the architectural plan).
|
||||||
|
* #13 (daedalus-fourier linkage): the daemon now pkg-config-links
|
||||||
|
against the daedalus-fourier kernel library (marfrit/
|
||||||
|
daedalus-fourier) and logs substrate availability at startup.
|
||||||
|
No kernels dispatched yet — this is the build-time / link-time
|
||||||
|
foundation for the H.264 daemon-rewrite plan in #11
|
||||||
|
(substituting daedalus-fourier IDCT 4×4 / IDCT 8×8 / luma
|
||||||
|
deblock primitives for libavcodec's per-MB pixel math, one
|
||||||
|
cycle at a time, measuring CPU saved per substitution).
|
||||||
|
* Build-deb.sh now fetches + builds + installs daedalus-fourier
|
||||||
|
(pinned at d87239d, marfrit/daedalus-fourier PR #1) into a
|
||||||
|
per-build temp prefix, then builds the daemon with
|
||||||
|
PKG_CONFIG_PATH pointing at it. daedalus-fourier is
|
||||||
|
statically linked into the daemon binary, so the resulting
|
||||||
|
.deb has no new runtime deps. Requires libvulkan-dev +
|
||||||
|
glslang-tools on the CI runner (the daedalus-fourier benches
|
||||||
|
already needed those).
|
||||||
|
* Wire protocol unchanged — DAEDALUS_PROTO_VERSION stays at 0.
|
||||||
|
No daedalus-v4l2-dkms bump needed.
|
||||||
|
|
||||||
|
-- Markus Fritsche <mfritsche@reauktion.de> Thu, 21 May 2026 16:30:00 +0000
|
||||||
|
|
||||||
|
daedalus-v4l2 (0.1.0+r33+g5d8b436-1) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
|
* Bump to 5d8b436 — reverts daedalus-v4l2 PRs #7 + #8 (the parking
|
||||||
|
design that broke libva-v4l2-request-fourier's 1:1 CAPTURE
|
||||||
|
contract; see daedalus-v4l2#9 + #10). After daemon-r28+g79256dc
|
||||||
|
landed, mpv (--hwdec=vaapi-copy) failed pre-playing with
|
||||||
|
"Unable to dequeue buffer: Resource temporarily unavailable" /
|
||||||
|
"Failed to end picture decode" because the daemon parked CAPTURE
|
||||||
|
buffers waiting for libavcodec to release H.264 B-frames in
|
||||||
|
display order — violating the V4L2 stateless 1:1 contract.
|
||||||
|
Firefox tolerated the mess (visible "2 1 4 3" pair-swap); mpv
|
||||||
|
bailed.
|
||||||
|
* This bump restores f0d4186-equivalent behaviour, plus PR #4
|
||||||
|
(cosmetic H.264 DECODE_MODE / START_CODE menu controls). PR #7
|
||||||
|
+ PR #8 wire-protocol additions (src_pts / output_src_pts /
|
||||||
|
RESP_FRAME flags) are reverted — DAEDALUS_PROTO_VERSION drops
|
||||||
|
back from 1 → 0. Lock-step install with daedalus-v4l2-dkms
|
||||||
|
0.1.0+r33+g5d8b436 REQUIRED.
|
||||||
|
* Visible regression: H.264 B-frame streams in Firefox revert to
|
||||||
|
the original "2 1 4 3 6 5" pair-swap visual. The proper fix
|
||||||
|
(concurrent in-flight requests in daemon + display-order reorder
|
||||||
|
in libva-v4l2-request-fourier) is tracked at daedalus-v4l2#11.
|
||||||
|
|
||||||
|
-- Markus Fritsche <mfritsche@reauktion.de> Thu, 21 May 2026 14:50:00 +0000
|
||||||
|
|
||||||
|
daedalus-v4l2 (0.1.0+r28+g79256dc-1) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
|
* Bump to 79256dc — H.264 B-frame display reorder fix (closes
|
||||||
|
daedalus-v4l2#6 + #4 menu controls). Daemon side: the
|
||||||
|
avcodec_send_packet → receive_frame loop now stamps pkt->pts =
|
||||||
|
req->src_pts so libavcodec's display-ordered frame->pts identifies
|
||||||
|
which OUTPUT bitstream's pixels each drained frame belongs to.
|
||||||
|
chardev_client maintains a (src_pts → cookie) lookup table so the
|
||||||
|
daemon can ship pixels to the cookie of the *originating*
|
||||||
|
bitstream, not the cookie of whatever REQ triggered the
|
||||||
|
receive_frame call. Multiple RESP_FRAME messages per REQ_DECODE
|
||||||
|
are now possible (one for the just-consumed src, one or more for
|
||||||
|
drained pixels).
|
||||||
|
* Wire-protocol bump (DAEDALUS_PROTO_VERSION 0 → 1): REQ_DECODE
|
||||||
|
gains __u64 src_pts; RESP_FRAME gains __u32 flags +
|
||||||
|
__u64 output_src_pts. Daemon + kernel must install atomically
|
||||||
|
(this package + daedalus-v4l2-dkms 0.1.0+r28+g79256dc).
|
||||||
|
* Also subsumes 79256dc's predecessor 7ff2d89 — H.264 DECODE_MODE +
|
||||||
|
START_CODE menu-control registration that retires the
|
||||||
|
"Unable to set control(s) error_idx=2/2" warning libva-v4l2-
|
||||||
|
request emitted on every context init.
|
||||||
|
|
||||||
|
-- Markus Fritsche <mfritsche@reauktion.de> Thu, 21 May 2026 12:00:00 +0000
|
||||||
|
|
||||||
|
daedalus-v4l2 (0.1.0+r24+gf0d4186-1) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
|
* Bump to f0d4186 — kernel per-ctx vb2 lock fix. daedalus_queue_init
|
||||||
|
was wiring src_vq->lock and dst_vq->lock to ctx->dev->m2m_lock (a
|
||||||
|
device-wide mutex), serialising every vb2 ioctl across all
|
||||||
|
concurrent clients of /dev/video0. For Firefox (which spawns
|
||||||
|
separate content + RDD + GPU processes that each open the device
|
||||||
|
and run libva probe simultaneously), one libva session's
|
||||||
|
S_FMT(OUTPUT_MPLANE) hit EBUSY while another was mid-streamon —
|
||||||
|
Firefox VAAPI playback fell apart at startup.
|
||||||
|
* Fix gives each open() its own ctx->vb_mutex; vb2 ioctls run
|
||||||
|
independently per client. Matches cedrus / rkvdec / hantro
|
||||||
|
pattern.
|
||||||
|
* Verified on higgs: Firefox YouTube playback engages VAAPI cleanly,
|
||||||
|
sustained ~230 fps decode at 640x368 through the daedalus daemon,
|
||||||
|
zero EBUSY in stderr or daemon journal.
|
||||||
|
|
||||||
|
-- Markus Fritsche <mfritsche@reauktion.de> Wed, 20 May 2026 23:00:00 +0000
|
||||||
|
|
||||||
|
daedalus-v4l2 (0.1.0+r22+g462aa4b-1) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
|
* Bump to 462aa4b — kernel-side fix for control-binding gap that
|
||||||
|
closes the libva→daemon SPS/PPS pipeline. Kernel device_run now
|
||||||
|
calls v4l2_ctrl_request_setup() before reading ctrl->p_cur, so
|
||||||
|
the daemon's daedalus_h264_meta block actually carries THIS
|
||||||
|
request's V4L2 stateless H.264 control values instead of stale
|
||||||
|
/default ones. Pairs with libva-v4l2-request-fourier r382+gc1bb444
|
||||||
|
(Fix 3 + Fix 4 from issue libva-v4l2-request-fourier#8).
|
||||||
|
* After-fix on higgs (Pi CM5): ffmpeg -hwaccel vaapi -i h264.mp4
|
||||||
|
produces unique decoded P-frames (per-frame fnv1a hashes differ)
|
||||||
|
and zero "error while decoding MB" / "reference frames exceeds
|
||||||
|
max" warnings.
|
||||||
|
|
||||||
|
-- Markus Fritsche <mfritsche@reauktion.de> Wed, 20 May 2026 22:00:00 +0000
|
||||||
|
|
||||||
|
daedalus-v4l2 (0.1.0+r20+g3dd0eb0-1) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
|
* Bump to 3dd0eb0 — DAEMON-PPS H.264 SPS/PPS NAL synthesiser.
|
||||||
|
Daemon now reconstructs AnnexB SPS+PPS NAL units from the V4L2
|
||||||
|
stateless H.264 control structs (forwarded by the kernel via
|
||||||
|
a new struct daedalus_h264_meta block in REQ_DECODE) and
|
||||||
|
prepends them to the slice bitstream before feeding libavcodec.
|
||||||
|
Without this, ffmpeg -hwaccel vaapi on H.264 sources failed
|
||||||
|
with "non-existing PPS 0 referenced" even after LIBVA-1/-2
|
||||||
|
routing correctly delivered the request.
|
||||||
|
* Wire protocol: new DAEDALUS_REQ_FLAG_H264_META bit + struct
|
||||||
|
daedalus_h264_meta; daemon and kernel must be installed in
|
||||||
|
lockstep (this package + daedalus-v4l2-dkms 0.1.0+r20+g3dd0eb0).
|
||||||
|
* VP9 / AV1 paths unchanged.
|
||||||
|
|
||||||
|
-- Markus Fritsche <mfritsche@reauktion.de> Wed, 20 May 2026 21:00:00 +0000
|
||||||
|
|
||||||
daedalus-v4l2 (0.1.0+r18+g481279c-1) bookworm trixie; urgency=medium
|
daedalus-v4l2 (0.1.0+r18+g481279c-1) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
* Bump to 481279c. Upstream landed the systemd unit + modules-load.d
|
* Bump to 481279c. Upstream landed the systemd unit + modules-load.d
|
||||||
|
|||||||
@@ -0,0 +1,137 @@
|
|||||||
|
From f760c0541586f43334c02611fcb4c212c08ad576 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Markus Fritsche <mfritsche@reauktion.de>
|
||||||
|
Date: Thu, 21 May 2026 21:40:22 +0200
|
||||||
|
Subject: [PATCH] avcodec/aarch64/h264dsp: route H.264 4x4 IDCT through
|
||||||
|
daedalus-fourier
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
H264DSPContext.idct_add (called per 4x4 block from the intra-4x4
|
||||||
|
decode path in h264_mb.c) now dispatches through
|
||||||
|
daedalus_recipe_dispatch_h264_idct4 instead of ff_h264_idct_add_neon.
|
||||||
|
|
||||||
|
The recipe layer picks the substrate; for cycle 6 (H.264 IDCT 4x4)
|
||||||
|
the recipe is CPU NEON, so this is effectively a NEON-to-NEON
|
||||||
|
substitution with one extra dispatch call and recipe-table lookup.
|
||||||
|
Provides the first end-to-end exercise of the daedalus-fourier
|
||||||
|
kernel pack inside the libavcodec.so decode hot path; follow-up
|
||||||
|
patches wire IDCT 8x8, luma-v deblock, and qpel mc20.
|
||||||
|
|
||||||
|
The library context is process-global, lazily initialised under
|
||||||
|
pthread_once on first call. We pick the no-QPU constructor because
|
||||||
|
libavcodec.so is loaded into arbitrary host processes
|
||||||
|
(firefox-fourier, mpv-fourier, daedalus_v4l2_daemon, ...) and we
|
||||||
|
cannot assume the host has a usable Vulkan instance. Higher cycles
|
||||||
|
(deblock luma-v, MC) that benefit from the QPU will provision their
|
||||||
|
own recipe-selected context once that path is wired.
|
||||||
|
|
||||||
|
Bulk paths (idct_add16, idct_add16intra, idct_add8 — used for
|
||||||
|
non-intra4x4 macroblocks) remain on the stock NEON .S implementations
|
||||||
|
and will be batched through daedalus_recipe_dispatch_h264_idct4 with
|
||||||
|
n_blocks>1 in a follow-up.
|
||||||
|
|
||||||
|
Bit-exact against ff_h264_idct_add_neon (daedalus-fourier cycle 6
|
||||||
|
green; see marfrit/daedalus-fourier/CYCLE_LOGS.md).
|
||||||
|
|
||||||
|
Refs reauktion/daedalus-v4l2#11 — substitution arc step 2.
|
||||||
|
---
|
||||||
|
libavcodec/aarch64/Makefile | 3 +-
|
||||||
|
libavcodec/aarch64/h264_idct_daedalus.c | 49 +++++++++++++++++++++++
|
||||||
|
libavcodec/aarch64/h264dsp_init_aarch64.c | 3 +-
|
||||||
|
3 files changed, 53 insertions(+), 2 deletions(-)
|
||||||
|
create mode 100644 libavcodec/aarch64/h264_idct_daedalus.c
|
||||||
|
|
||||||
|
diff --git a/libavcodec/aarch64/Makefile b/libavcodec/aarch64/Makefile
|
||||||
|
index 41ab025..7b95fb1 100644
|
||||||
|
--- a/libavcodec/aarch64/Makefile
|
||||||
|
+++ b/libavcodec/aarch64/Makefile
|
||||||
|
@@ -3,7 +3,8 @@ OBJS-$(CONFIG_AC3DSP) += aarch64/ac3dsp_init_aarch64.o
|
||||||
|
OBJS-$(CONFIG_FDCTDSP) += aarch64/fdctdsp_init_aarch64.o
|
||||||
|
OBJS-$(CONFIG_FMTCONVERT) += aarch64/fmtconvert_init.o
|
||||||
|
OBJS-$(CONFIG_H264CHROMA) += aarch64/h264chroma_init_aarch64.o
|
||||||
|
-OBJS-$(CONFIG_H264DSP) += aarch64/h264dsp_init_aarch64.o
|
||||||
|
+OBJS-$(CONFIG_H264DSP) += aarch64/h264dsp_init_aarch64.o \
|
||||||
|
+ aarch64/h264_idct_daedalus.o
|
||||||
|
OBJS-$(CONFIG_HUFFYUVDSP) += aarch64/huffyuvdsp_init_aarch64.o
|
||||||
|
OBJS-$(CONFIG_H264PRED) += aarch64/h264pred_init.o
|
||||||
|
OBJS-$(CONFIG_H264QPEL) += aarch64/h264qpel_init_aarch64.o
|
||||||
|
diff --git a/libavcodec/aarch64/h264_idct_daedalus.c b/libavcodec/aarch64/h264_idct_daedalus.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..538d223
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/libavcodec/aarch64/h264_idct_daedalus.c
|
||||||
|
@@ -0,0 +1,49 @@
|
||||||
|
+/*
|
||||||
|
+ * H.264 4x4 IDCT + add — daedalus-fourier substitution shim.
|
||||||
|
+ *
|
||||||
|
+ * Routes H264DSPContext.idct_add through
|
||||||
|
+ * daedalus_recipe_dispatch_h264_idct4 instead of ff_h264_idct_add_neon.
|
||||||
|
+ * The recipe layer picks the substrate (CPU NEON by default for
|
||||||
|
+ * cycle 6; future cycles may dispatch to V3D opportunistically).
|
||||||
|
+ *
|
||||||
|
+ * FFmpeg's 4x4 block memory layout matches daedalus's column-major
|
||||||
|
+ * convention: block[r + 4*c] = coefficient at (row r, col c). Both
|
||||||
|
+ * sides destructively zero the block after the transform.
|
||||||
|
+ *
|
||||||
|
+ * The library context is process-global and lazily initialised under
|
||||||
|
+ * pthread_once. We pick the no-QPU constructor here because
|
||||||
|
+ * libavcodec.so is loaded into arbitrary host processes
|
||||||
|
+ * (firefox-fourier, mpv-fourier, daedalus_v4l2_daemon, ...) and we
|
||||||
|
+ * cannot assume the host has a usable Vulkan instance. Higher cycles
|
||||||
|
+ * (deblock, MC) that benefit from the QPU initialise their own
|
||||||
|
+ * recipe-selected context once that path is wired.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <pthread.h>
|
||||||
|
+#include <stddef.h>
|
||||||
|
+#include <stdint.h>
|
||||||
|
+
|
||||||
|
+#include <daedalus.h>
|
||||||
|
+
|
||||||
|
+#include "libavutil/attributes.h"
|
||||||
|
+#include "libavcodec/h264dsp.h"
|
||||||
|
+
|
||||||
|
+static daedalus_ctx *g_dctx;
|
||||||
|
+static pthread_once_t g_dctx_once = PTHREAD_ONCE_INIT;
|
||||||
|
+
|
||||||
|
+static void daedalus_ctx_init_once(void)
|
||||||
|
+{
|
||||||
|
+ g_dctx = daedalus_ctx_create_no_qpu();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void ff_h264_idct_add_daedalus(uint8_t *dst, int16_t *block, int stride);
|
||||||
|
+
|
||||||
|
+void ff_h264_idct_add_daedalus(uint8_t *dst, int16_t *block, int stride)
|
||||||
|
+{
|
||||||
|
+ static const daedalus_h264_block_meta meta = { .dst_off = 0 };
|
||||||
|
+
|
||||||
|
+ pthread_once(&g_dctx_once, daedalus_ctx_init_once);
|
||||||
|
+
|
||||||
|
+ daedalus_recipe_dispatch_h264_idct4(g_dctx, dst, (size_t)stride,
|
||||||
|
+ block, 1, &meta);
|
||||||
|
+}
|
||||||
|
diff --git a/libavcodec/aarch64/h264dsp_init_aarch64.c b/libavcodec/aarch64/h264dsp_init_aarch64.c
|
||||||
|
index c684574..b993df2 100644
|
||||||
|
--- a/libavcodec/aarch64/h264dsp_init_aarch64.c
|
||||||
|
+++ b/libavcodec/aarch64/h264dsp_init_aarch64.c
|
||||||
|
@@ -66,6 +66,7 @@ void ff_biweight_h264_pixels_4_neon(uint8_t *dst, uint8_t *src, ptrdiff_t stride
|
||||||
|
int weights, int offset);
|
||||||
|
|
||||||
|
void ff_h264_idct_add_neon(uint8_t *dst, int16_t *block, int stride);
|
||||||
|
+void ff_h264_idct_add_daedalus(uint8_t *dst, int16_t *block, int stride);
|
||||||
|
void ff_h264_idct_dc_add_neon(uint8_t *dst, int16_t *block, int stride);
|
||||||
|
void ff_h264_idct_add16_neon(uint8_t *dst, const int *block_offset,
|
||||||
|
int16_t *block, int stride,
|
||||||
|
@@ -139,7 +140,7 @@ av_cold void ff_h264dsp_init_aarch64(H264DSPContext *c, const int bit_depth,
|
||||||
|
c->biweight_pixels_tab[1] = ff_biweight_h264_pixels_8_neon;
|
||||||
|
c->biweight_pixels_tab[2] = ff_biweight_h264_pixels_4_neon;
|
||||||
|
|
||||||
|
- c->idct_add = ff_h264_idct_add_neon;
|
||||||
|
+ c->idct_add = ff_h264_idct_add_daedalus;
|
||||||
|
c->idct_dc_add = ff_h264_idct_dc_add_neon;
|
||||||
|
c->idct_add16 = ff_h264_idct_add16_neon;
|
||||||
|
c->idct_add16intra = ff_h264_idct_add16intra_neon;
|
||||||
|
--
|
||||||
|
2.47.3
|
||||||
|
|
||||||
+41
-1
@@ -33,7 +33,15 @@ FFMPEG_VERSION=8.1
|
|||||||
# epoch 2 matches Debian's stock ffmpeg (currently 7:7.1.x in trixie);
|
# epoch 2 matches Debian's stock ffmpeg (currently 7:7.1.x in trixie);
|
||||||
# +rfourier suffix to avoid colliding with upstream/Debian rebuilds.
|
# +rfourier suffix to avoid colliding with upstream/Debian rebuilds.
|
||||||
PKGVER=2:${FFMPEG_VERSION}+rfourier+gb57fbbe
|
PKGVER=2:${FFMPEG_VERSION}+rfourier+gb57fbbe
|
||||||
PKGREL=2 # pkgrel=2 — Path A move to /opt/fourier prefix (2026-05-19)
|
PKGREL=5 # pkgrel=5 — H.264 IDCT 4x4 daedalus-fourier substitution; skip past
|
||||||
|
# an orphan -4 .deb sitting in the apt pool that made
|
||||||
|
# check-already-published.sh's `pool_ver ge source_full` short-
|
||||||
|
# circuit the previous -3 build (PR #76). (2026-05-21)
|
||||||
|
|
||||||
|
# daedalus-fourier pin — first kernel substitution in libavcodec (cycle 6
|
||||||
|
# H.264 IDCT 4x4). Same SHA as the daedalus-v4l2 daemon already ships
|
||||||
|
# inline; rev in lockstep with the daemon when the public API rolls.
|
||||||
|
DAEDALUS_FOURIER_COMMIT=d87239d8172307d9a1b93c95cbed116d175b85cc
|
||||||
|
|
||||||
HERE=$(dirname "$(readlink -f "$0")")
|
HERE=$(dirname "$(readlink -f "$0")")
|
||||||
|
|
||||||
@@ -57,6 +65,34 @@ fi
|
|||||||
# Apply patches (same as Arch).
|
# Apply patches (same as Arch).
|
||||||
patch -Np1 -i "$HERE/0001-libudev-bypass-fallback.patch"
|
patch -Np1 -i "$HERE/0001-libudev-bypass-fallback.patch"
|
||||||
patch -Np1 -i "$HERE/0002-nv15-to-p010-unpack.patch"
|
patch -Np1 -i "$HERE/0002-nv15-to-p010-unpack.patch"
|
||||||
|
patch -Np1 -i "$HERE/0003-h264-idct4-daedalus-fourier.patch"
|
||||||
|
|
||||||
|
# --- daedalus-fourier: fetch + build static .a with PIC, install to a
|
||||||
|
# per-build prefix; libavcodec.so links it into the shared object so
|
||||||
|
# H264DSPContext.idct_add (and follow-up kernels) dispatch through the
|
||||||
|
# daedalus recipe layer instead of the in-tree NEON .S code. ---
|
||||||
|
#
|
||||||
|
# PIC is mandatory — the static .a is linked into a .so, so all object
|
||||||
|
# code must be relocatable. Vulkan is PUBLIC-linked by daedalus_core
|
||||||
|
# (queryable QPU substrate); we add libvulkan1 to Debian Depends below
|
||||||
|
# so dlopen of libavcodec.so.62 succeeds on stock trixie.
|
||||||
|
FOURIER_PREFIX=$work/fourier-prefix
|
||||||
|
mkdir -p "$FOURIER_PREFIX"
|
||||||
|
|
||||||
|
pushd "$work" >/dev/null
|
||||||
|
curl --connect-timeout 10 --max-time 600 --retry 3 --retry-delay 5 -sSLfo daedalus-fourier.tar.gz \
|
||||||
|
"https://git.reauktion.de/marfrit/daedalus-fourier/archive/${DAEDALUS_FOURIER_COMMIT}.tar.gz"
|
||||||
|
tar xzf daedalus-fourier.tar.gz
|
||||||
|
pushd daedalus-fourier >/dev/null
|
||||||
|
cmake -B build -G Ninja \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
|
||||||
|
-DCMAKE_INSTALL_PREFIX="$FOURIER_PREFIX"
|
||||||
|
cmake --build build --target daedalus_core
|
||||||
|
cmake --install build
|
||||||
|
popd >/dev/null
|
||||||
|
popd >/dev/null
|
||||||
|
cd "$work/FFmpeg"
|
||||||
|
|
||||||
# Configure with Arch-parity flags. Drops the same set of features
|
# Configure with Arch-parity flags. Drops the same set of features
|
||||||
# (X11, AMF, CUDA, FireWire, AviSynth, Bluray, OpenMPT, JPEG-XL,
|
# (X11, AMF, CUDA, FireWire, AviSynth, Bluray, OpenMPT, JPEG-XL,
|
||||||
@@ -73,6 +109,9 @@ patch -Np1 -i "$HERE/0002-nv15-to-p010-unpack.patch"
|
|||||||
--mandir=/opt/fourier/share/man \
|
--mandir=/opt/fourier/share/man \
|
||||||
--extra-ldexeflags='-Wl,-rpath,/opt/fourier/lib' \
|
--extra-ldexeflags='-Wl,-rpath,/opt/fourier/lib' \
|
||||||
--extra-ldsoflags='-Wl,-rpath,/opt/fourier/lib' \
|
--extra-ldsoflags='-Wl,-rpath,/opt/fourier/lib' \
|
||||||
|
--extra-cflags="-I${FOURIER_PREFIX}/include" \
|
||||||
|
--extra-ldflags="-L${FOURIER_PREFIX}/lib" \
|
||||||
|
--extra-libs="-ldaedalus_core -lvulkan -lpthread" \
|
||||||
--disable-debug \
|
--disable-debug \
|
||||||
--disable-static \
|
--disable-static \
|
||||||
--disable-doc \
|
--disable-doc \
|
||||||
@@ -147,6 +186,7 @@ Priority: optional
|
|||||||
Architecture: arm64
|
Architecture: arm64
|
||||||
Depends: libc6,
|
Depends: libc6,
|
||||||
libdrm2,
|
libdrm2,
|
||||||
|
libvulkan1,
|
||||||
libfontconfig1,
|
libfontconfig1,
|
||||||
libfreetype6,
|
libfreetype6,
|
||||||
libfribidi0,
|
libfribidi0,
|
||||||
|
|||||||
@@ -1,3 +1,48 @@
|
|||||||
|
ffmpeg-v4l2-request-fourier (2:8.1+rfourier+gb57fbbe-5) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
|
* pkgrel-only bump (3 → 5) to force a rebuild of the H.264 IDCT 4x4
|
||||||
|
daedalus-fourier substitution that landed in marfrit-packages PR
|
||||||
|
#76. An orphan -4 .deb already sat in the apt pool (dated
|
||||||
|
2026-05-19, no matching source commit in main); CI's
|
||||||
|
check-already-published.sh compares with `dpkg --compare-versions
|
||||||
|
pool_ver ge source_full`, which short-circuited PR #76's -3
|
||||||
|
build. Skipping past -4 lets the CI workflow actually publish the
|
||||||
|
substitution.
|
||||||
|
* No source code change beyond PKGREL and this changelog entry.
|
||||||
|
Substitution + control + build-deb.sh wiring stay as PR #76 left
|
||||||
|
them.
|
||||||
|
|
||||||
|
-- Markus Fritsche <mfritsche@reauktion.de> Thu, 21 May 2026 21:30:00 +0000
|
||||||
|
|
||||||
|
ffmpeg-v4l2-request-fourier (2:8.1+rfourier+gb57fbbe-3) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
|
* Add 0003-h264-idct4-daedalus-fourier.patch — H264DSPContext.idct_add
|
||||||
|
(per-block 4x4 IDCT, called from the intra-4x4 decode path in
|
||||||
|
libavcodec/h264_mb.c) now dispatches through
|
||||||
|
daedalus_recipe_dispatch_h264_idct4 instead of
|
||||||
|
ff_h264_idct_add_neon. First end-to-end exercise of the
|
||||||
|
daedalus-fourier kernel pack inside libavcodec.so on the
|
||||||
|
production decode hot path (daedalus-v4l2#11 step 2 — cycle 6
|
||||||
|
H.264 IDCT 4x4, NEON-by-recipe).
|
||||||
|
* build-deb.sh: fetches + builds daedalus-fourier (pinned at
|
||||||
|
d87239d, lockstep with the daemon's static link) with
|
||||||
|
-fPIC into a per-build temp prefix, then passes
|
||||||
|
--extra-cflags=-I.../include --extra-ldflags=-L.../lib
|
||||||
|
--extra-libs="-ldaedalus_core -lvulkan -lpthread" to FFmpeg
|
||||||
|
configure. Static-linked into libavcodec.so.62.
|
||||||
|
* Bulk paths (idct_add16 / idct_add16intra / idct_add8) remain on
|
||||||
|
the stock NEON .S code and will be batched through
|
||||||
|
daedalus_recipe_dispatch_h264_idct4 with n_blocks>1 in a
|
||||||
|
follow-up. Cycles 7/8/9 (IDCT 8x8 / luma-v deblock / qpel mc20)
|
||||||
|
land in subsequent patches.
|
||||||
|
* Depends gains libvulkan1 — daedalus_core PUBLIC-links Vulkan
|
||||||
|
(queryable QPU substrate); the no-QPU constructor still works,
|
||||||
|
but the loader refuses libavcodec.so.62 at dlopen time without
|
||||||
|
libvulkan.so.1 present.
|
||||||
|
* No ABI change; SONAMEs stay 62/62/60.
|
||||||
|
|
||||||
|
-- Markus Fritsche <mfritsche@reauktion.de> Thu, 21 May 2026 20:00:00 +0000
|
||||||
|
|
||||||
ffmpeg-v4l2-request-fourier (2:8.1+rfourier+gb57fbbe-1) bookworm trixie; urgency=medium
|
ffmpeg-v4l2-request-fourier (2:8.1+rfourier+gb57fbbe-1) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
* Initial Debian packaging for the Kwiboo FFmpeg fork with V4L2
|
* Initial Debian packaging for the Kwiboo FFmpeg fork with V4L2
|
||||||
|
|||||||
+42
-5
@@ -10,10 +10,25 @@
|
|||||||
# 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. c454618 = PR #16 merge "picture,
|
||||||
# failing ctrl id on S_EXT_CTRLS failure" (Phase 8.13 diagnostic).
|
# request_pool: transparent OUTPUT-pool resize on bitstream overrun
|
||||||
UPSTREAM_COMMIT=de27e95571b67ef34619c23a12db4698f9b3454e
|
# (#15)" — follow-up root-cause fix to #13/#14. On a mid-stream
|
||||||
PKGVER=1.0.0+r376+gde27e95
|
# bitstream-budget overrun (typical cause: SPS-driven resolution
|
||||||
|
# upshift in an adaptive-bitrate stream), codec_store_buffer now
|
||||||
|
# snapshots the in-flight surface's accumulated bytes, releases its
|
||||||
|
# OUTPUT pool slot, calls request_pool_resize (STREAMOFF →
|
||||||
|
# REQBUFS(0) → S_FMT with 2×sizeimage hint, capped at 1 GiB, page-
|
||||||
|
# aligned → CREATE_BUFS → mmap → media_request_alloc → STREAMON),
|
||||||
|
# re-acquires a slot, re-mirrors the surface's source_{data,size,
|
||||||
|
# request_fd}, restores the bytes, and continues. The frame
|
||||||
|
# survives instead of being dropped back to libavcodec for surface
|
||||||
|
# recreation. CAPTURE side untouched (per-queue V4L2 streaming
|
||||||
|
# independence).
|
||||||
|
#
|
||||||
|
# Prior pin (2860d75) = PR #14 merge — codec_store_buffer bounds-
|
||||||
|
# check floor (#13).
|
||||||
|
UPSTREAM_COMMIT=c454618ae11addce2e17b560f4deeacbed067d98
|
||||||
|
PKGVER=1.0.0+r390+gc454618
|
||||||
PKGREL=1
|
PKGREL=1
|
||||||
|
|
||||||
HERE=$(dirname "$(readlink -f "$0")")
|
HERE=$(dirname "$(readlink -f "$0")")
|
||||||
@@ -25,7 +40,7 @@ work=$(mktemp -d)
|
|||||||
trap "rm -rf $work" EXIT
|
trap "rm -rf $work" EXIT
|
||||||
|
|
||||||
cd "$work"
|
cd "$work"
|
||||||
curl -sSLfo libva-fourier.tar.gz \
|
curl --connect-timeout 10 --max-time 600 --retry 3 --retry-delay 5 -sSLfo libva-fourier.tar.gz \
|
||||||
"https://git.reauktion.de/marfrit/libva-v4l2-request-fourier/archive/${UPSTREAM_COMMIT}.tar.gz"
|
"https://git.reauktion.de/marfrit/libva-v4l2-request-fourier/archive/${UPSTREAM_COMMIT}.tar.gz"
|
||||||
tar xzf libva-fourier.tar.gz
|
tar xzf libva-fourier.tar.gz
|
||||||
SRCDIR=$(echo libva-v4l2-request-fourier)
|
SRCDIR=$(echo libva-v4l2-request-fourier)
|
||||||
@@ -38,6 +53,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
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,51 @@
|
|||||||
|
libva-v4l2-request-fourier (1.0.0+r380+g9898331-1) bookworm trixie; urgency=medium
|
||||||
|
|
||||||
|
* Bump to 9898331 — LIBVA-2 close. Adds video_fd_daedalus to
|
||||||
|
any_fd_supports_output_format's probe list in config.c so the
|
||||||
|
profile enumerator actually sees daedalus_v4l2's OUTPUT formats
|
||||||
|
(VP9F + AV1F + S264). Before this commit, ffmpeg vaapi against
|
||||||
|
H.264 on higgs bailed with "No support for codec h264 profile 578"
|
||||||
|
because RequestQueryConfigProfiles only walked rkvdec/hantro/
|
||||||
|
rpi-hevc-dec/vpu981 fds and never asked daedalus what it could do.
|
||||||
|
* Backward-compatible on RK3399/3588 — new slot gated by
|
||||||
|
HAVE_DAEDALUS_V4L2 *and* video_fd_daedalus >= 0; both false in
|
||||||
|
those deployments.
|
||||||
|
|
||||||
|
-- Markus Fritsche <mfritsche@reauktion.de> Wed, 20 May 2026 19:30:00 +0000
|
||||||
|
|
||||||
|
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
|
||||||
|
|||||||
Vendored
+1
-1
@@ -23,7 +23,7 @@ work=$(mktemp -d)
|
|||||||
trap "rm -rf $work" EXIT
|
trap "rm -rf $work" EXIT
|
||||||
|
|
||||||
cd "$work"
|
cd "$work"
|
||||||
curl -sSLfo lmcp.tar.gz "https://git.reauktion.de/marfrit/lmcp/archive/${UPSTREAM_TAG}.tar.gz"
|
curl --connect-timeout 10 --max-time 600 --retry 3 --retry-delay 5 -sSLfo lmcp.tar.gz "https://git.reauktion.de/marfrit/lmcp/archive/${UPSTREAM_TAG}.tar.gz"
|
||||||
echo "$LMCP_TARBALL_SHA256 lmcp.tar.gz" | sha256sum -c
|
echo "$LMCP_TARBALL_SHA256 lmcp.tar.gz" | sha256sum -c
|
||||||
tar xzf lmcp.tar.gz
|
tar xzf lmcp.tar.gz
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -33,7 +33,7 @@ work=$(mktemp -d)
|
|||||||
trap "rm -rf $work" EXIT
|
trap "rm -rf $work" EXIT
|
||||||
|
|
||||||
cd "$work"
|
cd "$work"
|
||||||
curl -sSLfo mpv.tar.gz \
|
curl --connect-timeout 10 --max-time 600 --retry 3 --retry-delay 5 -sSLfo mpv.tar.gz \
|
||||||
"https://github.com/mpv-player/mpv/archive/v${MPV_VERSION}/mpv-${MPV_VERSION}.tar.gz"
|
"https://github.com/mpv-player/mpv/archive/v${MPV_VERSION}/mpv-${MPV_VERSION}.tar.gz"
|
||||||
echo "$MPV_TARBALL_SHA256 mpv.tar.gz" | sha256sum -c
|
echo "$MPV_TARBALL_SHA256 mpv.tar.gz" | sha256sum -c
|
||||||
tar xzf mpv.tar.gz
|
tar xzf mpv.tar.gz
|
||||||
|
|||||||
Reference in New Issue
Block a user