#955 overlaps several open PRs. Resolution:
- GuestPageTracker, GuestBufferCache, ShaderIdentity, SharedBackingViews: upstream's versions
(they carry the same allocation-free invalidation, hashing and lock-free reads as #944/#968).
- RELEASE_MEM: upstream's deferred release flush (supersedes #966).
- CommandStreamQueue.Done: ours (#941 queued frame boundary; upstream only reformatted).
- Flip snapshot pool: ours (locked; snapshots are taken on the command-stream thread and
retired on the render thread), upstream's unlocked pool dropped.
- Gen5SpirvTranslator: our per-register variables and structurer (#923, #975/#976) first,
upstream's guarded in-order blocks as the fallback, then the dispatcher; upstream's
lane-spill slots, bounded move-relative, exec-known-full and PS input sharing kept.
Only forward, nested branches were emitted as structured control flow; every program with a
loop, and every single-block program, went through the loop around a switch on the guest PC,
which keeps all registers live and stops the host compiler from optimizing across blocks.
A block that a later block branches back to - on a wave-uniform condition or with s_branch -
now opens a SPIR-V loop whose body is structured like any range, whose continue evaluates
that branch's condition, and whose iterations share the dispatcher's step guard so a guest
loop that never ends still cannot wedge the GPU queue. A conditional branch from the body to
the block after the latch is a break out of the innermost loop. Any other backward edge, or a
break past an outer loop, keeps the dispatcher as before.
Across eight games, programs left on the dispatcher went from 760 to 104 (Poppy, Silent Hill,
Oregon Trail and Dreaming Sarah to none); every emitted module passes spirv-val and the
frames match. Octopath's 12.5M-invocation instanced draw went from 12.2 to 10.8 ms.