perf(encode): pipeline the Vulkan Video encoder (frames in flight)

The Linux raw-Vulkan HEVC backend blocked on two GPU fences per frame, so
CPU readback and the next capture could not overlap the GPU encode. Refactor
into a small ring of per-in-flight-frame resources (own command buffers,
CSC descriptor set + Y/UV/NV12 scratch, bitstream buffer, feedback query and
sync objects) so submit() records into a free slot and returns without
waiting, and poll() reads back the oldest slot once its fence signals. The
pump's non-blocking poll then overlaps a frame's CSC+encode with the next
capture — the throughput win — with no capturer/pump change (VAAPI untouched).

- New `Frame` struct + `make_frame`; encoder holds `frames`/`ring`/`in_flight`.
- `record_submit` (non-blocking) + `read_slot` (fence-gated readback) replace
  the synchronous `encode_frame`; `enqueue` applies backpressure by draining
  the oldest slot when the ring is full.
- DPB self-barrier between consecutive encodes: orders frame N's reconstruct
  write before N+1's reference read now that they can be in flight together.
- flush() drains all in-flight slots in order; reset() waits idle + discards.
- Ring depth defaults to 3, overridable via PUNKTFUNK_VULKAN_INFLIGHT (2..=6).
- Smoke test drains via poll-loop + flush (async breaks one-AU-per-submit).

Headless-validated on real RADV 780M: cargo check (feature on/off) + clippy
-D warnings + rustfmt clean; smoke test at ring depth 2/3/6 all ffmpeg-decode
clean (I P P P P P) and drop-heal (I P P P P) with 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-12 19:51:21 +02:00
parent bbbb7f5723
commit e9d8f2bc04
File diff suppressed because it is too large Load Diff