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

nordisk/facett

facett-map/tests/blit_cost.rs

//! **What the offscreen pass's blit costs, at a real window size** — lane MP-a.
//!
//! The owner asked for the number at **1600×900** and to be told if it clears 1 ms/frame.
//! The depth pass buys correct ordering across tiles and chunks; a blit that cost a
//! millisecond would be paying 6 % of a 60 Hz frame for it, which is a different
//! trade and he should get to see it rather than be told it is fine.
//!
//! What is measured is the CPU-side cost of recording the blit — pipeline, bind group,
//! one `draw(0..3)` — not the GPU's execution of it. That is stated because it is the
//! honest limit of a clock taken inside `paint`: a callback has no encoder to bracket
//! and cannot time the device. A three-vertex textured triangle over the pane is not
//! where a frame goes, and the recording cost is what this lane ADDED to the CPU path.
//!
//! ```bash
//! FACETT_TEST_GPU=discrete cargo test -p facett-map --features wgpu --test blit_cost -- --nocapture
//! ```
#![cfg(feature = "wgpu")]

mod common;
use common::one_gpu;

use facett_map::layer::{LatLon, MapFacet, MapTheme, MapView, WaysLayer};
use facett_map::Way;

/// **The device opt-in, shared** — `common/gpu_gate.rs`, lane GG #5. This file used to
/// carry its own copy that recognised only `discrete|software`, which had no truthful
/// value for an integrated GPU.
#[path = "common/gpu_gate.rs"]
mod gpu_gate;

/// A real window, not a thumbnail.
const CANVAS: egui::Vec2 = egui::vec2(1600.0, 900.0);

fn gated(name: &str) -> bool {
    gpu_gate::gated("facett-map", name)
}

fn line(id: i64, lon0: f64, lon1: f64, lat: f64, tags: &[(&str, &str)]) -> Way {
    let t: Vec<(String, String)> =
        tags.iter().map(|(k, v)| ((*k).to_string(), (*v).to_string())).collect();
    Way::from_lonlat_with(id, &[(lon0, lat), (lon1, lat)], &t, &facett_map::MapPalette::cartographic(false))
        .expect("a 2-vertex line is a way")
}

#[test]
fn the_blit_costs_under_a_millisecond_at_1600x900() {
    if !gated("the_blit_costs_under_a_millisecond_at_1600x900") {
        return;
    }
    // A few hundred roads, so the offscreen pass has real work and the blit is not
    // being timed against an empty texture.
    let ways: Vec<Way> = (0..300)
        .map(|i| {
            let lat = 59.30 + f64::from(i) * 0.0002;
            line(i64::from(i), 18.00, 18.12, lat, &[("highway", if i % 3 == 0 { "motorway" } else { "residential" })])
        })
        .collect();
    let view = MapView::new(LatLon::new(59.33, 18.06), 13.0, (CANVAS.x, CANVAS.y));
    let mut f = MapFacet::new("blit-cost", view, MapTheme::default())
        .with_layer(Box::new(WaysLayer::new("osm-ways", ways)));

    use egui_kittest::wgpu::WgpuTestRenderer;
    let _turn = one_gpu::hold();
    let setup = facett_core::render::gpu::adapter_wgpu::facett_wgpu_options().wgpu_setup;
    let rs = egui_kittest::wgpu::create_render_state(setup, Default::default());
    facett_map::gpu::install_renderer(&rs);
    let mut h = egui_kittest::Harness::builder()
        .with_size(CANVAS)
        .renderer(WgpuTestRenderer::from_render_state(rs))
        .build_ui(move |ui| f.ui(ui));

    let mut samples: Vec<u64> = Vec::new();
    for _ in 0..12 {
        let _ = h.render().expect("the wgpu backend produced a frame");
        h.step();
        samples.push(facett_map::gpu::last_blit_us());
    }
    // Drop the first two: the first frame carries the upload and the target allocation,
    // which is a one-off and not the per-frame cost being asked about.
    let steady = &samples[2..];
    let worst = steady.iter().copied().max().unwrap_or(0);
    let median = {
        let mut v = steady.to_vec();
        v.sort_unstable();
        v[v.len() / 2]
    };
    let n = steady.len();
    eprintln!(
        "[blit] 1600x900, {n} steady frames: median {median} us, worst {worst} us  (all: {samples:?})"
    );
    nornir_testmatrix::functional_status(
        "facett-map",
        "gpu_lane_blit_cost_1600x900",
        worst < 1000,
        &format!("blit record cost at 1600x900: median {median} us, worst {worst} us"),
    );
    assert!(
        worst < 1000,
        "the blit must record in under 1 ms/frame at 1600x900 — worst {worst} us, median \
         {median} us. Above that the depth pass is buying correct ordering at 6 % of a \
         60 Hz frame and the owner should be told rather than reassured."
    );
}