facett-map3d/tests/gpu_lane_before_the_first_frame.rs
//! **A lane that has not been measured must not report the CPU painter.**
//!
//! # The defect, and how long it cost
//!
//! `Map3D::used_gpu()` read a `Cell<bool>` seeded `false` and written only inside
//! [`Map3D::view`]. Any host reading it OUTSIDE a paint therefore got `false` — the same
//! value the genuine failure produces. korp's `rebuild_map3d` logs one line per 3D
//! rebuild and that line runs *before the first frame*, so on the owner's session of
//! 2026-08-06 it printed:
//!
//! ```text
//! rebuild: … gpu=false building_ways=2 scene_ways=34965 …
//! rebuild: … gpu=false building_ways=0 scene_ways=86 …
//! ```
//!
//! on a build where the feature was compiled in (`map3d-gpu = ["facett-map3d/wgpu"]`),
//! the adapter had come up (`AMD Radeon 890M (RADV STRIX1)`), the renderer was installed
//! (`korp/src/main.rs`, `facett_map3d::gpu::install_renderer`) and the backend swap had
//! run (`with_gpu(true)`). Three separate people read that `false` as the root cause and
//! went looking for a broken install. There was none. The number was an artefact of WHERE
//! it was read.
//!
//! # What is asserted, and in which direction it goes red
//!
//! Two states that a `bool` cannot tell apart, asserted to be distinct:
//!
//! * **before any paint** — [`Map3D::used_gpu_observed`] is `None`. Restore the old
//! `Cell<bool>` (or make `used_gpu_observed` return `Some(self.used_gpu())`) and
//! `never_measured_is_not_the_cpu_painter` fails on this line, because `Some(false)`
//! is then indistinguishable from a real CPU-painter frame.
//! * **after a paint** — it is `Some(_)`, and `Some(false)` on the CPU lane. Delete the
//! `set(Some(..))` in `view` and `a_painted_frame_reports_its_lane` fails: the
//! observation never appears.
//!
//! And the question a host CAN answer early: [`Map3D::gpu_lane_selected`] is decided by
//! the constructor, so it is `true` the instant `with_gpu(true)` has run — which is the
//! half that separates "the lane was never chosen" from "the lane was chosen and
//! something fell back". Neutralise the swap in `with_gpu` and
//! `the_selected_lane_is_known_before_the_first_frame` goes red.
//!
//! Everything here is measured on APPLIED OUTPUT: the observation left behind by a real
//! `view()` call through a real egui pass, never a setter read back.
use facett_core::{Facet, Theme};
use facett_map::Way;
use facett_map3d::Map3D;
/// A tiny scene — this file is about the observation, not the geometry.
fn scene() -> Map3D {
let theme = Theme::default();
let ring = |lon: f64, lat: f64, h: f64| {
vec![(lon - h, lat - h), (lon + h, lat - h), (lon + h, lat + h), (lon - h, lat + h), (lon - h, lat - h)]
};
let mut ways: Vec<Way> = Vec::new();
for i in 0..6 {
let d = f64::from(i) * 0.0004;
ways.extend(Way::from_lonlat(
100 + i64::from(i),
&ring(18.0686 + d, 59.3293 + d, 0.00008),
&[("building", "yes")],
&theme,
));
}
Map3D::from_geometry("lane probe", &ways)
}
/// Run one real egui pass over `map` and hand back what it observed.
fn paint_once(mut map: Map3D) -> Option<bool> {
let seen = std::rc::Rc::new(std::cell::Cell::new(Some(true)));
let cell = seen.clone();
let mut harness = egui_kittest::Harness::builder()
.with_size(egui::vec2(320.0, 240.0))
.build_ui(move |ui| {
facett_core::set_theme(ui.ctx(), Theme::default());
map.ui(ui);
cell.set(map.used_gpu_observed());
});
harness.run_steps(2);
seen.get()
}
/// **THE RED LINE.** A freshly built scene has never been painted, so no lane has been
/// observed — and that is a different fact from "the CPU painter drew it".
#[test]
fn never_measured_is_not_the_cpu_painter() {
let map = scene();
assert_eq!(
map.used_gpu_observed(),
None,
"a scene that has not been painted must report NO observation, not Some(false) — \
`Some(false)` is the spelling of the actual defect and korp's log printed it as \
`gpu=false` for a working GPU build"
);
// The old signature is kept, and it is exactly as blind as it was — which is why the
// rule is that out-of-paint readers must not use it. Pinned so a future change that
// makes `used_gpu()` panic or diverge is caught here rather than in a host's log.
assert!(!map.used_gpu(), "the lossy spelling still collapses `None` to false");
}
/// After a real egui pass the observation EXISTS, and on the CPU lane it is `false`.
/// This is what makes the `None` above meaningful: the field is not simply always `None`.
#[test]
fn a_painted_frame_reports_its_lane() {
let observed = paint_once(scene());
assert_eq!(
observed,
Some(false),
"one real paint through the CPU painter must leave Some(false) behind — \
got {observed:?}"
);
}
/// The half that IS answerable before the first frame. Without the `wgpu` feature there
/// is only one backend, so the assertion is that the selected lane is reported honestly
/// as the CPU one — not that a GPU lane exists.
#[test]
fn the_selected_lane_is_known_before_the_first_frame() {
let map = scene();
assert!(!map.gpu_lane_selected(), "the default backend is the CPU painter");
assert_eq!(map.backend_name(), "cpu-painter", "and it says so by name");
assert_eq!(map.used_gpu_observed(), None, "…while nothing has been observed yet");
#[cfg(feature = "wgpu")]
{
let g = scene().with_gpu(true);
assert!(
g.gpu_lane_selected(),
"with_gpu(true) selects the wgpu lane, and that is knowable at construction"
);
assert_eq!(g.backend_name(), "wgpu-vello");
// **The owner's exact state, and the reason this file exists.** Selected, and not
// yet observed. A host printing `false` here is printing an artefact.
assert_eq!(
g.used_gpu_observed(),
None,
"the lane is selected but no frame has run — the two facts are independent"
);
}
}
/// **`Some(true)` on a REAL wgpu device, read AFTER the paint.** The other half of the
/// pair: without it, every assertion above is consistent with a lane that can only ever
/// report `false`, which is the shape of the very defect this file is about.
///
/// The adapter is printed, because "the GPU lane ran" on a llvmpipe/lavapipe software
/// adapter is a different claim from the same words on a real card, and korp has been
/// burned by not saying which.
///
/// Self-skipping when no adapter comes up (the honest CI answer), and it says so loudly
/// rather than passing quietly.
#[cfg(feature = "wgpu")]
#[test]
fn a_real_gpu_paint_reports_some_true() {
use egui_kittest::wgpu::{WgpuTestRenderer, create_render_state};
// **facett's OWN adapter policy, not egui_kittest's default.** `default_wgpu_setup()`
// lets wgpu's internal preference order answer, and on this box that hands back
// `llvmpipe [Cpu/Vulkan]` while an RTX 4090 sits beside it — so a green here would have
// said "the GPU lane ran" about a software rasteriser. `facett_wgpu_options` installs
// the same `native_adapter_selector` korp's `NativeOptions` does (discrete first,
// llvmpipe/lavapipe and BMC consoles LAST), which is the policy the shipped binary
// actually runs under.
let setup = facett_core::render::gpu::adapter_wgpu::facett_wgpu_options().wgpu_setup;
let rs = create_render_state(setup, Default::default());
let info = rs.adapter.get_info();
println!(" adapter: {} [{:?}/{:?}]", info.name, info.device_type, info.backend);
facett_map3d::gpu::install_renderer(&rs);
let mut map = scene().with_gpu(true);
assert!(map.gpu_lane_selected(), "the wgpu lane is selected before any frame");
assert_eq!(map.used_gpu_observed(), None, "…and nothing has been observed yet");
let seen = std::rc::Rc::new(std::cell::Cell::new(None));
let cell = seen.clone();
let mut harness = egui_kittest::Harness::builder()
.with_size(egui::vec2(640.0, 480.0))
.renderer(WgpuTestRenderer::from_render_state(rs))
.build_ui(move |ui| {
facett_core::set_theme(ui.ctx(), Theme::default());
map.ui(ui);
cell.set(map.used_gpu_observed());
});
harness.run_steps(3);
let _img = harness.render().expect("wgpu render");
assert_eq!(
seen.get(),
Some(true),
"a real wgpu paint through the installed renderer must observe the GPU lane — \
got {:?} on adapter {} [{:?}/{:?}]",
seen.get(),
info.name,
info.device_type,
info.backend,
);
println!(
" used_gpu AFTER paint = Some(true) on {} [{:?}/{:?}]",
info.name, info.device_type, info.backend
);
}
/// **`used_gpu` must mean "the GPU lane DISPATCHED", not "this backend ran".**
///
/// The two halves of the GPU path are useless apart — korp's own comment at the install
/// site says so — and the field that exists to separate them could not see the second one
/// missing. MEASURED 2026-08-06, RTX 4090 [DiscreteGpu/Vulkan]: `with_gpu(true)` with **no**
/// `install_renderer` reported `used_gpu = Some(true)`. "The install is not reaching" was
/// the leading theory for a flat 3D pane for most of that day, and the number everyone was
/// reading would have said `true` either way.
///
/// Asserted as an EQUALITY against `renderer_installed()` rather than against a constant,
/// because the lane registry is per-process and test order is not fixed: whichever state
/// this binary happens to be in, the two must agree. Restore the literal `true` in
/// `WgpuVelloBackend::paint` and this fails on any run where no renderer is installed.
#[cfg(feature = "wgpu")]
#[test]
fn used_gpu_means_the_lane_dispatched_not_that_the_backend_ran() {
use egui_kittest::wgpu::{WgpuTestRenderer, create_render_state};
let setup = facett_core::render::gpu::adapter_wgpu::facett_wgpu_options().wgpu_setup;
let rs = create_render_state(setup, Default::default());
let info = rs.adapter.get_info();
// DELIBERATELY no `install_renderer` — that is the whole experiment.
let mut map = scene().with_gpu(true);
let seen = std::rc::Rc::new(std::cell::Cell::new(None));
let cell = seen.clone();
let mut harness = egui_kittest::Harness::builder()
.with_size(egui::vec2(640.0, 480.0))
.renderer(WgpuTestRenderer::from_render_state(rs))
.build_ui(move |ui| {
facett_core::set_theme(ui.ctx(), Theme::default());
map.ui(ui);
cell.set(map.used_gpu_observed());
});
harness.run_steps(3);
let _ = harness.render();
let installed = facett_map3d::gpu::renderer_installed();
println!(
" with_gpu(true), renderer_installed={installed}, adapter {} [{:?}]: used_gpu = {:?}",
info.name,
info.device_type,
seen.get()
);
assert_eq!(
seen.get(),
Some(installed),
"`used_gpu` must equal `a Map3dRenderer is installed` — a `true` with no renderer \
is a claim about pixels nothing drew (adapter {} [{:?}])",
info.name,
info.device_type,
);
}
/// `state_json` must carry the same three-way answer, because that is the surface a robot
/// and korp's `$KORP_STATE` read. `used_gpu: null` before the first frame; the selected
/// lane beside it.
#[test]
fn state_json_publishes_pending_rather_than_false() {
let map = scene();
let js = Facet::state_json(&map);
assert!(
js["used_gpu"].is_null(),
"state_json says `null` (pending) before the first paint, got {}",
js["used_gpu"]
);
assert_eq!(js["gpu_lane_selected"], serde_json::json!(false));
assert_eq!(js["backend"], serde_json::json!("cpu-painter"));
}