Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
c187f16
feat: anime filters — BM3D/KNLMeans, AI upscaling, Descale
StuartCameronCode Oct 25, 2026
3c62572
feat: AnimeJaNai upscaling as an add-on; one add-on system with Setti…
StuartCameronCode Oct 25, 2026
6f129f2
fix(deps): VSNCNN arm64 deployment target; make set -e work in plugin…
StuartCameronCode Oct 25, 2026
619b233
docs(readme): anime overview, AI upscaling and Descale details
StuartCameronCode Oct 25, 2026
08d63e1
fix(crop-resize): upscale descriptions cover every method, not just N…
StuartCameronCode Oct 25, 2026
b1e8dd8
ci: lavapipe on the macOS arm64 runner too; longer GPU probe test tim…
StuartCameronCode Oct 25, 2026
36fe589
ci: macOS loader via ~/lib; crop the push-gate upscale frames
StuartCameronCode Oct 25, 2026
f898a84
feat(ui): NEW badges lead to what's new — options, methods, sections,…
StuartCameronCode Oct 25, 2026
46a8540
fix(settings): overlay the Add-ons tab's NEW badge so the tab doesn't…
StuartCameronCode Oct 25, 2026
97e698d
ci(macos): reach lavapipe through VAPOURBOX_VULKAN_LIBRARY
StuartCameronCode Oct 25, 2026
dee203e
ci(macos): print crash reports when the tests fail
StuartCameronCode Oct 25, 2026
69ef26e
ci(macos): no Vulkan device on the arm64 runner; GPU tests skip there
StuartCameronCode Oct 25, 2026
24379f8
feat(ui): presets sit in their own section; Upscale before Aspect Ratio
StuartCameronCode Oct 25, 2026
769c6c3
test: await reads before deleting temp files; stall limit for lavapip…
StuartCameronCode Oct 25, 2026
3ddcfe5
test: AI-upscale previews get the encode's budget on lavapipe
StuartCameronCode Oct 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/scripts/print-crash-reports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env python3
"""Print the faulting thread of recent macOS crash reports, for CI logs.

A plugin that segfaults inside vspipe leaves nothing in the test output but
"signal 11", and the hosted runners can't be logged into. macOS writes a crash
report (.ips) for every crashed process, naming the library and function that
faulted; this prints the newest few for the given process names.

Usage: print-crash-reports.py [process-name ...] (default: vspipe-bin python3)
"""
import glob
import json
import os
import sys

names = sys.argv[1:] or ["vspipe-bin", "python3", "python3.12"]
dirs = [os.path.expanduser("~/Library/Logs/DiagnosticReports"), "/Library/Logs/DiagnosticReports"]
reports = sorted(
(p for d in dirs for p in glob.glob(os.path.join(d, "*.ips"))
if any(os.path.basename(p).startswith(n) for n in names)),
key=os.path.getmtime,
reverse=True,
)[:3]

if not reports:
print(f"No crash reports for {', '.join(names)}.")
for path in reports:
print(f"=== {os.path.basename(path)}")
with open(path, encoding="utf-8", errors="replace") as f:
f.readline() # one-line JSON header
try:
body = json.loads(f.read())
except json.JSONDecodeError as e:
print(f" (unparseable: {e})")
continue
exc = body.get("exception", {})
print(f" {exc.get('type')} {exc.get('signal')} {exc.get('subtype', '')}".rstrip())
images = body.get("usedImages", [])
threads = body.get("threads", [])
faulting = body.get("faultingThread", 0)
if faulting >= len(threads):
continue
for i, frame in enumerate(threads[faulting].get("frames", [])[:30]):
image = images[frame.get("imageIndex", -1)] if 0 <= frame.get("imageIndex", -1) < len(images) else {}
lib = os.path.basename(image.get("path", image.get("name", "?")))
sym = frame.get("symbol", f"+{frame.get('imageOffset', 0):#x}")
print(f" {i:2} {lib:32} {sym}")
72 changes: 72 additions & 0 deletions .github/scripts/provision-vulkan.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/usr/bin/env bash
# Give a CI runner a Vulkan device, so the ncnn-on-Vulkan features (RIFE, and
# Real-ESRGAN / Real-CUGAN upscaling) are actually exercised rather than skipped.
#
# The hosted runners have no GPU, so Linux and Windows get Mesa's lavapipe, a
# Vulkan driver that runs on the CPU — slow, but the same plugin, model and
# script path a user's GPU takes, and ncnn accepts a CPU device. macOS arm64
# gets nothing: neither MoltenVK nor lavapipe can run there (see its case).
#
# Wherever a device is provisioned this sets VAPOURBOX_EXPECT_VULKAN=1, and the
# GPU tests then FAIL rather than skip if a feature reports itself unavailable
# (app/test/support/gpu_expectations.dart). On a platform that does not ship
# the features (macos-x64, linux-arm64) nothing is provisioned and the tests
# assert the "not available for this platform" answer instead.
#
# Usage: provision-vulkan.sh <platform> (macos-arm64, windows-x64, linux-x64, …)
set -euo pipefail

