From 3f579cf2cdfebc58ca4e302e272f09ffa2b7b40d Mon Sep 17 00:00:00 2001 From: koplas <54645365+koplas@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:59:28 +0200 Subject: [PATCH 1/2] Fix sync validation errors Simplify the fence usage to avoid errors with synchronization --- ash-examples/src/bin/texture.rs | 4 ++-- ash-examples/src/bin/triangle.rs | 2 +- ash-examples/src/lib.rs | 34 +++++++++++++++----------------- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/ash-examples/src/bin/texture.rs b/ash-examples/src/bin/texture.rs index c8e3f9357..b1f7615a4 100644 --- a/ash-examples/src/bin/texture.rs +++ b/ash-examples/src/bin/texture.rs @@ -354,7 +354,7 @@ fn main() -> Result<(), Box> { record_submit_commandbuffer( &base.device, base.setup_command_buffer, - base.setup_commands_reuse_fence, + base.submit_complete_fence, base.present_queue, &[], &[], @@ -721,7 +721,7 @@ fn main() -> Result<(), Box> { record_submit_commandbuffer( &base.device, base.draw_command_buffer, - base.draw_commands_reuse_fence, + base.submit_complete_fence, base.present_queue, &[vk::PipelineStageFlags::BOTTOM_OF_PIPE], &[base.present_complete_semaphore], diff --git a/ash-examples/src/bin/triangle.rs b/ash-examples/src/bin/triangle.rs index 1dcdc9827..52c44a6bc 100644 --- a/ash-examples/src/bin/triangle.rs +++ b/ash-examples/src/bin/triangle.rs @@ -383,7 +383,7 @@ fn main() -> Result<(), Box> { record_submit_commandbuffer( &base.device, base.draw_command_buffer, - base.draw_commands_reuse_fence, + base.submit_complete_fence, base.present_queue, &[vk::PipelineStageFlags::COLOR_ATTACHMENT_OUTPUT], &[base.present_complete_semaphore], diff --git a/ash-examples/src/lib.rs b/ash-examples/src/lib.rs index e1c2e2670..f73c28725 100644 --- a/ash-examples/src/lib.rs +++ b/ash-examples/src/lib.rs @@ -51,10 +51,6 @@ pub fn record_submit_commandbuffer( f: F, ) { unsafe { - device - .wait_for_fences(&[command_buffer_reuse_fence], true, u64::MAX) - .expect("Wait for fence failed."); - device .reset_fences(&[command_buffer_reuse_fence]) .expect("Reset fences failed."); @@ -169,8 +165,7 @@ pub struct ExampleBase { pub present_complete_semaphore: vk::Semaphore, pub rendering_complete_semaphore: vk::Semaphore, - pub draw_commands_reuse_fence: vk::Fence, - pub setup_commands_reuse_fence: vk::Fence, + pub submit_complete_fence: vk::Fence, } impl ExampleBase { @@ -194,7 +189,14 @@ impl ExampleBase { } => { elwp.exit(); } - Event::AboutToWait => f(), + Event::AboutToWait => { + unsafe { + self.device + .wait_for_fences(&[self.submit_complete_fence], true, u64::MAX) + .expect("Wait for fence failed."); + } + f() + } _ => (), } }) @@ -472,17 +474,14 @@ impl ExampleBase { let fence_create_info = vk::FenceCreateInfo::default().flags(vk::FenceCreateFlags::SIGNALED); - let draw_commands_reuse_fence = device - .create_fence(&fence_create_info, None) - .expect("Create fence failed."); - let setup_commands_reuse_fence = device + let submit_complete_fence = device .create_fence(&fence_create_info, None) .expect("Create fence failed."); record_submit_commandbuffer( &device, setup_command_buffer, - setup_commands_reuse_fence, + submit_complete_fence, present_queue, &[], &[], @@ -514,6 +513,9 @@ impl ExampleBase { ); }, ); + device + .wait_for_fences(&[submit_complete_fence], true, u64::MAX) + .expect("Wait for fence failed."); let depth_image_view_info = vk::ImageViewCreateInfo::default() .subresource_range( @@ -563,8 +565,7 @@ impl ExampleBase { depth_image_view, present_complete_semaphore, rendering_complete_semaphore, - draw_commands_reuse_fence, - setup_commands_reuse_fence, + submit_complete_fence, surface, debug_call_back, debug_utils_loader, @@ -582,10 +583,7 @@ impl Drop for ExampleBase { .destroy_semaphore(self.present_complete_semaphore, None); self.device .destroy_semaphore(self.rendering_complete_semaphore, None); - self.device - .destroy_fence(self.draw_commands_reuse_fence, None); - self.device - .destroy_fence(self.setup_commands_reuse_fence, None); + self.device.destroy_fence(self.submit_complete_fence, None); self.device.free_memory(self.depth_image_memory, None); self.device.destroy_image_view(self.depth_image_view, None); self.device.destroy_image(self.depth_image, None); From d01dea0b7882dcd8aa289dddd917022b4bf9773c Mon Sep 17 00:00:00 2001 From: koplas <54645365+koplas@users.noreply.github.com> Date: Sat, 21 Sep 2024 18:59:58 +0200 Subject: [PATCH 2/2] Mark record_submit_commandbuffer as unsafe --- ash-examples/src/lib.rs | 80 +++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/ash-examples/src/lib.rs b/ash-examples/src/lib.rs index f73c28725..0b7ca8c58 100644 --- a/ash-examples/src/lib.rs +++ b/ash-examples/src/lib.rs @@ -36,11 +36,15 @@ macro_rules! offset_of { } }}; } -/// Helper function for submitting command buffers. Immediately waits for the fence before the command buffer -/// is executed. That way we can delay the waiting for the fences by 1 frame which is good for performance. -/// Make sure to create the fence in a signaled state on the first use. +/// Helper function for submitting command buffers. +/// +/// # Safety +/// +/// The caller must ensure that the command buffer and the fence is +/// not currently used. The wait_mask must specify capabilities that +/// are supported by the queue. #[allow(clippy::too_many_arguments)] -pub fn record_submit_commandbuffer( +pub unsafe fn record_submit_commandbuffer( device: &Device, command_buffer: vk::CommandBuffer, command_buffer_reuse_fence: vk::Fence, @@ -50,41 +54,39 @@ pub fn record_submit_commandbuffer( signal_semaphores: &[vk::Semaphore], f: F, ) { - unsafe { - device - .reset_fences(&[command_buffer_reuse_fence]) - .expect("Reset fences failed."); - - device - .reset_command_buffer( - command_buffer, - vk::CommandBufferResetFlags::RELEASE_RESOURCES, - ) - .expect("Reset command buffer failed."); - - let command_buffer_begin_info = vk::CommandBufferBeginInfo::default() - .flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT); - - device - .begin_command_buffer(command_buffer, &command_buffer_begin_info) - .expect("Begin commandbuffer"); - f(device, command_buffer); - device - .end_command_buffer(command_buffer) - .expect("End commandbuffer"); - - let command_buffers = vec![command_buffer]; - - let submit_info = vk::SubmitInfo::default() - .wait_semaphores(wait_semaphores) - .wait_dst_stage_mask(wait_mask) - .command_buffers(&command_buffers) - .signal_semaphores(signal_semaphores); - - device - .queue_submit(submit_queue, &[submit_info], command_buffer_reuse_fence) - .expect("queue submit failed."); - } + device + .reset_fences(&[command_buffer_reuse_fence]) + .expect("Reset fences failed."); + + device + .reset_command_buffer( + command_buffer, + vk::CommandBufferResetFlags::RELEASE_RESOURCES, + ) + .expect("Reset command buffer failed."); + + let command_buffer_begin_info = + vk::CommandBufferBeginInfo::default().flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT); + + device + .begin_command_buffer(command_buffer, &command_buffer_begin_info) + .expect("Begin commandbuffer"); + f(device, command_buffer); + device + .end_command_buffer(command_buffer) + .expect("End commandbuffer"); + + let command_buffers = vec![command_buffer]; + + let submit_info = vk::SubmitInfo::default() + .wait_semaphores(wait_semaphores) + .wait_dst_stage_mask(wait_mask) + .command_buffers(&command_buffers) + .signal_semaphores(signal_semaphores); + + device + .queue_submit(submit_queue, &[submit_info], command_buffer_reuse_fence) + .expect("queue submit failed."); } unsafe extern "system" fn vulkan_debug_callback(