diff --git a/wgpu-core/src/resource.rs b/wgpu-core/src/resource.rs index 9c2252e665..6418053f1b 100644 --- a/wgpu-core/src/resource.rs +++ b/wgpu-core/src/resource.rs @@ -8,7 +8,10 @@ use crate::{ }, global::Global, hal_api::HalApi, - id::{AdapterId, BufferId, CommandEncoderId, DeviceId, SurfaceId, TextureId, TextureViewId}, + id::{ + AdapterId, BufferId, CommandEncoderId, DeviceId, QueueId, SurfaceId, TextureId, + TextureViewId, + }, init_tracker::{BufferInitTracker, TextureInitTracker}, lock::{rank, Mutex, RwLock}, resource_log, @@ -1388,6 +1391,21 @@ impl Global { hal_command_encoder_callback(None) } } + + /// # Safety + /// + /// - The raw queue handle must not be manually destroyed + pub unsafe fn queue_as_hal(&self, id: QueueId, hal_queue_callback: F) -> R + where + F: FnOnce(Option<&A::Queue>) -> R, + { + profiling::scope!("Queue::as_hal"); + + let queue = self.hub.queues.get(id); + let hal_queue = queue.raw().as_any().downcast_ref(); + + hal_queue_callback(hal_queue) + } } /// A texture that has been marked as destroyed and is staged for actual deletion soon. diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index fd190fc34a..61020c2a34 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -1982,6 +1982,7 @@ impl super::Adapter { device: Arc::clone(&shared), family_index, relay_semaphores: Mutex::new(relay_semaphores), + signal_semaphores: Mutex::new((Vec::new(), Vec::new())), }; let mem_allocator = { diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index 31a893e56e..b0d27a9a36 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -36,6 +36,7 @@ use std::{ ffi::{CStr, CString}, fmt, mem, num::NonZeroU32, + ops::DerefMut, sync::Arc, }; @@ -765,6 +766,7 @@ pub struct Queue { device: Arc, family_index: u32, relay_semaphores: Mutex, + signal_semaphores: Mutex<(Vec, Vec)>, } impl Drop for Queue { @@ -1216,6 +1218,15 @@ impl crate::Queue for Queue { signal_values.push(!0); } + let mut guards = self.signal_semaphores.lock(); + let (ref mut pending_signal_semaphores, ref mut pending_signal_semaphore_values) = + guards.deref_mut(); + assert!(pending_signal_semaphores.len() == pending_signal_semaphore_values.len()); + if !pending_signal_semaphores.is_empty() { + signal_semaphores.append(pending_signal_semaphores); + signal_values.append(pending_signal_semaphore_values); + } + // 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(&self.device)?; @@ -1344,6 +1355,19 @@ impl crate::Queue for Queue { } } +impl Queue { + pub fn raw_device(&self) -> &ash::Device { + &self.device.raw + } + + pub fn add_signal_semaphore(&self, semaphore: vk::Semaphore, semaphore_value: Option) { + let mut guards = self.signal_semaphores.lock(); + let (ref mut semaphores, ref mut semaphore_values) = guards.deref_mut(); + semaphores.push(semaphore); + semaphore_values.push(semaphore_value.unwrap_or(!0)); + } +} + /// Maps /// /// - VK_ERROR_OUT_OF_HOST_MEMORY