eventssynchronizationvulkan

How to wait (vkCmdWaitEvents) 2 different events most efficiently in one cmd buffer?


Say action 1,2,3 produce OutcomeA,

action 4,5,6 produce OutcomeB.

And,

action 7,8 needs OutcomeA, but don't need OutcomeB.

action 9 needs OutcomeB, but don't need OutcomeA.

If I wrote it like this, What's the scope of event B? Will action 9 be waiting OutcomeA (action 1,2,3) as well?

If the answer is Yes (which isn't what I want), what's the right way to do it ?

// Three dispatches that don’t have conflicting resource accesses
vkCmdDispatch( 1 );
vkCmdDispatch( 2 );
vkCmdDispatch( 3 );

// 4, 5, and 6 don’t share resources with 1, 2, and 3
// No reason for them to be blocked, so set an event to wait for later
vkCmdSetEvent( A, srcStageMask = COMPUTE );

vkCmdDispatch( 4 );
vkCmdDispatch( 5 );
vkCmdDispatch( 6 );

// 7 and 8 don’t use the same resources as 4, 5, and 6.  So use an event
vkCmdSetEvent( B, srcStageMask = COMPUTE );

// 7 and 8 need the results of 1, 2, and 3
// So we’ll wait for them by waiting on A
vkCmdWaitEvents( A, dstStageMask = COMPUTE );
vkCmdDispatch( 7 );
vkCmdDispatch( 8 );

// 9 uses the same resources as 4, 5, and 6 so we wait.
// Also assumed is that 9 needs nothing from 7 and 8
vkCmdWaitEvents( B, dstStageMask = COMPUTE );
vkCmdDispatch( 9 );

Solution

  • Yes, events will synchronize with every command submitted before the signal and after the wait, provided that they match the pipeline stage. If you really want maximum independence here, you'd need to submit these sets of commands to different queues/queue families.

    However, you should also keep in mind that just because the driver could schedule work in parallel, it doesn't necessarily do so - this depends on the size of your submissions and free hardware resources. Using multiple queues also isn't free, so you should benchmark whether that split is really worth it.