Skip to main content

lgpu_hal/vulkan/
sync.rs

1//! Vulkan timeline semaphore synchronization.
2
3use super::VulkanDevice;
4use crate::HalError;
5use ash::vk;
6
7pub struct VulkanTimelineSemaphore {
8    pub semaphore: vk::Semaphore,
9}
10
11unsafe impl Send for VulkanTimelineSemaphore {}
12unsafe impl Sync for VulkanTimelineSemaphore {}
13
14impl VulkanDevice {
15    pub fn create_timeline_semaphore(
16        &self,
17        initial_value: u64,
18    ) -> Result<VulkanTimelineSemaphore, HalError> {
19        let mut type_info = vk::SemaphoreTypeCreateInfo::default()
20            .semaphore_type(vk::SemaphoreType::TIMELINE)
21            .initial_value(initial_value);
22        let create_info = vk::SemaphoreCreateInfo::default().push_next(&mut type_info);
23
24        let semaphore = unsafe {
25            self.device
26                .create_semaphore(&create_info, None)
27                .map_err(|e| {
28                    HalError::BackendError(format!("Failed to create timeline semaphore: {e}"))
29                })?
30        };
31
32        Ok(VulkanTimelineSemaphore { semaphore })
33    }
34
35    pub fn wait_timeline_semaphore(
36        &self,
37        semaphore: &VulkanTimelineSemaphore,
38        value: u64,
39        timeout_nanos: u64,
40    ) -> Result<(), HalError> {
41        let semaphores = [semaphore.semaphore];
42        let values = [value];
43        let wait_info = vk::SemaphoreWaitInfo::default()
44            .semaphores(&semaphores)
45            .values(&values);
46
47        unsafe {
48            self.device
49                .wait_semaphores(&wait_info, timeout_nanos)
50                .map_err(|e| HalError::CommandError(format!("vkWaitSemaphores failed: {e}")))?;
51        }
52        Ok(())
53    }
54
55    pub fn get_timeline_semaphore_value(
56        &self,
57        semaphore: &VulkanTimelineSemaphore,
58    ) -> Result<u64, HalError> {
59        unsafe {
60            self.device
61                .get_semaphore_counter_value(semaphore.semaphore)
62                .map_err(|e| {
63                    HalError::CommandError(format!("vkGetSemaphoreCounterValue failed: {e}"))
64                })
65        }
66    }
67
68    pub fn signal_timeline_semaphore(
69        &self,
70        semaphore: &VulkanTimelineSemaphore,
71        value: u64,
72    ) -> Result<(), HalError> {
73        let signal_info = vk::SemaphoreSignalInfo::default()
74            .semaphore(semaphore.semaphore)
75            .value(value);
76        unsafe {
77            self.device
78                .signal_semaphore(&signal_info)
79                .map_err(|e| HalError::CommandError(format!("vkSignalSemaphore failed: {e}")))?;
80        }
81        Ok(())
82    }
83
84    pub fn destroy_timeline_semaphore(&self, semaphore: VulkanTimelineSemaphore) {
85        unsafe {
86            self.device.destroy_semaphore(semaphore.semaphore, None);
87        }
88    }
89}