From da543fb51e649c550a8c52531dbc18fc13910237 Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Fri, 17 May 2024 13:38:00 -0700 Subject: [PATCH] Turn `RelaySemaphores::wait` into an option. This allows us to delete `should_wait`, and makes `RelaySemaphoreState` the same as `RelaySemaphores`, so we can just return a clone of our current state. --- wgpu-hal/src/vulkan/mod.rs | 62 +++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 03b7ee9f9f1..bbf8d03c1ea 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -485,59 +485,59 @@ pub struct Device { render_doc: crate::auxil::renderdoc::RenderDoc, } -/// Semaphores that a given submission should wait on and signal. -struct RelaySemaphoreState { - wait: Option, - signal: vk::Semaphore, -} - /// A pair of binary semaphores that are used to synchronize each submission with the next. +#[derive(Clone)] struct RelaySemaphores { - wait: vk::Semaphore, - /// Signals if the wait semaphore should be waited on. + /// The semaphore the next submission should wait on. /// - /// Because nothing will signal the semaphore for the first submission, we don't want to wait on it. - should_wait: bool, + /// This is `None` for the very first submission, because that should not + /// wait on anything. We populate the `Option` at that point. + wait: Option, signal: vk::Semaphore, } impl RelaySemaphores { fn new(device: &ash::Device) -> Result { - let wait = unsafe { - device - .create_semaphore(&vk::SemaphoreCreateInfo::builder(), None) - .map_err(crate::DeviceError::from)? - }; let signal = unsafe { device .create_semaphore(&vk::SemaphoreCreateInfo::builder(), None) .map_err(crate::DeviceError::from)? }; - Ok(Self { - wait, - should_wait: false, - signal, - }) + Ok(Self { wait: None, signal }) } /// Advances the semaphores, returning the semaphores that should be used for a submission. - #[must_use] - fn advance(&mut self) -> RelaySemaphoreState { - let old = RelaySemaphoreState { - wait: self.should_wait.then_some(self.wait), - signal: self.signal, - }; + fn advance(&mut self, device: &ash::Device) -> Result { + let old = self.clone(); - mem::swap(&mut self.wait, &mut self.signal); - self.should_wait = true; + // Build the state for the next submission. + match self.wait { + None => { + // The `old` values describe the first submission to this queue. + // The second submission should wait on `old.signal`, and signal + // a new semaphore which we'll create now. + self.wait = Some(old.signal); + self.signal = unsafe { + device + .create_semaphore(&vk::SemaphoreCreateInfo::builder(), None) + .map_err(crate::DeviceError::from)? + }; + } + Some(ref mut wait) => { + // What this submission signals, the next should wait. + mem::swap(wait, &mut self.signal); + } + }; - old + Ok(old) } /// Destroys the semaphores. unsafe fn destroy(&self, device: &ash::Device) { unsafe { - device.destroy_semaphore(self.wait, None); + if let Some(wait) = self.wait { + device.destroy_semaphore(wait, None); + } device.destroy_semaphore(self.signal, None); } } @@ -930,7 +930,7 @@ impl crate::Queue for Queue { // In order for submissions to be strictly ordered, we encode a dependency between each submission // using a pair of semaphores. This adds a wait if it is needed, and signals the next semaphore. - let semaphore_state = self.relay_semaphores.lock().advance(); + let semaphore_state = self.relay_semaphores.lock().advance(&self.device.raw)?; if let Some(sem) = semaphore_state.wait { wait_stage_masks.push(vk::PipelineStageFlags::TOP_OF_PIPE);