@@ -25,6 +25,9 @@ use winit::{
2525 window:: WindowBuilder ,
2626} ;
2727
28+ // The maximum number of frames we allow to be in flight at any given time
29+ pub const MAX_FRAME_LATENCY : usize = 3 ;
30+
2831// Simple offset_of macro akin to C++ offsetof
2932#[ macro_export]
3033macro_rules! offset_of {
@@ -133,6 +136,7 @@ pub struct ExampleBase {
133136 pub debug_utils_loader : debug_utils:: Instance ,
134137 pub window : winit:: window:: Window ,
135138 pub event_loop : RefCell < EventLoop < ( ) > > ,
139+ pub frame_index : RefCell < usize > ,
136140 pub debug_call_back : vk:: DebugUtilsMessengerEXT ,
137141
138142 pub pdevice : vk:: PhysicalDevice ,
@@ -149,22 +153,22 @@ pub struct ExampleBase {
149153 pub present_image_views : Vec < vk:: ImageView > ,
150154
151155 pub pool : vk:: CommandPool ,
152- pub draw_command_buffer : vk:: CommandBuffer ,
156+ pub draw_command_buffers : [ vk:: CommandBuffer ; MAX_FRAME_LATENCY ] ,
153157 pub setup_command_buffer : vk:: CommandBuffer ,
154158 pub app_setup_command_buffer : vk:: CommandBuffer ,
155159
156160 pub depth_image : vk:: Image ,
157161 pub depth_image_view : vk:: ImageView ,
158162 pub depth_image_memory : vk:: DeviceMemory ,
159163
160- pub present_complete_semaphore : vk:: Semaphore ,
164+ pub present_complete_semaphores : [ vk:: Semaphore ; MAX_FRAME_LATENCY ] ,
161165 pub rendering_complete_semaphores : Vec < vk:: Semaphore > ,
162166
163- pub draw_commands_reuse_fence : vk:: Fence ,
167+ pub draw_commands_reuse_fences : [ vk:: Fence ; MAX_FRAME_LATENCY ] ,
164168}
165169
166170impl ExampleBase {
167- pub fn render_loop < F : Fn ( ) > ( & self , f : F ) -> Result < ( ) , impl Error > {
171+ pub fn render_loop < F : Fn ( usize ) > ( & self , f : F ) -> Result < ( ) , impl Error > {
168172 self . event_loop . borrow_mut ( ) . run_on_demand ( |event, elwp| {
169173 elwp. set_control_flow ( ControlFlow :: Poll ) ;
170174 match event {
@@ -185,19 +189,22 @@ impl ExampleBase {
185189 elwp. exit ( ) ;
186190 }
187191 Event :: AboutToWait => {
192+ let mut frame_index = self . frame_index . borrow_mut ( ) ;
193+
194+ // The fence from 3 frames ago, that will also be signaled this frame
195+ let draw_commands_reuse_fence =
196+ self . draw_commands_reuse_fences [ * frame_index % MAX_FRAME_LATENCY ] ;
188197 unsafe {
189- self . device . wait_for_fences (
190- & [ self . draw_commands_reuse_fence ] ,
191- true ,
192- u64:: MAX ,
193- )
198+ self . device
199+ . wait_for_fences ( & [ draw_commands_reuse_fence] , true , u64:: MAX )
194200 }
195201 . expect ( "Wait for fence failed." ) ;
196202
197- unsafe { self . device . reset_fences ( & [ self . draw_commands_reuse_fence ] ) }
203+ unsafe { self . device . reset_fences ( & [ draw_commands_reuse_fence] ) }
198204 . expect ( "Reset fences failed." ) ;
199205
200- f ( )
206+ f ( * frame_index) ;
207+ * frame_index += 1 ;
201208 }
202209 _ => ( ) ,
203210 }
@@ -404,7 +411,7 @@ impl ExampleBase {
404411 let pool = device. create_command_pool ( & pool_create_info, None ) . unwrap ( ) ;
405412
406413 let command_buffer_allocate_info = vk:: CommandBufferAllocateInfo :: default ( )
407- . command_buffer_count ( 3 )
414+ . command_buffer_count ( 2 + MAX_FRAME_LATENCY as u32 )
408415 . command_pool ( pool)
409416 . level ( vk:: CommandBufferLevel :: PRIMARY ) ;
410417
@@ -413,7 +420,9 @@ impl ExampleBase {
413420 . unwrap ( ) ;
414421 let setup_command_buffer = command_buffers[ 0 ] ;
415422 let app_setup_command_buffer = command_buffers[ 1 ] ;
416- let draw_command_buffer = command_buffers[ 2 ] ;
423+ let draw_command_buffers = command_buffers[ 2 ..] [ ..MAX_FRAME_LATENCY ]
424+ . try_into ( )
425+ . unwrap ( ) ;
417426
418427 let present_images = swapchain_loader. get_swapchain_images ( swapchain) . unwrap ( ) ;
419428 let present_image_views: Vec < vk:: ImageView > = present_images
@@ -472,13 +481,6 @@ impl ExampleBase {
472481 . bind_image_memory ( depth_image, depth_image_memory, 0 )
473482 . expect ( "Unable to bind depth image memory" ) ;
474483
475- let fence_create_info =
476- vk:: FenceCreateInfo :: default ( ) . flags ( vk:: FenceCreateFlags :: SIGNALED ) ;
477-
478- let draw_commands_reuse_fence = device
479- . create_fence ( & fence_create_info, None )
480- . expect ( "Create fence failed." ) ;
481-
482484 record_submit_commandbuffer (
483485 & device,
484486 setup_command_buffer,
@@ -532,9 +534,11 @@ impl ExampleBase {
532534
533535 let semaphore_create_info = vk:: SemaphoreCreateInfo :: default ( ) ;
534536
535- let present_complete_semaphore = device
536- . create_semaphore ( & semaphore_create_info, None )
537- . unwrap ( ) ;
537+ let present_complete_semaphores = std:: array:: from_fn ( |_| {
538+ device
539+ . create_semaphore ( & semaphore_create_info, None )
540+ . unwrap ( )
541+ } ) ;
538542 let rendering_complete_semaphores = ( 0 ..present_images. len ( ) )
539543 . map ( |_| {
540544 device
@@ -543,8 +547,18 @@ impl ExampleBase {
543547 } )
544548 . collect ( ) ;
545549
550+ let fence_create_info =
551+ vk:: FenceCreateInfo :: default ( ) . flags ( vk:: FenceCreateFlags :: SIGNALED ) ;
552+
553+ let draw_commands_reuse_fences = std:: array:: from_fn ( |_| {
554+ device
555+ . create_fence ( & fence_create_info, None )
556+ . expect ( "Create fence failed." )
557+ } ) ;
558+
546559 Ok ( Self {
547560 event_loop : RefCell :: new ( event_loop) ,
561+ frame_index : RefCell :: new ( 0 ) ,
548562 entry,
549563 instance,
550564 device,
@@ -561,14 +575,14 @@ impl ExampleBase {
561575 present_images,
562576 present_image_views,
563577 pool,
564- draw_command_buffer ,
578+ draw_command_buffers ,
565579 setup_command_buffer,
566580 app_setup_command_buffer,
567581 depth_image,
568582 depth_image_view,
569- present_complete_semaphore ,
583+ present_complete_semaphores ,
570584 rendering_complete_semaphores,
571- draw_commands_reuse_fence ,
585+ draw_commands_reuse_fences ,
572586 surface,
573587 debug_call_back,
574588 debug_utils_loader,
@@ -582,13 +596,15 @@ impl Drop for ExampleBase {
582596 fn drop ( & mut self ) {
583597 unsafe {
584598 self . device . device_wait_idle ( ) . unwrap ( ) ;
585- self . device
586- . destroy_semaphore ( self . present_complete_semaphore , None ) ;
599+ for & semaphore in & self . present_complete_semaphores {
600+ self . device . destroy_semaphore ( semaphore, None ) ;
601+ }
587602 for & semaphore in & self . rendering_complete_semaphores {
588603 self . device . destroy_semaphore ( semaphore, None ) ;
589604 }
590- self . device
591- . destroy_fence ( self . draw_commands_reuse_fence , None ) ;
605+ for & fence in & self . draw_commands_reuse_fences {
606+ self . device . destroy_fence ( fence, None ) ;
607+ }
592608 self . device . free_memory ( self . depth_image_memory , None ) ;
593609 self . device . destroy_image_view ( self . depth_image_view , None ) ;
594610 self . device . destroy_image ( self . depth_image , None ) ;
0 commit comments