Creating a device now returns an iterator to the queues

This commit is contained in:
Pierre Krieger 2016-05-12 17:40:31 +02:00
parent 5a2ff9ce59
commit b5231385e7
5 changed files with 61 additions and 28 deletions

View File

@ -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");

View File

@ -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");

View File

@ -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

View File

@ -75,7 +75,7 @@ impl Device {
// TODO: return Arc<Queue> 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<Device>, Vec<Arc<Queue>>), DeviceCreationError>
-> Result<(Arc<Device>, QueuesIter), DeviceCreationError>
where I: IntoIterator<Item = (QueueFamily<'a>, f32)>,
L: IntoIterator<Item = &'a &'a str>
{
@ -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),
// Iterator for the produced queues.
let output_queues = QueuesIter {
next_queue: 0,
device: device.clone(),
family: family,
id: id,
dedicated_semaphore: Mutex::new(None),
})
}
}).collect();
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<Device>,
families_and_ids: SmallVec<[(u32, u32); 8]>,
}
impl Iterator for QueuesIter {
type Item = Arc<Queue>;
fn next(&mut self) -> Option<Arc<Queue>> {
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<usize>) {
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 {

View File

@ -60,13 +60,13 @@ macro_rules! gfx_dev_and_queue {
return;
}
let (device, queues) = match Device::new(&physical, &features,
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())
});
}