mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-25 16:25:31 +00:00
Make PhysicalDevice
an independent object (#1967)
* Better validation and errors * Small fix * Make `PhysicalDevice` an independent object Co-authored-by: Austin Johnson <me@austinj.work>
This commit is contained in:
parent
b06b29afd2
commit
4abc27b9e5
@ -18,8 +18,7 @@ use vulkano::{
|
||||
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage},
|
||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
instance::{Instance, InstanceCreateInfo},
|
||||
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
||||
@ -45,14 +44,17 @@ fn main() {
|
||||
khr_storage_buffer_storage_class: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
// The Vulkan specs guarantee that a compliant implementation must provide at least one queue
|
||||
// that supports compute operations.
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_compute())
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.position(|q| q.queue_flags.compute)
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -75,7 +77,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -170,7 +175,7 @@ fn main() {
|
||||
// In order to execute our operation, we have to build a command buffer.
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -30,8 +30,7 @@ use vulkano::{
|
||||
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
||||
},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
||||
impl_vertex,
|
||||
@ -88,12 +87,18 @@ fn main() {
|
||||
khr_swapchain: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -115,7 +120,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -124,11 +132,13 @@ fn main() {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (mut swapchain, images) = {
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
@ -320,7 +330,7 @@ fn main() {
|
||||
let buffer = buffer_pool.chunk(data.to_vec()).unwrap();
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -14,8 +14,7 @@ use vulkano::{
|
||||
RenderPassBeginInfo, SubpassContents,
|
||||
},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
image::{view::ImageView, ImageUsage, SwapchainImage},
|
||||
instance::{Instance, InstanceCreateInfo},
|
||||
@ -59,12 +58,18 @@ fn main() {
|
||||
khr_swapchain: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -86,7 +91,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -94,11 +102,13 @@ fn main() {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (mut swapchain, images) = {
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
@ -203,7 +213,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -10,8 +10,7 @@
|
||||
use std::sync::Arc;
|
||||
use vulkano::{
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
format::Format,
|
||||
image::{ImageDimensions, ImmutableImage, MipmapsCount},
|
||||
@ -144,12 +143,13 @@ fn main() {
|
||||
let device_extensions = DeviceExtensions {
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.map(|p| {
|
||||
p.queue_families()
|
||||
.next()
|
||||
.map(|q| (p, q))
|
||||
(!p.queue_family_properties().is_empty())
|
||||
.then_some((p, 0))
|
||||
.expect("couldn't find a queue family")
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
@ -166,7 +166,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
|
@ -138,7 +138,7 @@ impl AmbientLightingSystem {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::secondary(
|
||||
self.gfx_queue.device().clone(),
|
||||
self.gfx_queue.family(),
|
||||
self.gfx_queue.queue_family_index(),
|
||||
CommandBufferUsage::MultipleSubmit,
|
||||
CommandBufferInheritanceInfo {
|
||||
render_pass: Some(self.subpass.clone().into()),
|
||||
|
@ -152,7 +152,7 @@ impl DirectionalLightingSystem {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::secondary(
|
||||
self.gfx_queue.device().clone(),
|
||||
self.gfx_queue.family(),
|
||||
self.gfx_queue.queue_family_index(),
|
||||
CommandBufferUsage::MultipleSubmit,
|
||||
CommandBufferInheritanceInfo {
|
||||
render_pass: Some(self.subpass.clone().into()),
|
||||
|
@ -165,7 +165,7 @@ impl PointLightingSystem {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::secondary(
|
||||
self.gfx_queue.device().clone(),
|
||||
self.gfx_queue.family(),
|
||||
self.gfx_queue.queue_family_index(),
|
||||
CommandBufferUsage::MultipleSubmit,
|
||||
CommandBufferInheritanceInfo {
|
||||
render_pass: Some(self.subpass.clone().into()),
|
||||
|
@ -305,7 +305,7 @@ impl FrameSystem {
|
||||
// Start the command buffer builder that will be filled throughout the frame handling.
|
||||
let mut command_buffer_builder = AutoCommandBufferBuilder::primary(
|
||||
self.gfx_queue.device().clone(),
|
||||
self.gfx_queue.family(),
|
||||
self.gfx_queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -32,8 +32,7 @@ use crate::{
|
||||
use cgmath::{Matrix4, SquareMatrix, Vector3};
|
||||
use vulkano::{
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
image::{view::ImageView, ImageUsage},
|
||||
instance::{Instance, InstanceCreateInfo},
|
||||
@ -78,12 +77,18 @@ fn main() {
|
||||
khr_swapchain: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -105,7 +110,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -113,11 +121,13 @@ fn main() {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (mut swapchain, mut images) = {
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
|
@ -91,7 +91,7 @@ impl TriangleDrawSystem {
|
||||
pub fn draw(&self, viewport_dimensions: [u32; 2]) -> SecondaryAutoCommandBuffer {
|
||||
let mut builder = AutoCommandBufferBuilder::secondary(
|
||||
self.gfx_queue.device().clone(),
|
||||
self.gfx_queue.family(),
|
||||
self.gfx_queue.queue_family_index(),
|
||||
CommandBufferUsage::MultipleSubmit,
|
||||
CommandBufferInheritanceInfo {
|
||||
render_pass: Some(self.subpass.clone().into()),
|
||||
|
@ -22,8 +22,7 @@ use vulkano::{
|
||||
layout::DescriptorType, DescriptorSet, PersistentDescriptorSet, WriteDescriptorSet,
|
||||
},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
instance::{Instance, InstanceCreateInfo},
|
||||
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
||||
@ -47,12 +46,15 @@ fn main() {
|
||||
khr_storage_buffer_storage_class: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_compute())
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.position(|q| q.queue_flags.compute)
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -74,7 +76,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -187,7 +192,7 @@ fn main() {
|
||||
// Build the command buffer, using different offsets for each call.
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -20,8 +20,7 @@ use vulkano::{
|
||||
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, CopyImageToBufferInfo},
|
||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
format::Format,
|
||||
image::{view::ImageView, ImageDimensions, StorageImage},
|
||||
@ -53,12 +52,15 @@ fn main() {
|
||||
let device_extensions = DeviceExtensions {
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_compute())
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.position(|q| q.queue_flags.compute)
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -80,7 +82,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -152,7 +157,7 @@ fn main() {
|
||||
// In this case we can find appropriate value in this table: https://vulkan.gpuinfo.org/
|
||||
// or just use fallback constant for simplicity, but failure to set proper
|
||||
// local size can lead to significant performance penalty.
|
||||
let (local_size_x, local_size_y) = match physical_device.properties().subgroup_size {
|
||||
let (local_size_x, local_size_y) = match device.physical_device().properties().subgroup_size {
|
||||
Some(subgroup_size) => {
|
||||
println!("Subgroup size is {}", subgroup_size);
|
||||
|
||||
@ -196,7 +201,7 @@ fn main() {
|
||||
array_layers: 1,
|
||||
},
|
||||
Format::R8G8B8A8_UNORM,
|
||||
Some(queue.family()),
|
||||
Some(queue.queue_family_index()),
|
||||
)
|
||||
.unwrap();
|
||||
let view = ImageView::new_default(image.clone()).unwrap();
|
||||
@ -219,7 +224,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -20,8 +20,8 @@ mod linux {
|
||||
},
|
||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, Queue, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, Queue,
|
||||
QueueCreateInfo,
|
||||
},
|
||||
format::Format,
|
||||
image::{view::ImageView, ImageCreateFlags, ImageUsage, StorageImage, SwapchainImage},
|
||||
@ -108,7 +108,7 @@ mod linux {
|
||||
mutable_format: true,
|
||||
..ImageCreateFlags::empty()
|
||||
},
|
||||
[queue.family()],
|
||||
[queue.queue_family_index()],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@ -303,7 +303,7 @@ mod linux {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
@ -440,14 +440,19 @@ mod linux {
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| {
|
||||
q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false)
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.graphics
|
||||
&& p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
.map(|q| (p, q))
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.filter(|(p, _)| p.properties().driver_uuid.unwrap() == display.driver_uuid().unwrap())
|
||||
.filter(|(p, _)| {
|
||||
@ -476,7 +481,10 @@ mod linux {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -485,11 +493,13 @@ mod linux {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (swapchain, images) = {
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
|
@ -18,8 +18,7 @@ use vulkano::{
|
||||
},
|
||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
format::Format,
|
||||
image::{
|
||||
@ -78,12 +77,18 @@ fn main() {
|
||||
khr_swapchain: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -105,7 +110,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -113,11 +121,13 @@ fn main() {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (mut swapchain, images) = {
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
@ -216,7 +226,7 @@ fn main() {
|
||||
device.clone(),
|
||||
dimensions,
|
||||
Format::R8G8B8A8_UNORM,
|
||||
[queue.family()],
|
||||
[queue.queue_family_index()],
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@ -233,7 +243,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
@ -396,7 +406,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -16,8 +16,7 @@ use vulkano::{
|
||||
},
|
||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
format::Format,
|
||||
image::{
|
||||
@ -76,12 +75,18 @@ fn main() {
|
||||
khr_swapchain: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -103,7 +108,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -111,11 +119,13 @@ fn main() {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (mut swapchain, images) = {
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
@ -313,7 +323,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -25,8 +25,7 @@ use vulkano::{
|
||||
},
|
||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
format::Format,
|
||||
image::{
|
||||
@ -82,12 +81,18 @@ fn main() {
|
||||
khr_swapchain: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -109,7 +114,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -117,11 +125,13 @@ fn main() {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (mut swapchain, images) = {
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
@ -324,7 +334,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -34,8 +34,7 @@ use vulkano::{
|
||||
},
|
||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
||||
impl_vertex,
|
||||
@ -96,12 +95,18 @@ fn main() {
|
||||
khr_storage_buffer_storage_class: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -123,7 +128,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -132,11 +140,13 @@ fn main() {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (mut swapchain, images) = {
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
@ -389,7 +399,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -20,8 +20,7 @@ use vulkano::{
|
||||
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
||||
},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
||||
impl_vertex,
|
||||
@ -94,12 +93,18 @@ fn main() {
|
||||
khr_swapchain: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -121,7 +126,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -130,11 +138,13 @@ fn main() {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (mut swapchain, images) = {
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
@ -361,7 +371,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -118,7 +118,7 @@ impl FractalComputePipeline {
|
||||
.unwrap();
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
self.queue.device().clone(),
|
||||
self.queue.family(),
|
||||
self.queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -155,7 +155,7 @@ impl PixelsDrawPipeline {
|
||||
) -> SecondaryAutoCommandBuffer {
|
||||
let mut builder = AutoCommandBufferBuilder::secondary(
|
||||
self.gfx_queue.device().clone(),
|
||||
self.gfx_queue.family(),
|
||||
self.gfx_queue.queue_family_index(),
|
||||
CommandBufferUsage::MultipleSubmit,
|
||||
CommandBufferInheritanceInfo {
|
||||
render_pass: Some(self.subpass.clone().into()),
|
||||
|
@ -79,7 +79,7 @@ impl RenderPassPlaceOverFrame {
|
||||
// Create primary command buffer builder
|
||||
let mut command_buffer_builder = AutoCommandBufferBuilder::primary(
|
||||
self.gfx_queue.device().clone(),
|
||||
self.gfx_queue.family(),
|
||||
self.gfx_queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -73,8 +73,7 @@ use vulkano::{
|
||||
RenderPassBeginInfo, SubpassContents,
|
||||
},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
format::Format,
|
||||
image::{view::ImageView, AttachmentImage, ImageDimensions, SampleCount, StorageImage},
|
||||
@ -112,12 +111,15 @@ fn main() {
|
||||
khr_swapchain: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics())
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.position(|q| q.queue_flags.graphics)
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -139,7 +141,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -170,7 +175,7 @@ fn main() {
|
||||
array_layers: 1,
|
||||
},
|
||||
Format::R8G8B8A8_UNORM,
|
||||
Some(queue.family()),
|
||||
Some(queue.queue_family_index()),
|
||||
)
|
||||
.unwrap();
|
||||
let view = ImageView::new_default(image.clone()).unwrap();
|
||||
@ -322,7 +327,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device,
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -24,8 +24,7 @@ use vulkano::{
|
||||
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
||||
},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
||||
impl_vertex,
|
||||
@ -94,14 +93,19 @@ fn main() {
|
||||
khr_swapchain: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| {
|
||||
q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false)
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.graphics
|
||||
&& p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
.map(|q| (p, q))
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -123,19 +127,21 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
(
|
||||
device,
|
||||
queues.next().unwrap(),
|
||||
physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
(device, queues.next().unwrap(), surface_capabilities)
|
||||
};
|
||||
|
||||
// The swapchain and framebuffer images for this perticular window
|
||||
@ -410,7 +416,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -112,7 +112,7 @@ impl GameOfLifeComputePipeline {
|
||||
) -> Box<dyn GpuFuture> {
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
self.compute_queue.device().clone(),
|
||||
self.compute_queue.family(),
|
||||
self.compute_queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -155,7 +155,7 @@ impl PixelsDrawPipeline {
|
||||
) -> SecondaryAutoCommandBuffer {
|
||||
let mut builder = AutoCommandBufferBuilder::secondary(
|
||||
self.gfx_queue.device().clone(),
|
||||
self.gfx_queue.family(),
|
||||
self.gfx_queue.queue_family_index(),
|
||||
CommandBufferUsage::MultipleSubmit,
|
||||
CommandBufferInheritanceInfo {
|
||||
render_pass: Some(self.subpass.clone().into()),
|
||||
|
@ -79,7 +79,7 @@ impl RenderPassPlaceOverFrame {
|
||||
// Create primary command buffer builder
|
||||
let mut command_buffer_builder = AutoCommandBufferBuilder::primary(
|
||||
self.gfx_queue.device().clone(),
|
||||
self.gfx_queue.family(),
|
||||
self.gfx_queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -22,8 +22,8 @@ use vulkano::{
|
||||
RenderPassBeginInfo, SubpassContents,
|
||||
},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, Features, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, Features,
|
||||
QueueCreateInfo,
|
||||
},
|
||||
format::Format,
|
||||
image::{
|
||||
@ -73,14 +73,14 @@ fn main() {
|
||||
multiview: true,
|
||||
..Features::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| {
|
||||
let (physical_device, queue_family_index) = instance.enumerate_physical_devices().unwrap()
|
||||
.filter(|p| {
|
||||
p.supported_extensions().contains(&device_extensions)
|
||||
})
|
||||
.filter(|&p| {
|
||||
.filter(|p| {
|
||||
p.supported_features().contains(&features)
|
||||
})
|
||||
.filter(|&p| {
|
||||
.filter(|p| {
|
||||
// This example renders to two layers of the framebuffer using the multiview
|
||||
// extension so we check that at least two views are supported by the device.
|
||||
// Not checking this on a device that doesn't support two views
|
||||
@ -90,9 +90,10 @@ fn main() {
|
||||
p.properties().max_multiview_view_count.unwrap_or(0) >= 2
|
||||
})
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics())
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.position(|q| q.queue_flags.graphics)
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -117,7 +118,10 @@ fn main() {
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
enabled_features: features,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -139,7 +143,7 @@ fn main() {
|
||||
..ImageUsage::empty()
|
||||
},
|
||||
ImageCreateFlags::empty(),
|
||||
Some(queue_family),
|
||||
Some(queue.queue_family_index()),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@ -291,7 +295,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue_family,
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -19,8 +19,8 @@ use vulkano::{
|
||||
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
||||
},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, DeviceOwned, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, DeviceOwned,
|
||||
QueueCreateInfo,
|
||||
},
|
||||
format::Format,
|
||||
image::{view::ImageView, AttachmentImage, ImageAccess, ImageUsage, SwapchainImage},
|
||||
@ -73,12 +73,18 @@ fn main() {
|
||||
khr_swapchain: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -100,7 +106,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -108,11 +117,13 @@ fn main() {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (mut swapchain, images) = {
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
@ -367,7 +378,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -33,8 +33,7 @@ use std::{
|
||||
};
|
||||
use vulkano::{
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
instance::{Instance, InstanceCreateInfo},
|
||||
pipeline::{cache::PipelineCache, ComputePipeline},
|
||||
@ -59,12 +58,15 @@ fn main() {
|
||||
khr_storage_buffer_storage_class: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_compute())
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.position(|q| q.queue_flags.compute)
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -87,7 +89,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
|
@ -17,8 +17,7 @@ use vulkano::{
|
||||
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage},
|
||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
instance::{Instance, InstanceCreateInfo},
|
||||
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
||||
@ -42,12 +41,15 @@ fn main() {
|
||||
khr_storage_buffer_storage_class: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_compute())
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.position(|q| q.queue_flags.compute)
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -69,7 +71,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -155,7 +160,7 @@ fn main() {
|
||||
// So be careful to only pass an instance of the struct generated by the `vulkano_shaders::shaders!` macro.
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -16,8 +16,7 @@ use vulkano::{
|
||||
},
|
||||
descriptor_set::WriteDescriptorSet,
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
format::Format,
|
||||
image::{
|
||||
@ -74,12 +73,18 @@ fn main() {
|
||||
khr_push_descriptor: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -101,7 +106,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -109,11 +117,13 @@ fn main() {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (mut swapchain, images) = {
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
@ -309,7 +319,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -27,8 +27,7 @@ use vulkano::{
|
||||
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
||||
},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
||||
impl_vertex,
|
||||
@ -89,12 +88,18 @@ fn main() {
|
||||
khr_swapchain: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -116,7 +121,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -124,11 +132,13 @@ fn main() {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (mut swapchain, images) = {
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
@ -298,7 +308,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::MultipleSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -21,8 +21,8 @@ use vulkano::{
|
||||
PersistentDescriptorSet, WriteDescriptorSet,
|
||||
},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, Features, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, Features,
|
||||
QueueCreateInfo,
|
||||
},
|
||||
format::Format,
|
||||
image::{
|
||||
@ -81,12 +81,18 @@ fn main() {
|
||||
khr_swapchain: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -115,7 +121,10 @@ fn main() {
|
||||
descriptor_binding_variable_descriptor_count: true,
|
||||
..Features::empty()
|
||||
},
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -123,11 +132,13 @@ fn main() {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (mut swapchain, images) = {
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
@ -446,7 +457,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -17,8 +17,7 @@ use vulkano::{
|
||||
},
|
||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
instance::{Instance, InstanceCreateInfo},
|
||||
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
||||
@ -42,12 +41,15 @@ fn main() {
|
||||
khr_storage_buffer_storage_class: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_compute())
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.position(|q| q.queue_flags.compute)
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -69,7 +71,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -134,7 +139,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -16,8 +16,7 @@ use vulkano::{
|
||||
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage},
|
||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
instance::{Instance, InstanceCreateInfo},
|
||||
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
||||
@ -41,12 +40,15 @@ fn main() {
|
||||
khr_storage_buffer_storage_class: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_compute())
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.position(|q| q.queue_flags.compute)
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -68,7 +70,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -138,7 +143,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -33,8 +33,8 @@ use vulkano::{
|
||||
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage},
|
||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, Queue, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, Queue,
|
||||
QueueCreateInfo,
|
||||
},
|
||||
instance::{Instance, InstanceCreateInfo},
|
||||
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
||||
@ -58,12 +58,15 @@ fn main() {
|
||||
khr_storage_buffer_storage_class: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_compute())
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.position(|q| q.queue_flags.compute)
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -85,7 +88,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -198,7 +204,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
queue.device().clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -23,8 +23,7 @@ use vulkano::{
|
||||
},
|
||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
image::{view::ImageView, ImageUsage},
|
||||
impl_vertex,
|
||||
@ -82,12 +81,18 @@ fn main() {
|
||||
khr_swapchain: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -108,7 +113,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -116,12 +124,14 @@ fn main() {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (swapchain, images) = {
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
@ -348,14 +358,14 @@ fn main() {
|
||||
vertex_buffer: true,
|
||||
..BufferUsage::empty()
|
||||
}, // Specify use as a storage buffer, vertex buffer, and transfer destination.
|
||||
device.active_queue_families(),
|
||||
device.active_queue_family_indices().iter().copied(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Create one-time command to copy between the buffers.
|
||||
let mut cbb = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
@ -486,7 +496,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -14,8 +14,7 @@ use vulkano::{
|
||||
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage},
|
||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
instance::{Instance, InstanceCreateInfo},
|
||||
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
||||
@ -39,12 +38,15 @@ fn main() {
|
||||
khr_storage_buffer_storage_class: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_compute())
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.position(|q| q.queue_flags.compute)
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -66,7 +68,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -139,7 +144,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -17,8 +17,7 @@ use vulkano::{
|
||||
},
|
||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
format::Format,
|
||||
image::{view::ImageView, AttachmentImage, ImageAccess, ImageUsage, SwapchainImage},
|
||||
@ -73,12 +72,18 @@ fn main() {
|
||||
khr_swapchain: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -100,7 +105,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -109,11 +117,13 @@ fn main() {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (mut swapchain, images) = {
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
@ -313,7 +323,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -26,8 +26,8 @@ use vulkano::{
|
||||
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
||||
},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, Features, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, Features,
|
||||
QueueCreateInfo,
|
||||
},
|
||||
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
||||
impl_vertex,
|
||||
@ -179,13 +179,19 @@ fn main() {
|
||||
fill_mode_non_solid: true,
|
||||
..Features::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter(|&p| p.supported_features().contains(&features))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter(|p| p.supported_features().contains(&features))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -208,7 +214,10 @@ fn main() {
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
enabled_features: features,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -216,11 +225,13 @@ fn main() {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (mut swapchain, images) = {
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
@ -404,7 +415,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -16,8 +16,7 @@ use vulkano::{
|
||||
},
|
||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
format::Format,
|
||||
image::{
|
||||
@ -78,12 +77,18 @@ fn main() {
|
||||
khr_swapchain: true,
|
||||
..DeviceExtensions::empty()
|
||||
};
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||
PhysicalDeviceType::DiscreteGpu => 0,
|
||||
@ -105,7 +110,10 @@ fn main() {
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -113,11 +121,13 @@ fn main() {
|
||||
let queue = queues.next().unwrap();
|
||||
|
||||
let (mut swapchain, images) = {
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
@ -314,7 +324,7 @@ fn main() {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -29,8 +29,8 @@ use vulkano::{
|
||||
AutoCommandBufferBuilder, CommandBufferUsage, RenderingAttachmentInfo, RenderingInfo,
|
||||
},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, Features, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, Features,
|
||||
QueueCreateInfo,
|
||||
},
|
||||
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
||||
impl_vertex,
|
||||
@ -106,12 +106,14 @@ fn main() {
|
||||
|
||||
// We then choose which physical device to use. First, we enumerate all the available physical
|
||||
// devices, then apply filters to narrow them down to those that can support our needs.
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| {
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| {
|
||||
// For this example, we require at least Vulkan 1.3.
|
||||
p.api_version() >= Version::V1_3
|
||||
})
|
||||
.filter(|&p| {
|
||||
.filter(|p| {
|
||||
// Some devices may not support the extensions or features that your application, or
|
||||
// report properties and limits that are not sufficient for your application. These
|
||||
// should be filtered out here.
|
||||
@ -130,17 +132,19 @@ fn main() {
|
||||
// real-life application, you may want to use a separate dedicated transfer queue to
|
||||
// handle data transfers in parallel with graphics operations. You may also need a
|
||||
// separate queue for compute operations, if your application uses those.
|
||||
p.queue_families()
|
||||
.find(|&q| {
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
// We select a queue family that supports graphics operations. When drawing to
|
||||
// a window surface, as we do in this example, we also need to check that queues
|
||||
// in this queue family are capable of presenting images to the surface.
|
||||
q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false)
|
||||
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
// The code here searches for the first queue family that is suitable. If none is
|
||||
// found, `None` is returned to `filter_map`, which disqualifies this physical
|
||||
// device.
|
||||
.map(|q| (p, q))
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
// All the physical devices that pass the filters above are suitable for the application.
|
||||
// However, not every device is equal, some are preferred over others. Now, we assign
|
||||
@ -194,7 +198,10 @@ fn main() {
|
||||
|
||||
// The list of queues that we are going to use. Here we only use one queue, from the
|
||||
// previously chosen queue family.
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
|
||||
..Default::default()
|
||||
},
|
||||
@ -212,13 +219,15 @@ fn main() {
|
||||
let (mut swapchain, images) = {
|
||||
// Querying the capabilities of the surface. When we create the swapchain we can only
|
||||
// pass values that are allowed by the capabilities.
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
|
||||
// Choosing the internal format that the images will have.
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
@ -497,7 +506,7 @@ fn main() {
|
||||
// buffer will only be executable on that given queue family.
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -24,8 +24,7 @@ use vulkano::{
|
||||
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
||||
},
|
||||
device::{
|
||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
||||
impl_vertex,
|
||||
@ -100,8 +99,10 @@ fn main() {
|
||||
|
||||
// We then choose which physical device to use. First, we enumerate all the available physical
|
||||
// devices, then apply filters to narrow them down to those that can support our needs.
|
||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| {
|
||||
let (physical_device, queue_family_index) = instance
|
||||
.enumerate_physical_devices()
|
||||
.unwrap()
|
||||
.filter(|p| {
|
||||
// Some devices may not support the extensions or features that your application, or
|
||||
// report properties and limits that are not sufficient for your application. These
|
||||
// should be filtered out here.
|
||||
@ -120,17 +121,19 @@ fn main() {
|
||||
// real-life application, you may want to use a separate dedicated transfer queue to
|
||||
// handle data transfers in parallel with graphics operations. You may also need a
|
||||
// separate queue for compute operations, if your application uses those.
|
||||
p.queue_families()
|
||||
.find(|&q| {
|
||||
p.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.position(|(i, q)| {
|
||||
// We select a queue family that supports graphics operations. When drawing to
|
||||
// a window surface, as we do in this example, we also need to check that queues
|
||||
// in this queue family are capable of presenting images to the surface.
|
||||
q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false)
|
||||
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||
})
|
||||
// The code here searches for the first queue family that is suitable. If none is
|
||||
// found, `None` is returned to `filter_map`, which disqualifies this physical
|
||||
// device.
|
||||
.map(|q| (p, q))
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
// All the physical devices that pass the filters above are suitable for the application.
|
||||
// However, not every device is equal, some are preferred over others. Now, we assign
|
||||
@ -175,7 +178,10 @@ fn main() {
|
||||
|
||||
// The list of queues that we are going to use. Here we only use one queue, from the
|
||||
// previously chosen queue family.
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
|
||||
..Default::default()
|
||||
},
|
||||
@ -193,13 +199,15 @@ fn main() {
|
||||
let (mut swapchain, images) = {
|
||||
// Querying the capabilities of the surface. When we create the swapchain we can only
|
||||
// pass values that are allowed by the capabilities.
|
||||
let surface_capabilities = physical_device
|
||||
let surface_capabilities = device
|
||||
.physical_device()
|
||||
.surface_capabilities(&surface, Default::default())
|
||||
.unwrap();
|
||||
|
||||
// Choosing the internal format that the images will have.
|
||||
let image_format = Some(
|
||||
physical_device
|
||||
device
|
||||
.physical_device()
|
||||
.surface_formats(&surface, Default::default())
|
||||
.unwrap()[0]
|
||||
.0,
|
||||
@ -515,7 +523,7 @@ fn main() {
|
||||
// buffer will only be executable on that given queue family.
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -149,7 +149,9 @@ impl VulkanoContext {
|
||||
});
|
||||
|
||||
// Get prioritized device
|
||||
let physical_device = PhysicalDevice::enumerate(&instance)
|
||||
let physical_device = instance
|
||||
.enumerate_physical_devices()
|
||||
.expect("Failed to enumerate physical devices")
|
||||
.filter(|p| (config.device_filter_fn)(p))
|
||||
.min_by_key(|p| (config.device_priority_fn)(p))
|
||||
.expect("Failed to create physical device");
|
||||
@ -181,34 +183,49 @@ impl VulkanoContext {
|
||||
/// Creates vulkano device with required queue families and required extensions. Creates a
|
||||
/// separate queue for compute if possible. If not, same queue as graphics is used.
|
||||
fn create_device(
|
||||
physical: PhysicalDevice,
|
||||
physical_device: Arc<PhysicalDevice>,
|
||||
device_extensions: DeviceExtensions,
|
||||
features: Features,
|
||||
) -> (Arc<Device>, Arc<Queue>, Arc<Queue>) {
|
||||
let (gfx_index, queue_family_graphics) = physical
|
||||
.queue_families()
|
||||
let queue_family_graphics = physical_device
|
||||
.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|&(_i, q)| q.supports_graphics())
|
||||
.map(|(i, q)| (i as u32, q))
|
||||
.find(|(_i, q)| q.queue_flags.graphics)
|
||||
.map(|(i, _)| i)
|
||||
.expect("Could not find a queue that supports graphics");
|
||||
// Try finding a separate queue for compute
|
||||
let compute_family_data = physical
|
||||
.queue_families()
|
||||
let queue_family_compute = physical_device
|
||||
.queue_family_properties()
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|&(i, q)| q.supports_compute() && i != gfx_index);
|
||||
.map(|(i, q)| (i as u32, q))
|
||||
.find(|(i, q)| q.queue_flags.compute && *i != queue_family_graphics)
|
||||
.map(|(i, _)| i);
|
||||
let is_separate_compute_queue = queue_family_compute.is_some();
|
||||
|
||||
let is_separate_compute_queue = compute_family_data.is_some();
|
||||
let queue_create_infos = if is_separate_compute_queue {
|
||||
let (_i, queue_family_compute) = compute_family_data.unwrap();
|
||||
let queue_create_infos = if let Some(queue_family_compute) = queue_family_compute {
|
||||
vec![
|
||||
QueueCreateInfo::family(queue_family_graphics),
|
||||
QueueCreateInfo::family(queue_family_compute),
|
||||
QueueCreateInfo {
|
||||
queue_family_index: queue_family_graphics,
|
||||
..Default::default()
|
||||
},
|
||||
QueueCreateInfo {
|
||||
queue_family_index: queue_family_compute,
|
||||
..Default::default()
|
||||
},
|
||||
]
|
||||
} else {
|
||||
vec![QueueCreateInfo::family(queue_family_graphics)]
|
||||
vec![QueueCreateInfo {
|
||||
queue_family_index: queue_family_graphics,
|
||||
..Default::default()
|
||||
}]
|
||||
};
|
||||
|
||||
let (device, mut queues) = {
|
||||
Device::new(
|
||||
physical,
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_extensions: device_extensions,
|
||||
enabled_features: features,
|
||||
|
@ -40,3 +40,6 @@ regex = "1.5"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
vk-parse = "0.7"
|
||||
|
||||
[features]
|
||||
document_unchecked = []
|
||||
|
@ -339,9 +339,9 @@ fn extensions_common_output(struct_name: Ident, members: &[ExtensionsMember]) ->
|
||||
}
|
||||
});
|
||||
|
||||
let from_cstr_for_extensions_items =
|
||||
let from_str_for_extensions_items =
|
||||
members.iter().map(|ExtensionsMember { name, raw, .. }| {
|
||||
let raw = Literal::byte_string(raw.as_bytes());
|
||||
let raw = Literal::string(raw);
|
||||
quote! {
|
||||
#raw => { extensions.#name = true; }
|
||||
}
|
||||
@ -519,12 +519,14 @@ fn extensions_common_output(struct_name: Ident, members: &[ExtensionsMember]) ->
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, I> From<I> for #struct_name where I: IntoIterator<Item = &'a std::ffi::CStr> {
|
||||
fn from(names: I) -> Self {
|
||||
impl<'a> FromIterator<&'a str> for #struct_name {
|
||||
fn from_iter<I>(iter: I) -> Self
|
||||
where I: IntoIterator<Item = &'a str>
|
||||
{
|
||||
let mut extensions = Self::empty();
|
||||
for name in names {
|
||||
match name.to_bytes() {
|
||||
#(#from_cstr_for_extensions_items)*
|
||||
for name in iter {
|
||||
match name {
|
||||
#(#from_str_for_extensions_items)*
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ use super::{
|
||||
};
|
||||
use crate::{
|
||||
buffer::{sys::UnsafeBufferCreateInfo, BufferCreationError, TypedBufferAccess},
|
||||
device::{physical::QueueFamily, Device, DeviceOwned},
|
||||
device::{Device, DeviceOwned},
|
||||
memory::{
|
||||
pool::{
|
||||
AllocFromRequirementsFilter, AllocLayout, MappingRequirement, MemoryPoolAlloc,
|
||||
@ -62,7 +62,7 @@ where
|
||||
memory: A,
|
||||
|
||||
// Queue families allowed to access this buffer.
|
||||
queue_families: SmallVec<[u32; 4]>,
|
||||
queue_family_indices: SmallVec<[u32; 4]>,
|
||||
|
||||
// Necessary to make it compile.
|
||||
marker: PhantomData<Box<T>>,
|
||||
@ -203,27 +203,21 @@ where
|
||||
/// # Panics
|
||||
///
|
||||
/// - Panics if `size` is zero.
|
||||
pub unsafe fn raw<'a, I>(
|
||||
pub unsafe fn raw(
|
||||
device: Arc<Device>,
|
||||
size: DeviceSize,
|
||||
usage: BufferUsage,
|
||||
host_cached: bool,
|
||||
queue_families: I,
|
||||
) -> Result<Arc<CpuAccessibleBuffer<T>>, DeviceMemoryAllocationError>
|
||||
where
|
||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
||||
{
|
||||
let queue_families = queue_families
|
||||
.into_iter()
|
||||
.map(|f| f.id())
|
||||
.collect::<SmallVec<[u32; 4]>>();
|
||||
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||
) -> Result<Arc<CpuAccessibleBuffer<T>>, DeviceMemoryAllocationError> {
|
||||
let queue_family_indices: SmallVec<[_; 4]> = queue_family_indices.into_iter().collect();
|
||||
|
||||
let buffer = {
|
||||
match UnsafeBuffer::new(
|
||||
device.clone(),
|
||||
UnsafeBufferCreateInfo {
|
||||
sharing: if queue_families.len() >= 2 {
|
||||
Sharing::Concurrent(queue_families.clone())
|
||||
sharing: if queue_family_indices.len() >= 2 {
|
||||
Sharing::Concurrent(queue_family_indices.clone())
|
||||
} else {
|
||||
Sharing::Exclusive
|
||||
},
|
||||
@ -247,7 +241,7 @@ where
|
||||
MappingRequirement::Map,
|
||||
Some(DedicatedAllocation::Buffer(&buffer)),
|
||||
|m| {
|
||||
if m.is_host_cached() {
|
||||
if m.property_flags.host_cached {
|
||||
if host_cached {
|
||||
AllocFromRequirementsFilter::Preferred
|
||||
} else {
|
||||
@ -269,7 +263,7 @@ where
|
||||
Ok(Arc::new(CpuAccessibleBuffer {
|
||||
inner: buffer,
|
||||
memory,
|
||||
queue_families,
|
||||
queue_family_indices,
|
||||
marker: PhantomData,
|
||||
}))
|
||||
}
|
||||
@ -280,18 +274,9 @@ where
|
||||
T: BufferContents + ?Sized,
|
||||
{
|
||||
/// Returns the queue families this buffer can be used on.
|
||||
// TODO: use a custom iterator
|
||||
#[inline]
|
||||
pub fn queue_families(&self) -> Vec<QueueFamily> {
|
||||
self.queue_families
|
||||
.iter()
|
||||
.map(|&num| {
|
||||
self.device()
|
||||
.physical_device()
|
||||
.queue_family_by_id(num)
|
||||
.unwrap()
|
||||
})
|
||||
.collect()
|
||||
pub fn queue_family_indices(&self) -> &[u32] {
|
||||
&self.queue_family_indices
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ use std::{
|
||||
/// let sub_buffer = buffer.next(data).unwrap();
|
||||
///
|
||||
/// // You can then use `sub_buffer` as if it was an entirely separate buffer.
|
||||
/// AutoCommandBufferBuilder::primary(device.clone(), queue.family(), CommandBufferUsage::OneTimeSubmit)
|
||||
/// AutoCommandBufferBuilder::primary(device.clone(), queue.queue_family_index(), CommandBufferUsage::OneTimeSubmit)
|
||||
/// .unwrap()
|
||||
/// // For the sake of the example we just call `update_buffer` on the buffer, even though
|
||||
/// // it is pointless to do that.
|
||||
|
@ -24,7 +24,7 @@ use crate::{
|
||||
AutoCommandBufferBuilder, CommandBufferBeginError, CommandBufferExecFuture,
|
||||
CommandBufferUsage, CopyBufferInfo, PrimaryAutoCommandBuffer, PrimaryCommandBuffer,
|
||||
},
|
||||
device::{physical::QueueFamily, Device, DeviceOwned, Queue},
|
||||
device::{Device, DeviceOwned, Queue},
|
||||
memory::{
|
||||
pool::{
|
||||
alloc_dedicated_with_exportable_fd, AllocFromRequirementsFilter, AllocLayout,
|
||||
@ -99,14 +99,14 @@ use std::{
|
||||
/// transfer_dst: true,
|
||||
/// ..BufferUsage::empty()
|
||||
/// }, // Specify use as a storage buffer and transfer destination.
|
||||
/// device.active_queue_families(),
|
||||
/// device.active_queue_family_indices().iter().copied(),
|
||||
/// )
|
||||
/// .unwrap();
|
||||
///
|
||||
/// // Create a one-time command to copy between the buffers.
|
||||
/// let mut cbb = AutoCommandBufferBuilder::primary(
|
||||
/// device.clone(),
|
||||
/// queue.family(),
|
||||
/// queue.queue_family_index(),
|
||||
/// CommandBufferUsage::OneTimeSubmit,
|
||||
/// )
|
||||
/// .unwrap();
|
||||
@ -138,7 +138,7 @@ where
|
||||
memory: A,
|
||||
|
||||
// Queue families allowed to access this buffer.
|
||||
queue_families: SmallVec<[u32; 4]>,
|
||||
queue_family_indices: SmallVec<[u32; 4]>,
|
||||
|
||||
// Necessary to make it compile.
|
||||
marker: PhantomData<Box<T>>,
|
||||
@ -154,16 +154,18 @@ where
|
||||
///
|
||||
/// - Panics if `T` has zero size.
|
||||
#[inline]
|
||||
pub fn new<'a, I>(
|
||||
pub fn new(
|
||||
device: Arc<Device>,
|
||||
usage: BufferUsage,
|
||||
queue_families: I,
|
||||
) -> Result<Arc<DeviceLocalBuffer<T>>, DeviceMemoryAllocationError>
|
||||
where
|
||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
||||
{
|
||||
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||
) -> Result<Arc<DeviceLocalBuffer<T>>, DeviceMemoryAllocationError> {
|
||||
unsafe {
|
||||
DeviceLocalBuffer::raw(device, size_of::<T>() as DeviceSize, usage, queue_families)
|
||||
DeviceLocalBuffer::raw(
|
||||
device,
|
||||
size_of::<T>() as DeviceSize,
|
||||
usage,
|
||||
queue_family_indices,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -204,12 +206,16 @@ where
|
||||
source.device().clone(),
|
||||
source.size(),
|
||||
actual_usage,
|
||||
source.device().active_queue_families(),
|
||||
source
|
||||
.device()
|
||||
.active_queue_family_indices()
|
||||
.iter()
|
||||
.copied(),
|
||||
)?;
|
||||
|
||||
let mut cbb = AutoCommandBufferBuilder::primary(
|
||||
source.device().clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::MultipleSubmit,
|
||||
)?;
|
||||
cbb.copy_buffer(CopyBufferInfo::buffers(source, buffer.clone()))
|
||||
@ -312,21 +318,18 @@ where
|
||||
/// - Panics if `T` has zero size.
|
||||
/// - Panics if `len` is zero.
|
||||
#[inline]
|
||||
pub fn array<'a, I>(
|
||||
pub fn array(
|
||||
device: Arc<Device>,
|
||||
len: DeviceSize,
|
||||
usage: BufferUsage,
|
||||
queue_families: I,
|
||||
) -> Result<Arc<DeviceLocalBuffer<[T]>>, DeviceMemoryAllocationError>
|
||||
where
|
||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
||||
{
|
||||
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||
) -> Result<Arc<DeviceLocalBuffer<[T]>>, DeviceMemoryAllocationError> {
|
||||
unsafe {
|
||||
DeviceLocalBuffer::raw(
|
||||
device,
|
||||
len * size_of::<T>() as DeviceSize,
|
||||
usage,
|
||||
queue_families,
|
||||
queue_family_indices,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -345,21 +348,15 @@ where
|
||||
/// # Panics
|
||||
///
|
||||
/// - Panics if `size` is zero.
|
||||
pub unsafe fn raw<'a, I>(
|
||||
pub unsafe fn raw(
|
||||
device: Arc<Device>,
|
||||
size: DeviceSize,
|
||||
usage: BufferUsage,
|
||||
queue_families: I,
|
||||
) -> Result<Arc<DeviceLocalBuffer<T>>, DeviceMemoryAllocationError>
|
||||
where
|
||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
||||
{
|
||||
let queue_families = queue_families
|
||||
.into_iter()
|
||||
.map(|f| f.id())
|
||||
.collect::<SmallVec<[u32; 4]>>();
|
||||
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||
) -> Result<Arc<DeviceLocalBuffer<T>>, DeviceMemoryAllocationError> {
|
||||
let queue_family_indices: SmallVec<[_; 4]> = queue_family_indices.into_iter().collect();
|
||||
|
||||
let (buffer, mem_reqs) = Self::build_buffer(&device, size, usage, &queue_families)?;
|
||||
let (buffer, mem_reqs) = Self::build_buffer(&device, size, usage, &queue_family_indices)?;
|
||||
|
||||
let memory = MemoryPool::alloc_from_requirements(
|
||||
device.standard_memory_pool(),
|
||||
@ -368,7 +365,7 @@ where
|
||||
MappingRequirement::DoNotMap,
|
||||
Some(DedicatedAllocation::Buffer(&buffer)),
|
||||
|t| {
|
||||
if t.is_device_local() {
|
||||
if t.property_flags.device_local {
|
||||
AllocFromRequirementsFilter::Preferred
|
||||
} else {
|
||||
AllocFromRequirementsFilter::Allowed
|
||||
@ -381,7 +378,7 @@ where
|
||||
Ok(Arc::new(DeviceLocalBuffer {
|
||||
inner: buffer,
|
||||
memory,
|
||||
queue_families,
|
||||
queue_family_indices,
|
||||
marker: PhantomData,
|
||||
}))
|
||||
}
|
||||
@ -391,24 +388,18 @@ where
|
||||
/// # Panics
|
||||
///
|
||||
/// - Panics if `size` is zero.
|
||||
pub unsafe fn raw_with_exportable_fd<'a, I>(
|
||||
pub unsafe fn raw_with_exportable_fd(
|
||||
device: Arc<Device>,
|
||||
size: DeviceSize,
|
||||
usage: BufferUsage,
|
||||
queue_families: I,
|
||||
) -> Result<Arc<DeviceLocalBuffer<T>>, DeviceMemoryAllocationError>
|
||||
where
|
||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
||||
{
|
||||
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||
) -> Result<Arc<DeviceLocalBuffer<T>>, DeviceMemoryAllocationError> {
|
||||
assert!(device.enabled_extensions().khr_external_memory_fd);
|
||||
assert!(device.enabled_extensions().khr_external_memory);
|
||||
|
||||
let queue_families = queue_families
|
||||
.into_iter()
|
||||
.map(|f| f.id())
|
||||
.collect::<SmallVec<[u32; 4]>>();
|
||||
let queue_family_indices: SmallVec<[_; 4]> = queue_family_indices.into_iter().collect();
|
||||
|
||||
let (buffer, mem_reqs) = Self::build_buffer(&device, size, usage, &queue_families)?;
|
||||
let (buffer, mem_reqs) = Self::build_buffer(&device, size, usage, &queue_family_indices)?;
|
||||
|
||||
let memory = alloc_dedicated_with_exportable_fd(
|
||||
device,
|
||||
@ -417,7 +408,7 @@ where
|
||||
MappingRequirement::DoNotMap,
|
||||
DedicatedAllocation::Buffer(&buffer),
|
||||
|t| {
|
||||
if t.is_device_local() {
|
||||
if t.property_flags.device_local {
|
||||
AllocFromRequirementsFilter::Preferred
|
||||
} else {
|
||||
AllocFromRequirementsFilter::Allowed
|
||||
@ -431,7 +422,7 @@ where
|
||||
Ok(Arc::new(DeviceLocalBuffer {
|
||||
inner: buffer,
|
||||
memory,
|
||||
queue_families,
|
||||
queue_family_indices,
|
||||
marker: PhantomData,
|
||||
}))
|
||||
}
|
||||
@ -440,14 +431,14 @@ where
|
||||
device: &Arc<Device>,
|
||||
size: DeviceSize,
|
||||
usage: BufferUsage,
|
||||
queue_families: &SmallVec<[u32; 4]>,
|
||||
queue_family_indices: &SmallVec<[u32; 4]>,
|
||||
) -> Result<(Arc<UnsafeBuffer>, MemoryRequirements), DeviceMemoryAllocationError> {
|
||||
let buffer = {
|
||||
match UnsafeBuffer::new(
|
||||
device.clone(),
|
||||
UnsafeBufferCreateInfo {
|
||||
sharing: if queue_families.len() >= 2 {
|
||||
Sharing::Concurrent(queue_families.clone())
|
||||
sharing: if queue_family_indices.len() >= 2 {
|
||||
Sharing::Concurrent(queue_family_indices.clone())
|
||||
} else {
|
||||
Sharing::Exclusive
|
||||
},
|
||||
@ -481,18 +472,9 @@ where
|
||||
T: BufferContents + ?Sized,
|
||||
{
|
||||
/// Returns the queue families this buffer can be used on.
|
||||
// TODO: use a custom iterator
|
||||
#[inline]
|
||||
pub fn queue_families(&self) -> Vec<QueueFamily> {
|
||||
self.queue_families
|
||||
.iter()
|
||||
.map(|&num| {
|
||||
self.device()
|
||||
.physical_device()
|
||||
.queue_family_by_id(num)
|
||||
.unwrap()
|
||||
})
|
||||
.collect()
|
||||
pub fn queue_family_indices(&self) -> &[u32] {
|
||||
&self.queue_family_indices
|
||||
}
|
||||
}
|
||||
|
||||
@ -646,7 +628,7 @@ mod tests {
|
||||
|
||||
let mut cbb = AutoCommandBufferBuilder::primary(
|
||||
device,
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::MultipleSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
@ -691,7 +673,7 @@ mod tests {
|
||||
|
||||
let mut cbb = AutoCommandBufferBuilder::primary(
|
||||
device,
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::MultipleSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -135,20 +135,31 @@ impl UnsafeBuffer {
|
||||
// Check sharing mode and queue families
|
||||
let (sharing_mode, queue_family_indices) = match &mut sharing {
|
||||
Sharing::Exclusive => (ash::vk::SharingMode::EXCLUSIVE, &[] as _),
|
||||
Sharing::Concurrent(ids) => {
|
||||
Sharing::Concurrent(queue_family_indices) => {
|
||||
// VUID-VkBufferCreateInfo-sharingMode-00914
|
||||
ids.sort_unstable();
|
||||
ids.dedup();
|
||||
assert!(ids.len() >= 2);
|
||||
queue_family_indices.sort_unstable();
|
||||
queue_family_indices.dedup();
|
||||
assert!(queue_family_indices.len() >= 2);
|
||||
|
||||
for &id in ids.iter() {
|
||||
for &queue_family_index in queue_family_indices.iter() {
|
||||
// VUID-VkBufferCreateInfo-sharingMode-01419
|
||||
if device.physical_device().queue_family_by_id(id).is_none() {
|
||||
return Err(BufferCreationError::SharingInvalidQueueFamilyId { id });
|
||||
if queue_family_index
|
||||
>= device.physical_device().queue_family_properties().len() as u32
|
||||
{
|
||||
return Err(BufferCreationError::SharingQueueFamilyIndexOutOfRange {
|
||||
queue_family_index,
|
||||
queue_family_count: device
|
||||
.physical_device()
|
||||
.queue_family_properties()
|
||||
.len() as u32,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
(ash::vk::SharingMode::CONCURRENT, ids.as_slice())
|
||||
(
|
||||
ash::vk::SharingMode::CONCURRENT,
|
||||
queue_family_indices.as_slice(),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
@ -332,7 +343,7 @@ impl UnsafeBuffer {
|
||||
let mem_reqs = mem_reqs.assume_init();
|
||||
mem_reqs.size <= (memory.allocation_size() - offset)
|
||||
&& (offset % mem_reqs.alignment) == 0
|
||||
&& mem_reqs.memory_type_bits & (1 << memory.memory_type().id()) != 0
|
||||
&& mem_reqs.memory_type_bits & (1 << memory.memory_type_index()) != 0
|
||||
});
|
||||
|
||||
// Check for alignment correctness.
|
||||
@ -479,9 +490,12 @@ pub enum BufferCreationError {
|
||||
/// The specified size exceeded the value of the `max_buffer_size` limit.
|
||||
MaxBufferSizeExceeded { size: DeviceSize, max: DeviceSize },
|
||||
|
||||
/// The sharing mode was set to `Concurrent`, but one of the specified queue family ids was not
|
||||
/// valid.
|
||||
SharingInvalidQueueFamilyId { id: u32 },
|
||||
/// The sharing mode was set to `Concurrent`, but one of the specified queue family indices was
|
||||
/// out of range.
|
||||
SharingQueueFamilyIndexOutOfRange {
|
||||
queue_family_index: u32,
|
||||
queue_family_count: u32,
|
||||
},
|
||||
}
|
||||
|
||||
impl Error for BufferCreationError {
|
||||
@ -511,8 +525,8 @@ impl Display for BufferCreationError {
|
||||
f,
|
||||
"the specified size exceeded the value of the `max_buffer_size` limit"
|
||||
),
|
||||
Self::SharingInvalidQueueFamilyId { .. } => {
|
||||
write!(f, "the sharing mode was set to `Concurrent`, but one of the specified queue family ids was not valid")
|
||||
Self::SharingQueueFamilyIndexOutOfRange { .. } => {
|
||||
write!(f, "the sharing mode was set to `Concurrent`, but one of the specified queue family indices was out of range")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ use super::{
|
||||
use crate::{
|
||||
buffer::{sys::UnsafeBuffer, BufferAccess},
|
||||
command_buffer::CommandBufferInheritanceRenderingInfo,
|
||||
device::{physical::QueueFamily, Device, DeviceOwned, Queue},
|
||||
device::{physical::QueueFamilyProperties, Device, DeviceOwned, Queue},
|
||||
format::Format,
|
||||
image::{sys::UnsafeImage, ImageAccess, ImageLayout, ImageSubresourceRange},
|
||||
query::{QueryControlFlags, QueryType},
|
||||
@ -49,8 +49,8 @@ pub struct AutoCommandBufferBuilder<L, P = StandardCommandPoolBuilder> {
|
||||
pub(super) inner: SyncCommandBufferBuilder,
|
||||
pool_builder_alloc: P, // Safety: must be dropped after `inner`
|
||||
|
||||
// The queue family that this command buffer is being created for.
|
||||
queue_family_id: u32,
|
||||
// The index of the queue family that this command buffer is being created for.
|
||||
queue_family_index: u32,
|
||||
|
||||
// The inheritance for secondary command buffers.
|
||||
// Must be `None` in a primary command buffer and `Some` in a secondary command buffer.
|
||||
@ -129,7 +129,7 @@ impl AutoCommandBufferBuilder<PrimaryAutoCommandBuffer, StandardCommandPoolBuild
|
||||
#[inline]
|
||||
pub fn primary(
|
||||
device: Arc<Device>,
|
||||
queue_family: QueueFamily,
|
||||
queue_family_index: u32,
|
||||
usage: CommandBufferUsage,
|
||||
) -> Result<
|
||||
AutoCommandBufferBuilder<PrimaryAutoCommandBuffer, StandardCommandPoolBuilder>,
|
||||
@ -138,7 +138,7 @@ impl AutoCommandBufferBuilder<PrimaryAutoCommandBuffer, StandardCommandPoolBuild
|
||||
unsafe {
|
||||
AutoCommandBufferBuilder::begin(
|
||||
device,
|
||||
queue_family,
|
||||
queue_family_index,
|
||||
CommandBufferLevel::Primary,
|
||||
CommandBufferBeginInfo {
|
||||
usage,
|
||||
@ -155,7 +155,7 @@ impl AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBui
|
||||
#[inline]
|
||||
pub fn secondary(
|
||||
device: Arc<Device>,
|
||||
queue_family: QueueFamily,
|
||||
queue_family_index: u32,
|
||||
usage: CommandBufferUsage,
|
||||
inheritance_info: CommandBufferInheritanceInfo,
|
||||
) -> Result<
|
||||
@ -165,7 +165,7 @@ impl AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBui
|
||||
unsafe {
|
||||
AutoCommandBufferBuilder::begin(
|
||||
device,
|
||||
queue_family,
|
||||
queue_family_index,
|
||||
CommandBufferLevel::Secondary,
|
||||
CommandBufferBeginInfo {
|
||||
usage,
|
||||
@ -183,12 +183,12 @@ impl<L> AutoCommandBufferBuilder<L, StandardCommandPoolBuilder> {
|
||||
// `begin_info.inheritance_info` must match `level`.
|
||||
unsafe fn begin(
|
||||
device: Arc<Device>,
|
||||
queue_family: QueueFamily,
|
||||
queue_family_index: u32,
|
||||
level: CommandBufferLevel,
|
||||
begin_info: CommandBufferBeginInfo,
|
||||
) -> Result<AutoCommandBufferBuilder<L, StandardCommandPoolBuilder>, CommandBufferBeginError>
|
||||
{
|
||||
Self::validate_begin(&device, &queue_family, level, &begin_info)?;
|
||||
Self::validate_begin(&device, queue_family_index, level, &begin_info)?;
|
||||
|
||||
let &CommandBufferBeginInfo {
|
||||
usage,
|
||||
@ -252,7 +252,7 @@ impl<L> AutoCommandBufferBuilder<L, StandardCommandPoolBuilder> {
|
||||
}
|
||||
}
|
||||
|
||||
device.with_standard_command_pool(queue_family, |pool| {
|
||||
device.with_standard_command_pool(queue_family_index, |pool| {
|
||||
let pool_builder_alloc = pool
|
||||
.allocate(level, 1)?
|
||||
.next()
|
||||
@ -263,7 +263,7 @@ impl<L> AutoCommandBufferBuilder<L, StandardCommandPoolBuilder> {
|
||||
Ok(AutoCommandBufferBuilder {
|
||||
inner,
|
||||
pool_builder_alloc,
|
||||
queue_family_id: queue_family.id(),
|
||||
queue_family_index,
|
||||
render_pass_state,
|
||||
query_state: HashMap::default(),
|
||||
inheritance_info,
|
||||
@ -275,7 +275,7 @@ impl<L> AutoCommandBufferBuilder<L, StandardCommandPoolBuilder> {
|
||||
|
||||
fn validate_begin(
|
||||
device: &Device,
|
||||
_queue_family: &QueueFamily,
|
||||
_queue_family_index: u32,
|
||||
level: CommandBufferLevel,
|
||||
begin_info: &CommandBufferBeginInfo,
|
||||
) -> Result<(), CommandBufferBeginError> {
|
||||
@ -694,11 +694,8 @@ impl From<OomError> for BuildError {
|
||||
|
||||
impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
#[inline]
|
||||
pub(super) fn queue_family(&self) -> QueueFamily {
|
||||
self.device()
|
||||
.physical_device()
|
||||
.queue_family_by_id(self.queue_family_id)
|
||||
.unwrap()
|
||||
pub(super) fn queue_family_properties(&self) -> &QueueFamilyProperties {
|
||||
&self.device().physical_device().queue_family_properties()[self.queue_family_index as usize]
|
||||
}
|
||||
|
||||
/// Returns the binding/setting state.
|
||||
@ -965,27 +962,25 @@ mod tests {
|
||||
synced::SyncCommandBufferBuilderError, BufferCopy, CopyBufferInfoTyped, CopyError,
|
||||
ExecuteCommandsError,
|
||||
},
|
||||
device::{physical::PhysicalDevice, DeviceCreateInfo, QueueCreateInfo},
|
||||
device::{DeviceCreateInfo, QueueCreateInfo},
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn copy_buffer_dimensions() {
|
||||
let instance = instance!();
|
||||
|
||||
let phys = match PhysicalDevice::enumerate(&instance).next() {
|
||||
let physical_device = match instance.enumerate_physical_devices().unwrap().next() {
|
||||
Some(p) => p,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let queue_family = match phys.queue_families().next() {
|
||||
Some(q) => q,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let (device, mut queues) = Device::new(
|
||||
phys,
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index: 0,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -1017,7 +1012,7 @@ mod tests {
|
||||
|
||||
let mut cbb = AutoCommandBufferBuilder::primary(
|
||||
device,
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
@ -1055,7 +1050,7 @@ mod tests {
|
||||
// Make a secondary CB that doesn't support simultaneous use.
|
||||
let builder = AutoCommandBufferBuilder::secondary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::MultipleSubmit,
|
||||
Default::default(),
|
||||
)
|
||||
@ -1065,7 +1060,7 @@ mod tests {
|
||||
{
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::SimultaneousUse,
|
||||
)
|
||||
.unwrap();
|
||||
@ -1088,7 +1083,7 @@ mod tests {
|
||||
{
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::SimultaneousUse,
|
||||
)
|
||||
.unwrap();
|
||||
@ -1097,7 +1092,7 @@ mod tests {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device,
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::SimultaneousUse,
|
||||
)
|
||||
.unwrap();
|
||||
@ -1138,7 +1133,7 @@ mod tests {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device,
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
@ -1188,7 +1183,7 @@ mod tests {
|
||||
|
||||
let mut builder = AutoCommandBufferBuilder::primary(
|
||||
device,
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -94,16 +94,18 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
// VUID-vkCmdBindDescriptorSets-pipelineBindPoint-parameter
|
||||
pipeline_bind_point.validate_device(self.device())?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdBindDescriptorSets-commandBuffer-cmdpool
|
||||
// VUID-vkCmdBindDescriptorSets-pipelineBindPoint-00361
|
||||
match pipeline_bind_point {
|
||||
PipelineBindPoint::Compute => {
|
||||
if !self.queue_family().supports_compute() {
|
||||
if !queue_family_properties.queue_flags.compute {
|
||||
return Err(BindPushError::NotSupportedByQueueFamily);
|
||||
}
|
||||
}
|
||||
PipelineBindPoint::Graphics => {
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(BindPushError::NotSupportedByQueueFamily);
|
||||
}
|
||||
}
|
||||
@ -171,8 +173,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
index_buffer: &dyn BufferAccess,
|
||||
index_type: IndexType,
|
||||
) -> Result<(), BindPushError> {
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdBindIndexBuffer-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(BindPushError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -221,8 +225,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
&self,
|
||||
pipeline: &ComputePipeline,
|
||||
) -> Result<(), BindPushError> {
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdBindPipeline-pipelineBindPoint-00777
|
||||
if !self.queue_family().supports_compute() {
|
||||
if !queue_family_properties.queue_flags.compute {
|
||||
return Err(BindPushError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -252,8 +258,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
&self,
|
||||
pipeline: &GraphicsPipeline,
|
||||
) -> Result<(), BindPushError> {
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdBindPipeline-pipelineBindPoint-00778
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(BindPushError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -339,8 +347,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
first_binding: u32,
|
||||
vertex_buffers: &[Arc<dyn BufferAccess>],
|
||||
) -> Result<(), BindPushError> {
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdBindVertexBuffers-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(BindPushError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -550,16 +560,18 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
// VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-parameter
|
||||
pipeline_bind_point.validate_device(self.device())?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool
|
||||
// VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-00363
|
||||
match pipeline_bind_point {
|
||||
PipelineBindPoint::Compute => {
|
||||
if !self.queue_family().supports_compute() {
|
||||
if !queue_family_properties.queue_flags.compute {
|
||||
return Err(BindPushError::NotSupportedByQueueFamily);
|
||||
}
|
||||
}
|
||||
PipelineBindPoint::Graphics => {
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(BindPushError::NotSupportedByQueueFamily);
|
||||
}
|
||||
}
|
||||
|
@ -63,8 +63,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
});
|
||||
}
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdBeginDebugUtilsLabelEXT-commandBuffer-cmdpool
|
||||
if !(self.queue_family().supports_graphics() || self.queue_family().supports_compute()) {
|
||||
if !(queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
return Err(DebugUtilsError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -103,8 +107,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
});
|
||||
}
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdEndDebugUtilsLabelEXT-commandBuffer-cmdpool
|
||||
if !(self.queue_family().supports_graphics() || self.queue_family().supports_compute()) {
|
||||
if !(queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
return Err(DebugUtilsError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -151,8 +159,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
});
|
||||
}
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdInsertDebugUtilsLabelEXT-commandBuffer-cmdpool
|
||||
if !(self.queue_family().supports_graphics() || self.queue_family().supports_compute()) {
|
||||
if !(queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
return Err(DebugUtilsError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
|
@ -75,8 +75,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::BlendConstants)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetBlendConstants-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -117,8 +119,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::ColorWriteEnable)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetColorWriteEnableEXT-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -179,8 +183,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
// VUID-vkCmdSetCullMode-cullMode-parameter
|
||||
cull_mode.validate_device(self.device())?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetCullMode-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -235,8 +241,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::DepthBias)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetDepthBias-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -277,8 +285,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
fn validate_set_depth_bias_enable(&self, _enable: bool) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::DepthBiasEnable)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetDepthBiasEnable-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -325,8 +335,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::DepthBounds)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetDepthBounds-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -376,8 +388,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::DepthBoundsTestEnable)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetDepthBoundsTestEnable-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -427,8 +441,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
// VUID-vkCmdSetDepthCompareOp-depthCompareOp-parameter
|
||||
compare_op.validate_device(self.device())?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetDepthCompareOp-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -472,8 +488,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
fn validate_set_depth_test_enable(&self, _enable: bool) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::DepthTestEnable)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetDepthTestEnable-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -517,8 +535,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
fn validate_set_depth_write_enable(&self, _enable: bool) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::DepthWriteEnable)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetDepthWriteEnable-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -574,8 +594,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::DiscardRectangle)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetDiscardRectangle-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -638,8 +660,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
// VUID-vkCmdSetFrontFace-frontFace-parameter
|
||||
face.validate_device(self.device())?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetFrontFace-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -687,8 +711,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::LineStipple)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetLineStippleEXT-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -731,8 +757,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
fn validate_set_line_width(&self, line_width: f32) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::LineWidth)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetLineWidth-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -776,8 +804,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
// VUID-vkCmdSetLogicOpEXT-logicOp-parameter
|
||||
logic_op.validate_device(self.device())?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetLogicOpEXT-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -826,8 +856,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
fn validate_set_patch_control_points(&self, num: u32) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::PatchControlPoints)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetPatchControlPointsEXT-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -896,8 +928,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::PrimitiveRestartEnable)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetPrimitiveRestartEnable-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -951,8 +985,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
// VUID-vkCmdSetPrimitiveTopology-primitiveTopology-parameter
|
||||
topology.validate_device(self.device())?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetPrimitiveTopology-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -1031,8 +1067,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::RasterizerDiscardEnable)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetRasterizerDiscardEnable-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -1084,8 +1122,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::Scissor)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetScissor-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -1160,8 +1200,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::ScissorWithCount)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetScissorWithCount-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -1232,8 +1274,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
// VUID-vkCmdSetStencilCompareMask-faceMask-parameter
|
||||
faces.validate_device(self.device())?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetStencilCompareMask-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -1294,8 +1338,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
// VUID-vkCmdSetStencilOp-compareOp-parameter
|
||||
compare_op.validate_device(self.device())?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetStencilOp-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -1343,8 +1389,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
// VUID-vkCmdSetStencilReference-faceMask-parameter
|
||||
faces.validate_device(self.device())?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetStencilReference-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -1374,8 +1422,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
fn validate_set_stencil_test_enable(&self, _enable: bool) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::StencilTestEnable)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetStencilTestEnable-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -1423,8 +1473,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
// VUID-vkCmdSetStencilWriteMask-faceMask-parameter
|
||||
faces.validate_device(self.device())?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetStencilWriteMask-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -1463,8 +1515,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::Viewport)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetViewport-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -1539,8 +1593,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
) -> Result<(), SetDynamicStateError> {
|
||||
self.validate_pipeline_fixed_state(DynamicState::ViewportWithCount)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdSetViewportWithCount-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
|
@ -86,8 +86,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||
}
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdBlitImage2-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(CopyError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -586,8 +588,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||
}
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdClearColorImage-commandBuffer-cmdpool
|
||||
if !(self.queue_family().supports_graphics() || self.queue_family().supports_compute()) {
|
||||
if !(queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
return Err(CopyError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -734,8 +740,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||
}
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdClearDepthStencilImage-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(CopyError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -890,8 +898,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||
}
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdResolveImage2-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(CopyError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
|
@ -70,8 +70,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
}
|
||||
|
||||
fn validate_dispatch(&self, group_counts: [u32; 3]) -> Result<(), PipelineExecutionError> {
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdDispatch-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_compute() {
|
||||
if !queue_family_properties.queue_flags.compute {
|
||||
return Err(PipelineExecutionError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -135,8 +137,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
&self,
|
||||
indirect_buffer: &dyn BufferAccess,
|
||||
) -> Result<(), PipelineExecutionError> {
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdDispatchIndirect-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_compute() {
|
||||
if !queue_family_properties.queue_flags.compute {
|
||||
return Err(PipelineExecutionError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ use crate::{
|
||||
sys::UnsafeCommandBufferBuilder,
|
||||
AutoCommandBufferBuilder,
|
||||
},
|
||||
device::{physical::QueueFamily, DeviceOwned},
|
||||
device::DeviceOwned,
|
||||
query::{
|
||||
QueriesRange, Query, QueryControlFlags, QueryPool, QueryResultElement, QueryResultFlags,
|
||||
QueryType,
|
||||
@ -71,8 +71,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
query: u32,
|
||||
flags: QueryControlFlags,
|
||||
) -> Result<(), QueryError> {
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdBeginQuery-commandBuffer-cmdpool
|
||||
if !(self.queue_family().supports_graphics() || self.queue_family().supports_compute()) {
|
||||
if !(queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
return Err(QueryError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -91,7 +95,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
QueryType::Occlusion => {
|
||||
// VUID-vkCmdBeginQuery-commandBuffer-cmdpool
|
||||
// // VUID-vkCmdBeginQuery-queryType-00803
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(QueryError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -110,8 +114,9 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
// VUID-vkCmdBeginQuery-commandBuffer-cmdpool
|
||||
// VUID-vkCmdBeginQuery-queryType-00804
|
||||
// VUID-vkCmdBeginQuery-queryType-00805
|
||||
if statistic_flags.is_compute() && !self.queue_family().supports_compute()
|
||||
|| statistic_flags.is_graphics() && !self.queue_family().supports_graphics()
|
||||
if statistic_flags.is_compute() && !queue_family_properties.queue_flags.compute
|
||||
|| statistic_flags.is_graphics()
|
||||
&& !queue_family_properties.queue_flags.graphics
|
||||
{
|
||||
return Err(QueryError::NotSupportedByQueueFamily);
|
||||
}
|
||||
@ -165,8 +170,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
}
|
||||
|
||||
fn validate_end_query(&self, query_pool: &QueryPool, query: u32) -> Result<(), QueryError> {
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdEndQuery-commandBuffer-cmdpool
|
||||
if !(self.queue_family().supports_graphics() || self.queue_family().supports_compute()) {
|
||||
if !(queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
return Err(QueryError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -209,7 +218,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
query: u32,
|
||||
stage: PipelineStage,
|
||||
) -> Result<&mut Self, QueryError> {
|
||||
self.validate_write_timestamp(self.queue_family(), &query_pool, query, stage)?;
|
||||
self.validate_write_timestamp(&query_pool, query, stage)?;
|
||||
|
||||
self.inner.write_timestamp(query_pool, query, stage);
|
||||
|
||||
@ -218,15 +227,16 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
|
||||
fn validate_write_timestamp(
|
||||
&self,
|
||||
queue_family: QueueFamily,
|
||||
query_pool: &QueryPool,
|
||||
query: u32,
|
||||
stage: PipelineStage,
|
||||
) -> Result<(), QueryError> {
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdWriteTimestamp-commandBuffer-cmdpool
|
||||
if !(self.queue_family().explicitly_supports_transfers()
|
||||
|| self.queue_family().supports_graphics()
|
||||
|| self.queue_family().supports_compute())
|
||||
if !(queue_family_properties.queue_flags.transfer
|
||||
|| queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
return Err(QueryError::NotSupportedByQueueFamily);
|
||||
}
|
||||
@ -237,7 +247,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
assert_eq!(device, query_pool.device());
|
||||
|
||||
// VUID-vkCmdWriteTimestamp-pipelineStage-04074
|
||||
if !queue_family.supports_stage(stage) {
|
||||
if !queue_family_properties.supports_stage(stage) {
|
||||
return Err(QueryError::StageNotSupported);
|
||||
}
|
||||
|
||||
@ -276,7 +286,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
}
|
||||
|
||||
// VUID-vkCmdWriteTimestamp-timestampValidBits-00829
|
||||
if queue_family.timestamp_valid_bits().is_none() {
|
||||
if queue_family_properties.timestamp_valid_bits.is_none() {
|
||||
return Err(QueryError::NoTimestampValidBits);
|
||||
}
|
||||
|
||||
@ -346,8 +356,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
D: ?Sized + TypedBufferAccess<Content = [T]>,
|
||||
T: QueryResultElement,
|
||||
{
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdCopyQueryPoolResults-commandBuffer-cmdpool
|
||||
if !(self.queue_family().supports_graphics() || self.queue_family().supports_compute()) {
|
||||
if !(queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
return Err(QueryError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -431,8 +445,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
return Err(QueryError::ForbiddenInsideRenderPass);
|
||||
}
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdResetQueryPool-commandBuffer-cmdpool
|
||||
if !(self.queue_family().supports_graphics() || self.queue_family().supports_compute()) {
|
||||
if !(queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
return Err(QueryError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
|
@ -101,8 +101,10 @@ where
|
||||
// VUID-VkSubpassBeginInfo-contents-parameter
|
||||
contents.validate_device(device)?;
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdBeginRenderPass2-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(RenderPassError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -453,7 +455,10 @@ where
|
||||
}
|
||||
|
||||
// VUID-vkCmdNextSubpass2-commandBuffer-cmdpool
|
||||
debug_assert!(self.queue_family().supports_graphics());
|
||||
debug_assert!({
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
queue_family_properties.queue_flags.graphics
|
||||
});
|
||||
|
||||
// VUID-vkCmdNextSubpass2-bufferlevel
|
||||
// Ensured by the type of the impl block
|
||||
@ -509,7 +514,10 @@ where
|
||||
}
|
||||
|
||||
// VUID-vkCmdEndRenderPass2-commandBuffer-cmdpool
|
||||
debug_assert!(self.queue_family().supports_graphics());
|
||||
debug_assert!({
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
queue_family_properties.queue_flags.graphics
|
||||
});
|
||||
|
||||
// VUID-vkCmdEndRenderPass2-bufferlevel
|
||||
// Ensured by the type of the impl block
|
||||
@ -675,8 +683,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
});
|
||||
}
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdBeginRendering-commandBuffer-cmdpool
|
||||
if !self.queue_family().supports_graphics() {
|
||||
if !queue_family_properties.queue_flags.graphics {
|
||||
return Err(RenderPassError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -1228,7 +1238,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
}
|
||||
|
||||
// VUID-vkCmdEndRendering-commandBuffer-cmdpool
|
||||
debug_assert!(self.queue_family().supports_graphics());
|
||||
debug_assert!({
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
queue_family_properties.queue_flags.graphics
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -1476,7 +1489,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
}
|
||||
|
||||
// VUID-vkCmdClearAttachments-commandBuffer-cmdpool
|
||||
debug_assert!(self.queue_family().supports_graphics());
|
||||
debug_assert!({
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
queue_family_properties.queue_flags.graphics
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -114,10 +114,12 @@ where
|
||||
// VUID-vkCmdExecuteCommands-commonparent
|
||||
assert_eq!(self.device(), command_buffer.device());
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdExecuteCommands-commandBuffer-cmdpool
|
||||
if !(self.queue_family().explicitly_supports_transfers()
|
||||
|| self.queue_family().supports_graphics()
|
||||
|| self.queue_family().supports_compute())
|
||||
if !(queue_family_properties.queue_flags.transfer
|
||||
|| queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
return Err(ExecuteCommandsError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
@ -63,10 +63,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||
}
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdCopyBuffer2-commandBuffer-cmdpool
|
||||
if !(self.queue_family().explicitly_supports_transfers()
|
||||
|| self.queue_family().supports_graphics()
|
||||
|| self.queue_family().supports_compute())
|
||||
if !(queue_family_properties.queue_flags.transfer
|
||||
|| queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
return Err(CopyError::NotSupportedByQueueFamily);
|
||||
}
|
||||
@ -211,10 +213,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||
}
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdCopyImage2-commandBuffer-cmdpool
|
||||
if !(self.queue_family().explicitly_supports_transfers()
|
||||
|| self.queue_family().supports_graphics()
|
||||
|| self.queue_family().supports_compute())
|
||||
if !(queue_family_properties.queue_flags.transfer
|
||||
|| queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
return Err(CopyError::NotSupportedByQueueFamily);
|
||||
}
|
||||
@ -319,7 +323,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
});
|
||||
}
|
||||
|
||||
let extent_alignment = match self.queue_family().min_image_transfer_granularity() {
|
||||
let extent_alignment = match queue_family_properties.min_image_transfer_granularity {
|
||||
[0, 0, 0] => None,
|
||||
min_image_transfer_granularity => {
|
||||
let granularity = move |block_extent: [u32; 3], is_multi_plane: bool| {
|
||||
@ -861,10 +865,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||
}
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdCopyBufferToImage2-commandBuffer-cmdpool
|
||||
if !(self.queue_family().explicitly_supports_transfers()
|
||||
|| self.queue_family().supports_graphics()
|
||||
|| self.queue_family().supports_compute())
|
||||
if !(queue_family_properties.queue_flags.transfer
|
||||
|| queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
return Err(CopyError::NotSupportedByQueueFamily);
|
||||
}
|
||||
@ -888,7 +894,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
let mut image_aspects = dst_image.format().aspects();
|
||||
|
||||
// VUID-VkCopyBufferToImageInfo2-commandBuffer-04477
|
||||
if !self.queue_family().supports_graphics() && !image_aspects.color {
|
||||
if !queue_family_properties.queue_flags.graphics && !image_aspects.color {
|
||||
return Err(CopyError::DepthStencilNotSupportedByQueueFamily);
|
||||
}
|
||||
|
||||
@ -941,7 +947,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
});
|
||||
}
|
||||
|
||||
let extent_alignment = match self.queue_family().min_image_transfer_granularity() {
|
||||
let extent_alignment = match queue_family_properties.min_image_transfer_granularity {
|
||||
[0, 0, 0] => None,
|
||||
min_image_transfer_granularity => {
|
||||
let granularity = move |block_extent: [u32; 3], is_multi_plane: bool| {
|
||||
@ -1218,8 +1224,8 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
|
||||
// VUID-VkCopyBufferToImageInfo2-commandBuffer-04052
|
||||
// Make the alignment a multiple of 4.
|
||||
if !(self.queue_family().supports_graphics()
|
||||
|| self.queue_family().supports_compute())
|
||||
if !(queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
if buffer_offset_alignment % 2 != 0 {
|
||||
buffer_offset_alignment *= 2;
|
||||
@ -1290,10 +1296,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||
}
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdCopyImageToBuffer2-commandBuffer-cmdpool
|
||||
if !(self.queue_family().explicitly_supports_transfers()
|
||||
|| self.queue_family().supports_graphics()
|
||||
|| self.queue_family().supports_compute())
|
||||
if !(queue_family_properties.queue_flags.transfer
|
||||
|| queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
return Err(CopyError::NotSupportedByQueueFamily);
|
||||
}
|
||||
@ -1365,7 +1373,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
});
|
||||
}
|
||||
|
||||
let extent_alignment = match self.queue_family().min_image_transfer_granularity() {
|
||||
let extent_alignment = match queue_family_properties.min_image_transfer_granularity {
|
||||
[0, 0, 0] => None,
|
||||
min_image_transfer_granularity => {
|
||||
let granularity = move |block_extent: [u32; 3], is_multi_plane: bool| {
|
||||
@ -1640,8 +1648,8 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
|
||||
// VUID-VkCopyImageToBufferInfo2-commandBuffer-04052
|
||||
// Make the alignment a multiple of 4.
|
||||
if !(self.queue_family().supports_graphics()
|
||||
|| self.queue_family().supports_compute())
|
||||
if !(queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
if buffer_offset_alignment % 2 != 0 {
|
||||
buffer_offset_alignment *= 2;
|
||||
@ -1717,17 +1725,20 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||
}
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
if device.api_version() >= Version::V1_1 || device.enabled_extensions().khr_maintenance1 {
|
||||
// VUID-vkCmdFillBuffer-commandBuffer-cmdpool
|
||||
if !(self.queue_family().explicitly_supports_transfers()
|
||||
|| self.queue_family().supports_graphics()
|
||||
|| self.queue_family().supports_compute())
|
||||
if !(queue_family_properties.queue_flags.transfer
|
||||
|| queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
return Err(CopyError::NotSupportedByQueueFamily);
|
||||
}
|
||||
} else {
|
||||
// VUID-vkCmdFillBuffer-commandBuffer-00030
|
||||
if !(self.queue_family().supports_graphics() || self.queue_family().supports_compute())
|
||||
if !(queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
return Err(CopyError::NotSupportedByQueueFamily);
|
||||
}
|
||||
@ -1833,10 +1844,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||
}
|
||||
|
||||
let queue_family_properties = self.queue_family_properties();
|
||||
|
||||
// VUID-vkCmdUpdateBuffer-commandBuffer-cmdpool
|
||||
if !(self.queue_family().explicitly_supports_transfers()
|
||||
|| self.queue_family().supports_graphics()
|
||||
|| self.queue_family().supports_compute())
|
||||
if !(queue_family_properties.queue_flags.transfer
|
||||
|| queue_family_properties.queue_flags.graphics
|
||||
|| queue_family_properties.queue_flags.compute)
|
||||
{
|
||||
return Err(CopyError::NotSupportedByQueueFamily);
|
||||
}
|
||||
|
@ -63,7 +63,7 @@
|
||||
//! # let graphics_pipeline: std::sync::Arc<vulkano::pipeline::graphics::GraphicsPipeline> = return;
|
||||
//! let cb = AutoCommandBufferBuilder::primary(
|
||||
//! device.clone(),
|
||||
//! queue.family(),
|
||||
//! queue.queue_family_index(),
|
||||
//! CommandBufferUsage::MultipleSubmit
|
||||
//! ).unwrap()
|
||||
//! .begin_render_pass(render_pass_begin_info, SubpassContents::Inline).unwrap()
|
||||
|
@ -24,10 +24,7 @@ pub use self::{
|
||||
},
|
||||
};
|
||||
use super::CommandBufferLevel;
|
||||
use crate::{
|
||||
device::{physical::QueueFamily, DeviceOwned},
|
||||
OomError,
|
||||
};
|
||||
use crate::{device::DeviceOwned, OomError};
|
||||
|
||||
pub mod standard;
|
||||
mod sys;
|
||||
@ -70,8 +67,8 @@ pub unsafe trait CommandPool: DeviceOwned {
|
||||
command_buffer_count: u32,
|
||||
) -> Result<Self::Iter, OomError>;
|
||||
|
||||
/// Returns the queue family that this pool targets.
|
||||
fn queue_family(&self) -> QueueFamily;
|
||||
/// Returns the index of the queue family that this pool targets.
|
||||
fn queue_family_index(&self) -> u32;
|
||||
}
|
||||
|
||||
/// A command buffer allocated from a pool and that can be recorded.
|
||||
@ -90,8 +87,8 @@ pub unsafe trait CommandPoolBuilderAlloc: DeviceOwned {
|
||||
/// Turns this builder into a command buffer that is pending execution.
|
||||
fn into_alloc(self) -> Self::Alloc;
|
||||
|
||||
/// Returns the queue family that the pool targets.
|
||||
fn queue_family(&self) -> QueueFamily;
|
||||
/// Returns the index of the queue family that the pool targets.
|
||||
fn queue_family_index(&self) -> u32;
|
||||
}
|
||||
|
||||
/// A command buffer allocated from a pool that has finished being recorded.
|
||||
@ -104,6 +101,6 @@ pub unsafe trait CommandPoolAlloc: DeviceOwned + Send + Sync {
|
||||
/// Returns the internal object that contains the command buffer.
|
||||
fn inner(&self) -> &UnsafeCommandPoolAlloc;
|
||||
|
||||
/// Returns the queue family that the pool targets.
|
||||
fn queue_family(&self) -> QueueFamily;
|
||||
/// Returns the index of the queue family that the pool targets.
|
||||
fn queue_family_index(&self) -> u32;
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ use super::{
|
||||
};
|
||||
use crate::{
|
||||
command_buffer::CommandBufferLevel,
|
||||
device::{physical::QueueFamily, Device, DeviceOwned},
|
||||
OomError, VulkanObject,
|
||||
device::{Device, DeviceOwned},
|
||||
OomError,
|
||||
};
|
||||
use crossbeam_queue::SegQueue;
|
||||
use std::{marker::PhantomData, mem::ManuallyDrop, ptr, sync::Arc, vec::IntoIter as VecIntoIter};
|
||||
@ -45,17 +45,16 @@ impl StandardCommandPool {
|
||||
/// - Panics if the device and the queue family don't belong to the same physical device.
|
||||
pub fn new(
|
||||
device: Arc<Device>,
|
||||
queue_family: QueueFamily,
|
||||
queue_family_index: u32,
|
||||
) -> Result<StandardCommandPool, OomError> {
|
||||
assert_eq!(
|
||||
device.physical_device().internal_object(),
|
||||
queue_family.physical_device().internal_object()
|
||||
assert!(
|
||||
queue_family_index < device.physical_device().queue_family_properties().len() as u32
|
||||
);
|
||||
|
||||
let inner = UnsafeCommandPool::new(
|
||||
device,
|
||||
UnsafeCommandPoolCreateInfo {
|
||||
queue_family_index: queue_family.id(),
|
||||
queue_family_index,
|
||||
reset_command_buffer: true,
|
||||
..Default::default()
|
||||
},
|
||||
@ -135,8 +134,8 @@ unsafe impl CommandPool for Arc<StandardCommandPool> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn queue_family(&self) -> QueueFamily {
|
||||
self.inner.queue_family()
|
||||
fn queue_family_index(&self) -> u32 {
|
||||
self.inner.queue_family_index()
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,8 +169,8 @@ unsafe impl CommandPoolBuilderAlloc for StandardCommandPoolBuilder {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn queue_family(&self) -> QueueFamily {
|
||||
self.inner.queue_family()
|
||||
fn queue_family_index(&self) -> u32 {
|
||||
self.inner.queue_family_index()
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,8 +199,8 @@ unsafe impl CommandPoolAlloc for StandardCommandPoolAlloc {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn queue_family(&self) -> QueueFamily {
|
||||
self.pool.queue_family()
|
||||
fn queue_family_index(&self) -> u32 {
|
||||
self.pool.queue_family_index()
|
||||
}
|
||||
}
|
||||
|
||||
@ -242,7 +241,7 @@ mod tests {
|
||||
let (device, queue) = gfx_dev_and_queue!();
|
||||
|
||||
device
|
||||
.with_standard_command_pool(queue.family(), |pool| {
|
||||
.with_standard_command_pool(queue.queue_family_index(), |pool| {
|
||||
let cb = pool
|
||||
.allocate(CommandBufferLevel::Primary, 1)
|
||||
.unwrap()
|
||||
@ -269,7 +268,7 @@ mod tests {
|
||||
let (device, queue) = (device, queue);
|
||||
move || {
|
||||
device
|
||||
.with_standard_command_pool(queue.family(), |pool| {
|
||||
.with_standard_command_pool(queue.queue_family_index(), |pool| {
|
||||
pool.allocate(CommandBufferLevel::Primary, 1)
|
||||
.unwrap()
|
||||
.next()
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
use crate::{
|
||||
command_buffer::CommandBufferLevel,
|
||||
device::{physical::QueueFamily, Device, DeviceOwned},
|
||||
device::{Device, DeviceOwned},
|
||||
OomError, RequiresOneOf, Version, VulkanError, VulkanObject,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
@ -111,14 +111,10 @@ impl UnsafeCommandPool {
|
||||
} = create_info;
|
||||
|
||||
// VUID-vkCreateCommandPool-queueFamilyIndex-01937
|
||||
if device
|
||||
.physical_device()
|
||||
.queue_family_by_id(queue_family_index)
|
||||
.is_none()
|
||||
{
|
||||
if queue_family_index >= device.physical_device().queue_family_properties().len() as u32 {
|
||||
return Err(UnsafeCommandPoolCreationError::QueueFamilyIndexOutOfRange {
|
||||
queue_family_index,
|
||||
queue_family_count: device.physical_device().queue_families().len() as u32,
|
||||
queue_family_count: device.physical_device().queue_family_properties().len() as u32,
|
||||
});
|
||||
}
|
||||
|
||||
@ -308,11 +304,8 @@ impl UnsafeCommandPool {
|
||||
|
||||
/// Returns the queue family on which command buffers of this pool can be executed.
|
||||
#[inline]
|
||||
pub fn queue_family(&self) -> QueueFamily {
|
||||
self.device
|
||||
.physical_device()
|
||||
.queue_family_by_id(self.queue_family_index)
|
||||
.unwrap()
|
||||
pub fn queue_family_index(&self) -> u32 {
|
||||
self.queue_family_index
|
||||
}
|
||||
}
|
||||
|
||||
@ -364,7 +357,7 @@ impl Hash for UnsafeCommandPool {
|
||||
}
|
||||
|
||||
/// Error that can happen when creating an `UnsafeCommandPool`.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum UnsafeCommandPoolCreationError {
|
||||
/// Not enough memory.
|
||||
OomError(OomError),
|
||||
@ -576,7 +569,7 @@ mod tests {
|
||||
let _ = UnsafeCommandPool::new(
|
||||
device,
|
||||
UnsafeCommandPoolCreateInfo {
|
||||
queue_family_index: queue.family().id(),
|
||||
queue_family_index: queue.queue_family_index(),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -589,12 +582,12 @@ mod tests {
|
||||
let pool = UnsafeCommandPool::new(
|
||||
device,
|
||||
UnsafeCommandPoolCreateInfo {
|
||||
queue_family_index: queue.family().id(),
|
||||
queue_family_index: queue.queue_family_index(),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(pool.queue_family().id(), queue.family().id());
|
||||
assert_eq!(pool.queue_family_index(), queue.queue_family_index());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -618,7 +611,7 @@ mod tests {
|
||||
let pool = UnsafeCommandPool::new(
|
||||
device.clone(),
|
||||
UnsafeCommandPoolCreateInfo {
|
||||
queue_family_index: queue.family().id(),
|
||||
queue_family_index: queue.queue_family_index(),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -660,7 +653,7 @@ mod tests {
|
||||
let pool = UnsafeCommandPool::new(
|
||||
device,
|
||||
UnsafeCommandPoolCreateInfo {
|
||||
queue_family_index: queue.family().id(),
|
||||
queue_family_index: queue.queue_family_index(),
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
|
@ -136,7 +136,12 @@ impl<'a> SubmitBindSparseBuilder<'a> {
|
||||
/// Submits the command. Calls `vkQueueBindSparse`.
|
||||
pub fn submit(self, queue: &Queue) -> Result<(), SubmitBindSparseError> {
|
||||
unsafe {
|
||||
debug_assert!(queue.family().supports_sparse_binding());
|
||||
debug_assert!(
|
||||
queue.device().physical_device().queue_family_properties()
|
||||
[queue.queue_family_index() as usize]
|
||||
.queue_flags
|
||||
.sparse_binding
|
||||
);
|
||||
|
||||
let fns = queue.device().fns();
|
||||
let queue = queue.internal_object_guard();
|
||||
|
@ -553,7 +553,7 @@ mod tests {
|
||||
let (device, queue) = gfx_dev_and_queue!();
|
||||
|
||||
let pool_builder_alloc = device
|
||||
.with_standard_command_pool(queue.family(), |pool| {
|
||||
.with_standard_command_pool(queue.queue_family_index(), |pool| {
|
||||
pool.allocate(CommandBufferLevel::Primary, 1)
|
||||
.unwrap()
|
||||
.next()
|
||||
@ -598,7 +598,7 @@ mod tests {
|
||||
.map(|_| {
|
||||
let mut builder = AutoCommandBufferBuilder::secondary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::SimultaneousUse,
|
||||
Default::default(),
|
||||
)
|
||||
@ -614,7 +614,7 @@ mod tests {
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let allocs = device
|
||||
.with_standard_command_pool(queue.family(), |pool| {
|
||||
.with_standard_command_pool(queue.queue_family_index(), |pool| {
|
||||
pool.allocate(CommandBufferLevel::Primary, 2)
|
||||
.unwrap()
|
||||
.collect::<Vec<_>>()
|
||||
@ -676,7 +676,7 @@ mod tests {
|
||||
let (device, queue) = gfx_dev_and_queue!();
|
||||
|
||||
let pool_builder_alloc = device
|
||||
.with_standard_command_pool(queue.family(), |pool| {
|
||||
.with_standard_command_pool(queue.queue_family_index(), |pool| {
|
||||
pool.allocate(CommandBufferLevel::Primary, 1)
|
||||
.unwrap()
|
||||
.next()
|
||||
@ -717,7 +717,7 @@ mod tests {
|
||||
let (device, queue) = gfx_dev_and_queue!();
|
||||
|
||||
let pool_builder_alloc = device
|
||||
.with_standard_command_pool(queue.family(), |pool| {
|
||||
.with_standard_command_pool(queue.queue_family_index(), |pool| {
|
||||
pool.allocate(CommandBufferLevel::Primary, 1)
|
||||
.unwrap()
|
||||
.next()
|
||||
|
@ -29,11 +29,13 @@
|
||||
//!
|
||||
//! // We just choose the first physical device. In a real application you would choose depending
|
||||
//! // on the capabilities of the physical device and the user's preferences.
|
||||
//! let physical_device = PhysicalDevice::enumerate(&instance).next().expect("No physical device");
|
||||
//! let physical_device = instance
|
||||
//! .enumerate_physical_devices()
|
||||
//! .unwrap_or_else(|err| panic!("Couldn't enumerate physical devices: {:?}", err))
|
||||
//! .next().expect("No physical device");
|
||||
//!
|
||||
//! // Here is the device-creating code.
|
||||
//! let device = {
|
||||
//! let queue_family = physical_device.queue_families().next().unwrap();
|
||||
//! let features = Features::empty();
|
||||
//! let extensions = DeviceExtensions::empty();
|
||||
//!
|
||||
@ -42,7 +44,10 @@
|
||||
//! DeviceCreateInfo {
|
||||
//! enabled_extensions: extensions,
|
||||
//! enabled_features: features,
|
||||
//! queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
//! queue_create_infos: vec![QueueCreateInfo {
|
||||
//! queue_family_index: 0,
|
||||
//! ..Default::default()
|
||||
//! }],
|
||||
//! ..Default::default()
|
||||
//! },
|
||||
//! ) {
|
||||
@ -96,7 +101,7 @@
|
||||
//!
|
||||
//! TODO: write
|
||||
|
||||
use self::physical::{PhysicalDevice, QueueFamily};
|
||||
use self::physical::PhysicalDevice;
|
||||
pub(crate) use self::{features::FeaturesFfi, properties::PropertiesFfi};
|
||||
pub use self::{
|
||||
features::{FeatureRestriction, FeatureRestrictionError, Features},
|
||||
@ -142,8 +147,7 @@ pub(crate) mod properties;
|
||||
#[derive(Debug)]
|
||||
pub struct Device {
|
||||
handle: ash::vk::Device,
|
||||
instance: Arc<Instance>,
|
||||
physical_device: usize,
|
||||
physical_device: Arc<PhysicalDevice>,
|
||||
|
||||
// The highest version that is supported for this device.
|
||||
// This is the minimum of Instance::max_api_version and PhysicalDevice::api_version.
|
||||
@ -153,7 +157,7 @@ pub struct Device {
|
||||
standard_memory_pool: OnceCell<Arc<StandardMemoryPool>>,
|
||||
enabled_extensions: DeviceExtensions,
|
||||
enabled_features: Features,
|
||||
active_queue_families: SmallVec<[u32; 2]>,
|
||||
active_queue_family_indices: SmallVec<[u32; 2]>,
|
||||
allocation_count: Mutex<u32>,
|
||||
fence_pool: Mutex<Vec<ash::vk::Fence>>,
|
||||
semaphore_pool: Mutex<Vec<ash::vk::Semaphore>>,
|
||||
@ -178,7 +182,7 @@ impl Device {
|
||||
/// - Panics if `create_info.queues` contains an element where `queues` contains a value that is
|
||||
/// not between 0.0 and 1.0 inclusive.
|
||||
pub fn new(
|
||||
physical_device: PhysicalDevice,
|
||||
physical_device: Arc<PhysicalDevice>,
|
||||
create_info: DeviceCreateInfo,
|
||||
) -> Result<(Arc<Device>, impl ExactSizeIterator<Item = Arc<Queue>>), DeviceCreationError> {
|
||||
let DeviceCreateInfo {
|
||||
@ -197,7 +201,7 @@ impl Device {
|
||||
*/
|
||||
|
||||
struct QueueToGet {
|
||||
family: u32,
|
||||
queue_family_index: u32,
|
||||
id: u32,
|
||||
}
|
||||
|
||||
@ -206,26 +210,27 @@ impl Device {
|
||||
|
||||
let mut queue_create_infos_vk: SmallVec<[_; 2]> =
|
||||
SmallVec::with_capacity(queue_create_infos.len());
|
||||
let mut active_queue_families: SmallVec<[_; 2]> =
|
||||
let mut active_queue_family_indices: SmallVec<[_; 2]> =
|
||||
SmallVec::with_capacity(queue_create_infos.len());
|
||||
let mut queues_to_get: SmallVec<[_; 2]> = SmallVec::with_capacity(queue_create_infos.len());
|
||||
|
||||
for QueueCreateInfo {
|
||||
family,
|
||||
queues,
|
||||
for queue_create_info in &queue_create_infos {
|
||||
let &QueueCreateInfo {
|
||||
queue_family_index,
|
||||
ref queues,
|
||||
_ne: _,
|
||||
} in &queue_create_infos
|
||||
{
|
||||
assert_eq!(
|
||||
family.physical_device().internal_object(),
|
||||
physical_device.internal_object()
|
||||
);
|
||||
} = queue_create_info;
|
||||
|
||||
// VUID-VkDeviceQueueCreateInfo-queueFamilyIndex-00381
|
||||
// TODO: return error instead of panicking?
|
||||
let queue_family_properties =
|
||||
&physical_device.queue_family_properties()[queue_family_index as usize];
|
||||
|
||||
// VUID-VkDeviceCreateInfo-queueFamilyIndex-02802
|
||||
assert!(
|
||||
queue_create_infos
|
||||
.iter()
|
||||
.filter(|qc2| qc2.family == *family)
|
||||
.filter(|qc2| qc2.queue_family_index == queue_family_index)
|
||||
.count()
|
||||
== 1
|
||||
);
|
||||
@ -238,24 +243,26 @@ impl Device {
|
||||
.iter()
|
||||
.all(|&priority| (0.0..=1.0).contains(&priority)));
|
||||
|
||||
if queues.len() > family.queues_count() {
|
||||
if queues.len() > queue_family_properties.queue_count as usize {
|
||||
return Err(DeviceCreationError::TooManyQueuesForFamily);
|
||||
}
|
||||
|
||||
let family = family.id();
|
||||
queue_create_infos_vk.push(ash::vk::DeviceQueueCreateInfo {
|
||||
flags: ash::vk::DeviceQueueCreateFlags::empty(),
|
||||
queue_family_index: family,
|
||||
queue_family_index,
|
||||
queue_count: queues.len() as u32,
|
||||
p_queue_priorities: queues.as_ptr(), // borrows from queue_create
|
||||
..Default::default()
|
||||
});
|
||||
active_queue_families.push(family);
|
||||
queues_to_get.extend((0..queues.len() as u32).map(move |id| QueueToGet { family, id }));
|
||||
active_queue_family_indices.push(queue_family_index);
|
||||
queues_to_get.extend((0..queues.len() as u32).map(move |id| QueueToGet {
|
||||
queue_family_index,
|
||||
id,
|
||||
}));
|
||||
}
|
||||
|
||||
active_queue_families.sort_unstable();
|
||||
active_queue_families.dedup();
|
||||
active_queue_family_indices.sort_unstable();
|
||||
active_queue_family_indices.dedup();
|
||||
let supported_extensions = physical_device.supported_extensions();
|
||||
|
||||
if supported_extensions.khr_portability_subset {
|
||||
@ -404,14 +411,13 @@ impl Device {
|
||||
|
||||
let device = Arc::new(Device {
|
||||
handle,
|
||||
instance: physical_device.instance().clone(),
|
||||
physical_device: physical_device.index(),
|
||||
physical_device,
|
||||
api_version,
|
||||
fns,
|
||||
standard_memory_pool: OnceCell::new(),
|
||||
enabled_extensions,
|
||||
enabled_features,
|
||||
active_queue_families,
|
||||
active_queue_family_indices,
|
||||
allocation_count: Mutex::new(0),
|
||||
fence_pool: Mutex::new(Vec::new()),
|
||||
semaphore_pool: Mutex::new(Vec::new()),
|
||||
@ -421,20 +427,28 @@ impl Device {
|
||||
// Iterator to return the queues
|
||||
let queues_iter = {
|
||||
let device = device.clone();
|
||||
queues_to_get
|
||||
.into_iter()
|
||||
.map(move |QueueToGet { family, id }| unsafe {
|
||||
queues_to_get.into_iter().map(
|
||||
move |QueueToGet {
|
||||
queue_family_index,
|
||||
id,
|
||||
}| unsafe {
|
||||
let fns = device.fns();
|
||||
let mut output = MaybeUninit::uninit();
|
||||
(fns.v1_0.get_device_queue)(handle, family, id, output.as_mut_ptr());
|
||||
(fns.v1_0.get_device_queue)(
|
||||
handle,
|
||||
queue_family_index,
|
||||
id,
|
||||
output.as_mut_ptr(),
|
||||
);
|
||||
|
||||
Arc::new(Queue {
|
||||
handle: Mutex::new(output.assume_init()),
|
||||
device: device.clone(),
|
||||
family,
|
||||
queue_family_index,
|
||||
id,
|
||||
})
|
||||
})
|
||||
},
|
||||
)
|
||||
};
|
||||
|
||||
Ok((device, queues_iter))
|
||||
@ -456,47 +470,22 @@ impl Device {
|
||||
&self.fns
|
||||
}
|
||||
|
||||
/// Waits until all work on this device has finished. You should never need to call
|
||||
/// this function, but it can be useful for debugging or benchmarking purposes.
|
||||
///
|
||||
/// > **Note**: This is the Vulkan equivalent of OpenGL's `glFinish`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This function is not thread-safe. You must not submit anything to any of the queue
|
||||
/// of the device (either explicitly or implicitly, for example with a future's destructor)
|
||||
/// while this function is waiting.
|
||||
///
|
||||
pub unsafe fn wait(&self) -> Result<(), OomError> {
|
||||
let fns = self.fns();
|
||||
(fns.v1_0.device_wait_idle)(self.handle)
|
||||
.result()
|
||||
.map_err(VulkanError::from)?;
|
||||
Ok(())
|
||||
/// Returns the physical device that was used to create this device.
|
||||
#[inline]
|
||||
pub fn physical_device(&self) -> &Arc<PhysicalDevice> {
|
||||
&self.physical_device
|
||||
}
|
||||
|
||||
/// Returns the instance used to create this device.
|
||||
#[inline]
|
||||
pub fn instance(&self) -> &Arc<Instance> {
|
||||
&self.instance
|
||||
self.physical_device.instance()
|
||||
}
|
||||
|
||||
/// Returns the physical device that was used to create this device.
|
||||
/// Returns the queue family indices that this device uses.
|
||||
#[inline]
|
||||
pub fn physical_device(&self) -> PhysicalDevice {
|
||||
PhysicalDevice::from_index(&self.instance, self.physical_device).unwrap()
|
||||
}
|
||||
|
||||
/// Returns an iterator to the list of queues families that this device uses.
|
||||
///
|
||||
/// > **Note**: Will return `-> impl ExactSizeIterator<Item = QueueFamily>` in the future.
|
||||
// TODO: ^
|
||||
#[inline]
|
||||
pub fn active_queue_families(&self) -> impl ExactSizeIterator<Item = QueueFamily> {
|
||||
let physical_device = self.physical_device();
|
||||
self.active_queue_families
|
||||
.iter()
|
||||
.map(move |&id| physical_device.queue_family_by_id(id).unwrap())
|
||||
pub fn active_queue_family_indices(&self) -> &[u32] {
|
||||
&self.active_queue_family_indices
|
||||
}
|
||||
|
||||
/// Returns the extensions that have been enabled on the device.
|
||||
@ -561,7 +550,7 @@ impl Device {
|
||||
/// - Panics if called again from within the callback.
|
||||
pub fn with_standard_command_pool<T>(
|
||||
self: &Arc<Self>,
|
||||
queue_family: QueueFamily,
|
||||
queue_family_index: u32,
|
||||
f: impl FnOnce(&Arc<StandardCommandPool>) -> T,
|
||||
) -> Result<T, OomError> {
|
||||
thread_local! {
|
||||
@ -571,11 +560,11 @@ impl Device {
|
||||
|
||||
TLS.with(|tls| {
|
||||
let mut tls = tls.borrow_mut();
|
||||
let pool = match tls.entry((self.internal_object(), queue_family.id())) {
|
||||
let pool = match tls.entry((self.internal_object(), queue_family_index)) {
|
||||
Entry::Occupied(entry) => entry.into_mut(),
|
||||
Entry::Vacant(entry) => entry.insert(Arc::new(StandardCommandPool::new(
|
||||
self.clone(),
|
||||
queue_family,
|
||||
queue_family_index,
|
||||
)?)),
|
||||
};
|
||||
|
||||
@ -680,7 +669,7 @@ impl Device {
|
||||
};
|
||||
|
||||
unsafe {
|
||||
let fns = self.instance.fns();
|
||||
let fns = self.instance().fns();
|
||||
(fns.ext_debug_utils.set_debug_utils_object_name_ext)(self.handle, &info)
|
||||
.result()
|
||||
.map_err(VulkanError::from)?;
|
||||
@ -688,6 +677,25 @@ impl Device {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Waits until all work on this device has finished. You should never need to call
|
||||
/// this function, but it can be useful for debugging or benchmarking purposes.
|
||||
///
|
||||
/// > **Note**: This is the Vulkan equivalent of OpenGL's `glFinish`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// This function is not thread-safe. You must not submit anything to any of the queue
|
||||
/// of the device (either explicitly or implicitly, for example with a future's destructor)
|
||||
/// while this function is waiting.
|
||||
///
|
||||
pub unsafe fn wait(&self) -> Result<(), OomError> {
|
||||
let fns = self.fns();
|
||||
(fns.v1_0.device_wait_idle)(self.handle)
|
||||
.result()
|
||||
.map_err(VulkanError::from)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Device {
|
||||
@ -722,7 +730,7 @@ unsafe impl VulkanObject for Device {
|
||||
impl PartialEq for Device {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.handle == other.handle && self.instance == other.instance
|
||||
self.handle == other.handle && self.physical_device == other.physical_device
|
||||
}
|
||||
}
|
||||
|
||||
@ -732,7 +740,7 @@ impl Hash for Device {
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.handle.hash(state);
|
||||
self.instance.hash(state);
|
||||
self.physical_device.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
@ -840,7 +848,7 @@ impl From<FeatureRestrictionError> for DeviceCreationError {
|
||||
|
||||
/// Parameters to create a new `Device`.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DeviceCreateInfo<'qf> {
|
||||
pub struct DeviceCreateInfo {
|
||||
/// The extensions to enable on the device.
|
||||
///
|
||||
/// The default value is [`DeviceExtensions::empty()`].
|
||||
@ -854,12 +862,12 @@ pub struct DeviceCreateInfo<'qf> {
|
||||
/// The queues to create for the device.
|
||||
///
|
||||
/// The default value is empty, which must be overridden.
|
||||
pub queue_create_infos: Vec<QueueCreateInfo<'qf>>,
|
||||
pub queue_create_infos: Vec<QueueCreateInfo>,
|
||||
|
||||
pub _ne: crate::NonExhaustive,
|
||||
}
|
||||
|
||||
impl Default for DeviceCreateInfo<'static> {
|
||||
impl Default for DeviceCreateInfo {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
@ -873,9 +881,11 @@ impl Default for DeviceCreateInfo<'static> {
|
||||
|
||||
/// Parameters to create queues in a new `Device`.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct QueueCreateInfo<'qf> {
|
||||
/// The queue family to create queues for.
|
||||
pub family: QueueFamily<'qf>,
|
||||
pub struct QueueCreateInfo {
|
||||
/// The index of the queue family to create queues for.
|
||||
///
|
||||
/// The default value is `0`.
|
||||
pub queue_family_index: u32,
|
||||
|
||||
/// The queues to create for the given queue family, each with a relative priority.
|
||||
///
|
||||
@ -890,12 +900,11 @@ pub struct QueueCreateInfo<'qf> {
|
||||
pub _ne: crate::NonExhaustive,
|
||||
}
|
||||
|
||||
impl<'qf> QueueCreateInfo<'qf> {
|
||||
/// Returns a `QueueCreateInfo` with the given queue family.
|
||||
impl Default for QueueCreateInfo {
|
||||
#[inline]
|
||||
pub fn family(family: QueueFamily) -> QueueCreateInfo {
|
||||
QueueCreateInfo {
|
||||
family,
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
queue_family_index: 0,
|
||||
queues: vec![0.5],
|
||||
_ne: crate::NonExhaustive(()),
|
||||
}
|
||||
@ -1011,7 +1020,7 @@ impl From<RequirementNotMet> for MemoryFdPropertiesError {
|
||||
pub struct Queue {
|
||||
handle: Mutex<ash::vk::Queue>,
|
||||
device: Arc<Device>,
|
||||
family: u32,
|
||||
queue_family_index: u32,
|
||||
id: u32, // id within family
|
||||
}
|
||||
|
||||
@ -1022,16 +1031,13 @@ impl Queue {
|
||||
&self.device
|
||||
}
|
||||
|
||||
/// Returns the family this queue belongs to.
|
||||
/// Returns the queue family that this queue belongs to.
|
||||
#[inline]
|
||||
pub fn family(&self) -> QueueFamily {
|
||||
self.device
|
||||
.physical_device()
|
||||
.queue_family_by_id(self.family)
|
||||
.unwrap()
|
||||
pub fn queue_family_index(&self) -> u32 {
|
||||
self.queue_family_index
|
||||
}
|
||||
|
||||
/// Returns the index of this queue within its family.
|
||||
/// Returns the index of this queue within its queue family.
|
||||
#[inline]
|
||||
pub fn id_within_family(&self) -> u32 {
|
||||
self.id
|
||||
@ -1224,7 +1230,9 @@ unsafe impl DeviceOwned for Queue {
|
||||
|
||||
impl PartialEq for Queue {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.id == other.id && self.family == other.family && self.device == other.device
|
||||
self.id == other.id
|
||||
&& self.queue_family_index == other.queue_family_index
|
||||
&& self.device == other.device
|
||||
}
|
||||
}
|
||||
|
||||
@ -1234,7 +1242,7 @@ impl Hash for Queue {
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.id.hash(state);
|
||||
self.family.hash(state);
|
||||
self.queue_family_index.hash(state);
|
||||
self.device.hash(state);
|
||||
}
|
||||
}
|
||||
@ -1269,8 +1277,8 @@ impl Display for DebugUtilsError {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::device::{
|
||||
physical::PhysicalDevice, Device, DeviceCreateInfo, DeviceCreationError,
|
||||
FeatureRestriction, FeatureRestrictionError, Features, QueueCreateInfo,
|
||||
Device, DeviceCreateInfo, DeviceCreationError, FeatureRestriction, FeatureRestrictionError,
|
||||
Features, QueueCreateInfo,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -1283,20 +1291,25 @@ mod tests {
|
||||
#[test]
|
||||
fn too_many_queues() {
|
||||
let instance = instance!();
|
||||
let physical = match PhysicalDevice::enumerate(&instance).next() {
|
||||
let physical_device = match instance.enumerate_physical_devices().unwrap().next() {
|
||||
Some(p) => p,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let family = physical.queue_families().next().unwrap();
|
||||
let _queues = (0..family.queues_count() + 1).map(|_| (family, 1.0));
|
||||
let queue_family_index = 0;
|
||||
let queue_family_properties =
|
||||
&physical_device.queue_family_properties()[queue_family_index as usize];
|
||||
let queues = (0..queue_family_properties.queue_count + 1)
|
||||
.map(|_| (0.5))
|
||||
.collect();
|
||||
|
||||
match Device::new(
|
||||
physical,
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queues: (0..family.queues_count() + 1).map(|_| (0.5)).collect(),
|
||||
..QueueCreateInfo::family(family)
|
||||
queue_family_index,
|
||||
queues,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
@ -1307,26 +1320,27 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unsupposed_features() {
|
||||
fn unsupported_features() {
|
||||
let instance = instance!();
|
||||
let physical = match PhysicalDevice::enumerate(&instance).next() {
|
||||
let physical_device = match instance.enumerate_physical_devices().unwrap().next() {
|
||||
Some(p) => p,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let family = physical.queue_families().next().unwrap();
|
||||
|
||||
let features = Features::all();
|
||||
// In the unlikely situation where the device supports everything, we ignore the test.
|
||||
if physical.supported_features().contains(&features) {
|
||||
if physical_device.supported_features().contains(&features) {
|
||||
return;
|
||||
}
|
||||
|
||||
match Device::new(
|
||||
physical,
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
enabled_features: features,
|
||||
queue_create_infos: vec![QueueCreateInfo::family(family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index: 0,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
) {
|
||||
@ -1341,20 +1355,19 @@ mod tests {
|
||||
#[test]
|
||||
fn priority_out_of_range() {
|
||||
let instance = instance!();
|
||||
let physical = match PhysicalDevice::enumerate(&instance).next() {
|
||||
let physical_device = match instance.enumerate_physical_devices().unwrap().next() {
|
||||
Some(p) => p,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let family = physical.queue_families().next().unwrap();
|
||||
|
||||
assert_should_panic!({
|
||||
Device::new(
|
||||
physical,
|
||||
physical_device.clone(),
|
||||
DeviceCreateInfo {
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index: 0,
|
||||
queues: vec![1.4],
|
||||
..QueueCreateInfo::family(family)
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
@ -1363,11 +1376,12 @@ mod tests {
|
||||
|
||||
assert_should_panic!({
|
||||
Device::new(
|
||||
physical,
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index: 0,
|
||||
queues: vec![-0.2],
|
||||
..QueueCreateInfo::family(family)
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -443,7 +443,7 @@ impl AttachmentImage {
|
||||
MappingRequirement::DoNotMap,
|
||||
Some(DedicatedAllocation::Image(&image)),
|
||||
|t| {
|
||||
if t.is_device_local() {
|
||||
if t.property_flags.device_local {
|
||||
AllocFromRequirementsFilter::Preferred
|
||||
} else {
|
||||
AllocFromRequirementsFilter::Allowed
|
||||
@ -523,7 +523,7 @@ impl AttachmentImage {
|
||||
MappingRequirement::DoNotMap,
|
||||
DedicatedAllocation::Image(&image),
|
||||
|t| {
|
||||
if t.is_device_local() {
|
||||
if t.property_flags.device_local {
|
||||
AllocFromRequirementsFilter::Preferred
|
||||
} else {
|
||||
AllocFromRequirementsFilter::Allowed
|
||||
|
@ -19,7 +19,7 @@ use crate::{
|
||||
CommandBufferUsage, CopyBufferToImageInfo, ImageBlit, PrimaryAutoCommandBuffer,
|
||||
PrimaryCommandBuffer,
|
||||
},
|
||||
device::{physical::QueueFamily, Device, DeviceOwned, Queue},
|
||||
device::{Device, DeviceOwned, Queue},
|
||||
format::Format,
|
||||
image::sys::UnsafeImageCreateInfo,
|
||||
memory::{
|
||||
@ -101,38 +101,31 @@ fn generate_mipmaps<L>(
|
||||
impl ImmutableImage {
|
||||
#[deprecated(note = "use ImmutableImage::uninitialized instead")]
|
||||
#[inline]
|
||||
pub fn new<'a, I>(
|
||||
pub fn new(
|
||||
device: Arc<Device>,
|
||||
dimensions: ImageDimensions,
|
||||
format: Format,
|
||||
queue_families: I,
|
||||
) -> Result<Arc<ImmutableImage>, ImmutableImageCreationError>
|
||||
where
|
||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
||||
{
|
||||
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||
) -> Result<Arc<ImmutableImage>, ImmutableImageCreationError> {
|
||||
#[allow(deprecated)]
|
||||
ImmutableImage::with_mipmaps(
|
||||
device,
|
||||
dimensions,
|
||||
format,
|
||||
MipmapsCount::One,
|
||||
queue_families,
|
||||
queue_family_indices,
|
||||
)
|
||||
}
|
||||
|
||||
#[deprecated(note = "use ImmutableImage::uninitialized instead")]
|
||||
#[inline]
|
||||
pub fn with_mipmaps<'a, I, M>(
|
||||
pub fn with_mipmaps(
|
||||
device: Arc<Device>,
|
||||
dimensions: ImageDimensions,
|
||||
format: Format,
|
||||
mip_levels: M,
|
||||
queue_families: I,
|
||||
) -> Result<Arc<ImmutableImage>, ImmutableImageCreationError>
|
||||
where
|
||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
||||
M: Into<MipmapsCount>,
|
||||
{
|
||||
mip_levels: impl Into<MipmapsCount>,
|
||||
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||
) -> Result<Arc<ImmutableImage>, ImmutableImageCreationError> {
|
||||
let usage = ImageUsage {
|
||||
transfer_src: true, // for blits
|
||||
transfer_dst: true,
|
||||
@ -150,7 +143,7 @@ impl ImmutableImage {
|
||||
usage,
|
||||
flags,
|
||||
ImageLayout::ShaderReadOnlyOptimal,
|
||||
queue_families,
|
||||
queue_family_indices,
|
||||
)?;
|
||||
Ok(image)
|
||||
}
|
||||
@ -158,24 +151,18 @@ impl ImmutableImage {
|
||||
/// Builds an uninitialized immutable image.
|
||||
///
|
||||
/// Returns two things: the image, and a special access that should be used for the initial upload to the image.
|
||||
pub fn uninitialized<'a, I, M>(
|
||||
pub fn uninitialized(
|
||||
device: Arc<Device>,
|
||||
dimensions: ImageDimensions,
|
||||
format: Format,
|
||||
mip_levels: M,
|
||||
mip_levels: impl Into<MipmapsCount>,
|
||||
usage: ImageUsage,
|
||||
flags: ImageCreateFlags,
|
||||
layout: ImageLayout,
|
||||
queue_families: I,
|
||||
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||
) -> Result<(Arc<ImmutableImage>, Arc<ImmutableImageInitialization>), ImmutableImageCreationError>
|
||||
where
|
||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
||||
M: Into<MipmapsCount>,
|
||||
{
|
||||
let queue_families = queue_families
|
||||
.into_iter()
|
||||
.map(|f| f.id())
|
||||
.collect::<SmallVec<[u32; 4]>>();
|
||||
let queue_family_indices: SmallVec<[_; 4]> = queue_family_indices.into_iter().collect();
|
||||
|
||||
let image = UnsafeImage::new(
|
||||
device.clone(),
|
||||
@ -188,8 +175,8 @@ impl ImmutableImage {
|
||||
MipmapsCount::One => 1,
|
||||
},
|
||||
usage,
|
||||
sharing: if queue_families.len() >= 2 {
|
||||
Sharing::Concurrent(queue_families.iter().cloned().collect())
|
||||
sharing: if queue_family_indices.len() >= 2 {
|
||||
Sharing::Concurrent(queue_family_indices)
|
||||
} else {
|
||||
Sharing::Exclusive
|
||||
},
|
||||
@ -209,7 +196,7 @@ impl ImmutableImage {
|
||||
MappingRequirement::DoNotMap,
|
||||
Some(DedicatedAllocation::Image(&image)),
|
||||
|t| {
|
||||
if t.is_device_local() {
|
||||
if t.property_flags.device_local {
|
||||
AllocFromRequirementsFilter::Preferred
|
||||
} else {
|
||||
AllocFromRequirementsFilter::Allowed
|
||||
@ -299,12 +286,16 @@ impl ImmutableImage {
|
||||
usage,
|
||||
flags,
|
||||
layout,
|
||||
source.device().active_queue_families(),
|
||||
source
|
||||
.device()
|
||||
.active_queue_family_indices()
|
||||
.iter()
|
||||
.copied(),
|
||||
)?;
|
||||
|
||||
let mut cbb = AutoCommandBufferBuilder::primary(
|
||||
source.device().clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::MultipleSubmit,
|
||||
)?;
|
||||
cbb.copy_buffer_to_image(CopyBufferToImageInfo::buffer_image(source, initializer))
|
||||
|
@ -12,7 +12,7 @@ use super::{
|
||||
ImageDescriptorLayouts, ImageDimensions, ImageInner, ImageLayout, ImageUsage,
|
||||
};
|
||||
use crate::{
|
||||
device::{physical::QueueFamily, Device, DeviceOwned, Queue},
|
||||
device::{Device, DeviceOwned, Queue},
|
||||
format::Format,
|
||||
image::{sys::UnsafeImageCreateInfo, view::ImageView},
|
||||
memory::{
|
||||
@ -53,15 +53,12 @@ where
|
||||
impl StorageImage {
|
||||
/// Creates a new image with the given dimensions and format.
|
||||
#[inline]
|
||||
pub fn new<'a, I>(
|
||||
pub fn new(
|
||||
device: Arc<Device>,
|
||||
dimensions: ImageDimensions,
|
||||
format: Format,
|
||||
queue_families: I,
|
||||
) -> Result<Arc<StorageImage>, ImageCreationError>
|
||||
where
|
||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
||||
{
|
||||
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||
) -> Result<Arc<StorageImage>, ImageCreationError> {
|
||||
let aspects = format.aspects();
|
||||
let is_depth = aspects.depth || aspects.stencil;
|
||||
|
||||
@ -81,25 +78,26 @@ impl StorageImage {
|
||||
};
|
||||
let flags = ImageCreateFlags::empty();
|
||||
|
||||
StorageImage::with_usage(device, dimensions, format, usage, flags, queue_families)
|
||||
StorageImage::with_usage(
|
||||
device,
|
||||
dimensions,
|
||||
format,
|
||||
usage,
|
||||
flags,
|
||||
queue_family_indices,
|
||||
)
|
||||
}
|
||||
|
||||
/// Same as `new`, but allows specifying the usage.
|
||||
pub fn with_usage<'a, I>(
|
||||
pub fn with_usage(
|
||||
device: Arc<Device>,
|
||||
dimensions: ImageDimensions,
|
||||
format: Format,
|
||||
usage: ImageUsage,
|
||||
flags: ImageCreateFlags,
|
||||
queue_families: I,
|
||||
) -> Result<Arc<StorageImage>, ImageCreationError>
|
||||
where
|
||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
||||
{
|
||||
let queue_families = queue_families
|
||||
.into_iter()
|
||||
.map(|f| f.id())
|
||||
.collect::<SmallVec<[u32; 4]>>();
|
||||
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||
) -> Result<Arc<StorageImage>, ImageCreationError> {
|
||||
let queue_family_indices: SmallVec<[_; 4]> = queue_family_indices.into_iter().collect();
|
||||
|
||||
let image = UnsafeImage::new(
|
||||
device.clone(),
|
||||
@ -107,8 +105,8 @@ impl StorageImage {
|
||||
dimensions,
|
||||
format: Some(format),
|
||||
usage,
|
||||
sharing: if queue_families.len() >= 2 {
|
||||
Sharing::Concurrent(queue_families.iter().cloned().collect())
|
||||
sharing: if queue_family_indices.len() >= 2 {
|
||||
Sharing::Concurrent(queue_family_indices)
|
||||
} else {
|
||||
Sharing::Exclusive
|
||||
},
|
||||
@ -128,7 +126,7 @@ impl StorageImage {
|
||||
MappingRequirement::DoNotMap,
|
||||
Some(DedicatedAllocation::Image(&image)),
|
||||
|t| {
|
||||
if t.is_device_local() {
|
||||
if t.property_flags.device_local {
|
||||
AllocFromRequirementsFilter::Preferred
|
||||
} else {
|
||||
AllocFromRequirementsFilter::Allowed
|
||||
@ -147,21 +145,15 @@ impl StorageImage {
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn new_with_exportable_fd<'a, I>(
|
||||
pub fn new_with_exportable_fd(
|
||||
device: Arc<Device>,
|
||||
dimensions: ImageDimensions,
|
||||
format: Format,
|
||||
usage: ImageUsage,
|
||||
flags: ImageCreateFlags,
|
||||
queue_families: I,
|
||||
) -> Result<Arc<StorageImage>, ImageCreationError>
|
||||
where
|
||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
||||
{
|
||||
let queue_families = queue_families
|
||||
.into_iter()
|
||||
.map(|f| f.id())
|
||||
.collect::<SmallVec<[u32; 4]>>();
|
||||
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||
) -> Result<Arc<StorageImage>, ImageCreationError> {
|
||||
let queue_family_indices: SmallVec<[_; 4]> = queue_family_indices.into_iter().collect();
|
||||
|
||||
let image = UnsafeImage::new(
|
||||
device.clone(),
|
||||
@ -169,8 +161,8 @@ impl StorageImage {
|
||||
dimensions,
|
||||
format: Some(format),
|
||||
usage,
|
||||
sharing: if queue_families.len() >= 2 {
|
||||
Sharing::Concurrent(queue_families.iter().cloned().collect())
|
||||
sharing: if queue_family_indices.len() >= 2 {
|
||||
Sharing::Concurrent(queue_family_indices)
|
||||
} else {
|
||||
Sharing::Exclusive
|
||||
},
|
||||
@ -194,7 +186,7 @@ impl StorageImage {
|
||||
MappingRequirement::DoNotMap,
|
||||
DedicatedAllocation::Image(&image),
|
||||
|t| {
|
||||
if t.is_device_local() {
|
||||
if t.property_flags.device_local {
|
||||
AllocFromRequirementsFilter::Preferred
|
||||
} else {
|
||||
AllocFromRequirementsFilter::Allowed
|
||||
@ -232,7 +224,7 @@ impl StorageImage {
|
||||
format,
|
||||
usage,
|
||||
flags,
|
||||
Some(queue.family()),
|
||||
Some(queue.queue_family_index()),
|
||||
);
|
||||
match image_result {
|
||||
Ok(image) => {
|
||||
@ -359,7 +351,7 @@ mod tests {
|
||||
array_layers: 1,
|
||||
},
|
||||
Format::R8G8B8A8_UNORM,
|
||||
Some(queue.family()),
|
||||
Some(queue.queue_family_index()),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
@ -485,16 +485,24 @@ impl UnsafeImage {
|
||||
|
||||
match sharing {
|
||||
Sharing::Exclusive => (),
|
||||
Sharing::Concurrent(ids) => {
|
||||
Sharing::Concurrent(queue_family_indices) => {
|
||||
// VUID-VkImageCreateInfo-sharingMode-00942
|
||||
ids.sort_unstable();
|
||||
ids.dedup();
|
||||
assert!(ids.len() >= 2);
|
||||
queue_family_indices.sort_unstable();
|
||||
queue_family_indices.dedup();
|
||||
assert!(queue_family_indices.len() >= 2);
|
||||
|
||||
for &id in ids.iter() {
|
||||
for &queue_family_index in queue_family_indices.iter() {
|
||||
// VUID-VkImageCreateInfo-sharingMode-01420
|
||||
if device.physical_device().queue_family_by_id(id).is_none() {
|
||||
return Err(ImageCreationError::SharingInvalidQueueFamilyId { id });
|
||||
if queue_family_index
|
||||
>= device.physical_device().queue_family_properties().len() as u32
|
||||
{
|
||||
return Err(ImageCreationError::SharingQueueFamilyIndexOutOfRange {
|
||||
queue_family_index,
|
||||
queue_family_count: device
|
||||
.physical_device()
|
||||
.queue_family_properties()
|
||||
.len() as u32,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1022,7 +1030,7 @@ impl UnsafeImage {
|
||||
let mem_reqs = mem_reqs.assume_init();
|
||||
mem_reqs.size <= memory.allocation_size() - offset
|
||||
&& offset % mem_reqs.alignment == 0
|
||||
&& mem_reqs.memory_type_bits & (1 << memory.memory_type().id()) != 0
|
||||
&& mem_reqs.memory_type_bits & (1 << memory.memory_type_index()) != 0
|
||||
});
|
||||
|
||||
(fns.v1_0.bind_image_memory)(
|
||||
@ -1626,10 +1634,11 @@ pub enum ImageCreationError {
|
||||
supported: SampleCounts,
|
||||
},
|
||||
|
||||
/// The sharing mode was set to `Concurrent`, but one of the specified queue family ids was not
|
||||
/// valid.
|
||||
SharingInvalidQueueFamilyId {
|
||||
id: u32,
|
||||
/// The sharing mode was set to `Concurrent`, but one of the specified queue family indices was
|
||||
/// out of range.
|
||||
SharingQueueFamilyIndexOutOfRange {
|
||||
queue_family_index: u32,
|
||||
queue_family_count: u32,
|
||||
},
|
||||
|
||||
/// A YCbCr format was given, but the specified width and/or height was not a multiple of 2
|
||||
@ -1757,8 +1766,8 @@ impl Display for ImageCreationError {
|
||||
"the sample count is not supported by the device for this image configuration"
|
||||
)
|
||||
}
|
||||
Self::SharingInvalidQueueFamilyId { .. } => {
|
||||
write!(f, "the sharing mode was set to `Concurrent`, but one of the specified queue family ids was not valid")
|
||||
Self::SharingQueueFamilyIndexOutOfRange { .. } => {
|
||||
write!(f, "the sharing mode was set to `Concurrent`, but one of the specified queue family indices was out of range")
|
||||
}
|
||||
Self::YcbcrFormatInvalidDimensions => {
|
||||
write!(f, "a YCbCr format was given, but the specified width and/or height was not a multiple of 2 as required by the format's chroma subsampling")
|
||||
|
@ -37,7 +37,7 @@
|
||||
//!
|
||||
//! # let library = VulkanLibrary::new().unwrap();
|
||||
//! # let instance = Instance::new(library, Default::default()).unwrap();
|
||||
//! for physical_device in PhysicalDevice::enumerate(&instance) {
|
||||
//! for physical_device in instance.enumerate_physical_devices().unwrap() {
|
||||
//! println!("Available device: {}", physical_device.properties().device_name);
|
||||
//! }
|
||||
//! ```
|
||||
@ -45,7 +45,7 @@
|
||||
//! # Enumerating physical devices and creating a device
|
||||
//!
|
||||
//! After you have created an instance, the next step is usually to enumerate the physical devices
|
||||
//! that are available on the system with `PhysicalDevice::enumerate()` (see above).
|
||||
//! that are available on the system with `Instance::enumerate_physical_devices()` (see above).
|
||||
//!
|
||||
//! When choosing which physical device to use, keep in mind that physical devices may or may not
|
||||
//! be able to draw to a certain surface (ie. to a window or a monitor), or may even not be able
|
||||
@ -57,9 +57,8 @@
|
||||
use self::debug::{DebugUtilsMessengerCreateInfo, UserCallback};
|
||||
pub use self::{extensions::InstanceExtensions, layers::LayerProperties};
|
||||
use crate::{
|
||||
device::physical::{init_physical_devices, PhysicalDeviceInfo},
|
||||
instance::debug::trampoline,
|
||||
OomError, RequiresOneOf, VulkanError, VulkanLibrary, VulkanObject,
|
||||
device::physical::PhysicalDevice, instance::debug::trampoline, OomError, RequiresOneOf,
|
||||
VulkanError, VulkanLibrary, VulkanObject,
|
||||
};
|
||||
pub use crate::{
|
||||
extensions::{ExtensionRestriction, ExtensionRestrictionError},
|
||||
@ -234,7 +233,6 @@ mod layers;
|
||||
pub struct Instance {
|
||||
handle: ash::vk::Instance,
|
||||
fns: InstanceFunctions,
|
||||
pub(crate) physical_device_infos: Vec<PhysicalDeviceInfo>,
|
||||
|
||||
api_version: Version,
|
||||
enabled_extensions: InstanceExtensions,
|
||||
@ -452,10 +450,9 @@ impl Instance {
|
||||
})
|
||||
};
|
||||
|
||||
let mut instance = Instance {
|
||||
Ok(Arc::new(Instance {
|
||||
handle,
|
||||
fns,
|
||||
physical_device_infos: Vec::new(),
|
||||
|
||||
api_version,
|
||||
enabled_extensions,
|
||||
@ -463,12 +460,7 @@ impl Instance {
|
||||
library,
|
||||
max_api_version,
|
||||
_user_callbacks: user_callbacks,
|
||||
};
|
||||
|
||||
// Enumerating all physical devices.
|
||||
instance.physical_device_infos = init_physical_devices(&instance)?;
|
||||
|
||||
Ok(Arc::new(instance))
|
||||
}))
|
||||
}
|
||||
|
||||
/// Returns the Vulkan library used to create this instance.
|
||||
@ -510,6 +502,60 @@ impl Instance {
|
||||
pub fn enabled_layers(&self) -> &[String] {
|
||||
&self.enabled_layers
|
||||
}
|
||||
|
||||
/// Returns an iterator that enumerates the physical devices available.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use vulkano::{
|
||||
/// # instance::{Instance, InstanceExtensions},
|
||||
/// # Version, VulkanLibrary,
|
||||
/// # };
|
||||
///
|
||||
/// # let library = VulkanLibrary::new().unwrap();
|
||||
/// # let instance = Instance::new(library, Default::default()).unwrap();
|
||||
/// for physical_device in instance.enumerate_physical_devices().unwrap() {
|
||||
/// println!("Available device: {}", physical_device.properties().device_name);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn enumerate_physical_devices(
|
||||
self: &Arc<Self>,
|
||||
) -> Result<impl ExactSizeIterator<Item = Arc<PhysicalDevice>>, VulkanError> {
|
||||
let fns = self.fns();
|
||||
|
||||
unsafe {
|
||||
let handles = loop {
|
||||
let mut count = 0;
|
||||
(fns.v1_0.enumerate_physical_devices)(self.handle, &mut count, ptr::null_mut())
|
||||
.result()
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
let mut handles = Vec::with_capacity(count as usize);
|
||||
let result = (fns.v1_0.enumerate_physical_devices)(
|
||||
self.handle,
|
||||
&mut count,
|
||||
handles.as_mut_ptr(),
|
||||
);
|
||||
|
||||
match result {
|
||||
ash::vk::Result::SUCCESS => {
|
||||
handles.set_len(count as usize);
|
||||
break handles;
|
||||
}
|
||||
ash::vk::Result::INCOMPLETE => (),
|
||||
err => return Err(VulkanError::from(err)),
|
||||
}
|
||||
};
|
||||
|
||||
let physical_devices: SmallVec<[_; 4]> = handles
|
||||
.into_iter()
|
||||
.map(|handle| PhysicalDevice::from_handle(handle, self.clone()))
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
Ok(physical_devices.into_iter())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Instance {
|
||||
@ -553,7 +599,6 @@ impl Debug for Instance {
|
||||
let Self {
|
||||
handle,
|
||||
fns,
|
||||
physical_device_infos,
|
||||
api_version,
|
||||
enabled_extensions,
|
||||
enabled_layers,
|
||||
@ -565,7 +610,6 @@ impl Debug for Instance {
|
||||
f.debug_struct("Instance")
|
||||
.field("handle", handle)
|
||||
.field("fns", fns)
|
||||
.field("physical_device_infos", physical_device_infos)
|
||||
.field("api_version", api_version)
|
||||
.field("enabled_extensions", enabled_extensions)
|
||||
.field("enabled_layers", enabled_layers)
|
||||
@ -763,28 +807,9 @@ impl From<VulkanError> for InstanceCreationError {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::device::physical::PhysicalDevice;
|
||||
|
||||
#[test]
|
||||
fn create_instance() {
|
||||
let _ = instance!();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn queue_family_by_id() {
|
||||
let instance = instance!();
|
||||
|
||||
let phys = match PhysicalDevice::enumerate(&instance).next() {
|
||||
Some(p) => p,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let queue_family = match phys.queue_families().next() {
|
||||
Some(q) => q,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let by_id = phys.queue_family_by_id(queue_family.id()).unwrap();
|
||||
assert_eq!(by_id.id(), queue_family.id());
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
//! - The [`PhysicalDevice`](crate::device::physical::PhysicalDevice) object represents a
|
||||
//! Vulkan-capable device that is available on the system (eg. a graphics card, a software
|
||||
//! implementation, etc.). Physical devices can be enumerated from an instance with
|
||||
//! [`PhysicalDevice::enumerate`](crate::device::physical::PhysicalDevice::enumerate).
|
||||
//! [`Instance::enumerate_physical_devices`](crate::instance::Instance::enumerate_physical_devices).
|
||||
//!
|
||||
//! - Once you have chosen a physical device to use, you can create a
|
||||
//! [`Device`](crate::device::Device) object from it. The `Device` is the most important
|
||||
|
@ -142,11 +142,14 @@ impl VulkanLibrary {
|
||||
}
|
||||
};
|
||||
|
||||
InstanceExtensions::from(
|
||||
extension_properties
|
||||
.iter()
|
||||
.map(|property| CStr::from_ptr(property.extension_name.as_ptr())),
|
||||
)
|
||||
.map(|property| {
|
||||
CStr::from_ptr(property.extension_name.as_ptr())
|
||||
.to_str()
|
||||
.unwrap()
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
|
||||
Ok(Arc::new(VulkanLibrary {
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
use super::DedicatedAllocation;
|
||||
use crate::{
|
||||
device::{physical::MemoryType, Device, DeviceOwned},
|
||||
device::{Device, DeviceOwned},
|
||||
macros::{vulkan_bitflags, vulkan_enum},
|
||||
DeviceSize, OomError, RequirementNotMet, RequiresOneOf, Version, VulkanError, VulkanObject,
|
||||
};
|
||||
@ -35,14 +35,14 @@ use std::{
|
||||
/// use vulkano::memory::{DeviceMemory, MemoryAllocateInfo};
|
||||
///
|
||||
/// # let device: std::sync::Arc<vulkano::device::Device> = return;
|
||||
/// let memory_type = device.physical_device().memory_types().next().unwrap();
|
||||
/// let memory_type_index = 0;
|
||||
///
|
||||
/// // Allocates 1KB of memory.
|
||||
/// let memory = DeviceMemory::allocate(
|
||||
/// device.clone(),
|
||||
/// MemoryAllocateInfo {
|
||||
/// allocation_size: 1024,
|
||||
/// memory_type_index: memory_type.id(),
|
||||
/// memory_type_index,
|
||||
/// ..Default::default()
|
||||
/// },
|
||||
/// ).unwrap();
|
||||
@ -150,19 +150,21 @@ impl DeviceMemory {
|
||||
*dedicated_allocation = None;
|
||||
}
|
||||
|
||||
let memory_properties = device.physical_device().memory_properties();
|
||||
|
||||
// VUID-vkAllocateMemory-pAllocateInfo-01714
|
||||
let memory_type = device
|
||||
.physical_device()
|
||||
.memory_type_by_id(memory_type_index)
|
||||
.ok_or_else(|| DeviceMemoryAllocationError::MemoryTypeIndexOutOfRange {
|
||||
let memory_type = memory_properties
|
||||
.memory_types
|
||||
.get(memory_type_index as usize)
|
||||
.ok_or(DeviceMemoryAllocationError::MemoryTypeIndexOutOfRange {
|
||||
memory_type_index,
|
||||
memory_type_count: device.physical_device().memory_types().len() as u32,
|
||||
memory_type_count: memory_properties.memory_types.len() as u32,
|
||||
})?;
|
||||
|
||||
// VUID-VkMemoryAllocateInfo-memoryTypeIndex-01872
|
||||
if memory_type.is_protected() && !device.enabled_features().protected_memory {
|
||||
if memory_type.property_flags.protected && !device.enabled_features().protected_memory {
|
||||
return Err(DeviceMemoryAllocationError::RequirementNotMet {
|
||||
required_for: "`allocate_info.memory_type_index` refers to a memory type where `flags.protected` is set",
|
||||
required_for: "`allocate_info.memory_type_index` refers to a memory type where `property_flags.protected` is set",
|
||||
requires_one_of: RequiresOneOf {
|
||||
features: &["protected_memory"],
|
||||
..Default::default()
|
||||
@ -174,7 +176,7 @@ impl DeviceMemory {
|
||||
assert!(allocation_size != 0);
|
||||
|
||||
// VUID-vkAllocateMemory-pAllocateInfo-01713
|
||||
let heap_size = memory_type.heap().size();
|
||||
let heap_size = memory_properties.memory_heaps[memory_type.heap_index as usize].size;
|
||||
if heap_size != 0 && allocation_size > heap_size {
|
||||
return Err(DeviceMemoryAllocationError::MemoryTypeHeapSizeExceeded {
|
||||
allocation_size,
|
||||
@ -473,13 +475,10 @@ impl DeviceMemory {
|
||||
Ok(handle)
|
||||
}
|
||||
|
||||
/// Returns the memory type that this memory was allocated from.
|
||||
/// Returns the index of the memory type that this memory was allocated from.
|
||||
#[inline]
|
||||
pub fn memory_type(&self) -> MemoryType {
|
||||
self.device
|
||||
.physical_device()
|
||||
.memory_type_by_id(self.memory_type_index)
|
||||
.unwrap()
|
||||
pub fn memory_type_index(&self) -> u32 {
|
||||
self.memory_type_index
|
||||
}
|
||||
|
||||
/// Returns the size in bytes of the memory allocation.
|
||||
@ -1122,16 +1121,21 @@ impl From<RequirementNotMet> for DeviceMemoryExportError {
|
||||
///
|
||||
/// # let device: std::sync::Arc<vulkano::device::Device> = return;
|
||||
/// // The memory type must be mappable.
|
||||
/// let memory_type = device.physical_device().memory_types()
|
||||
/// .filter(|t| t.is_host_visible())
|
||||
/// .next().unwrap(); // Vk specs guarantee that this can't fail
|
||||
/// let memory_type_index = device
|
||||
/// .physical_device()
|
||||
/// .memory_properties()
|
||||
/// .memory_types
|
||||
/// .iter()
|
||||
/// .position(|t| t.property_flags.host_visible)
|
||||
/// .map(|i| i as u32)
|
||||
/// .unwrap(); // Vk specs guarantee that this can't fail
|
||||
///
|
||||
/// // Allocates 1KB of memory.
|
||||
/// let memory = DeviceMemory::allocate(
|
||||
/// device.clone(),
|
||||
/// MemoryAllocateInfo {
|
||||
/// allocation_size: 1024,
|
||||
/// memory_type_index: memory_type.id(),
|
||||
/// memory_type_index,
|
||||
/// ..Default::default()
|
||||
/// },
|
||||
/// ).unwrap();
|
||||
@ -1191,13 +1195,16 @@ impl MappedDeviceMemory {
|
||||
});
|
||||
}
|
||||
|
||||
let device = memory.device();
|
||||
let memory_type = &device.physical_device().memory_properties().memory_types
|
||||
[memory.memory_type_index() as usize];
|
||||
|
||||
// VUID-vkMapMemory-memory-00682
|
||||
if !memory.memory_type().is_host_visible() {
|
||||
if !memory_type.property_flags.host_visible {
|
||||
return Err(MemoryMapError::NotHostVisible);
|
||||
}
|
||||
|
||||
let device = memory.device();
|
||||
let coherent = memory.memory_type().is_host_coherent();
|
||||
let coherent = memory_type.property_flags.host_coherent;
|
||||
let atom_size = device.physical_device().properties().non_coherent_atom_size;
|
||||
|
||||
// Not required for merely mapping, but without this check the user can end up with
|
||||
@ -1544,12 +1551,11 @@ mod tests {
|
||||
#[test]
|
||||
fn create() {
|
||||
let (device, _) = gfx_dev_and_queue!();
|
||||
let memory_type = device.physical_device().memory_types().next().unwrap();
|
||||
let _ = DeviceMemory::allocate(
|
||||
device.clone(),
|
||||
device,
|
||||
MemoryAllocateInfo {
|
||||
allocation_size: 256,
|
||||
memory_type_index: memory_type.id(),
|
||||
memory_type_index: 0,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -1559,13 +1565,12 @@ mod tests {
|
||||
#[test]
|
||||
fn zero_size() {
|
||||
let (device, _) = gfx_dev_and_queue!();
|
||||
let memory_type = device.physical_device().memory_types().next().unwrap();
|
||||
assert_should_panic!({
|
||||
let _ = DeviceMemory::allocate(
|
||||
device.clone(),
|
||||
MemoryAllocateInfo {
|
||||
allocation_size: 0,
|
||||
memory_type_index: memory_type.id(),
|
||||
memory_type_index: 0,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -1577,17 +1582,20 @@ mod tests {
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
fn oom_single() {
|
||||
let (device, _) = gfx_dev_and_queue!();
|
||||
let memory_type = device
|
||||
let memory_type_index = device
|
||||
.physical_device()
|
||||
.memory_types()
|
||||
.find(|m| !m.is_lazily_allocated())
|
||||
.memory_properties()
|
||||
.memory_types
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(i, m)| (!m.property_flags.lazily_allocated).then_some(i as u32))
|
||||
.unwrap();
|
||||
|
||||
match DeviceMemory::allocate(
|
||||
device.clone(),
|
||||
device,
|
||||
MemoryAllocateInfo {
|
||||
allocation_size: 0xffffffffffffffff,
|
||||
memory_type_index: memory_type.id(),
|
||||
memory_type_index,
|
||||
..Default::default()
|
||||
},
|
||||
) {
|
||||
@ -1600,12 +1608,17 @@ mod tests {
|
||||
#[ignore] // TODO: test fails for now on Mesa+Intel
|
||||
fn oom_multi() {
|
||||
let (device, _) = gfx_dev_and_queue!();
|
||||
let memory_type = device
|
||||
let (memory_type_index, memory_type) = device
|
||||
.physical_device()
|
||||
.memory_types()
|
||||
.find(|m| !m.is_lazily_allocated())
|
||||
.memory_properties()
|
||||
.memory_types
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find_map(|(i, m)| (!m.property_flags.lazily_allocated).then_some((i as u32, m)))
|
||||
.unwrap();
|
||||
let heap_size = memory_type.heap().size();
|
||||
let heap_size = device.physical_device().memory_properties().memory_heaps
|
||||
[memory_type.heap_index as usize]
|
||||
.size;
|
||||
|
||||
let mut allocs = Vec::new();
|
||||
|
||||
@ -1614,7 +1627,7 @@ mod tests {
|
||||
device.clone(),
|
||||
MemoryAllocateInfo {
|
||||
allocation_size: heap_size / 3,
|
||||
memory_type_index: memory_type.id(),
|
||||
memory_type_index,
|
||||
..Default::default()
|
||||
},
|
||||
) {
|
||||
@ -1630,13 +1643,12 @@ mod tests {
|
||||
#[test]
|
||||
fn allocation_count() {
|
||||
let (device, _) = gfx_dev_and_queue!();
|
||||
let memory_type = device.physical_device().memory_types().next().unwrap();
|
||||
assert_eq!(*device.allocation_count().lock(), 0);
|
||||
let _mem1 = DeviceMemory::allocate(
|
||||
device.clone(),
|
||||
MemoryAllocateInfo {
|
||||
allocation_size: 256,
|
||||
memory_type_index: memory_type.id(),
|
||||
memory_type_index: 0,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
@ -1647,7 +1659,7 @@ mod tests {
|
||||
device.clone(),
|
||||
MemoryAllocateInfo {
|
||||
allocation_size: 256,
|
||||
memory_type_index: memory_type.id(),
|
||||
memory_type_index: 0,
|
||||
..Default::default()
|
||||
},
|
||||
)
|
||||
|
@ -21,8 +21,8 @@
|
||||
//! ```
|
||||
//! // Enumerating memory heaps.
|
||||
//! # let physical_device: vulkano::device::physical::PhysicalDevice = return;
|
||||
//! for heap in physical_device.memory_heaps() {
|
||||
//! println!("Heap #{:?} has a capacity of {:?} bytes", heap.id(), heap.size());
|
||||
//! for (index, heap) in physical_device.memory_properties().memory_heaps.iter().enumerate() {
|
||||
//! println!("Heap #{:?} has a capacity of {:?} bytes", index, heap.size);
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
@ -38,10 +38,10 @@
|
||||
//! ```
|
||||
//! // Enumerating memory types.
|
||||
//! # let physical_device: vulkano::device::physical::PhysicalDevice = return;
|
||||
//! for ty in physical_device.memory_types() {
|
||||
//! println!("Memory type belongs to heap #{:?}", ty.heap().id());
|
||||
//! println!("Host-accessible: {:?}", ty.is_host_visible());
|
||||
//! println!("Device-local: {:?}", ty.is_device_local());
|
||||
//! for ty in physical_device.memory_properties().memory_types.iter() {
|
||||
//! println!("Memory type belongs to heap #{:?}", ty.heap_index);
|
||||
//! println!("Host-accessible: {:?}", ty.property_flags.host_visible);
|
||||
//! println!("Device-local: {:?}", ty.property_flags.device_local);
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
@ -69,13 +69,13 @@
|
||||
//!
|
||||
//! # let device: std::sync::Arc<vulkano::device::Device> = return;
|
||||
//! // Taking the first memory type for the sake of this example.
|
||||
//! let memory_type = device.physical_device().memory_types().next().unwrap();
|
||||
//! let memory_type_index = 0;
|
||||
//!
|
||||
//! let memory = DeviceMemory::allocate(
|
||||
//! device.clone(),
|
||||
//! MemoryAllocateInfo {
|
||||
//! allocation_size: 1024,
|
||||
//! memory_type_index: memory_type.id(),
|
||||
//! memory_type_index,
|
||||
//! ..Default::default()
|
||||
//! },
|
||||
//! ).expect("Failed to allocate memory");
|
||||
|
@ -8,8 +8,7 @@
|
||||
// according to those terms.
|
||||
|
||||
use crate::{
|
||||
device::{physical::MemoryType, Device},
|
||||
instance::Instance,
|
||||
device::Device,
|
||||
memory::{
|
||||
device_memory::MemoryAllocateInfo, DeviceMemory, DeviceMemoryAllocationError,
|
||||
MappedDeviceMemory,
|
||||
@ -23,7 +22,7 @@ use std::{cmp, ops::Range, sync::Arc};
|
||||
#[derive(Debug)]
|
||||
pub struct StandardHostVisibleMemoryTypePool {
|
||||
device: Arc<Device>,
|
||||
memory_type: u32,
|
||||
memory_type_index: u32,
|
||||
// TODO: obviously very inefficient
|
||||
occupied: Mutex<Vec<(Arc<MappedDeviceMemory>, Vec<Range<DeviceSize>>)>>,
|
||||
}
|
||||
@ -33,27 +32,21 @@ impl StandardHostVisibleMemoryTypePool {
|
||||
///
|
||||
/// # Panic
|
||||
///
|
||||
/// - Panics if the `device` and `memory_type` don't belong to the same physical device.
|
||||
/// - Panics if the memory type is not host-visible.
|
||||
/// - Panics if `memory_type_index` is out of range.
|
||||
/// - Panics if `memory_type_index` refers to a memory type that is not host-visible.
|
||||
///
|
||||
#[inline]
|
||||
pub fn new(
|
||||
device: Arc<Device>,
|
||||
memory_type: MemoryType,
|
||||
memory_type_index: u32,
|
||||
) -> Arc<StandardHostVisibleMemoryTypePool> {
|
||||
assert_eq!(
|
||||
&**device.physical_device().instance() as *const Instance,
|
||||
&**memory_type.physical_device().instance() as *const Instance
|
||||
);
|
||||
assert_eq!(
|
||||
device.physical_device().index(),
|
||||
memory_type.physical_device().index()
|
||||
);
|
||||
assert!(memory_type.is_host_visible());
|
||||
let memory_type =
|
||||
&device.physical_device().memory_properties().memory_types[memory_type_index as usize];
|
||||
assert!(memory_type.property_flags.host_visible);
|
||||
|
||||
Arc::new(StandardHostVisibleMemoryTypePool {
|
||||
device,
|
||||
memory_type: memory_type.id(),
|
||||
memory_type_index,
|
||||
occupied: Mutex::new(Vec::new()),
|
||||
})
|
||||
}
|
||||
@ -120,7 +113,7 @@ impl StandardHostVisibleMemoryTypePool {
|
||||
self.device.clone(),
|
||||
MemoryAllocateInfo {
|
||||
allocation_size,
|
||||
memory_type_index: self.memory_type().id(),
|
||||
memory_type_index: self.memory_type_index,
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
@ -143,13 +136,10 @@ impl StandardHostVisibleMemoryTypePool {
|
||||
&self.device
|
||||
}
|
||||
|
||||
/// Returns the memory type this pool operates on.
|
||||
/// Returns the index of the memory type this pool operates on.
|
||||
#[inline]
|
||||
pub fn memory_type(&self) -> MemoryType {
|
||||
self.device
|
||||
.physical_device()
|
||||
.memory_type_by_id(self.memory_type)
|
||||
.unwrap()
|
||||
pub fn memory_type_index(&self) -> u32 {
|
||||
self.memory_type_index
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,34 +33,40 @@ mod pool;
|
||||
// the pool. This prevents the pool from overallocating a significant amount of memory.
|
||||
const MAX_POOL_ALLOC: DeviceSize = 256 * 1024 * 1024;
|
||||
|
||||
fn choose_allocation_memory_type<'s, F>(
|
||||
device: &'s Arc<Device>,
|
||||
fn choose_allocation_memory_type<F>(
|
||||
device: &Arc<Device>,
|
||||
requirements: &MemoryRequirements,
|
||||
mut filter: F,
|
||||
map: MappingRequirement,
|
||||
) -> MemoryType<'s>
|
||||
) -> u32
|
||||
where
|
||||
F: FnMut(MemoryType) -> AllocFromRequirementsFilter,
|
||||
F: FnMut(&MemoryType) -> AllocFromRequirementsFilter,
|
||||
{
|
||||
let mem_ty = {
|
||||
let mut filter = |ty: MemoryType| {
|
||||
if map == MappingRequirement::Map && !ty.is_host_visible() {
|
||||
let mut filter = |ty: &MemoryType| {
|
||||
if map == MappingRequirement::Map && !ty.property_flags.host_visible {
|
||||
return AllocFromRequirementsFilter::Forbidden;
|
||||
}
|
||||
filter(ty)
|
||||
};
|
||||
let first_loop = device
|
||||
.physical_device()
|
||||
.memory_types()
|
||||
.map(|t| (t, AllocFromRequirementsFilter::Preferred));
|
||||
.memory_properties()
|
||||
.memory_types
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, t)| (i as u32, t, AllocFromRequirementsFilter::Preferred));
|
||||
let second_loop = device
|
||||
.physical_device()
|
||||
.memory_types()
|
||||
.map(|t| (t, AllocFromRequirementsFilter::Allowed));
|
||||
.memory_properties()
|
||||
.memory_types
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, t)| (i as u32, t, AllocFromRequirementsFilter::Allowed));
|
||||
first_loop
|
||||
.chain(second_loop)
|
||||
.filter(|&(t, _)| (requirements.memory_type_bits & (1 << t.id())) != 0)
|
||||
.find(|&(t, rq)| filter(t) == rq)
|
||||
.filter(|(i, _, _)| (requirements.memory_type_bits & (1 << *i)) != 0)
|
||||
.find(|&(_, t, rq)| filter(t) == rq)
|
||||
.expect("Couldn't find a memory type to allocate from")
|
||||
.0
|
||||
};
|
||||
@ -78,17 +84,17 @@ pub(crate) fn alloc_dedicated_with_exportable_fd<F>(
|
||||
filter: F,
|
||||
) -> Result<PotentialDedicatedAllocation<StandardMemoryPoolAlloc>, DeviceMemoryAllocationError>
|
||||
where
|
||||
F: FnMut(MemoryType) -> AllocFromRequirementsFilter,
|
||||
F: FnMut(&MemoryType) -> AllocFromRequirementsFilter,
|
||||
{
|
||||
assert!(device.enabled_extensions().khr_external_memory_fd);
|
||||
assert!(device.enabled_extensions().khr_external_memory);
|
||||
|
||||
let memory_type = choose_allocation_memory_type(&device, requirements, filter, map);
|
||||
let memory_type_index = choose_allocation_memory_type(&device, requirements, filter, map);
|
||||
let memory = DeviceMemory::allocate(
|
||||
device.clone(),
|
||||
device,
|
||||
MemoryAllocateInfo {
|
||||
allocation_size: requirements.size,
|
||||
memory_type_index: memory_type.id(),
|
||||
memory_type_index,
|
||||
export_handle_types: ExternalMemoryHandleTypes {
|
||||
opaque_fd: true,
|
||||
..ExternalMemoryHandleTypes::empty()
|
||||
@ -134,7 +140,7 @@ pub unsafe trait MemoryPool: DeviceOwned {
|
||||
///
|
||||
fn alloc_generic(
|
||||
&self,
|
||||
ty: MemoryType,
|
||||
memory_type_index: u32,
|
||||
size: DeviceSize,
|
||||
alignment: DeviceSize,
|
||||
layout: AllocLayout,
|
||||
@ -179,15 +185,16 @@ pub unsafe trait MemoryPool: DeviceOwned {
|
||||
filter: F,
|
||||
) -> Result<PotentialDedicatedAllocation<Self::Alloc>, DeviceMemoryAllocationError>
|
||||
where
|
||||
F: FnMut(MemoryType) -> AllocFromRequirementsFilter,
|
||||
F: FnMut(&MemoryType) -> AllocFromRequirementsFilter,
|
||||
{
|
||||
// Choose a suitable memory type.
|
||||
let memory_type = choose_allocation_memory_type(self.device(), requirements, filter, map);
|
||||
let memory_type_index =
|
||||
choose_allocation_memory_type(self.device(), requirements, filter, map);
|
||||
|
||||
// Redirect to `self.alloc_generic` if we don't perform a dedicated allocation.
|
||||
if !requirements.prefer_dedicated && requirements.size <= MAX_POOL_ALLOC {
|
||||
let alloc = self.alloc_generic(
|
||||
memory_type,
|
||||
memory_type_index,
|
||||
requirements.size,
|
||||
requirements.alignment,
|
||||
layout,
|
||||
@ -197,7 +204,7 @@ pub unsafe trait MemoryPool: DeviceOwned {
|
||||
}
|
||||
if dedicated_allocation.is_none() {
|
||||
let alloc = self.alloc_generic(
|
||||
memory_type,
|
||||
memory_type_index,
|
||||
requirements.size,
|
||||
requirements.alignment,
|
||||
layout,
|
||||
@ -211,7 +218,7 @@ pub unsafe trait MemoryPool: DeviceOwned {
|
||||
self.device().clone(),
|
||||
MemoryAllocateInfo {
|
||||
allocation_size: requirements.size,
|
||||
memory_type_index: memory_type.id(),
|
||||
memory_type_index,
|
||||
dedicated_allocation,
|
||||
..Default::default()
|
||||
},
|
||||
|
@ -8,8 +8,7 @@
|
||||
// according to those terms.
|
||||
|
||||
use crate::{
|
||||
device::{physical::MemoryType, Device},
|
||||
instance::Instance,
|
||||
device::Device,
|
||||
memory::{device_memory::MemoryAllocateInfo, DeviceMemory, DeviceMemoryAllocationError},
|
||||
DeviceSize,
|
||||
};
|
||||
@ -20,7 +19,7 @@ use std::{cmp, ops::Range, sync::Arc};
|
||||
#[derive(Debug)]
|
||||
pub struct StandardNonHostVisibleMemoryTypePool {
|
||||
device: Arc<Device>,
|
||||
memory_type: u32,
|
||||
memory_type_index: u32,
|
||||
// TODO: obviously very inefficient
|
||||
occupied: Mutex<Vec<(Arc<DeviceMemory>, Vec<Range<DeviceSize>>)>>,
|
||||
}
|
||||
@ -30,25 +29,18 @@ impl StandardNonHostVisibleMemoryTypePool {
|
||||
///
|
||||
/// # Panic
|
||||
///
|
||||
/// - Panics if the `device` and `memory_type` don't belong to the same physical device.
|
||||
///
|
||||
/// - Panics if `memory_type_index` is out of range.
|
||||
#[inline]
|
||||
pub fn new(
|
||||
device: Arc<Device>,
|
||||
memory_type: MemoryType,
|
||||
memory_type_index: u32,
|
||||
) -> Arc<StandardNonHostVisibleMemoryTypePool> {
|
||||
assert_eq!(
|
||||
&**device.physical_device().instance() as *const Instance,
|
||||
&**memory_type.physical_device().instance() as *const Instance
|
||||
);
|
||||
assert_eq!(
|
||||
device.physical_device().index(),
|
||||
memory_type.physical_device().index()
|
||||
);
|
||||
let _ =
|
||||
&device.physical_device().memory_properties().memory_types[memory_type_index as usize];
|
||||
|
||||
Arc::new(StandardNonHostVisibleMemoryTypePool {
|
||||
device,
|
||||
memory_type: memory_type.id(),
|
||||
memory_type_index,
|
||||
occupied: Mutex::new(Vec::new()),
|
||||
})
|
||||
}
|
||||
@ -115,7 +107,7 @@ impl StandardNonHostVisibleMemoryTypePool {
|
||||
self.device.clone(),
|
||||
MemoryAllocateInfo {
|
||||
allocation_size,
|
||||
memory_type_index: self.memory_type().id(),
|
||||
memory_type_index: self.memory_type_index,
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
@ -131,19 +123,10 @@ impl StandardNonHostVisibleMemoryTypePool {
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the device this pool operates on.
|
||||
/// Returns the index of the memory type this pool operates on.
|
||||
#[inline]
|
||||
pub fn device(&self) -> &Arc<Device> {
|
||||
&self.device
|
||||
}
|
||||
|
||||
/// Returns the memory type this pool operates on.
|
||||
#[inline]
|
||||
pub fn memory_type(&self) -> MemoryType {
|
||||
self.device
|
||||
.physical_device()
|
||||
.memory_type_by_id(self.memory_type)
|
||||
.unwrap()
|
||||
pub fn memory_type_index(&self) -> u32 {
|
||||
self.memory_type_index
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
// according to those terms.
|
||||
|
||||
use crate::{
|
||||
device::{physical::MemoryType, Device, DeviceOwned},
|
||||
device::{Device, DeviceOwned},
|
||||
memory::{
|
||||
pool::{
|
||||
AllocLayout, MappingRequirement, MemoryPool, MemoryPoolAlloc,
|
||||
@ -37,7 +37,11 @@ impl StandardMemoryPool {
|
||||
/// Creates a new pool.
|
||||
#[inline]
|
||||
pub fn new(device: Arc<Device>) -> Arc<StandardMemoryPool> {
|
||||
let cap = device.physical_device().memory_types().len();
|
||||
let cap = device
|
||||
.physical_device()
|
||||
.memory_properties()
|
||||
.memory_types
|
||||
.len();
|
||||
|
||||
Arc::new(StandardMemoryPool {
|
||||
device,
|
||||
@ -48,7 +52,7 @@ impl StandardMemoryPool {
|
||||
|
||||
fn generic_allocation(
|
||||
mem_pool: Arc<StandardMemoryPool>,
|
||||
memory_type: MemoryType,
|
||||
memory_type_index: u32,
|
||||
size: DeviceSize,
|
||||
alignment: DeviceSize,
|
||||
layout: AllocLayout,
|
||||
@ -56,10 +60,19 @@ fn generic_allocation(
|
||||
) -> Result<StandardMemoryPoolAlloc, DeviceMemoryAllocationError> {
|
||||
let mut pools = mem_pool.pools.lock();
|
||||
|
||||
let memory_type_host_visible = memory_type.is_host_visible();
|
||||
let memory_properties = mem_pool.device().physical_device().memory_properties();
|
||||
let memory_type = memory_properties
|
||||
.memory_types
|
||||
.get(memory_type_index as usize)
|
||||
.ok_or(DeviceMemoryAllocationError::MemoryTypeIndexOutOfRange {
|
||||
memory_type_index,
|
||||
memory_type_count: memory_properties.memory_types.len() as u32,
|
||||
})?;
|
||||
|
||||
let memory_type_host_visible = memory_type.property_flags.host_visible;
|
||||
assert!(memory_type_host_visible || map == MappingRequirement::DoNotMap);
|
||||
|
||||
match pools.entry((memory_type.id(), layout, map)) {
|
||||
match pools.entry((memory_type_index, layout, map)) {
|
||||
Entry::Occupied(entry) => match *entry.get() {
|
||||
Pool::HostVisible(ref pool) => {
|
||||
let alloc = pool.alloc(size, alignment)?;
|
||||
@ -81,8 +94,10 @@ fn generic_allocation(
|
||||
|
||||
Entry::Vacant(entry) => {
|
||||
if memory_type_host_visible {
|
||||
let pool =
|
||||
StandardHostVisibleMemoryTypePool::new(mem_pool.device.clone(), memory_type);
|
||||
let pool = StandardHostVisibleMemoryTypePool::new(
|
||||
mem_pool.device.clone(),
|
||||
memory_type_index,
|
||||
);
|
||||
entry.insert(Pool::HostVisible(pool.clone()));
|
||||
let alloc = pool.alloc(size, alignment)?;
|
||||
let inner = StandardMemoryPoolAllocInner::HostVisible(alloc);
|
||||
@ -91,8 +106,10 @@ fn generic_allocation(
|
||||
_pool: mem_pool.clone(),
|
||||
})
|
||||
} else {
|
||||
let pool =
|
||||
StandardNonHostVisibleMemoryTypePool::new(mem_pool.device.clone(), memory_type);
|
||||
let pool = StandardNonHostVisibleMemoryTypePool::new(
|
||||
mem_pool.device.clone(),
|
||||
memory_type_index,
|
||||
);
|
||||
entry.insert(Pool::NonHostVisible(pool.clone()));
|
||||
let alloc = pool.alloc(size, alignment)?;
|
||||
let inner = StandardMemoryPoolAllocInner::NonHostVisible(alloc);
|
||||
@ -110,13 +127,20 @@ unsafe impl MemoryPool for Arc<StandardMemoryPool> {
|
||||
|
||||
fn alloc_generic(
|
||||
&self,
|
||||
memory_type: MemoryType,
|
||||
memory_type_index: u32,
|
||||
size: DeviceSize,
|
||||
alignment: DeviceSize,
|
||||
layout: AllocLayout,
|
||||
map: MappingRequirement,
|
||||
) -> Result<StandardMemoryPoolAlloc, DeviceMemoryAllocationError> {
|
||||
generic_allocation(self.clone(), memory_type, size, alignment, layout, map)
|
||||
generic_allocation(
|
||||
self.clone(),
|
||||
memory_type_index,
|
||||
size,
|
||||
alignment,
|
||||
layout,
|
||||
map,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -513,7 +513,7 @@ mod tests {
|
||||
|
||||
let mut cbb = AutoCommandBufferBuilder::primary(
|
||||
device.clone(),
|
||||
queue.family(),
|
||||
queue.queue_family_index(),
|
||||
CommandBufferUsage::OneTimeSubmit,
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -29,8 +29,8 @@
|
||||
#![allow(unused_variables)] // TODO: this module isn't finished
|
||||
|
||||
use crate::{
|
||||
device::physical::PhysicalDevice, instance::Instance, swapchain::SupportedSurfaceTransforms,
|
||||
OomError, VulkanError, VulkanObject,
|
||||
device::physical::PhysicalDevice, swapchain::SupportedSurfaceTransforms, OomError, VulkanError,
|
||||
VulkanObject,
|
||||
};
|
||||
use std::{
|
||||
ffi::CStr,
|
||||
@ -46,8 +46,7 @@ use std::{
|
||||
// TODO: plane capabilities
|
||||
// TODO: store properties in the instance?
|
||||
pub struct DisplayPlane {
|
||||
instance: Arc<Instance>,
|
||||
physical_device: usize,
|
||||
physical_device: Arc<PhysicalDevice>,
|
||||
index: u32,
|
||||
properties: ash::vk::DisplayPlanePropertiesKHR,
|
||||
supported_displays: Vec<ash::vk::DisplayKHR>,
|
||||
@ -55,17 +54,19 @@ pub struct DisplayPlane {
|
||||
|
||||
impl DisplayPlane {
|
||||
/// See the docs of enumerate().
|
||||
pub fn enumerate_raw(device: PhysicalDevice) -> Result<IntoIter<DisplayPlane>, OomError> {
|
||||
let fns = device.instance().fns();
|
||||
pub fn enumerate_raw(
|
||||
physical_device: Arc<PhysicalDevice>,
|
||||
) -> Result<IntoIter<DisplayPlane>, OomError> {
|
||||
let fns = physical_device.instance().fns();
|
||||
|
||||
assert!(device.instance().enabled_extensions().khr_display); // TODO: return error instead
|
||||
assert!(physical_device.instance().enabled_extensions().khr_display); // TODO: return error instead
|
||||
|
||||
let display_plane_properties = unsafe {
|
||||
loop {
|
||||
let mut count = 0;
|
||||
(fns.khr_display
|
||||
.get_physical_device_display_plane_properties_khr)(
|
||||
device.internal_object(),
|
||||
physical_device.internal_object(),
|
||||
&mut count,
|
||||
ptr::null_mut(),
|
||||
)
|
||||
@ -76,7 +77,7 @@ impl DisplayPlane {
|
||||
let result = (fns
|
||||
.khr_display
|
||||
.get_physical_device_display_plane_properties_khr)(
|
||||
device.internal_object(),
|
||||
physical_device.internal_object(),
|
||||
&mut count,
|
||||
properties.as_mut_ptr(),
|
||||
);
|
||||
@ -100,7 +101,7 @@ impl DisplayPlane {
|
||||
loop {
|
||||
let mut count = 0;
|
||||
(fns.khr_display.get_display_plane_supported_displays_khr)(
|
||||
device.internal_object(),
|
||||
physical_device.internal_object(),
|
||||
index as u32,
|
||||
&mut count,
|
||||
ptr::null_mut(),
|
||||
@ -111,7 +112,7 @@ impl DisplayPlane {
|
||||
|
||||
let mut displays = Vec::with_capacity(count as usize);
|
||||
let result = (fns.khr_display.get_display_plane_supported_displays_khr)(
|
||||
device.internal_object(),
|
||||
physical_device.internal_object(),
|
||||
index as u32,
|
||||
&mut count,
|
||||
displays.as_mut_ptr(),
|
||||
@ -129,8 +130,7 @@ impl DisplayPlane {
|
||||
};
|
||||
|
||||
DisplayPlane {
|
||||
instance: device.instance().clone(),
|
||||
physical_device: device.index(),
|
||||
physical_device: physical_device.clone(),
|
||||
index: index as u32,
|
||||
properties: prop,
|
||||
supported_displays,
|
||||
@ -148,14 +148,14 @@ impl DisplayPlane {
|
||||
///
|
||||
// TODO: move iterator creation here from raw constructor?
|
||||
#[inline]
|
||||
pub fn enumerate(device: PhysicalDevice) -> IntoIter<DisplayPlane> {
|
||||
DisplayPlane::enumerate_raw(device).unwrap()
|
||||
pub fn enumerate(physical_device: Arc<PhysicalDevice>) -> IntoIter<DisplayPlane> {
|
||||
DisplayPlane::enumerate_raw(physical_device).unwrap()
|
||||
}
|
||||
|
||||
/// Returns the physical device that was used to create this display.
|
||||
#[inline]
|
||||
pub fn physical_device(&self) -> PhysicalDevice {
|
||||
PhysicalDevice::from_index(&self.instance, self.physical_device).unwrap()
|
||||
pub fn physical_device(&self) -> &Arc<PhysicalDevice> {
|
||||
&self.physical_device
|
||||
}
|
||||
|
||||
/// Returns the index of the plane.
|
||||
@ -182,22 +182,23 @@ impl DisplayPlane {
|
||||
// TODO: store properties in the instance?
|
||||
#[derive(Clone)]
|
||||
pub struct Display {
|
||||
instance: Arc<Instance>,
|
||||
physical_device: usize,
|
||||
physical_device: Arc<PhysicalDevice>,
|
||||
properties: Arc<ash::vk::DisplayPropertiesKHR>, // TODO: Arc because struct isn't clone
|
||||
}
|
||||
|
||||
impl Display {
|
||||
/// See the docs of enumerate().
|
||||
pub fn enumerate_raw(device: PhysicalDevice) -> Result<IntoIter<Display>, OomError> {
|
||||
let fns = device.instance().fns();
|
||||
assert!(device.instance().enabled_extensions().khr_display); // TODO: return error instead
|
||||
pub fn enumerate_raw(
|
||||
physical_device: Arc<PhysicalDevice>,
|
||||
) -> Result<IntoIter<Display>, OomError> {
|
||||
let fns = physical_device.instance().fns();
|
||||
assert!(physical_device.instance().enabled_extensions().khr_display); // TODO: return error instead
|
||||
|
||||
let display_properties = unsafe {
|
||||
loop {
|
||||
let mut count = 0;
|
||||
(fns.khr_display.get_physical_device_display_properties_khr)(
|
||||
device.internal_object(),
|
||||
physical_device.internal_object(),
|
||||
&mut count,
|
||||
ptr::null_mut(),
|
||||
)
|
||||
@ -206,7 +207,7 @@ impl Display {
|
||||
|
||||
let mut properties = Vec::with_capacity(count as usize);
|
||||
let result = (fns.khr_display.get_physical_device_display_properties_khr)(
|
||||
device.internal_object(),
|
||||
physical_device.internal_object(),
|
||||
&mut count,
|
||||
properties.as_mut_ptr(),
|
||||
);
|
||||
@ -225,8 +226,7 @@ impl Display {
|
||||
Ok(display_properties
|
||||
.into_iter()
|
||||
.map(|prop| Display {
|
||||
instance: device.instance().clone(),
|
||||
physical_device: device.index(),
|
||||
physical_device: physical_device.clone(),
|
||||
properties: Arc::new(prop),
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
@ -241,8 +241,8 @@ impl Display {
|
||||
///
|
||||
// TODO: move iterator creation here from raw constructor?
|
||||
#[inline]
|
||||
pub fn enumerate(device: PhysicalDevice) -> IntoIter<Display> {
|
||||
Display::enumerate_raw(device).unwrap()
|
||||
pub fn enumerate(physical_device: Arc<PhysicalDevice>) -> IntoIter<Display> {
|
||||
Display::enumerate_raw(physical_device).unwrap()
|
||||
}
|
||||
|
||||
/// Returns the name of the display.
|
||||
@ -257,8 +257,8 @@ impl Display {
|
||||
|
||||
/// Returns the physical device that was used to create this display.
|
||||
#[inline]
|
||||
pub fn physical_device(&self) -> PhysicalDevice {
|
||||
PhysicalDevice::from_index(&self.instance, self.physical_device).unwrap()
|
||||
pub fn physical_device(&self) -> &Arc<PhysicalDevice> {
|
||||
&self.physical_device
|
||||
}
|
||||
|
||||
/// Returns the physical dimensions of the display in millimeters.
|
||||
@ -298,7 +298,7 @@ impl Display {
|
||||
|
||||
/// See the docs of display_modes().
|
||||
pub fn display_modes_raw(&self) -> Result<IntoIter<DisplayMode>, OomError> {
|
||||
let fns = self.instance.fns();
|
||||
let fns = self.physical_device.instance().fns();
|
||||
|
||||
let mode_properties = unsafe {
|
||||
loop {
|
||||
|
@ -452,19 +452,28 @@ impl<W> Swapchain<W> {
|
||||
|
||||
match image_sharing {
|
||||
Sharing::Exclusive => (),
|
||||
Sharing::Concurrent(ids) => {
|
||||
Sharing::Concurrent(queue_family_indices) => {
|
||||
// VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01278
|
||||
// VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01428
|
||||
ids.sort_unstable();
|
||||
ids.dedup();
|
||||
assert!(ids.len() >= 2);
|
||||
queue_family_indices.sort_unstable();
|
||||
queue_family_indices.dedup();
|
||||
assert!(queue_family_indices.len() >= 2);
|
||||
|
||||
for &id in ids.iter() {
|
||||
for &queue_family_index in queue_family_indices.iter() {
|
||||
// VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01428
|
||||
if device.physical_device().queue_family_by_id(id).is_none() {
|
||||
return Err(SwapchainCreationError::ImageSharingInvalidQueueFamilyId {
|
||||
id,
|
||||
});
|
||||
if queue_family_index
|
||||
>= device.physical_device().queue_family_properties().len() as u32
|
||||
{
|
||||
return Err(
|
||||
SwapchainCreationError::ImageSharingQueueFamilyIndexOutOfRange {
|
||||
queue_family_index,
|
||||
queue_family_count: device
|
||||
.physical_device()
|
||||
.queue_family_properties()
|
||||
.len()
|
||||
as u32,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1111,8 +1120,11 @@ pub enum SwapchainCreationError {
|
||||
ImageFormatPropertiesNotSupported,
|
||||
|
||||
/// The provided `image_sharing` was set to `Concurrent`, but one of the specified queue family
|
||||
/// ids was not valid.
|
||||
ImageSharingInvalidQueueFamilyId { id: u32 },
|
||||
/// indices was out of range.
|
||||
ImageSharingQueueFamilyIndexOutOfRange {
|
||||
queue_family_index: u32,
|
||||
queue_family_count: u32,
|
||||
},
|
||||
|
||||
/// The provided `image_usage` has fields set that are not supported by the surface for this
|
||||
/// device.
|
||||
@ -1204,10 +1216,10 @@ impl Display for SwapchainCreationError {
|
||||
f,
|
||||
"the provided image parameters are not supported as queried from `image_format_properties`",
|
||||
),
|
||||
Self::ImageSharingInvalidQueueFamilyId { id } => write!(
|
||||
Self::ImageSharingQueueFamilyIndexOutOfRange { queue_family_index, queue_family_count: _ } => write!(
|
||||
f,
|
||||
"the provided `image_sharing` was set to `Concurrent`, but one of the specified queue family ids ({}) was not valid",
|
||||
id,
|
||||
"the provided `image_sharing` was set to `Concurrent`, but one of the specified queue family indices ({}) was out of range",
|
||||
queue_family_index,
|
||||
),
|
||||
Self::ImageUsageNotSupported { .. } => write!(
|
||||
f,
|
||||
@ -1266,6 +1278,7 @@ impl From<SurfacePropertiesError> for SwapchainCreationError {
|
||||
SurfacePropertiesError::OomError(err) => Self::OomError(err),
|
||||
SurfacePropertiesError::SurfaceLost => Self::SurfaceLost,
|
||||
SurfacePropertiesError::NotSupported => unreachable!(),
|
||||
SurfacePropertiesError::QueueFamilyIndexOutOfRange { .. } => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +152,12 @@ impl<'a> From<&'a Arc<Queue>> for SharingMode {
|
||||
impl<'a> From<&'a [&'a Arc<Queue>]> for SharingMode {
|
||||
#[inline]
|
||||
fn from(queues: &'a [&'a Arc<Queue>]) -> SharingMode {
|
||||
SharingMode::Concurrent(queues.iter().map(|queue| queue.family().id()).collect())
|
||||
SharingMode::Concurrent(
|
||||
queues
|
||||
.iter()
|
||||
.map(|queue| queue.queue_family_index())
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -501,9 +501,7 @@ impl From<OomError> for SemaphoreExportError {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
device::{
|
||||
physical::PhysicalDevice, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||
},
|
||||
device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo},
|
||||
instance::{Instance, InstanceCreateInfo, InstanceExtensions},
|
||||
sync::{ExternalSemaphoreHandleTypes, Semaphore, SemaphoreCreateInfo},
|
||||
VulkanLibrary, VulkanObject,
|
||||
@ -554,8 +552,10 @@ mod tests {
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
let physical_device = PhysicalDevice::enumerate(&instance).next().unwrap();
|
||||
let queue_family = physical_device.queue_families().next().unwrap();
|
||||
let physical_device = match instance.enumerate_physical_devices() {
|
||||
Ok(mut x) => x.next().unwrap(),
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
let (device, _) = match Device::new(
|
||||
physical_device,
|
||||
@ -565,7 +565,10 @@ mod tests {
|
||||
khr_external_semaphore_fd: true,
|
||||
..DeviceExtensions::empty()
|
||||
},
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index: 0,
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
) {
|
||||
|
@ -29,7 +29,7 @@ macro_rules! instance {
|
||||
/// Creates a device and a queue for graphics operations.
|
||||
macro_rules! gfx_dev_and_queue {
|
||||
($($feature:ident),*) => ({
|
||||
use crate::device::physical::{PhysicalDevice, PhysicalDeviceType};
|
||||
use crate::device::physical::PhysicalDeviceType;
|
||||
use crate::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
|
||||
use crate::device::Features;
|
||||
|
||||
@ -42,15 +42,18 @@ macro_rules! gfx_dev_and_queue {
|
||||
.. Features::empty()
|
||||
};
|
||||
|
||||
let select = PhysicalDevice::enumerate(&instance)
|
||||
.filter(|&p| {
|
||||
let select = match instance.enumerate_physical_devices() {
|
||||
Ok(x) => x,
|
||||
Err(_) => return,
|
||||
}
|
||||
.filter(|p| {
|
||||
p.supported_extensions().contains(&enabled_extensions) &&
|
||||
p.supported_features().contains(&enabled_features)
|
||||
})
|
||||
.filter_map(|p| {
|
||||
p.queue_families()
|
||||
.find(|&q| q.supports_graphics())
|
||||
.map(|q| (p, q))
|
||||
p.queue_family_properties().iter()
|
||||
.position(|q| q.queue_flags.graphics)
|
||||
.map(|i| (p, i as u32))
|
||||
})
|
||||
.min_by_key(|(p, _)| {
|
||||
match p.properties().device_type {
|
||||
@ -62,7 +65,7 @@ macro_rules! gfx_dev_and_queue {
|
||||
}
|
||||
});
|
||||
|
||||
let (physical_device, queue_family) = match select {
|
||||
let (physical_device, queue_family_index) = match select {
|
||||
Some(x) => x,
|
||||
None => return,
|
||||
};
|
||||
@ -70,7 +73,10 @@ macro_rules! gfx_dev_and_queue {
|
||||
let (device, mut queues) = match Device::new(
|
||||
physical_device,
|
||||
DeviceCreateInfo {
|
||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
||||
queue_create_infos: vec![QueueCreateInfo {
|
||||
queue_family_index,
|
||||
..Default::default()
|
||||
}],
|
||||
enabled_extensions,
|
||||
enabled_features,
|
||||
..Default::default()
|
||||
|
Loading…
Reference in New Issue
Block a user