Skip to content

Commit b5d52fe

Browse files
committed
[hal/vk] Use a single semaphore to order submissions.
1 parent b10ca35 commit b5d52fe

3 files changed

Lines changed: 30 additions & 76 deletions

File tree

wgpu-hal/src/vulkan/adapter.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,14 +1793,12 @@ impl super::Adapter {
17931793
framebuffers: Mutex::new(Default::default()),
17941794
});
17951795

1796-
let relay_semaphores = super::RelaySemaphores::new(&shared.raw)?;
1797-
17981796
let queue = super::Queue {
17991797
raw: raw_queue,
18001798
swapchain_fn,
18011799
device: Arc::clone(&shared),
18021800
family_index,
1803-
relay_semaphores: Mutex::new(relay_semaphores),
1801+
relay_semaphore: Mutex::new(None),
18041802
};
18051803

18061804
let mem_allocator = {

wgpu-hal/src/vulkan/device.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -851,10 +851,9 @@ impl crate::Device for super::Device {
851851
unsafe { self.mem_allocator.into_inner().cleanup(&*self.shared) };
852852
unsafe { self.desc_allocator.into_inner().cleanup(&*self.shared) };
853853
unsafe {
854-
queue
855-
.relay_semaphores
856-
.into_inner()
857-
.destroy(&self.shared.raw)
854+
if let Some(semaphore) = queue.relay_semaphore.into_inner() {
855+
self.shared.raw.destroy_semaphore(semaphore, None);
856+
}
858857
};
859858
unsafe { self.shared.free_resources() };
860859
}

wgpu-hal/src/vulkan/mod.rs

Lines changed: 26 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ mod conv;
3131
mod device;
3232
mod instance;
3333

34-
use std::{borrow::Borrow, collections::HashSet, ffi::CStr, fmt, mem, num::NonZeroU32, sync::Arc};
34+
use std::{borrow::Borrow, collections::HashSet, ffi::CStr, fmt, num::NonZeroU32, sync::Arc};
3535

3636
use arrayvec::ArrayVec;
3737
use ash::{
@@ -485,70 +485,12 @@ pub struct Device {
485485
render_doc: crate::auxil::renderdoc::RenderDoc,
486486
}
487487

488-
/// Semaphores that a given submission should wait on and signal.
489-
struct RelaySemaphoreState {
490-
wait: Option<vk::Semaphore>,
491-
signal: vk::Semaphore,
492-
}
493-
494-
/// A pair of binary semaphores that are used to synchronize each submission with the next.
495-
struct RelaySemaphores {
496-
wait: vk::Semaphore,
497-
/// Signals if the wait semaphore should be waited on.
498-
///
499-
/// Because nothing will signal the semaphore for the first submission, we don't want to wait on it.
500-
should_wait: bool,
501-
signal: vk::Semaphore,
502-
}
503-
504-
impl RelaySemaphores {
505-
fn new(device: &ash::Device) -> Result<Self, crate::DeviceError> {
506-
let wait = unsafe {
507-
device
508-
.create_semaphore(&vk::SemaphoreCreateInfo::builder(), None)
509-
.map_err(crate::DeviceError::from)?
510-
};
511-
let signal = unsafe {
512-
device
513-
.create_semaphore(&vk::SemaphoreCreateInfo::builder(), None)
514-
.map_err(crate::DeviceError::from)?
515-
};
516-
Ok(Self {
517-
wait,
518-
should_wait: false,
519-
signal,
520-
})
521-
}
522-
523-
/// Advances the semaphores, returning the semaphores that should be used for a submission.
524-
#[must_use]
525-
fn advance(&mut self) -> RelaySemaphoreState {
526-
let old = RelaySemaphoreState {
527-
wait: self.should_wait.then_some(self.wait),
528-
signal: self.signal,
529-
};
530-
531-
mem::swap(&mut self.wait, &mut self.signal);
532-
self.should_wait = true;
533-
534-
old
535-
}
536-
537-
/// Destroys the semaphores.
538-
unsafe fn destroy(&self, device: &ash::Device) {
539-
unsafe {
540-
device.destroy_semaphore(self.wait, None);
541-
device.destroy_semaphore(self.signal, None);
542-
}
543-
}
544-
}
545-
546488
pub struct Queue {
547489
raw: vk::Queue,
548490
swapchain_fn: khr::Swapchain,
549491
device: Arc<DeviceShared>,
550492
family_index: u32,
551-
relay_semaphores: Mutex<RelaySemaphores>,
493+
relay_semaphore: Mutex<Option<vk::Semaphore>>,
552494
}
553495

554496
#[derive(Debug)]
@@ -928,16 +870,31 @@ impl crate::Queue for Queue {
928870
signal_values.push(!0);
929871
}
930872

931-
// In order for submissions to be strictly ordered, we encode a dependency between each submission
932-
// using a pair of semaphores. This adds a wait if it is needed, and signals the next semaphore.
933-
let semaphore_state = self.relay_semaphores.lock().advance();
934-
935-
if let Some(sem) = semaphore_state.wait {
936-
wait_stage_masks.push(vk::PipelineStageFlags::TOP_OF_PIPE);
937-
wait_semaphores.push(sem);
938-
}
873+
let signal_semaphore = match *self.relay_semaphore.lock() {
874+
Some(sem) => {
875+
// Wait for the previous submission to complete.
876+
wait_stage_masks.push(vk::PipelineStageFlags::TOP_OF_PIPE);
877+
wait_semaphores.push(sem);
878+
sem
879+
}
880+
ref mut next @ None => {
881+
// This is the first submission to this queue, so we needn't
882+
// wait for any prior submissions to complete. But we do need to
883+
// create a semaphore for this submission to signal when it's
884+
// complete.
885+
let new_sem = unsafe {
886+
self.device
887+
.raw
888+
.create_semaphore(&vk::SemaphoreCreateInfo::builder(), None)
889+
.map_err(crate::DeviceError::from)?
890+
};
891+
*next = Some(new_sem);
892+
new_sem
893+
}
894+
};
939895

940-
signal_semaphores.push(semaphore_state.signal);
896+
// This submission must signal the semaphore that the next one waits on.
897+
signal_semaphores.push(signal_semaphore);
941898
signal_values.push(!0);
942899

943900
// We need to signal our wgpu::Fence if we have one, this adds it to the signal list.

0 commit comments

Comments
 (0)