From cd8f2d5fc38ef5e10824e97c1a14da65bde1f9f7 Mon Sep 17 00:00:00 2001 From: Rua Date: Thu, 10 Oct 2024 15:54:48 +0200 Subject: [PATCH 1/2] Add a transfer queue to `VulkanoContext` --- vulkano-util/src/context.rs | 95 +++++++++++++++++++++++++++---------- 1 file changed, 69 insertions(+), 26 deletions(-) diff --git a/vulkano-util/src/context.rs b/vulkano-util/src/context.rs index 28dfbcab17..70e93af793 100644 --- a/vulkano-util/src/context.rs +++ b/vulkano-util/src/context.rs @@ -95,6 +95,7 @@ pub struct VulkanoContext { device: Arc, graphics_queue: Arc, compute_queue: Arc, + transfer_queue: Option>, memory_allocator: Arc, } @@ -166,13 +167,18 @@ impl VulkanoContext { } // Create device - let (device, graphics_queue, compute_queue) = Self::create_device( + let (device, queues) = Self::create_device( physical_device, config.device_extensions, config.device_features, ); let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone())); + let Queues { + graphics_queue, + compute_queue, + transfer_queue, + } = queues; Self { instance, @@ -180,6 +186,7 @@ impl VulkanoContext { device, graphics_queue, compute_queue, + transfer_queue, memory_allocator, } } @@ -190,7 +197,7 @@ impl VulkanoContext { physical_device: Arc, device_extensions: DeviceExtensions, device_features: DeviceFeatures, - ) -> (Arc, Arc, Arc) { + ) -> (Arc, Queues) { let queue_family_graphics = physical_device .queue_family_properties() .iter() @@ -209,25 +216,37 @@ impl VulkanoContext { q.queue_flags.intersects(QueueFlags::COMPUTE) && *i != queue_family_graphics }) .map(|(i, _)| i); - let is_separate_compute_queue = queue_family_compute.is_some(); + // Try finding a separate queue for transfer + let queue_family_transfer = physical_device + .queue_family_properties() + .iter() + .enumerate() + .map(|(i, q)| (i as u32, q)) + .find(|(_i, q)| { + q.queue_flags.intersects(QueueFlags::TRANSFER) + && !q + .queue_flags + .intersects(QueueFlags::GRAPHICS | QueueFlags::COMPUTE) + }) + .map(|(i, _)| i); - let queue_create_infos = if let Some(queue_family_compute) = queue_family_compute { - vec![ - QueueCreateInfo { - queue_family_index: queue_family_graphics, - ..Default::default() - }, - QueueCreateInfo { - queue_family_index: queue_family_compute, - ..Default::default() - }, - ] - } else { - vec![QueueCreateInfo { + let queue_create_infos: Vec<_> = [ + Some(QueueCreateInfo { queue_family_index: queue_family_graphics, ..Default::default() - }] - }; + }), + queue_family_compute.map(|queue_family_index| QueueCreateInfo { + queue_family_index, + ..Default::default() + }), + queue_family_transfer.map(|queue_family_index| QueueCreateInfo { + queue_family_index, + ..Default::default() + }), + ] + .into_iter() + .flatten() + .collect(); let (device, mut queues) = { Device::new( @@ -241,13 +260,24 @@ impl VulkanoContext { ) .expect("failed to create device") }; - let gfx_queue = queues.next().unwrap(); - let compute_queue = if is_separate_compute_queue { - queues.next().unwrap() - } else { - gfx_queue.clone() - }; - (device, gfx_queue, compute_queue) + + let graphics_queue = queues.next().unwrap(); + let compute_queue = queue_family_compute + .is_some() + .then(|| queues.next().unwrap()) + .unwrap_or(graphics_queue.clone()); + let transfer_queue = queue_family_transfer + .is_some() + .then(|| queues.next().unwrap()); + + ( + device, + Queues { + graphics_queue, + compute_queue, + transfer_queue, + }, + ) } /// Returns the name of the device. @@ -291,15 +321,28 @@ impl VulkanoContext { /// Returns the compute queue. /// - /// Depending on your device, this might be the same as graphics queue. + /// Depending on your device, this might be the same as the graphics queue. #[inline] pub fn compute_queue(&self) -> &Arc { &self.compute_queue } + /// Returns the transfer queue, if the device has a queue family that is dedicated for + /// transfers (does not support graphics or compute). + #[inline] + pub fn transfer_queue(&self) -> Option<&Arc> { + self.transfer_queue.as_ref() + } + /// Returns the memory allocator. #[inline] pub fn memory_allocator(&self) -> &Arc { &self.memory_allocator } } + +struct Queues { + graphics_queue: Arc, + compute_queue: Arc, + transfer_queue: Option>, +} From e21c9d23b262985125966a9eb6ed6e544727fb33 Mon Sep 17 00:00:00 2001 From: Rua Date: Thu, 10 Oct 2024 15:58:15 +0200 Subject: [PATCH 2/2] Might as well --- vulkano-util/src/context.rs | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/vulkano-util/src/context.rs b/vulkano-util/src/context.rs index 70e93af793..a99610da35 100644 --- a/vulkano-util/src/context.rs +++ b/vulkano-util/src/context.rs @@ -93,9 +93,7 @@ pub struct VulkanoContext { instance: Arc, _debug_utils_messenger: Option, device: Arc, - graphics_queue: Arc, - compute_queue: Arc, - transfer_queue: Option>, + queues: Queues, memory_allocator: Arc, } @@ -172,21 +170,13 @@ impl VulkanoContext { config.device_extensions, config.device_features, ); - let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone())); - let Queues { - graphics_queue, - compute_queue, - transfer_queue, - } = queues; Self { instance, _debug_utils_messenger, device, - graphics_queue, - compute_queue, - transfer_queue, + queues, memory_allocator, } } @@ -316,7 +306,7 @@ impl VulkanoContext { /// Returns the graphics queue. #[inline] pub fn graphics_queue(&self) -> &Arc { - &self.graphics_queue + &self.queues.graphics_queue } /// Returns the compute queue. @@ -324,14 +314,14 @@ impl VulkanoContext { /// Depending on your device, this might be the same as the graphics queue. #[inline] pub fn compute_queue(&self) -> &Arc { - &self.compute_queue + &self.queues.compute_queue } /// Returns the transfer queue, if the device has a queue family that is dedicated for /// transfers (does not support graphics or compute). #[inline] pub fn transfer_queue(&self) -> Option<&Arc> { - self.transfer_queue.as_ref() + self.queues.transfer_queue.as_ref() } /// Returns the memory allocator.