d6647b9183
The punktfunk-session Vulkan client (clients/linux-session, now clients/session) builds and runs on Windows; the WinUI shell spawns it for every stream. Verified live: 10-bit HEVC via Vulkan Video on both AMD (iGPU) and NVIDIA, 5120x1440 at 130 fps / 8 ms end-to-end on the RTX 4090. - pf-ffvk: Windows bindgen branch (FFMPEG_DIR + PF_FFVK_VULKAN_INCLUDE, no pkg-config); provisioning fetches Vulkan-Headers (pinned v1.4.309). - pf-client-core: builds on Windows — WASAPI audio (audio_wasapi.rs, cfg-swapped via #[path], same surface as the PipeWire twin), VAAPI/dmabuf gated inline (chain = vulkan -> software), trust reads the WinUI shell's %APPDATA% stores (parity tests pin both serialized shapes), Settings gains adapter/hdr_enabled (serde-defaulted; Linux stores unaffected). - pf-presenter: builds on Windows — dmabuf module Linux-gated; SDL keyboard grab while captured (Alt+Tab/Win reach the host); pick_device ranks discrete over integrated (device 0 was the iGPU on hybrid boxes — the silent footgun) and honors PUNKTFUNK_VK_ADAPTER (the Settings GPU pick, exported by the session). - run loop: block in one SDL wait woken by input AND decoded frames (a per- session forwarder pushes a FrameWake user event) instead of a 1 ms poll — measured 111%% -> 5%% of a core (NVIDIA), 86%% -> 3.5%% (AMD), stats unchanged. The pump's decode-fence wait became once-per-window sampling (no per-frame pipeline stall; the stat now shows true backlog). - pf-console-ui: builds on Windows (skia-safe msvc prebuilts); font lookup falls through fontconfig aliases to concrete DirectWrite families (Consolas/Segoe UI) — browse/coverflow works, verified against a live host. - WinUI shell: session-always via new src/spawn.rs (GTK spawn.rs port — CREATE_NO_WINDOW, stdout contract, kill handle); the Stream screen is a status card (chips + stage lines from the child's stats). The legacy in-process D3D11VA path stays behind Settings "Streaming engine" / PUNKTFUNK_BUILTIN_ STREAM=1 as the A/B baseline until Phase 8 deletes it. SessionParams.video_caps makes the HDR toggle real. - clients/linux-session renamed to clients/session (builds for both OSes). - CI/MSIX: both workflows build/test both bins with widened path filters; the MSIX ships punktfunk-session.exe. ARM64 session builds --no-default-features (rust-skia has no aarch64-pc-windows-msvc prebuilts; flip when it does). A/B on this box (5120x1440 HEVC vs home-worker-5): NVIDIA Vulkan 130 fps / 8 ms e2e / 1.6 ms decode — clearly better than the built-in path. The AMD iGPU VCN saturates at ~52 fps where its own D3D11VA does ~70 — Adrenalin Vulkan decode is slower on APU silicon; discrete RDNA validation gates Phase 8. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
120 lines
7.7 KiB
PowerShell
120 lines
7.7 KiB
PowerShell
# Layers punktfunk-specific tooling onto the shared unom Windows CI runner: per-arch FFmpeg
|
|
# (host + client native builds), Inno Setup (the host installer), and the aarch64-pc-windows-msvc
|
|
# rustup target (windows-msix.yml's ARM64 leg). The runner itself - act_runner, Node, rustup,
|
|
# VS Build Tools/NASM/CMake/LLVM - is provisioned generically by unom/infra
|
|
# (windows-runner/windows-runner.pkr.hcl + proxmox/windows-runner's Terraform clone); this script
|
|
# is what punktfunk adds on top, since FFmpeg/Inno Setup/the ARM64 target aren't every project's
|
|
# concern. See also provision-windows-wdk.ps1 for the driver-build toolchain (also punktfunk-only).
|
|
#
|
|
# Idempotent - safe to re-run. Run ELEVATED (admin) on the runner.
|
|
[CmdletBinding()]
|
|
param()
|
|
$ErrorActionPreference = "Stop"
|
|
function info($m) { Write-Host "[provision-punktfunk-extras] $m" }
|
|
|
|
$env:RUSTUP_HOME = "C:\Users\Public\.rustup"
|
|
$env:CARGO_HOME = "C:\Users\Public\.cargo"
|
|
|
|
# --- ARM64 cross-compile target (windows.yml / windows-msix.yml build aarch64-pc-windows-msvc off
|
|
# this x64 box; the ARM64 MSVC cross compiler itself comes from unom/infra's generic VS Build
|
|
# Tools provisioning, which already includes the ARM64 component). ---
|
|
$rustup = "C:\Users\Public\.cargo\bin\rustup.exe"
|
|
if (Test-Path $rustup) {
|
|
info "rustup target add aarch64-pc-windows-msvc"
|
|
& $rustup target add aarch64-pc-windows-msvc
|
|
} else {
|
|
Write-Warning "rustup not found at $rustup - has unom/infra's setup-gitea-runner-base.ps1 run on this box yet?"
|
|
}
|
|
|
|
# --- FFmpeg shared trees for the host (amf-qsv encode) + clients (decode). BtbN **lgpl-shared**
|
|
# builds: the AMD/Intel AMF + Intel QSV encoders, swscale, and the HEVC decoder are all present in
|
|
# the LGPL build, and punktfunk never calls the GPL-only encoders (x264/x265 - software encode is
|
|
# the separate BSD-2 openh264 crate; NVENC is the direct NVIDIA SDK). lgpl-shared keeps the
|
|
# bundled DLLs LGPL-2.1+ (dynamic linking satisfies the relink duty) rather than GPL, so the
|
|
# shipped installer/MSIX stay consistent with punktfunk's MIT OR Apache-2.0 posture.
|
|
# MIGRATION: a runner previously provisioned with the old *gpl-shared* trees must be
|
|
# re-provisioned - delete C:\Users\Public\ffmpeg and C:\Users\Public\ffmpeg-arm64, then re-run.
|
|
function Get-BtbnFfmpeg {
|
|
param([string]$Dir, [string]$ZipTag) # ZipTag: 'win64' (x64) or 'winarm64' (ARM64 cross tree)
|
|
if (Test-Path (Join-Path $Dir 'lib\avcodec.lib')) { info "FFmpeg ($ZipTag) already present at $Dir"; return }
|
|
info "fetching FFmpeg ($ZipTag, BtbN lgpl-shared)"
|
|
$url = "https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-n7.1-latest-$ZipTag-lgpl-shared-7.1.zip"
|
|
$zip = "$Dir.zip"; $tmp = "$Dir-extract"
|
|
Invoke-WebRequest -Uri $url -OutFile $zip -UseBasicParsing
|
|
if (Test-Path $tmp) { Remove-Item -Recurse -Force $tmp }
|
|
Expand-Archive -Path $zip -DestinationPath $tmp -Force # BtbN zips have one top-level folder
|
|
$inner = Get-ChildItem $tmp -Directory | Select-Object -First 1
|
|
if (Test-Path $Dir) { Remove-Item -Recurse -Force $Dir }
|
|
Move-Item -Path $inner.FullName -Destination $Dir
|
|
Remove-Item -Force $zip; Remove-Item -Recurse -Force $tmp -ErrorAction SilentlyContinue
|
|
}
|
|
Get-BtbnFfmpeg -Dir "C:\Users\Public\ffmpeg" -ZipTag 'win64'
|
|
Get-BtbnFfmpeg -Dir "C:\Users\Public\ffmpeg-arm64" -ZipTag 'winarm64'
|
|
|
|
# --- Vulkan-Headers (pf-ffvk's bindgen: libavutil/hwcontext_vulkan.h includes <vulkan/vulkan.h>,
|
|
# and Windows has no system copy). Headers only - the loader (vulkan-1.dll) is a GPU-driver
|
|
# component and is never linked at build time, so the full Vulkan SDK is deliberately NOT
|
|
# required. Pinned Khronos tag; bump deliberately alongside FFmpeg/driver expectations. ---
|
|
$vkHdrDir = "C:\Users\Public\vulkan-headers"
|
|
$vkHdrTag = "v1.4.309"
|
|
if (-not (Test-Path (Join-Path $vkHdrDir 'include\vulkan\vulkan.h'))) {
|
|
info "fetching Vulkan-Headers $vkHdrTag"
|
|
$url = "https://github.com/KhronosGroup/Vulkan-Headers/archive/refs/tags/$vkHdrTag.zip"
|
|
$zip = "$vkHdrDir.zip"; $tmp = "$vkHdrDir-extract"
|
|
Invoke-WebRequest -Uri $url -OutFile $zip -UseBasicParsing
|
|
if (Test-Path $tmp) { Remove-Item -Recurse -Force $tmp }
|
|
Expand-Archive -Path $zip -DestinationPath $tmp -Force # one top-level Vulkan-Headers-<ver> folder
|
|
$inner = Get-ChildItem $tmp -Directory | Select-Object -First 1
|
|
if (Test-Path $vkHdrDir) { Remove-Item -Recurse -Force $vkHdrDir }
|
|
Move-Item -Path $inner.FullName -Destination $vkHdrDir
|
|
Remove-Item -Force $zip; Remove-Item -Recurse -Force $tmp -ErrorAction SilentlyContinue
|
|
} else { info "Vulkan-Headers already present at $vkHdrDir" }
|
|
|
|
# --- Inno Setup (ISCC.exe) for the host installer build (windows-host.yml). pack-host-installer.ps1
|
|
# locates it at its fixed Program Files path, so it need not be on PATH - just present. The .iss
|
|
# uses the 6.6+ styling (WizardStyle dark/dynamic + the windows11 style); an older 6.x compiles a
|
|
# plain-modern fallback, so upgrade a pre-6.6 install rather than silently shipping the old look. ---
|
|
$isccPath = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe"
|
|
$innoVer = (Get-ItemProperty 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Inno Setup 6_is1' -ErrorAction SilentlyContinue).DisplayVersion
|
|
if (-not (Test-Path $isccPath) -or ($innoVer -and [version]$innoVer -lt [version]'6.6.0')) {
|
|
if (Get-Command choco -ErrorAction SilentlyContinue) {
|
|
info "installing/upgrading Inno Setup (ISCC; found: $innoVer)"
|
|
choco upgrade innosetup -y --no-progress
|
|
} else { Write-Warning "Inno Setup missing or pre-6.6 ($innoVer) and choco unavailable - install/upgrade it for windows-host.yml." }
|
|
}
|
|
|
|
# --- VB-CABLE (the streaming virtual microphone the host installer bundles). Pinned official
|
|
# package, SHA-256 verified - a silent hash change means VB-Audio shipped a new pack: verify it,
|
|
# then update BOTH the pin here and the notice if terms changed (packaging/windows/licenses/
|
|
# VB-CABLE-NOTICE.txt). Donationware by VB-Audio (https://vb-audio.com), redistributed under
|
|
# VB-Audio's bundling grant; only the base cable, never A+B/C+D. windows-host.yml points
|
|
# VBCABLE_DIR here so pack-host-installer.ps1 bundles it. ---
|
|
$vbDir = "C:\Users\Public\vbcable"
|
|
$vbUrl = "https://download.vb-audio.com/Download_CABLE/VBCABLE_Driver_Pack45.zip"
|
|
$vbSha = "B950E39F01AF1D04EA623C8F6D8EB9B6EA5C477C637295FABF20631C85116BFB"
|
|
if (-not (Test-Path (Join-Path $vbDir 'VBCABLE_Setup_x64.exe'))) {
|
|
info "fetching VB-CABLE (official base package, pinned)"
|
|
$vbZip = "$vbDir.zip"
|
|
Invoke-WebRequest -Uri $vbUrl -OutFile $vbZip -UseBasicParsing
|
|
$got = (Get-FileHash $vbZip -Algorithm SHA256).Hash
|
|
if ($got -ne $vbSha) { Remove-Item $vbZip -Force; throw "VB-CABLE download hash mismatch (got $got, pinned $vbSha) - vendor package changed; re-verify before re-pinning." }
|
|
if (Test-Path $vbDir) { Remove-Item -Recurse -Force $vbDir }
|
|
Expand-Archive -Path $vbZip -DestinationPath $vbDir -Force # flat zip (setup exes + signed drivers)
|
|
Remove-Item $vbZip -Force
|
|
info "VB-CABLE staged at $vbDir"
|
|
} else { info "VB-CABLE already present at $vbDir" }
|
|
|
|
# --- Drop punktfunk's env vars into the generic runner's daemon wrapper extension point (see
|
|
# unom/infra's scripts/setup-gitea-runner-base.ps1) so the act_runner daemon - and therefore every
|
|
# job it runs - sees FFMPEG_DIR without unom/infra needing to know punktfunk exists. ---
|
|
$projectEnv = "C:\Users\Public\act-runner\project-env.ps1"
|
|
@'
|
|
$env:FFMPEG_DIR = "C:\Users\Public\ffmpeg"
|
|
$env:VBCABLE_DIR = "C:\Users\Public\vbcable"
|
|
$env:PF_FFVK_VULKAN_INCLUDE = "C:\Users\Public\vulkan-headers\include"
|
|
$env:PATH = "C:\Users\Public\ffmpeg\bin;" + $env:PATH
|
|
'@ | Set-Content -Encoding UTF8 $projectEnv
|
|
info "wrote $projectEnv (FFMPEG_DIR, VBCABLE_DIR, PF_FFVK_VULKAN_INCLUDE) - restart the gitea-act-runner scheduled task to pick it up"
|
|
|
|
info "punktfunk extras provisioned OK."
|