From 88b2ebfaa9d9c5f7549ba5520cce9353441ef5b3 Mon Sep 17 00:00:00 2001 From: claude-noether Date: Thu, 21 May 2026 18:00:46 +0200 Subject: [PATCH] daemon: link daedalus-fourier + log substrate availability at startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First incremental step toward H.264 daemon-rewrite (daedalus-v4l2#11): make the daedalus-fourier kernel library available to the daemon process so subsequent patches can substitute its primitives (IDCT 4×4, IDCT 8×8, luma vertical deblock, etc.) for libavcodec's per-MB pixel math. This patch does NOT yet dispatch any kernels. It only: - Adds `pkg_check_modules(DAEDALUS_FOURIER REQUIRED daedalus-fourier)` to the daemon's CMakeLists, with explicit link ordering (libdaedalus_core.a must precede -lvulkan because the static archive references vulkan symbols and the linker resolves left-to-right). We bypass IMPORTED_TARGET because pkg-config's Requires.private chain leaves CMake's dependency graph reordering the archive after -lvulkan, breaking the static link. - Calls daedalus_ctx_create_no_qpu() at daemon startup, logs the substrate-availability line, destroys the context at exit. no_qpu mode skips V3D Vulkan probe — proves linkage works without depending on shader-path resolution (which is a separate piece of work, since v3d_runner currently loads .spv files from cwd-relative paths and consumer would need a search path override). Sample journal line: [2026-05-21 17:59:35.271 INFO] daedalus-fourier: linked, ctx alive (no_qpu mode; has_qpu=0) Build-test verified on hertz (Pi 5 dev host) against an installed copy of daedalus-fourier r35+gd87239d (from marfrit/daedalus-fourier PR #1). Binary links cleanly, --help prints, daemon mode opens chardev (fails predictably on hertz which has no daedalus_v4l2 kmod; on higgs this is the existing working path). Follow-up patches per daedalus-v4l2#11: 1. Instrument the existing libavcodec decode path to count per-frame IDCT blocks / deblock edges / MC tiles so we have a baseline of what work the daemon dispatches for a typical YouTube H.264 stream. 2. Substitute daedalus-fourier kernels one at a time, measuring CPU saved per substitution. 3. Wire shader path resolution into daedalus_ctx_create() for the QPU substrate (V3D opportunistic helper paths). Wire protocol unchanged. DAEDALUS_PROTO_VERSION stays at 0. --- daemon/CMakeLists.txt | 24 ++++++++++++++++++++++++ daemon/src/main.c | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt index 9dde650..8c5b237 100644 --- a/daemon/CMakeLists.txt +++ b/daemon/CMakeLists.txt @@ -28,6 +28,20 @@ find_package(PkgConfig REQUIRED) pkg_check_modules(FFMPEG REQUIRED IMPORTED_TARGET libavformat libavcodec libavutil) +# daedalus-fourier — VC VII (V3D) + ARM NEON back-end kernel library. +# Linked statically. Today only the no-QPU smoke-test path is wired +# (a ctx_create_no_qpu at daemon startup, log-and-destroy at exit); +# follow-up patches (per daedalus-v4l2#11) substitute the +# `daedalus_recipe_dispatch_h264_*` family for libavcodec's per-MB +# pixel primitives, one cycle at a time. +# +# We bypass IMPORTED_TARGET and consume pkg-config's static variables +# (--static --libs path) directly so we control the link order: +# libdaedalus_core.a must precede -lvulkan because the static archive +# references vulkan symbols and the linker resolves left-to-right. +pkg_check_modules(DAEDALUS_FOURIER REQUIRED daedalus-fourier) +find_package(Vulkan REQUIRED) + add_executable(daedalus_v4l2_daemon src/main.c src/ffmpeg_loader.c @@ -45,13 +59,23 @@ target_include_directories(daedalus_v4l2_daemon src ${CMAKE_CURRENT_SOURCE_DIR}/../include ${FFMPEG_INCLUDE_DIRS} + ${DAEDALUS_FOURIER_INCLUDE_DIRS} ) # dl for dlopen, pthread for future threading work. +target_link_directories(daedalus_v4l2_daemon + PRIVATE + ${DAEDALUS_FOURIER_LIBRARY_DIRS} +) + target_link_libraries(daedalus_v4l2_daemon PRIVATE dl pthread + # Order matters: libdaedalus_core.a first (so its undefined + # vulkan symbols register), then -lvulkan to satisfy them. + ${DAEDALUS_FOURIER_LIBRARIES} + Vulkan::Vulkan ) install(TARGETS daedalus_v4l2_daemon diff --git a/daemon/src/main.c b/daemon/src/main.c index eb12eb3..b3459ae 100644 --- a/daemon/src/main.c +++ b/daemon/src/main.c @@ -22,6 +22,8 @@ #include +#include + static volatile sig_atomic_t g_terminate = 0; static void on_signal(int sig) @@ -120,6 +122,26 @@ int main(int argc, char **argv) /* Mute FFmpeg's own chattiness unless the user asked. */ fm.av_log_set_level(verbose ? AV_LOG_INFO : AV_LOG_WARNING); + /* + * Initialise daedalus-fourier early so we can log substrate + * availability up front. daedalus_ctx_create_no_qpu() skips + * the V3D Vulkan probe — we're not dispatching any kernels + * yet, this is just the linkage sanity check + a marker in the + * journal that the binary is wired against the right + * daedalus-fourier version. Future work (per daedalus-v4l2#11) + * promotes to daedalus_ctx_create() once shader-path resolution + * is wired through the public API. + */ + daedalus_ctx *df_ctx = daedalus_ctx_create_no_qpu(); + if (df_ctx) { + log_info("daedalus-fourier: linked, ctx alive (no_qpu mode; " + "has_qpu=%d)", + daedalus_ctx_has_qpu(df_ctx)); + } else { + log_warn("daedalus-fourier: ctx_create_no_qpu returned NULL " + "(out of memory?) — continuing without backend kernels"); + } + int rc; const char *cmd = argv[i++]; if (strcmp(cmd, "parse") == 0) { @@ -132,6 +154,8 @@ int main(int argc, char **argv) rc = 2; } + if (df_ctx) + daedalus_ctx_destroy(df_ctx); ffmpeg_loader_cleanup(&fm); log_cleanup(); return rc; -- 2.47.3