platform="${1:?usage: provision-vulkan.sh <platform>}"

# Windows: the Khronos loader from LunarG's runtime components and lavapipe from
# mesa-dist-win (MIT), each pinned by hash. Keep these with the README's note.
VKRT_VERSION="1.4.328.1"
VKRT_SHA256="293efbb2c11e60429df7770f40e3c5c811a7fa42af81de0cc41e8718ddb2b373"
MESA_VERSION="26.2.2"
MESA_SHA256="0f21394d44036019bb5c07a3788dd278fd7b7b3469077a4686f0d639e8e874a1"

case "$platform" in
linux-x64)
sudo apt-get update -qq
sudo apt-get install -y -qq --no-install-recommends mesa-vulkan-drivers libvulkan1 vulkan-tools
vulkaninfo --summary || true
echo "VAPOURBOX_EXPECT_VULKAN=1" >> "$GITHUB_ENV"
;;
windows-x64)
dir="$RUNNER_TEMP/vulkan"
rm -rf "$dir" && mkdir -p "$dir"
curl -fsSL -o "$dir/vkrt.zip" \
"https://sdk.lunarg.com/sdk/download/$VKRT_VERSION/windows/VulkanRT-X64-$VKRT_VERSION-Components.zip"
echo "$VKRT_SHA256 $dir/vkrt.zip" | sha256sum -c -
unzip -q -j "$dir/vkrt.zip" \
"VulkanRT-X64-$VKRT_VERSION-Components/x64/vulkan-1.dll" \
"VulkanRT-X64-$VKRT_VERSION-Components/x64/vulkaninfo.exe" -d "$dir"
curl -fsSL -o "$dir/mesa.7z" \
"https://github.com/pal1000/mesa-dist-win/releases/download/$MESA_VERSION/mesa3d-$MESA_VERSION-release-msvc.7z"
echo "$MESA_SHA256 $dir/mesa.7z" | sha256sum -c -
"/c/Program Files/7-Zip/7z.exe" x -y -o"$dir/mesa" "$dir/mesa.7z" \
x64/vulkan_lvp.dll x64/lvp_icd.x86_64.json >/dev/null
icd="$(cygpath -w "$dir/mesa/x64/lvp_icd.x86_64.json")"
# The loader reads VK_DRIVER_FILES; older loaders read VK_ICD_FILENAMES.
echo "VK_DRIVER_FILES=$icd" >> "$GITHUB_ENV"
echo "VK_ICD_FILENAMES=$icd" >> "$GITHUB_ENV"
# vulkan-1.dll on PATH, where the plugins' LoadLibrary finds it.
cygpath -w "$dir" >> "$GITHUB_PATH"
VK_DRIVER_FILES="$icd" "$dir/vulkaninfo.exe" --summary || true
echo "VAPOURBOX_EXPECT_VULKAN=1" >> "$GITHUB_ENV"
;;
macos-arm64)
# No device here, and none can be provided. The runners are VMs whose Metal
# device MoltenVK cannot open (it segfaults creating the instance), and
# lavapipe crashes in its shader compiler: the bundle's akarin links LLVM
# statically and exports its symbols, ~2,300 of them weak, and dyld binds
# lavapipe's own LLVM to akarin's copy of those (crash report: libLLVM.23
# in PassBuilder::registerCGSCCAnalyses; CI run 40160839608). So the GPU
# tests skip here, the probe still has to answer with a real reason, and
# MoltenVK is tested on real Macs only.
echo "macOS arm64 runner: no usable Vulkan device; GPU tests skip (see the comment above)."
;;
*)
echo "No GPU features ship on $platform; the tests assert that answer instead."
;;
esac
22 changes: 22 additions & 0 deletions .github/workflows/ci-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ jobs:
ln -sfn "$BP/opt/whisper-cpp/bin" addons/whisper/bin
ln -sfn "$BP/opt/whisper-cpp/lib" addons/whisper/lib

- name: Provision Vulkan (RIFE, AI upscaling)
# Lavapipe on the GPU-less Linux/Windows runners; sets
# VAPOURBOX_EXPECT_VULKAN=1 so the GPU tests must run, not skip.
run: bash .github/scripts/provision-vulkan.sh macos-${{ matrix.arch }}

