facett-map/tests/paint_depth.rs
//! **A depth value derived from `PaintKey`, so ordering survives across submissions** —
//! lane MP-a, 2026-09-05.
//!
//! # Why depth and not a better sort
//!
//! `PaintKey` orders the stream **inside one submitted stream** and, in the module's own
//! words, *"has no way to reach across two of them"*. The lane submits one
//! `draw_indirect` per chunk and the tiled path iterates per tile, so a later tile's dark
//! **casing** lands on an earlier tile's bright **fill** — measured on an RTX 4090
//! (`gpu_lane_paint_order::which_tile_a_road_landed_in_cannot_decide_which_road_is_on_top`):
//! crossing pixel `[56, 78, 92]` where the motorway is `[70, 198, 224]` and the
//! residential `[85, 98, 117]`.
//!
//! No submission order fixes that in general, because the tiles a camera holds are not
//! known when the rank is assigned. **Depth is the only thing that reaches across
//! submissions**: the rank rides in Z, the depth test decides, and which pass drew first
//! stops mattering.
//!
//! | gate | red arm |
//! |---|---|
//! | a higher rank is CLOSER (smaller depth, `Less` compare) | invert the mapping |
//! | a casing sits just BEHIND its own fill, and in front of the next rank down | give the casing the same depth |
//! | every rank in the real range lands inside `0.0 ..= 1.0` | drop the clamp |
//! | two ranks one `CLASS_STEP` apart are separated by more than the casing offset | widen the offset past the band |
//!
//! ```bash
//! cargo test -p facett-map --test paint_depth
//! ```
use facett_map::paint_order::{depth_of, CASING_DEPTH_BIAS, CLASS_STEP, LANDMASS_BAND};
/// The ranks the live classifier actually produces (measured 2026-09-05, `way_rank`).
const MOTORWAY: i32 = 1240;
const SECONDARY: i32 = 1230;
const RESIDENTIAL: i32 = 1210;
const FOOTWAY: i32 = 1100;
const RIVER: i32 = 1090;
const MOTORWAY_BRIDGE: i32 = 101240;
/// **Higher rank paints closer.** With `depth_compare: Less` and the buffer cleared to
/// `1.0`, the smaller depth wins — so the ladder must run downwards as rank runs up.
#[test]
fn a_higher_rank_is_closer() {
let ladder = [MOTORWAY_BRIDGE, MOTORWAY, SECONDARY, RESIDENTIAL, FOOTWAY, RIVER];
for w in ladder.windows(2) {
let (hi, lo) = (depth_of(w[0], false), depth_of(w[1], false));
assert!(
hi < lo,
"rank {} must be CLOSER than rank {} — got depth {hi} vs {lo}",
w[0],
w[1]
);
}
// The landmass is the floor and must be the farthest thing there is.
assert!(
depth_of(LANDMASS_BAND, false) > depth_of(RIVER, false),
"the land silhouette sits behind every way"
);
}
/// **A casing sits just behind its own fill — and still in front of the next rank
/// down.**
///
/// Both halves matter. Behind its own fill, or the dark casing covers the bright line it
/// exists to outline. In front of the next rank down, or the fix trades one overpaint for
/// another: a motorway's casing falling behind a residential's fill is the same defect
/// with the roles swapped.
#[test]
fn a_casing_is_behind_its_own_fill_and_in_front_of_the_rank_below() {
let fill = depth_of(MOTORWAY, false);
let casing = depth_of(MOTORWAY, true);
assert!(casing > fill, "the casing is BEHIND its own fill: {casing} vs {fill}");
assert!(
casing < depth_of(RESIDENTIAL, false),
"…and still in FRONT of the residential's fill: {casing} vs {}",
depth_of(RESIDENTIAL, false)
);
assert!(
casing < depth_of(SECONDARY, false),
"…and in front of the next rank down, one TIER_STEP away: {casing} vs {}",
depth_of(SECONDARY, false)
);
}
/// **Every rank the ladder can produce lands in `0.0 ..= 1.0`.** A depth outside the
/// range is clipped by the rasteriser, which drops the geometry silently — a way that
/// vanishes is worse than a way in the wrong order, because nothing on screen points
/// back here.
#[test]
fn every_real_rank_lands_inside_the_depth_range() {
for r in [
LANDMASS_BAND,
facett_map::paint_order::WAY_RANK_FLOOR,
RIVER,
FOOTWAY,
RESIDENTIAL,
MOTORWAY,
MOTORWAY_BRIDGE,
8 * facett_map::paint_order::LAYER_STEP + facett_map::paint_order::LABEL_BAND,
] {
for casing in [false, true] {
let d = depth_of(r, casing);
assert!(
(0.0..=1.0).contains(&d),
"rank {r} (casing={casing}) gives depth {d}, outside the clip range — the \
rasteriser would DROP it"
);
}
}
}
/// **The casing bias must not eat a class gap.** If the offset were as large as the gap
/// between two classes, a road's casing would sort past the class below it and the
/// ordering would be wrong in a way no single test of one pair would catch.
#[test]
fn the_casing_bias_is_smaller_than_the_tightest_class_gap() {
let gap = depth_of(1200, false) - depth_of(1200 + CLASS_STEP, false);
assert!(
CASING_DEPTH_BIAS < gap,
"the casing bias {CASING_DEPTH_BIAS} must be under the tightest class gap {gap}, \
or a casing sorts into the class below"
);
const _: () = assert!(CASING_DEPTH_BIAS > 0.0, "a zero bias puts the casing ON its fill");
}
/// **A FILL'S OUTLINE SITS IN FRONT OF ITS OWN FILL AND BEHIND THE BAND ABOVE** —
/// lane GG #1, the device-free half.
///
/// The GPU oracle (`gpu_lane_paint_order::a_road_crossing_a_landcover_ring_edge_is_still_the_road`)
/// needs a discrete adapter and is skipped on a box without one. This one runs anywhere
/// and pins the two properties the pixels depend on, so the arithmetic cannot drift while
/// the pixel proof is unavailable.
///
/// **In front of its own fill** is the half that is easy to get backwards: the outline is
/// not a casing. The tile lane pins a whole run of fills to `depth_of(band, false)` and
/// then draws the outlines with the full depth range restored, so an outline one bias
/// *behind* would be rejected by `Less` everywhere its own fill wrote depth — which is
/// the whole interior of the ring. The shoreline would lose its edge, and on this lane
/// that edge is also the fill's only anti-aliasing.
///
/// **Behind the band above** is the bound that keeps the fix from becoming the bug: an
/// outline that climbed a whole class gap would be the `0.0` defect again with a smaller
/// number.
#[test]
fn a_fill_outline_is_in_front_of_its_own_fill_and_behind_the_band_above() {
use facett_map::paint_order::{
depth_of, fill_outline_depth, AREA_BAND, CASING_DEPTH_BIAS, LINE_BAND,
};
// Water 100, park 200, building 300, other 400 — the AREA band's real spacing.
for band in [AREA_BAND + 100, AREA_BAND + 200, AREA_BAND + 300, AREA_BAND + 400] {
let fill = depth_of(band, false);
let outline = fill_outline_depth(band);
assert!(
outline < fill,
"band {band}: the outline ({outline}) must be IN FRONT of its own fill \
({fill}), or `Less` rejects it wherever the fill already wrote depth and the \
ring loses both its edge and its AA"
);
let above = depth_of(band + 100, false);
assert!(
outline > above,
"band {band}: the outline ({outline}) must still be BEHIND the class above \
({above} at band {}), or the fix is the `0.0` defect with a smaller number",
band + 100
);
// The step is the bias and nothing more — proven by size, not by reading the body.
assert!(
(fill - outline - CASING_DEPTH_BIAS).abs() <= f32::EPSILON,
"band {band}: the step must be exactly one CASING_DEPTH_BIAS, got {}",
fill - outline
);
}
// A LINE-band value clamps rather than escaping the range.
let l = fill_outline_depth(LINE_BAND);
assert!((0.0..=1.0).contains(&l), "an outline depth outside the clip range is dropped: {l}");
}
/// **THE DEFAULT DEPTH OF A RANKLESS RUN IS THE FARTHEST PLANE, NEVER THE CLOSEST.**
///
/// `LineExpander::push_pts` is the entry point for a point run that has no
/// `LinePolyline` and therefore no rank to give. Its depth default was `0.0`, which
/// reads as a neutral zero and is the exact opposite: against a buffer cleared to `1.0`
/// under `Less` it is the closest plane in the clip volume. That one constant is lane
/// GG #1.
///
/// Asserted on the SOURCE rather than on a render, because the property is about what a
/// future caller inherits: a pixel test only sees the callers that exist today, and the
/// whole point of a default is the caller nobody has written yet.
#[test]
fn the_rankless_push_defaults_to_the_farthest_plane() {
let src = include_str!("../src/gpu/line.rs");
// Comments strip first: this file argues about `0.0` in prose, and a gate that
// matched its own explanation would be green over a reverted body.
let code: String =
src.lines().map(|l| l.split("//").next().unwrap_or("")).collect::<Vec<_>>().join("\n");
let body = code
.split("pub fn push_pts(")
.nth(1)
.expect("push_pts is still spelled that way")
.split("pub fn")
.next()
.expect("the function has a body");
assert!(
body.contains("col, 1.0)"),
"push_pts must default to 1.0, the FARTHEST plane — a default that is wrong can \
only be wrong in one direction, and this one makes an unranked run invisible \
rather than making it erase the map. Body: {body}"
);
assert!(
!body.contains("col, 0.0)"),
"0.0 is the CLOSEST plane, not a neutral zero: {body}"
);
}
/// **THE SHADER'S SAMPLE COUNT AND THE TARGET'S MUST BE ONE NUMBER** — lane GG #2.
///
/// `line.wgsl` builds its own `@builtin(sample_mask)` from `coverage_inside`, and to do
/// that it has to know how many samples there ARE — as a WGSL `const`, because the mask is
/// a compile-time-shaped bit run. The Rust side allocates the offscreen pair at
/// [`facett_map::gpu::MAP_MSAA_SAMPLES`]. Two spellings of one number, and nothing in the
/// type system holds them together.
///
/// Drift is silent in both directions, which is why this is a guard and not a comment:
///
/// * shader **higher** than the target → the mask sets bits the pass does not have. They
/// are dropped, so full coverage stops meaning full coverage and every road quietly
/// thins.
/// * shader **lower** → `coverage_mask` can never reach all four bits, so no fragment is
/// ever fully opaque and every road edge keeps a permanent partial-coverage seam.
///
/// Neither raises a wgpu validation error and neither is visible in a unit test of either
/// side alone. It is asserted on the SHADER TEXT with comments stripped, the same way
/// `push_pts` is checked above — the value that matters is the one the compiler sees.
/// Gated: it reads `facett_map::gpu`, which is behind the `wgpu` feature. The rest of this
/// file is pure `paint_order` and deliberately builds without it.
#[cfg(feature = "wgpu")]
#[test]
fn the_line_shader_knows_the_offscreen_sample_count() {
let src = facett_map::gpu::line::LINE_WGSL;
let code: String =
src.lines().map(|l| l.split("//").next().unwrap_or("")).collect::<Vec<_>>().join("\n");
let want = format!("const MSAA_SAMPLES: u32 = {}u;", facett_map::gpu::MAP_MSAA_SAMPLES);
assert!(
code.contains(&want),
"line.wgsl must declare `{want}` to match \
`facett_map::gpu::MAP_MSAA_SAMPLES` = {}. Found: {:?}",
facett_map::gpu::MAP_MSAA_SAMPLES,
code.lines().find(|l| l.contains("MSAA_SAMPLES")).unwrap_or("<no MSAA_SAMPLES line>")
);
// …and the constant must still be REACHED. A declaration nothing reads is a value that
// cannot drift because nothing depends on it, and a guard on it would be theatre.
assert!(
code.contains("f32(MSAA_SAMPLES)"),
"line.wgsl declares MSAA_SAMPLES but no longer uses it — the coverage mask has \
stopped being derived from the sample count, so this guard now protects nothing"
);
const _: () = assert!(
facett_map::gpu::MAP_MSAA_SAMPLES > 1,
"the offscreen pair is single-sample again, so the sample mask in line.wgsl can \
only ever say 'all of the one sample' and lane GG #2's cure is inert"
);
}