@@ -485,59 +485,59 @@ pub struct Device {
485485 render_doc : crate :: auxil:: renderdoc:: RenderDoc ,
486486}
487487
488- /// Semaphores that a given submission should wait on and signal.
489- struct RelaySemaphoreState {
490- wait : Option < vk:: Semaphore > ,
491- signal : vk:: Semaphore ,
492- }
493-
494488/// A pair of binary semaphores that are used to synchronize each submission with the next.
489+ #[ derive( Clone ) ]
495490struct RelaySemaphores {
496- wait : vk:: Semaphore ,
497- /// Signals if the wait semaphore should be waited on.
491+ /// The semaphore the next submission should wait on.
498492 ///
499- /// Because nothing will signal the semaphore for the first submission, we don't want to wait on it.
500- should_wait : bool ,
493+ /// This is `None` for the very first submission, because that should not
494+ /// wait on anything. We populate the `Option` at that point.
495+ wait : Option < vk:: Semaphore > ,
501496 signal : vk:: Semaphore ,
502497}
503498
504499impl RelaySemaphores {
505500 fn new ( device : & ash:: Device ) -> Result < Self , crate :: DeviceError > {
506- let wait = unsafe {
507- device
508- . create_semaphore ( & vk:: SemaphoreCreateInfo :: builder ( ) , None )
509- . map_err ( crate :: DeviceError :: from) ?
510- } ;
511501 let signal = unsafe {
512502 device
513503 . create_semaphore ( & vk:: SemaphoreCreateInfo :: builder ( ) , None )
514504 . map_err ( crate :: DeviceError :: from) ?
515505 } ;
516- Ok ( Self {
517- wait,
518- should_wait : false ,
519- signal,
520- } )
506+ Ok ( Self { wait : None , signal } )
521507 }
522508
523509 /// Advances the semaphores, returning the semaphores that should be used for a submission.
524- #[ must_use]
525- fn advance ( & mut self ) -> RelaySemaphoreState {
526- let old = RelaySemaphoreState {
527- wait : self . should_wait . then_some ( self . wait ) ,
528- signal : self . signal ,
529- } ;
510+ fn advance ( & mut self , device : & ash:: Device ) -> Result < Self , crate :: DeviceError > {
511+ let old = self . clone ( ) ;
530512
531- mem:: swap ( & mut self . wait , & mut self . signal ) ;
532- self . should_wait = true ;
513+ // Build the state for the next submission.
514+ match self . wait {
515+ None => {
516+ // The `old` values describe the first submission to this queue.
517+ // The second submission should wait on `old.signal`, and signal
518+ // a new semaphore which we'll create now.
519+ self . wait = Some ( old. signal ) ;
520+ self . signal = unsafe {
521+ device
522+ . create_semaphore ( & vk:: SemaphoreCreateInfo :: builder ( ) , None )
523+ . map_err ( crate :: DeviceError :: from) ?
524+ } ;
525+ }
526+ Some ( ref mut wait) => {
527+ // What this submission signals, the next should wait.
528+ mem:: swap ( wait, & mut self . signal ) ;
529+ }
530+ } ;
533531
534- old
532+ Ok ( old)
535533 }
536534
537535 /// Destroys the semaphores.
538536 unsafe fn destroy ( & self , device : & ash:: Device ) {
539537 unsafe {
540- device. destroy_semaphore ( self . wait , None ) ;
538+ if let Some ( wait) = self . wait {
539+ device. destroy_semaphore ( wait, None ) ;
540+ }
541541 device. destroy_semaphore ( self . signal , None ) ;
542542 }
543543 }
@@ -930,7 +930,7 @@ impl crate::Queue for Queue {
930930
931931 // In order for submissions to be strictly ordered, we encode a dependency between each submission
932932 // using a pair of semaphores. This adds a wait if it is needed, and signals the next semaphore.
933- let semaphore_state = self . relay_semaphores . lock ( ) . advance ( ) ;
933+ let semaphore_state = self . relay_semaphores . lock ( ) . advance ( & self . device . raw ) ? ;
934934
935935 if let Some ( sem) = semaphore_state. wait {
936936 wait_stage_masks. push ( vk:: PipelineStageFlags :: TOP_OF_PIPE ) ;
0 commit comments