Skip to content

Commit

Permalink
Turn RelaySemaphores::wait into an option.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jimblandy committed May 17, 2024
1 parent 0b51ece commit da543fb
Showing 1 changed file with 31 additions and 31 deletions.
62 changes: 31 additions & 31 deletions wgpu-hal/src/vulkan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<vk::Semaphore>,
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<vk::Semaphore>,
signal: vk::Semaphore,
}

impl RelaySemaphores {
fn new(device: &ash::Device) -> Result<Self, crate::DeviceError> {
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<Self, crate::DeviceError> {
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);
}
}
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit da543fb

Please sign in to comment.