From b5231385e76cce9ba9a53bf9dff744a34c7fe81c Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 12 May 2016 17:40:31 +0200 Subject: [PATCH] Creating a device now returns an iterator to the queues --- examples/src/bin/image.rs | 4 +-- examples/src/bin/teapot.rs | 4 +-- examples/src/bin/triangle.rs | 10 +++--- vulkano/src/device.rs | 65 +++++++++++++++++++++++++++--------- vulkano/src/tests.rs | 6 ++-- 5 files changed, 61 insertions(+), 28 deletions(-) diff --git a/examples/src/bin/image.rs b/examples/src/bin/image.rs index cb0337c7..2677b340 100644 --- a/examples/src/bin/image.rs +++ b/examples/src/bin/image.rs @@ -45,10 +45,10 @@ fn main() { khr_swapchain: true, .. vulkano::device::DeviceExtensions::none() }; - let (device, queues) = vulkano::device::Device::new(&physical, physical.supported_features(), + let (device, mut queues) = vulkano::device::Device::new(&physical, physical.supported_features(), &device_ext, &[], [(queue, 0.5)].iter().cloned()) .expect("failed to create device"); - let queue = queues.into_iter().next().unwrap(); + let queue = queues.next().unwrap(); let (swapchain, images) = { let caps = window.surface().get_capabilities(&physical).expect("failed to get surface capabilities"); diff --git a/examples/src/bin/teapot.rs b/examples/src/bin/teapot.rs index 6419fc64..4d6e2748 100644 --- a/examples/src/bin/teapot.rs +++ b/examples/src/bin/teapot.rs @@ -50,10 +50,10 @@ fn main() { .. vulkano::device::DeviceExtensions::none() }; - let (device, queues) = vulkano::device::Device::new(&physical, physical.supported_features(), + let (device, mut queues) = vulkano::device::Device::new(&physical, physical.supported_features(), &device_ext, None, [(queue, 0.5)].iter().cloned()) .expect("failed to create device"); - let queue = queues.into_iter().next().unwrap(); + let queue = queues.next().unwrap(); let (swapchain, images) = { let caps = window.surface().get_capabilities(&physical).expect("failed to get surface capabilities"); diff --git a/examples/src/bin/triangle.rs b/examples/src/bin/triangle.rs index 93826a46..e396ff58 100644 --- a/examples/src/bin/triangle.rs +++ b/examples/src/bin/triangle.rs @@ -141,7 +141,7 @@ fn main() { // much it should prioritize queues between one another. // // The list of created queues is returned by the function alongside with the device. - let (device, queues) = { + let (device, mut queues) = { let device_ext = vulkano::device::DeviceExtensions { khr_swapchain: true, .. vulkano::device::DeviceExtensions::none() @@ -151,10 +151,10 @@ fn main() { [(queue, 0.5)].iter().cloned()).expect("failed to create device") }; - // Since we can request multiple queues, the `queues` variable is in fact a `Vec`. In this - // example we use only one queue, so we just retreive the first and only element of the `Vec` - // and throw away the `Vec` itself. - let queue = queues.into_iter().next().unwrap(); + // Since we can request multiple queues, the `queues` variable is in fact an iterator. In this + // example we use only one queue, so we just retreive the first and only element of the + // iterator and throw it away. + let queue = queues.next().unwrap(); // Before we can draw on the surface, we have to create what is called a swapchain. Creating // a swapchain allocates the color buffers that will contain the image that will ultimately diff --git a/vulkano/src/device.rs b/vulkano/src/device.rs index 1058108b..ddcaa29f 100644 --- a/vulkano/src/device.rs +++ b/vulkano/src/device.rs @@ -75,7 +75,7 @@ impl Device { // TODO: return Arc and handle synchronization in the Queue pub fn new<'a, I, L>(phys: &'a PhysicalDevice, requested_features: &Features, extensions: &DeviceExtensions, layers: L, queue_families: I) - -> Result<(Arc, Vec>), DeviceCreationError> + -> Result<(Arc, QueuesIter), DeviceCreationError> where I: IntoIterator, f32)>, L: IntoIterator { @@ -86,7 +86,7 @@ impl Device { let vk_i = phys.instance().pointers(); // this variable will contain the queue family ID and queue ID of each requested queue - let mut output_queues: Vec<(u32, u32)> = Vec::with_capacity(queue_families.size_hint().0); + let mut output_queues: SmallVec<[(u32, u32); 8]> = SmallVec::new(); let layers = layers.into_iter().map(|&layer| { // FIXME: check whether each layer is supported @@ -195,20 +195,12 @@ impl Device { *pool_dest = Some(StdMemoryPool::new(&device)); } - // querying the queues - let output_queues = output_queues.into_iter().map(|(family, id)| { - unsafe { - let mut output = mem::uninitialized(); - device.vk.GetDeviceQueue(device.device, family, id, &mut output); - Arc::new(Queue { - queue: Mutex::new(output), - device: device.clone(), - family: family, - id: id, - dedicated_semaphore: Mutex::new(None), - }) - } - }).collect(); + // Iterator for the produced queues. + let output_queues = QueuesIter { + next_queue: 0, + device: device.clone(), + families_and_ids: output_queues, + }; Ok((device, output_queues)) } @@ -306,6 +298,47 @@ impl Drop for Device { } } +/// Iterator that returns the queues produced when creating a device. +pub struct QueuesIter { + next_queue: usize, + device: Arc, + families_and_ids: SmallVec<[(u32, u32); 8]>, +} + +impl Iterator for QueuesIter { + type Item = Arc; + + fn next(&mut self) -> Option> { + unsafe { + let &(family, id) = match self.families_and_ids.get(self.next_queue) { + Some(a) => a, + None => return None + }; + + self.next_queue += 1; + + let mut output = mem::uninitialized(); + self.device.vk.GetDeviceQueue(self.device.device, family, id, &mut output); + + Some(Arc::new(Queue { + queue: Mutex::new(output), + device: self.device.clone(), + family: family, + id: id, + dedicated_semaphore: Mutex::new(None), + })) + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let len = self.families_and_ids.len().saturating_sub(self.next_queue); + (len, Some(len)) + } +} + +impl ExactSizeIterator for QueuesIter {} + /// Error that can be returned when creating a device. #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum DeviceCreationError { diff --git a/vulkano/src/tests.rs b/vulkano/src/tests.rs index 84338dd1..68f41880 100644 --- a/vulkano/src/tests.rs +++ b/vulkano/src/tests.rs @@ -60,13 +60,13 @@ macro_rules! gfx_dev_and_queue { return; } - let (device, queues) = match Device::new(&physical, &features, - &extensions, None, [(queue, 0.5)].iter().cloned()) + let (device, mut queues) = match Device::new(&physical, &features, + &extensions, None, [(queue, 0.5)].iter().cloned()) { Ok(r) => r, Err(_) => return }; - (device, queues.into_iter().next().unwrap()) + (device, queues.next().unwrap()) }); }