fix(encode/pyrowave): stop stamping GPU scheduling priority over pf-frame's auto gate #72

Merged
enricobuehler merged 1 commits from worktree-pyrowave-gpu-priority into main 2026-08-06 13:15:07 +00:00
Owner

Rescued from a July branch triage. Draft — needs an on-glass re-verify on .173 before merging. See "Why this is a draft" below.

The bug, confirmed still live on main

Two owners of one process-wide setting.

pf-frame::dxgi owns GPU scheduling priority for the whole process and runs from create_device — the call the Windows capture path always makes. Its default auto mode starts at HIGH and then upgrades to REALTIME once it has established that is safe (HAGS off, or HAGS on with VRAM headroom), leaving a monitor running that drops back when VRAM tightens — because REALTIME + NVIDIA + HAGS + near-full VRAM is a documented NVENC hang.

crates/pf-encode/src/enc/windows/pyrowave.rs then calls raise_process_gpu_priority() at every session open, which stamps HIGH back over that and orphans the monitor's decision. The ceiling-raise is lost on exactly the GPU-saturated workload PyroWave exists to survive: it encodes on the shader cores a game saturates, where the measured spike is ~2 ms to 15–18 ms.

Both halves verified present on main today (pyrowave.rs:193 still makes the call; the auto-gate lives in pf-frame/src/dxgi.rs).

The fix

Removed rather than reconciled. PyroWaveEncoder::open takes no device, so there was nothing session-specific to preserve, and the surviving owner is strictly better informed — it knows the adapter, HAGS state and VRAM headroom, none of which this call site had.

The duplicated knob goes with it: PUNKTFUNK_GPU_PRIORITY is retired in favour of PUNKTFUNK_GPU_PRIORITY_CLASS (off|normal|high|realtime|auto, default auto), which is a superset — the removed knob could not express the auto gate at all. I re-checked on current main: the old knob has no other reference anywhere in the tree, so nothing else breaks.

Why this is a draft

This is a removal, so it is the one of the three rescued July commits that carries real regression risk:

  • It deletes a function, its call site, and a documented env knob.
  • The original was verified on .173 across 7 clippy legs — but that was 734 commits ago.
  • pyrowave.rs is Windows-only, so none of it compiles on the Mac. I verified the cherry-pick applies clean and that no dangling reference to raise_process_gpu_priority or PUNKTFUNK_GPU_PRIORITY remains in the file — that is the limit of what I could check from here.

Owed before merge: the clippy legs re-run on .173 (host + pf-encode --all-targets at nvenc, amf-qsv, qsv, amf-qsv-without-qsv, qsv-alone, no-features), and ideally a PyroWave session on glass confirming the REALTIME upgrade now survives session open.