- name: Rust tests
# Debug build: DependencyLocator's upward search then finds the repo-root
# deps/ and addons/ (release mode looks under ~/Library).
Expand All @@ -116,6 +121,12 @@ jobs:
# run in nightly.yml. The script-only integration tests + unit tests run here.
run: cd app && flutter test --exclude-tags heavy

- name: Crash reports (on failure)
# A plugin that segfaults in vspipe shows only "signal 11" in the test
# output; macOS's crash report names the library and function.
if: failure()
run: python3 .github/scripts/print-crash-reports.py

windows:
runs-on: windows-latest
env:
Expand Down Expand Up @@ -172,6 +183,12 @@ jobs:
cp "$(dirname "$CLI")"/*.dll addons/whisper/ 2>/dev/null || true
ls addons/whisper/

- name: Provision Vulkan (RIFE, AI upscaling)
# Lavapipe on the GPU-less Linux/Windows runners; sets
# VAPOURBOX_EXPECT_VULKAN=1 so the GPU tests must run, not skip.
shell: bash
run: bash .github/scripts/provision-vulkan.sh windows-x64

- name: Rust tests
run: cd worker && cargo test -- --nocapture

Expand Down Expand Up @@ -260,6 +277,11 @@ jobs:
ln -sfn "${{ github.workspace }}/deps" "$HOME/.local/share/VapourBox/deps"
ln -sfn "${{ github.workspace }}/addons" "$HOME/.local/share/VapourBox/addons"

- name: Provision Vulkan (RIFE, AI upscaling)
# Lavapipe on the GPU-less Linux/Windows runners; sets
# VAPOURBOX_EXPECT_VULKAN=1 so the GPU tests must run, not skip.
run: bash .github/scripts/provision-vulkan.sh linux-x64

- name: Rust tests
run: cd worker && cargo test -- --nocapture

Expand Down
22 changes: 22 additions & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ jobs:
ln -sfn "$BP/opt/whisper-cpp/bin" addons/whisper/bin
ln -sfn "$BP/opt/whisper-cpp/lib" addons/whisper/lib

- name: Provision Vulkan (RIFE, AI upscaling)
# Lavapipe on the GPU-less Linux/Windows runners; sets
# VAPOURBOX_EXPECT_VULKAN=1 so the GPU tests must run, not skip.
run: bash .github/scripts/provision-vulkan.sh macos-${{ matrix.arch }}

- name: Build worker (debug)
run: cd worker && cargo build

Expand All @@ -128,6 +133,12 @@ jobs:
VAPOURBOX_WORKER: ${{ github.workspace }}/worker/target/debug/vapourbox-worker
run: cd app && flutter test --tags heavy

- name: Crash reports (on failure)
# A plugin that segfaults in vspipe shows only "signal 11" in the test
# output; macOS's crash report names the library and function.
if: failure()
run: python3 .github/scripts/print-crash-reports.py

windows:
if: ${{ github.event_name == 'schedule' || inputs.platform == 'all' || inputs.platform == 'windows' }}
# Both CPU-tier bundles (issue #92); see the macOS job for what the v2 run proves.
Expand Down Expand Up @@ -189,6 +200,12 @@ jobs:
cp "$(dirname "$CLI")"/*.exe addons/whisper/ 2>/dev/null || true
cp "$(dirname "$CLI")"/*.dll addons/whisper/ 2>/dev/null || true

- name: Provision Vulkan (RIFE, AI upscaling)
# Lavapipe on the GPU-less Linux/Windows runners; sets
# VAPOURBOX_EXPECT_VULKAN=1 so the GPU tests must run, not skip.
shell: bash
run: bash .github/scripts/provision-vulkan.sh windows-x64

- name: Build worker (debug)
run: cd worker && cargo build

Expand Down Expand Up @@ -273,6 +290,11 @@ jobs:
ln -sfn "${{ github.workspace }}/deps" "$HOME/.local/share/VapourBox/deps"
ln -sfn "${{ github.workspace }}/addons" "$HOME/.local/share/VapourBox/addons"

- name: Provision Vulkan (RIFE, AI upscaling)
# Lavapipe on the GPU-less Linux/Windows runners; sets
# VAPOURBOX_EXPECT_VULKAN=1 so the GPU tests must run, not skip.
run: bash .github/scripts/provision-vulkan.sh linux-x64

- name: Build worker (debug)
run: cd worker && cargo build

Expand Down
Loading
Loading