Files
DarkRoom/core/dr-gpu/examples/bench.rs
T
dtourolle 0f202fd3f9 Add requirements traceability gate and Gitea pipelines
Ports JellyTau's traceability tooling to Rust, carrying across the bug it
was repaired for. That gate divided a traced count by frozen literal
denominators; the requirements file outgrew them and it reported 158%
coverage, so it could never fail its own threshold.

Two rules, both enforced by the extractor's own tests:

  - denominators parsed from docs/requirements.md at run time
  - coverage is |traced ∩ defined| / |defined|, never a raw traced count

The gate additionally fails hard on a misconfigured run — zero
requirements parsed or zero files scanned — rather than reporting a
plausible 0%, and on any orphan tag naming a requirement that does not
exist.

Adapted for DarkRoom: IDs are FR-CAT-1 / NFR-P13 / FR-DEV-3a shapes
rather than JellyTau's fixed three digits, and decisions (D), spikes (S),
milestone items (M) and test ids remain taggable while being excluded
from the denominator — counting them inflated it by 25.

Also adds dr-sync: the RemoteBackend trait and capability model, so the
Nextcloud connector is one implementation rather than the only shape the
engine understands. No mature Nextcloud crate exists (reqwest_dav is too
thin), so the connector will be hand-rolled over reqwest per D7.

Gitea workflows follow the same style: containerised, commented with the
reasoning, desktop and Android on every push, plus a CI check that no
core/ crate depends on the UI toolkit (ARCH §6.5a).

Coverage today: 13.3% (19/143). 50 tests passing.
2026-08-09 08:01:32 +02:00

54 lines
1.4 KiB
Rust

// Measures the per-frame cost at several canvas sizes, isolating the readback
// path from windowing.
use dr_gpu::{GpuContext, RenderTarget};
use std::time::Instant;
fn main() {
env_logger::init();
let ctx = pollster::block_on(GpuContext::new_headless()).unwrap();
println!("adapter: {}\n", ctx.adapter_name());
println!(
"{:>12} {:>10} {:>10} {:>8}",
"size", "compute", "+readback", "fps"
);
for &(w, h) in &[
(840u32, 692u32),
(1280, 720),
(1920, 1080),
(2048, 1152),
(3840, 2160),
] {
let rt = RenderTarget::new(&ctx, w, h).unwrap();
// warm
for i in 0..10 {
rt.render(i as f32 * 0.01);
let _ = pollster::block_on(rt.read_pixels());
}
let n = 40;
let t0 = Instant::now();
for i in 0..n {
rt.render(i as f32 * 0.01);
}
ctx.device.poll(wgpu::Maintain::Wait);
let compute = t0.elapsed().as_secs_f64() / n as f64;
let t1 = Instant::now();
for i in 0..n {
rt.render(i as f32 * 0.01);
let _ = pollster::block_on(rt.read_pixels()).unwrap();
}
let full = t1.elapsed().as_secs_f64() / n as f64;
println!(
"{:>5}x{:<6} {:>8.2}ms {:>8.2}ms {:>8.0}",
w,
h,
compute * 1000.0,
full * 1000.0,
1.0 / full
);
}
}