Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/facett

facett-helix/tests/gpu_bloom.rs

//! **GPU render-proof — the helix on the emissive bloom lane (reused from
//! facett-graph3d).**
//!
//! Drives [`HelixView::gpu_scene`] headlessly through
//! [`facett_graph3d::graph_gpu::render_graph_offscreen`]: it projects the helix nodes +
//! the soft rubberband spline edges into instanced emissive discs/filaments, renders
//! them into the shared HDR offscreen (additive blend) and runs the bright→blur→
//! composite bloom chain, then reads the LDR framebuffer + draw counts back. Every
//! assertion is on DATA (draw counts, luminance, bloom A/B energy) — never a pixel.
//!
//! Run: `cargo test -p facett-helix --features wgpu --test gpu_bloom`
//! (needs a wgpu adapter / `lavapipe`; self-skips with a printed note when none is
//! present, so a CPU-only box never sees a false failure).
#![cfg(feature = "wgpu")]

use facett_graph3d::graph_gpu::{render_graph_offscreen, BloomParams};
use facett_helix::HelixView;

/// Serialise GPU work across test threads (spinning up several software adapters
/// concurrently can SIGSEGV in lavapipe).
static GPU_GUARD: std::sync::Mutex<()> = std::sync::Mutex::new(());

/// CPU-only oracle (no GPU): `gpu_scene` projects every node + emits spline-edge
/// segments, and the emissive scaling pushes radiance **above 1.0** so the bright pass
/// (threshold ≈ 1.0) catches the helix. Runs on every box.
#[test]
fn gpu_scene_emits_emissive_helix_instances() {
    let v = HelixView::demo().with_clock(1.0);
    let scene = v.gpu_scene(256.0, 256.0);
    assert!(scene.nodes.len() >= 6, "one instance per helix node");
    assert!(!scene.edges.is_empty(), "the rounded spline edges emit filament segments");
    let peak = scene.nodes.iter().flat_map(|n| [n.color[0], n.color[1], n.color[2]]).fold(0.0f32, f32::max);
    assert!(peak > 1.0, "node emissive radiance must exceed 1.0 to bloom (got {peak})");
}

/// INJECT-ASSERT (render proof): the GPU lane draws the helix's node + spline-segment
/// instances, produces a **non-blank** frame, and bloom adds measurable energy
/// (bloom-on mean luminance strictly exceeds bloom-off).
#[test]
fn helix_gpu_draws_with_bloom_energy() {
    let _guard = GPU_GUARD.lock().unwrap_or_else(|p| p.into_inner());
    let v = HelixView::demo().with_clock(1.0);
    let scene = v.gpu_scene(256.0, 256.0);
    let (w, h) = (256, 256);

    let Some(on) = render_graph_offscreen(w, h, &scene, BloomParams::default()) else {
        facett_core::testmatrix::gpu_skip(
            "facett-helix",
            "helix_gpu_draws_with_bloom_energy",
            "no wgpu adapter",
            "the helix lane issues every node and spline-edge instance and the bloom pass \
             adds measurable energy",
        );
        return;
    };
    assert_eq!(on.node_instances as usize, scene.nodes.len(), "all node instances issued");
    assert_eq!(on.edge_instances as usize, scene.edges.len(), "all spline-edge segments issued");
    let luma_on = on.mean_luma();
    eprintln!("[helix-gpu] mean luma bloom-on = {luma_on:.5}");
    assert!(luma_on > 0.01, "frame must be non-blank (got {luma_on:.5})");

    let off = render_graph_offscreen(w, h, &scene, BloomParams::default().off()).expect("adapter present");
    let luma_off = off.mean_luma();
    eprintln!("[helix-gpu] mean luma bloom-off = {luma_off:.5}");
    assert!(luma_on > luma_off * 1.02, "bloom must add energy: on={luma_on:.5} > off={luma_off:.5}");
}