mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
hal/vulkan: use multiple semaphores in a relay (#2212)
This commit is contained in:
parent
f4d51451fa
commit
5f6c067815
@ -1172,15 +1172,19 @@ impl super::Adapter {
|
|||||||
render_passes: Mutex::new(Default::default()),
|
render_passes: Mutex::new(Default::default()),
|
||||||
framebuffers: Mutex::new(Default::default()),
|
framebuffers: Mutex::new(Default::default()),
|
||||||
});
|
});
|
||||||
|
let mut relay_semaphores = [vk::Semaphore::null(); 2];
|
||||||
|
for sem in relay_semaphores.iter_mut() {
|
||||||
|
*sem = shared
|
||||||
|
.raw
|
||||||
|
.create_semaphore(&vk::SemaphoreCreateInfo::builder(), None)?;
|
||||||
|
}
|
||||||
let queue = super::Queue {
|
let queue = super::Queue {
|
||||||
raw: raw_queue,
|
raw: raw_queue,
|
||||||
swapchain_fn,
|
swapchain_fn,
|
||||||
device: Arc::clone(&shared),
|
device: Arc::clone(&shared),
|
||||||
family_index,
|
family_index,
|
||||||
relay_semaphore: shared
|
relay_semaphores,
|
||||||
.raw
|
relay_index: None,
|
||||||
.create_semaphore(&vk::SemaphoreCreateInfo::builder(), None)?,
|
|
||||||
relay_active: false,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mem_allocator = {
|
let mem_allocator = {
|
||||||
|
|||||||
@ -674,9 +674,9 @@ impl crate::Device<super::Api> for super::Device {
|
|||||||
unsafe fn exit(self, queue: super::Queue) {
|
unsafe fn exit(self, queue: super::Queue) {
|
||||||
self.mem_allocator.into_inner().cleanup(&*self.shared);
|
self.mem_allocator.into_inner().cleanup(&*self.shared);
|
||||||
self.desc_allocator.into_inner().cleanup(&*self.shared);
|
self.desc_allocator.into_inner().cleanup(&*self.shared);
|
||||||
self.shared
|
for &sem in queue.relay_semaphores.iter() {
|
||||||
.raw
|
self.shared.raw.destroy_semaphore(sem, None);
|
||||||
.destroy_semaphore(queue.relay_semaphore, None);
|
}
|
||||||
self.shared.free_resources();
|
self.shared.free_resources();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -336,12 +336,13 @@ pub struct Queue {
|
|||||||
swapchain_fn: khr::Swapchain,
|
swapchain_fn: khr::Swapchain,
|
||||||
device: Arc<DeviceShared>,
|
device: Arc<DeviceShared>,
|
||||||
family_index: u32,
|
family_index: u32,
|
||||||
/// This special semaphore is used to synchronize GPU work of
|
/// We use a redundant chain of semaphores to pass on the signal
|
||||||
/// everything on a queue with... itself. Yikes!
|
/// from submissions to the last present, since it's required by the
|
||||||
/// It's required by the confusing portion of the spec to be signalled
|
/// specification.
|
||||||
/// by last submission and waited by the present.
|
/// It would be correct to use a single semaphore there, but
|
||||||
relay_semaphore: vk::Semaphore,
|
/// https://gitlab.freedesktop.org/mesa/mesa/-/issues/5508
|
||||||
relay_active: bool,
|
relay_semaphores: [vk::Semaphore; 2],
|
||||||
|
relay_index: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -567,7 +568,7 @@ impl crate::Queue<Api> for Queue {
|
|||||||
|
|
||||||
let mut fence_raw = vk::Fence::null();
|
let mut fence_raw = vk::Fence::null();
|
||||||
let mut vk_timeline_info;
|
let mut vk_timeline_info;
|
||||||
let mut semaphores = [self.relay_semaphore, vk::Semaphore::null()];
|
let mut signal_semaphores = [vk::Semaphore::null(), vk::Semaphore::null()];
|
||||||
let signal_values;
|
let signal_values;
|
||||||
|
|
||||||
if let Some((fence, value)) = signal_fence {
|
if let Some((fence, value)) = signal_fence {
|
||||||
@ -575,7 +576,7 @@ impl crate::Queue<Api> for Queue {
|
|||||||
match *fence {
|
match *fence {
|
||||||
Fence::TimelineSemaphore(raw) => {
|
Fence::TimelineSemaphore(raw) => {
|
||||||
signal_values = [!0, value];
|
signal_values = [!0, value];
|
||||||
semaphores[1] = raw;
|
signal_semaphores[1] = raw;
|
||||||
vk_timeline_info = vk::TimelineSemaphoreSubmitInfo::builder()
|
vk_timeline_info = vk::TimelineSemaphoreSubmitInfo::builder()
|
||||||
.signal_semaphore_values(&signal_values);
|
.signal_semaphore_values(&signal_values);
|
||||||
vk_info = vk_info.push_next(&mut vk_timeline_info);
|
vk_info = vk_info.push_next(&mut vk_timeline_info);
|
||||||
@ -598,18 +599,24 @@ impl crate::Queue<Api> for Queue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let wait_stage_mask = [vk::PipelineStageFlags::TOP_OF_PIPE];
|
let wait_stage_mask = [vk::PipelineStageFlags::TOP_OF_PIPE];
|
||||||
if self.relay_active {
|
let sem_index = match self.relay_index {
|
||||||
vk_info = vk_info
|
Some(old_index) => {
|
||||||
.wait_semaphores(&semaphores[..1])
|
vk_info = vk_info
|
||||||
.wait_dst_stage_mask(&wait_stage_mask);
|
.wait_semaphores(&self.relay_semaphores[old_index..old_index + 1])
|
||||||
}
|
.wait_dst_stage_mask(&wait_stage_mask);
|
||||||
self.relay_active = true;
|
(old_index + 1) % self.relay_semaphores.len()
|
||||||
let signal_count = if semaphores[1] == vk::Semaphore::null() {
|
}
|
||||||
|
None => 0,
|
||||||
|
};
|
||||||
|
self.relay_index = Some(sem_index);
|
||||||
|
signal_semaphores[0] = self.relay_semaphores[sem_index];
|
||||||
|
|
||||||
|
let signal_count = if signal_semaphores[1] == vk::Semaphore::null() {
|
||||||
1
|
1
|
||||||
} else {
|
} else {
|
||||||
2
|
2
|
||||||
};
|
};
|
||||||
vk_info = vk_info.signal_semaphores(&semaphores[..signal_count]);
|
vk_info = vk_info.signal_semaphores(&signal_semaphores[..signal_count]);
|
||||||
|
|
||||||
profiling::scope!("vkQueueSubmit");
|
profiling::scope!("vkQueueSubmit");
|
||||||
self.device
|
self.device
|
||||||
@ -627,14 +634,12 @@ impl crate::Queue<Api> for Queue {
|
|||||||
|
|
||||||
let swapchains = [ssc.raw];
|
let swapchains = [ssc.raw];
|
||||||
let image_indices = [texture.index];
|
let image_indices = [texture.index];
|
||||||
let semaphores = [self.relay_semaphore];
|
|
||||||
let mut vk_info = vk::PresentInfoKHR::builder()
|
let mut vk_info = vk::PresentInfoKHR::builder()
|
||||||
.swapchains(&swapchains)
|
.swapchains(&swapchains)
|
||||||
.image_indices(&image_indices);
|
.image_indices(&image_indices);
|
||||||
|
|
||||||
if self.relay_active {
|
if let Some(old_index) = self.relay_index.take() {
|
||||||
vk_info = vk_info.wait_semaphores(&semaphores);
|
vk_info = vk_info.wait_semaphores(&self.relay_semaphores[old_index..old_index + 1]);
|
||||||
self.relay_active = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let suboptimal = {
|
let suboptimal = {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user