feat(host): vendor PyroWave + minimal Granite subset as crates/pyrowave-sys
Phase 0 of design/pyrowave-codec-plan.md — the opt-in wired-LAN ultra-low- latency codec. Vendored at upstream 509e4f88 (API 0.4.0, Granite 44362775, volk + vulkan-headers pins in PUNKTFUNK-VENDOR.txt), pruned to the 6.6 MB the standalone no-renderer build needs; scripts/vendor-pyrowave.sh reproduces the tree (a pin bump is protocol-affecting, plan §4.2). build.rs drives the wrapper CMakeLists (static archives incl. a static C-API lib upstream only ships shared) + bindgen over pyrowave.h; Linux and Windows only, empty stub elsewhere (Apple gets a native Metal port, §4.7). Offline-safe by construction: no network, no system lib, vendored Vulkan headers — same model as the opus dep (flatpak builder has no network). Phase-0 validation on .21 (RTX 5070 Ti, driver 610.43.03): - upstream pyrowave-c-test + interop test (incl. dmabuf/DRM-modifier Vulkan<->Vulkan) pass, from the pristine AND the pruned tree - GPU kernel times at ~1.6 bpp noise: encode/decode 0.090/0.042 ms @800p, 0.146/0.067 @1080p, 0.226/0.103 @1440p, 0.477/0.201 @4K — order of magnitude under NVENC's 1-2 ms retrieve, CBR lands within ~100 B of target - cargo test -p pyrowave-sys green (static link + API-version pin check) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
//! Build the vendored PyroWave codec (C++/Vulkan compute) as static archives via
|
||||
//! CMake and generate bindings over its C API (`pyrowave.h`).
|
||||
//!
|
||||
//! Linux + Windows only — the platforms whose hosts/clients run the Vulkan codec
|
||||
//! path (design/pyrowave-codec-plan.md §5). Other targets get an empty bindings
|
||||
//! file so the workspace builds everywhere (the Apple client is a native Metal
|
||||
//! port, §4.7 — it never links this crate).
|
||||
//!
|
||||
//! Everything compiles from the committed vendor tree: no network, no system
|
||||
//! pyrowave, no pkg-config — CI, MSVC, and the offline flatpak builder all get
|
||||
//! reproducible builds (§4.1). Vulkan headers come vendored too; only a libclang
|
||||
//! for bindgen is required on the build machine.
|
||||
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=wrapper.h");
|
||||
println!("cargo:rerun-if-changed=CMakeLists.txt");
|
||||
println!("cargo:rerun-if-changed=vendor/pyrowave");
|
||||
|
||||
let out = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
let bindings_path = out.join("bindings.rs");
|
||||
|
||||
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();
|
||||
if target_os != "linux" && target_os != "windows" {
|
||||
std::fs::write(
|
||||
&bindings_path,
|
||||
"// pyrowave-sys: Linux/Windows-only, empty on this target\n",
|
||||
)
|
||||
.unwrap();
|
||||
return;
|
||||
}
|
||||
|
||||
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
|
||||
let vendor = manifest_dir.join("vendor/pyrowave");
|
||||
let vk_include = vendor.join("Granite/third_party/khronos/vulkan-headers/include");
|
||||
|
||||
// Always Release: a debug build of the wavelet kernels' host code buys no
|
||||
// debuggability (the hot path is GPU shaders baked into the source) and the
|
||||
// MSVC debug CRT would clash with Rust's release CRT.
|
||||
let dst = cmake::Config::new(&manifest_dir)
|
||||
.profile("Release")
|
||||
.build_target("pyrowave-capi")
|
||||
.build();
|
||||
let build = dst.join("build");
|
||||
|
||||
// Static link closure, dependents before dependencies (GNU ld is order-sensitive).
|
||||
println!("cargo:rustc-link-search=native={}", build.display());
|
||||
for sub in [
|
||||
"pyrowave",
|
||||
"Granite/vulkan",
|
||||
"Granite/util",
|
||||
"Granite/math",
|
||||
"Granite/third_party",
|
||||
] {
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}",
|
||||
build.join(sub).display()
|
||||
);
|
||||
// MSVC multi-config generators put archives in a Release/ subdir.
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}",
|
||||
build.join(sub).join("Release").display()
|
||||
);
|
||||
}
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}",
|
||||
build.join("Release").display()
|
||||
);
|
||||
for lib in [
|
||||
"pyrowave-capi",
|
||||
"pyrowave",
|
||||
"granite-vulkan",
|
||||
"granite-util",
|
||||
"granite-math",
|
||||
"granite-volk",
|
||||
] {
|
||||
println!("cargo:rustc-link-lib=static={lib}");
|
||||
}
|
||||
if target_os == "linux" {
|
||||
println!("cargo:rustc-link-lib=dylib=stdc++");
|
||||
// volk loads the Vulkan loader at runtime.
|
||||
println!("cargo:rustc-link-lib=dylib=dl");
|
||||
println!("cargo:rustc-link-lib=dylib=pthread");
|
||||
}
|
||||
|
||||
let bindings = bindgen::Builder::default()
|
||||
.header("wrapper.h")
|
||||
.clang_arg(format!("-I{}", vendor.display()))
|
||||
.clang_arg(format!("-I{}", vk_include.display()))
|
||||
.allowlist_function("pyrowave_.*")
|
||||
.allowlist_type("pyrowave_.*")
|
||||
.allowlist_var("PYROWAVE_.*")
|
||||
// The Vk* handles/structs the API mentions come along via the allowlist
|
||||
// closure; they are ABI-identical to ash's, callers cast at the seam.
|
||||
.derive_default(true)
|
||||
.generate()
|
||||
.expect("bindgen failed for pyrowave.h");
|
||||
bindings
|
||||
.write_to_file(&bindings_path)
|
||||
.expect("failed to write pyrowave bindings");
|
||||
}
|
||||
Reference in New Issue
Block a user