Files
iw4L/crates/perf
vtroc 2fb3e4558b Decode on the loader's own threads and only what is still claimed, and time the age of the presented state.
Image decode takes the pool it runs on as a parameter and every lane hands it
the loader's. `ComputeTaskPool` is the frame's pool, with its own thread count
and its own affinity, so a load stage that decoded on it ran on the frame's
threads and competed with the frame for them. Material compile chunks move onto
the same load pool instead of raw `std::thread::scope` threads: the pool's
workers set their affinity to the process CPUs when they spawn, while a thread
spawned from an `AsyncComputeTaskPool` worker inherits that pool's narrower set.
The compile scope is explicitly non-cooperative, so the calling thread waits for
its chunks rather than ticking the pool's queue.

The `common_mp` FPV plan is held rather than enqueued, and decodes once the
donor plans have merged. `prune_to` drops every demand whose rows the merge
would not fill — the same predicate `apply` uses, so pruning changes when the
question is asked and not what the catalog ends up holding — and
`release_claims` hands the rows back when nothing survives, which is otherwise
`apply`'s job and would leave later stages skipping every name the plan had
claimed. The census counts `pruned_variants` and `pruned_rows` on their own,
apart from duplicate claims and from discards, and the report line carries what
was cut, what is left and what asking cost.

`presented_state_age` and `presented_frames_behind` measure from a render
frame's extract to the render graph's Finish set: how old the state a frame drew
was, and how many main frames had opened since it was taken. They get their own
table in the counter report, because an age divided by a frame is not a share of
one, and a line in the frames section beside main/render overlap — what
pipelining costs, next to what it buys. Both say where they stop: bevy presents
after the graph schedule returns, so the present, the compositor and the panel
are outside, and neither is an input-to-photon latency.

`IW4L_FRAME_LATENCY` sets the surface's `desired_maximum_frame_latency` without
a rebuild. The backend may clamp it, so the manifest records the number asked
for and never a grant this process cannot read back. Env switches now read
through one rule in `perf::switch`: absent, empty, `0`, `false` and `off` are
off. `IW4L_MULTI_DRAW=0` therefore turns the indirect path off instead of
enabling it, which is what a paired run across it needs.

A lightmap page counts the bytes of all six of its images in `handed_bytes`,
`bytes_total` and against the budget pacing the overlay frames, and a slot that
takes another slot's handle no longer counts as having handed anything over.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 00:44:05 +03:00
..
2026-09-13 13:52:33 +03:00