Rescued from a July branch triage. **Draft — needs an on-glass re-verify on .173 before merging.** See "Why this is a draft" below. ## The bug, confirmed still live on `main` Two owners of one process-wide setting. `pf-frame::dxgi` owns GPU scheduling priority for the whole process and runs from `create_device` — the call the Windows capture path always makes. Its default `auto` mode starts at HIGH and then **upgrades** to REALTIME once it has established that is safe (HAGS off, or HAGS on with VRAM headroom), leaving a monitor running that drops back when VRAM tightens — because REALTIME + NVIDIA + HAGS + near-full VRAM is a documented NVENC hang. `crates/pf-encode/src/enc/windows/pyrowave.rs` then calls `raise_process_gpu_priority()` at every session open, which stamps HIGH back over that **and** orphans the monitor's decision. The ceiling-raise is lost on exactly the GPU-saturated workload PyroWave exists to survive: it encodes on the shader cores a game saturates, where the measured spike is ~2 ms to 15–18 ms. Both halves verified present on `main` today (`pyrowave.rs:193` still makes the call; the auto-gate lives in `pf-frame/src/dxgi.rs`). ## The fix Removed rather than reconciled. `PyroWaveEncoder::open` takes no device, so there was nothing session-specific to preserve, and the surviving owner is strictly better informed — it knows the adapter, HAGS state and VRAM headroom, none of which this call site had. The duplicated knob goes with it: `PUNKTFUNK_GPU_PRIORITY` is retired in favour of `PUNKTFUNK_GPU_PRIORITY_CLASS` (`off|normal|high|realtime|auto`, default `auto`), which is a superset — the removed knob could not express the auto gate at all. I re-checked on current `main`: the old knob has no other reference anywhere in the tree, so nothing else breaks. ## Why this is a draft This is a **removal**, so it is the one of the three rescued July commits that carries real regression risk: - It deletes a function, its call site, and a documented env knob. - The original was verified on .173 across 7 clippy legs — but that was **734 commits ago**. - `pyrowave.rs` is Windows-only, so none of it compiles on the Mac. I verified the cherry-pick applies clean and that no dangling reference to `raise_process_gpu_priority` or `PUNKTFUNK_GPU_PRIORITY` remains in the file — that is the limit of what I could check from here. **Owed before merge:** the clippy legs re-run on .173 (host + pf-encode `--all-targets` at nvenc, amf-qsv, qsv, amf-qsv-without-qsv, qsv-alone, no-features), and ideally a PyroWave session on glass confirming the REALTIME upgrade now survives session open.
enricobuehler added 1 commit 2026-08-06 13:09:17 +00:00
fix(encode/pyrowave): stop stamping GPU scheduling priority over pf-frame's auto gate
apple / swift (pull_request) Successful in 1m26s
apple / screenshots (pull_request) Skipped
android / android (pull_request) Successful in 4m41s
ci / rust-arm64 (pull_request) Successful in 2m35s
ci / web (pull_request) Successful in 2m27s
ci / docs-site (pull_request) Successful in 3m35s
ci / rust (pull_request) Successful in 8m25s
70684e5079
`windows/pyrowave.rs` raised the process's WDDM scheduling class to HIGH itself, once per
process, at every session open. `pf-frame::dxgi::auto_priority_gate` already owns that policy
for the whole process and runs from `create_device` — the call the Windows capture path always
makes before any PyroWave texture exists. Two owners of one process-wide setting.

The audit filed this as "downgrades REALTIME to HIGH", which undersells it. pf-frame's default
`auto` mode starts at HIGH and then UPGRADES to REALTIME once it has established that is safe —
HAGS off, or HAGS on with VRAM headroom — and leaves a monitor running that drops back when VRAM
tightens, because REALTIME + NVIDIA + HAGS + near-full VRAM is a documented NVENC hang. Opening
a PyroWave session after that upgrade stamped HIGH back over the class AND orphaned the
monitor's decision, losing the ceiling-raise on exactly the GPU-saturated workload PyroWave
exists to survive: it encodes on the shader cores a game saturates, where the measured spike is
~2 ms to 15-18 ms.

Removed rather than reconciled. `PyroWaveEncoder::open` takes no device, so there was nothing
session-specific to preserve, and the surviving owner is strictly better informed — it knows the
adapter, HAGS state and VRAM headroom, none of which this call site had.

The duplicated knob goes with it: `PUNKTFUNK_GPU_PRIORITY` is retired in favour of
`PUNKTFUNK_GPU_PRIORITY_CLASS` (`off|normal|high|realtime|auto`, default `auto`), which is a
superset — the removed knob could not express the auto gate at all. No other reference to it
exists in the tree.

Verified on .173: clippy -D warnings at nvenc,amf-qsv,qsv (host + pf-encode --all-targets),
amf-qsv without qsv, qsv alone, no-features, cargo test --features qsv (34 passed), rustfmt —
7 legs green. Windows-only file, so the Linux legs do not compile it.
enricobuehler marked the pull request as ready for review 2026-08-06 13:15:00 +00:00
enricobuehler merged commit 65996621d8 into main 2026-08-06 13:15:07 +00:00
enricobuehler deleted branch worktree-pyrowave-gpu-priority 2026-08-06 13:15:08 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: unom/punktfunk#72