Repository navigation
nvn: implement nvnCommandBufferWaitEvent and per-queue command parking - #1728
ksolenk38ze wants to merge 1 commit into
Conversation
When a guest records nvnCommandBufferWaitEvent on an NVNevent whose counter is signaled later on another NVNqueue or from the CPU via nvnEventSignal, the waiting queue must pause replay at the WaitEvent boundary until the target event value is reached. Executing past an unsatisfied WaitEvent reads compute or render outputs before the signaling queue has produced them, while spinning on the submission lock deadlocks when the signal is submitted later on the same thread. Record OP_SIGNAL_EVENT with bit 1 set in nvnCommandBufferWaitEvent, track the latest GPU-signaled value per event address across in-flight command buffers, and park the active queue's remaining command stream (including its active OP_CALL return stack and pending post-submission callbacks) when a WaitEvent is not yet satisfied. Unpark and drain ready queues when an event is signaled on the GPU or CPU, or when nvnSyncWait, nvnQueueFlush, nvnQueueFinish, or nvnQueuePresentTexture flushes pending work. Verified in The Legend of Zelda: Ocarina of Time (0400486024DEC000) on Apple M-series (macOS) and with the dm/gfx/tests suite.
cf4b70a to
f20469b
Compare
|
We are evaluating this against #1245 on an iPad Pro (M5) with Ocarina of Time (0400486024DEC000 v131072), Docked 1536x864. Data point for why: #1245 as merged on our stack fixes the game's one-frame fog and shadow flicker (#1703), but its chunking costs the iPad. The game makes about 6 submissions a frame; cut at every event signal and wait they become 37 host submissions, and the GPU drains between a chunk and the next while the host commits it: 2.5 ms (p50) of GPU idle inside a 22.9 ms frame, against 0 idle in a 20.4 ms frame with the waits ignored, at the same GPU time. Parking keeps one command buffer per Two points to watch from reading it, no result yet:
|
|
Thanks @aksmith-git for testing this on the iPad Pro (M5)! Keeping one host submission per Looking forward to your iPad frame numbers, and happy to add a counter/log line on |
|
Thanks. The mechanism landed in ea0c98d ( |
What and why
nvnCommandBufferWaitEventwas a no-op stub, and when a game submitted command buffers across multipleNVNqueueinstances (q=0compute/transfer andq=1graphics),SubmitCommandsdrained and executed the secondary queue immediately on the calling thread instead of ordering it behind earlier submissions waiting on a sharedNVNevent. In The Legend of Zelda: Ocarina of Time (0400486024DEC000), compute skinning, shadow/sky passes, and object updates across queues race ahead of or behindq=1draws when event waits are ignored, causing one-frame shadow/sky drops, flickering or missing dynamic meshes, and synchronization stalls.This change:
P_WAIT_EVENTcommands innvnCommandBufferWaitEventandP_SIGNAL_EVENTinnvnCommandBufferSignalEvent, tracking whether a command handle contains event waits (has_wait) or signals (has_signal).q_submit_or_park) when an unsatisfiedP_WAIT_EVENTis encountered, and drains parked queues (q_drain_parked) as soon as a matchingSignalEventor CPU write satisfies the condition.P_WAIT_EVENTat replay boundaries innvn_mtl.m(ev_wait_ready, bounded spin for cross-queue event writes) and wakes parked queues when submission post-op events complete.docs/reference/rendering.mdand updatesdocs/agents/symptoms.md.Related
Checked
make -C dm/gfx/tests GAME=0400486024DEC000 run(t_pool_notes,t_upgrade_alias,t_image_alias,t_alias_takeover,t_srgb_alias,t_rt_lifetime,t_pool_chunks),python3 dm/tools/docs_symptoms.py0400486024DEC000, v131072, SDK 22.2.8), played through Kokiri Forest, Hyrule Field, Zora's Domain, and Forest Temple at 60 fps.Docs
docs/reference/<subsystem>.mdentry, andpython3 dm/tools/docs_symptoms.pywas run (the symptom index)