From 4abc27b9e54117c80b38c38a3bf27fc8c4c0063b Mon Sep 17 00:00:00 2001 From: Rua Date: Sat, 10 Sep 2022 08:00:08 +0200 Subject: [PATCH] Make `PhysicalDevice` an independent object (#1967) * Better validation and errors * Small fix * Make `PhysicalDevice` an independent object Co-authored-by: Austin Johnson --- examples/src/bin/basic-compute-shader.rs | 23 +- examples/src/bin/buffer-pool.rs | 32 +- examples/src/bin/clear_attachments.rs | 32 +- examples/src/bin/debug.rs | 19 +- .../deferred/frame/ambient_lighting_system.rs | 2 +- .../frame/directional_lighting_system.rs | 2 +- .../deferred/frame/point_lighting_system.rs | 2 +- examples/src/bin/deferred/frame/system.rs | 2 +- examples/src/bin/deferred/main.rs | 30 +- .../src/bin/deferred/triangle_draw_system.rs | 2 +- examples/src/bin/dynamic-buffers.rs | 23 +- examples/src/bin/dynamic-local-size.rs | 27 +- examples/src/bin/gl-interop.rs | 36 +- examples/src/bin/image-self-copy-blit/main.rs | 36 +- examples/src/bin/image/main.rs | 32 +- examples/src/bin/immutable-sampler/main.rs | 32 +- examples/src/bin/indirect.rs | 32 +- examples/src/bin/instancing.rs | 32 +- .../fractal_compute_pipeline.rs | 2 +- .../pixels_draw_pipeline.rs | 2 +- .../interactive_fractal/place_over_frame.rs | 2 +- examples/src/bin/msaa-renderpass.rs | 25 +- examples/src/bin/multi-window.rs | 40 +- .../multi_window_game_of_life/game_of_life.rs | 2 +- .../multi_window_game_of_life/pixels_draw.rs | 2 +- .../multi_window_game_of_life/render_pass.rs | 2 +- examples/src/bin/multiview.rs | 28 +- examples/src/bin/occlusion-query.rs | 33 +- examples/src/bin/pipeline-caching.rs | 21 +- examples/src/bin/push-constants.rs | 23 +- examples/src/bin/push-descriptors/main.rs | 32 +- examples/src/bin/runtime-shader/main.rs | 32 +- examples/src/bin/runtime_array/main.rs | 33 +- examples/src/bin/self-copy-buffer.rs | 23 +- examples/src/bin/shader-include/main.rs | 23 +- examples/src/bin/shader-types-sharing.rs | 24 +- examples/src/bin/simple-particles.rs | 36 +- examples/src/bin/specialization-constants.rs | 23 +- examples/src/bin/teapot/main.rs | 32 +- examples/src/bin/tessellation.rs | 35 +- examples/src/bin/texture_array/main.rs | 32 +- examples/src/bin/triangle-v1_3.rs | 35 +- examples/src/bin/triangle.rs | 32 +- vulkano-util/src/context.rs | 47 +- vulkano/Cargo.toml | 3 + vulkano/autogen/extensions.rs | 16 +- vulkano/src/buffer/cpu_access.rs | 39 +- vulkano/src/buffer/cpu_pool.rs | 2 +- vulkano/src/buffer/device_local.rs | 106 +- vulkano/src/buffer/sys.rs | 42 +- vulkano/src/command_buffer/auto.rs | 61 +- .../src/command_buffer/commands/bind_push.rs | 28 +- vulkano/src/command_buffer/commands/debug.rs | 18 +- .../command_buffer/commands/dynamic_state.rs | 112 +- vulkano/src/command_buffer/commands/image.rs | 18 +- .../src/command_buffer/commands/pipeline.rs | 8 +- vulkano/src/command_buffer/commands/query.rs | 48 +- .../command_buffer/commands/render_pass.rs | 28 +- .../src/command_buffer/commands/secondary.rs | 8 +- .../src/command_buffer/commands/transfer.rs | 67 +- vulkano/src/command_buffer/mod.rs | 2 +- vulkano/src/command_buffer/pool/mod.rs | 17 +- vulkano/src/command_buffer/pool/standard.rs | 29 +- vulkano/src/command_buffer/pool/sys.rs | 29 +- .../src/command_buffer/submit/bind_sparse.rs | 7 +- vulkano/src/command_buffer/synced/mod.rs | 10 +- vulkano/src/device/mod.rs | 252 +- vulkano/src/device/physical.rs | 2280 +++++++++-------- vulkano/src/image/attachment.rs | 4 +- vulkano/src/image/immutable.rs | 55 +- vulkano/src/image/storage.rs | 64 +- vulkano/src/image/sys.rs | 37 +- vulkano/src/instance/mod.rs | 95 +- vulkano/src/lib.rs | 2 +- vulkano/src/library.rs | 13 +- vulkano/src/macros.rs | 130 +- vulkano/src/memory/device_memory.rs | 96 +- vulkano/src/memory/mod.rs | 16 +- vulkano/src/memory/pool/host_visible.rs | 36 +- vulkano/src/memory/pool/mod.rs | 51 +- vulkano/src/memory/pool/non_host_visible.rs | 39 +- vulkano/src/memory/pool/pool.rs | 46 +- vulkano/src/pipeline/compute.rs | 2 +- vulkano/src/swapchain/display.rs | 62 +- vulkano/src/swapchain/swapchain.rs | 41 +- vulkano/src/sync/mod.rs | 7 +- vulkano/src/sync/semaphore.rs | 15 +- vulkano/src/tests.rs | 22 +- 88 files changed, 2796 insertions(+), 2284 deletions(-) diff --git a/examples/src/bin/basic-compute-shader.rs b/examples/src/bin/basic-compute-shader.rs index 339ee254..41526840 100644 --- a/examples/src/bin/basic-compute-shader.rs +++ b/examples/src/bin/basic-compute-shader.rs @@ -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(); diff --git a/examples/src/bin/buffer-pool.rs b/examples/src/bin/buffer-pool.rs index b910e734..efc66ae4 100644 --- a/examples/src/bin/buffer-pool.rs +++ b/examples/src/bin/buffer-pool.rs @@ -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(); diff --git a/examples/src/bin/clear_attachments.rs b/examples/src/bin/clear_attachments.rs index 055e5e3a..11051a9a 100644 --- a/examples/src/bin/clear_attachments.rs +++ b/examples/src/bin/clear_attachments.rs @@ -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(); diff --git a/examples/src/bin/debug.rs b/examples/src/bin/debug.rs index e7b40d87..927d5467 100644 --- a/examples/src/bin/debug.rs +++ b/examples/src/bin/debug.rs @@ -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() }, ) diff --git a/examples/src/bin/deferred/frame/ambient_lighting_system.rs b/examples/src/bin/deferred/frame/ambient_lighting_system.rs index 2f3c3c33..56d3e09d 100644 --- a/examples/src/bin/deferred/frame/ambient_lighting_system.rs +++ b/examples/src/bin/deferred/frame/ambient_lighting_system.rs @@ -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()), diff --git a/examples/src/bin/deferred/frame/directional_lighting_system.rs b/examples/src/bin/deferred/frame/directional_lighting_system.rs index d483d199..8512d350 100644 --- a/examples/src/bin/deferred/frame/directional_lighting_system.rs +++ b/examples/src/bin/deferred/frame/directional_lighting_system.rs @@ -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()), diff --git a/examples/src/bin/deferred/frame/point_lighting_system.rs b/examples/src/bin/deferred/frame/point_lighting_system.rs index 1a7a5dcc..11232324 100644 --- a/examples/src/bin/deferred/frame/point_lighting_system.rs +++ b/examples/src/bin/deferred/frame/point_lighting_system.rs @@ -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()), diff --git a/examples/src/bin/deferred/frame/system.rs b/examples/src/bin/deferred/frame/system.rs index ef3bac5c..0f017322 100644 --- a/examples/src/bin/deferred/frame/system.rs +++ b/examples/src/bin/deferred/frame/system.rs @@ -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(); diff --git a/examples/src/bin/deferred/main.rs b/examples/src/bin/deferred/main.rs index b8c649ab..d7fd0284 100644 --- a/examples/src/bin/deferred/main.rs +++ b/examples/src/bin/deferred/main.rs @@ -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, diff --git a/examples/src/bin/deferred/triangle_draw_system.rs b/examples/src/bin/deferred/triangle_draw_system.rs index 57a2ccac..dd446d5a 100644 --- a/examples/src/bin/deferred/triangle_draw_system.rs +++ b/examples/src/bin/deferred/triangle_draw_system.rs @@ -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()), diff --git a/examples/src/bin/dynamic-buffers.rs b/examples/src/bin/dynamic-buffers.rs index eb337f75..9a288dfc 100644 --- a/examples/src/bin/dynamic-buffers.rs +++ b/examples/src/bin/dynamic-buffers.rs @@ -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(); diff --git a/examples/src/bin/dynamic-local-size.rs b/examples/src/bin/dynamic-local-size.rs index dfe67e09..97797abb 100644 --- a/examples/src/bin/dynamic-local-size.rs +++ b/examples/src/bin/dynamic-local-size.rs @@ -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(); diff --git a/examples/src/bin/gl-interop.rs b/examples/src/bin/gl-interop.rs index a2576a15..7154389d 100644 --- a/examples/src/bin/gl-interop.rs +++ b/examples/src/bin/gl-interop.rs @@ -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, diff --git a/examples/src/bin/image-self-copy-blit/main.rs b/examples/src/bin/image-self-copy-blit/main.rs index 728cd19d..ca6bb3d6 100644 --- a/examples/src/bin/image-self-copy-blit/main.rs +++ b/examples/src/bin/image-self-copy-blit/main.rs @@ -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(); diff --git a/examples/src/bin/image/main.rs b/examples/src/bin/image/main.rs index 3c605224..742b65b3 100644 --- a/examples/src/bin/image/main.rs +++ b/examples/src/bin/image/main.rs @@ -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(); diff --git a/examples/src/bin/immutable-sampler/main.rs b/examples/src/bin/immutable-sampler/main.rs index 7d538636..23d04f08 100644 --- a/examples/src/bin/immutable-sampler/main.rs +++ b/examples/src/bin/immutable-sampler/main.rs @@ -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(); diff --git a/examples/src/bin/indirect.rs b/examples/src/bin/indirect.rs index 2b415fbd..55ea69ac 100644 --- a/examples/src/bin/indirect.rs +++ b/examples/src/bin/indirect.rs @@ -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(); diff --git a/examples/src/bin/instancing.rs b/examples/src/bin/instancing.rs index aec6f240..5c3eab14 100644 --- a/examples/src/bin/instancing.rs +++ b/examples/src/bin/instancing.rs @@ -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(); diff --git a/examples/src/bin/interactive_fractal/fractal_compute_pipeline.rs b/examples/src/bin/interactive_fractal/fractal_compute_pipeline.rs index 48ede3ce..d6e43f31 100644 --- a/examples/src/bin/interactive_fractal/fractal_compute_pipeline.rs +++ b/examples/src/bin/interactive_fractal/fractal_compute_pipeline.rs @@ -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(); diff --git a/examples/src/bin/interactive_fractal/pixels_draw_pipeline.rs b/examples/src/bin/interactive_fractal/pixels_draw_pipeline.rs index 6a162e4d..7e8f11bd 100644 --- a/examples/src/bin/interactive_fractal/pixels_draw_pipeline.rs +++ b/examples/src/bin/interactive_fractal/pixels_draw_pipeline.rs @@ -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()), diff --git a/examples/src/bin/interactive_fractal/place_over_frame.rs b/examples/src/bin/interactive_fractal/place_over_frame.rs index a79ac8e2..d51a7d17 100644 --- a/examples/src/bin/interactive_fractal/place_over_frame.rs +++ b/examples/src/bin/interactive_fractal/place_over_frame.rs @@ -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(); diff --git a/examples/src/bin/msaa-renderpass.rs b/examples/src/bin/msaa-renderpass.rs index 6fa422a5..859ff555 100644 --- a/examples/src/bin/msaa-renderpass.rs +++ b/examples/src/bin/msaa-renderpass.rs @@ -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(); diff --git a/examples/src/bin/multi-window.rs b/examples/src/bin/multi-window.rs index 9f10fb39..69413802 100644 --- a/examples/src/bin/multi-window.rs +++ b/examples/src/bin/multi-window.rs @@ -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 - .surface_capabilities(&surface, Default::default()) - .unwrap(), - ) + let surface_capabilities = device + .physical_device() + .surface_capabilities(&surface, Default::default()) + .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(); diff --git a/examples/src/bin/multi_window_game_of_life/game_of_life.rs b/examples/src/bin/multi_window_game_of_life/game_of_life.rs index ebbd9934..af9601d2 100644 --- a/examples/src/bin/multi_window_game_of_life/game_of_life.rs +++ b/examples/src/bin/multi_window_game_of_life/game_of_life.rs @@ -112,7 +112,7 @@ impl GameOfLifeComputePipeline { ) -> Box { let mut builder = AutoCommandBufferBuilder::primary( self.compute_queue.device().clone(), - self.compute_queue.family(), + self.compute_queue.queue_family_index(), CommandBufferUsage::OneTimeSubmit, ) .unwrap(); diff --git a/examples/src/bin/multi_window_game_of_life/pixels_draw.rs b/examples/src/bin/multi_window_game_of_life/pixels_draw.rs index 081992e9..0eaa2a26 100644 --- a/examples/src/bin/multi_window_game_of_life/pixels_draw.rs +++ b/examples/src/bin/multi_window_game_of_life/pixels_draw.rs @@ -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()), diff --git a/examples/src/bin/multi_window_game_of_life/render_pass.rs b/examples/src/bin/multi_window_game_of_life/render_pass.rs index b186c5b0..17c9d71c 100644 --- a/examples/src/bin/multi_window_game_of_life/render_pass.rs +++ b/examples/src/bin/multi_window_game_of_life/render_pass.rs @@ -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(); diff --git a/examples/src/bin/multiview.rs b/examples/src/bin/multiview.rs index fac8d731..ba87d01f 100644 --- a/examples/src/bin/multiview.rs +++ b/examples/src/bin/multiview.rs @@ -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(); diff --git a/examples/src/bin/occlusion-query.rs b/examples/src/bin/occlusion-query.rs index 52734e88..c7eb669e 100644 --- a/examples/src/bin/occlusion-query.rs +++ b/examples/src/bin/occlusion-query.rs @@ -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(); diff --git a/examples/src/bin/pipeline-caching.rs b/examples/src/bin/pipeline-caching.rs index 4abaf953..6f09c0d5 100644 --- a/examples/src/bin/pipeline-caching.rs +++ b/examples/src/bin/pipeline-caching.rs @@ -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() }, ) diff --git a/examples/src/bin/push-constants.rs b/examples/src/bin/push-constants.rs index 479f201a..ed8a4fb4 100644 --- a/examples/src/bin/push-constants.rs +++ b/examples/src/bin/push-constants.rs @@ -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(); diff --git a/examples/src/bin/push-descriptors/main.rs b/examples/src/bin/push-descriptors/main.rs index dd27c1c4..a495ed3a 100644 --- a/examples/src/bin/push-descriptors/main.rs +++ b/examples/src/bin/push-descriptors/main.rs @@ -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(); diff --git a/examples/src/bin/runtime-shader/main.rs b/examples/src/bin/runtime-shader/main.rs index b4a288bd..55efc965 100644 --- a/examples/src/bin/runtime-shader/main.rs +++ b/examples/src/bin/runtime-shader/main.rs @@ -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(); diff --git a/examples/src/bin/runtime_array/main.rs b/examples/src/bin/runtime_array/main.rs index 69b7e3cc..a748a1bf 100644 --- a/examples/src/bin/runtime_array/main.rs +++ b/examples/src/bin/runtime_array/main.rs @@ -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(); diff --git a/examples/src/bin/self-copy-buffer.rs b/examples/src/bin/self-copy-buffer.rs index 763875ce..45aabbf0 100644 --- a/examples/src/bin/self-copy-buffer.rs +++ b/examples/src/bin/self-copy-buffer.rs @@ -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(); diff --git a/examples/src/bin/shader-include/main.rs b/examples/src/bin/shader-include/main.rs index 07fd560c..a3e67302 100644 --- a/examples/src/bin/shader-include/main.rs +++ b/examples/src/bin/shader-include/main.rs @@ -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(); diff --git a/examples/src/bin/shader-types-sharing.rs b/examples/src/bin/shader-types-sharing.rs index 67953715..b38e6cd1 100644 --- a/examples/src/bin/shader-types-sharing.rs +++ b/examples/src/bin/shader-types-sharing.rs @@ -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(); diff --git a/examples/src/bin/simple-particles.rs b/examples/src/bin/simple-particles.rs index d16f4a23..1dae3113 100644 --- a/examples/src/bin/simple-particles.rs +++ b/examples/src/bin/simple-particles.rs @@ -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(); diff --git a/examples/src/bin/specialization-constants.rs b/examples/src/bin/specialization-constants.rs index b7eb911f..5ca03f24 100644 --- a/examples/src/bin/specialization-constants.rs +++ b/examples/src/bin/specialization-constants.rs @@ -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(); diff --git a/examples/src/bin/teapot/main.rs b/examples/src/bin/teapot/main.rs index f7b0c4cb..164b8916 100644 --- a/examples/src/bin/teapot/main.rs +++ b/examples/src/bin/teapot/main.rs @@ -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(); diff --git a/examples/src/bin/tessellation.rs b/examples/src/bin/tessellation.rs index 1213a81d..63bddb1e 100644 --- a/examples/src/bin/tessellation.rs +++ b/examples/src/bin/tessellation.rs @@ -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(); diff --git a/examples/src/bin/texture_array/main.rs b/examples/src/bin/texture_array/main.rs index 55a1ba37..59a12d81 100644 --- a/examples/src/bin/texture_array/main.rs +++ b/examples/src/bin/texture_array/main.rs @@ -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(); diff --git a/examples/src/bin/triangle-v1_3.rs b/examples/src/bin/triangle-v1_3.rs index f7c5be27..3c86a8c3 100644 --- a/examples/src/bin/triangle-v1_3.rs +++ b/examples/src/bin/triangle-v1_3.rs @@ -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(); diff --git a/examples/src/bin/triangle.rs b/examples/src/bin/triangle.rs index 343d7876..5d3e0b66 100644 --- a/examples/src/bin/triangle.rs +++ b/examples/src/bin/triangle.rs @@ -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(); diff --git a/vulkano-util/src/context.rs b/vulkano-util/src/context.rs index d25a2a00..e25fd8a8 100644 --- a/vulkano-util/src/context.rs +++ b/vulkano-util/src/context.rs @@ -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, device_extensions: DeviceExtensions, features: Features, ) -> (Arc, Arc, Arc) { - 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, diff --git a/vulkano/Cargo.toml b/vulkano/Cargo.toml index 2b3879ac..6f871ca0 100644 --- a/vulkano/Cargo.toml +++ b/vulkano/Cargo.toml @@ -40,3 +40,6 @@ regex = "1.5" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" vk-parse = "0.7" + +[features] +document_unchecked = [] diff --git a/vulkano/autogen/extensions.rs b/vulkano/autogen/extensions.rs index 4266c7e7..cfea57c5 100644 --- a/vulkano/autogen/extensions.rs +++ b/vulkano/autogen/extensions.rs @@ -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 for #struct_name where I: IntoIterator { - fn from(names: I) -> Self { + impl<'a> FromIterator<&'a str> for #struct_name { + fn from_iter(iter: I) -> Self + where I: IntoIterator + { 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)* _ => (), } } diff --git a/vulkano/src/buffer/cpu_access.rs b/vulkano/src/buffer/cpu_access.rs index 64cc7a79..fcd81dd9 100644 --- a/vulkano/src/buffer/cpu_access.rs +++ b/vulkano/src/buffer/cpu_access.rs @@ -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>, @@ -203,27 +203,21 @@ where /// # Panics /// /// - Panics if `size` is zero. - pub unsafe fn raw<'a, I>( + pub unsafe fn raw( device: Arc, size: DeviceSize, usage: BufferUsage, host_cached: bool, - queue_families: I, - ) -> Result>, DeviceMemoryAllocationError> - where - I: IntoIterator>, - { - let queue_families = queue_families - .into_iter() - .map(|f| f.id()) - .collect::>(); + queue_family_indices: impl IntoIterator, + ) -> Result>, 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 { - 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 } } diff --git a/vulkano/src/buffer/cpu_pool.rs b/vulkano/src/buffer/cpu_pool.rs index d1dfb733..8dec6072 100644 --- a/vulkano/src/buffer/cpu_pool.rs +++ b/vulkano/src/buffer/cpu_pool.rs @@ -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. diff --git a/vulkano/src/buffer/device_local.rs b/vulkano/src/buffer/device_local.rs index 9b93104e..4b01d375 100644 --- a/vulkano/src/buffer/device_local.rs +++ b/vulkano/src/buffer/device_local.rs @@ -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>, @@ -154,16 +154,18 @@ where /// /// - Panics if `T` has zero size. #[inline] - pub fn new<'a, I>( + pub fn new( device: Arc, usage: BufferUsage, - queue_families: I, - ) -> Result>, DeviceMemoryAllocationError> - where - I: IntoIterator>, - { + queue_family_indices: impl IntoIterator, + ) -> Result>, DeviceMemoryAllocationError> { unsafe { - DeviceLocalBuffer::raw(device, size_of::() as DeviceSize, usage, queue_families) + DeviceLocalBuffer::raw( + device, + size_of::() 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, len: DeviceSize, usage: BufferUsage, - queue_families: I, - ) -> Result>, DeviceMemoryAllocationError> - where - I: IntoIterator>, - { + queue_family_indices: impl IntoIterator, + ) -> Result>, DeviceMemoryAllocationError> { unsafe { DeviceLocalBuffer::raw( device, len * size_of::() 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, size: DeviceSize, usage: BufferUsage, - queue_families: I, - ) -> Result>, DeviceMemoryAllocationError> - where - I: IntoIterator>, - { - let queue_families = queue_families - .into_iter() - .map(|f| f.id()) - .collect::>(); + queue_family_indices: impl IntoIterator, + ) -> Result>, 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, size: DeviceSize, usage: BufferUsage, - queue_families: I, - ) -> Result>, DeviceMemoryAllocationError> - where - I: IntoIterator>, - { + queue_family_indices: impl IntoIterator, + ) -> Result>, 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::>(); + 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, size: DeviceSize, usage: BufferUsage, - queue_families: &SmallVec<[u32; 4]>, + queue_family_indices: &SmallVec<[u32; 4]>, ) -> Result<(Arc, 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 { - 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(); diff --git a/vulkano/src/buffer/sys.rs b/vulkano/src/buffer/sys.rs index 583a2ccc..ac25ddde 100644 --- a/vulkano/src/buffer/sys.rs +++ b/vulkano/src/buffer/sys.rs @@ -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") } } } diff --git a/vulkano/src/command_buffer/auto.rs b/vulkano/src/command_buffer/auto.rs index 6e25471d..6dc279d2 100644 --- a/vulkano/src/command_buffer/auto.rs +++ b/vulkano/src/command_buffer/auto.rs @@ -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 { 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, - queue_family: QueueFamily, + queue_family_index: u32, usage: CommandBufferUsage, ) -> Result< AutoCommandBufferBuilder, @@ -138,7 +138,7 @@ impl AutoCommandBufferBuilder, - queue_family: QueueFamily, + queue_family_index: u32, usage: CommandBufferUsage, inheritance_info: CommandBufferInheritanceInfo, ) -> Result< @@ -165,7 +165,7 @@ impl AutoCommandBufferBuilder AutoCommandBufferBuilder { // `begin_info.inheritance_info` must match `level`. unsafe fn begin( device: Arc, - queue_family: QueueFamily, + queue_family_index: u32, level: CommandBufferLevel, begin_info: CommandBufferBeginInfo, ) -> Result, 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 AutoCommandBufferBuilder { } } - 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { 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 for BuildError { impl AutoCommandBufferBuilder { #[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(); diff --git a/vulkano/src/command_buffer/commands/bind_push.rs b/vulkano/src/command_buffer/commands/bind_push.rs index 2b565c4f..53416bc6 100644 --- a/vulkano/src/command_buffer/commands/bind_push.rs +++ b/vulkano/src/command_buffer/commands/bind_push.rs @@ -94,16 +94,18 @@ impl AutoCommandBufferBuilder { // 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { &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 AutoCommandBufferBuilder { &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 AutoCommandBufferBuilder { first_binding: u32, vertex_buffers: &[Arc], ) -> 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 AutoCommandBufferBuilder { // 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); } } diff --git a/vulkano/src/command_buffer/commands/debug.rs b/vulkano/src/command_buffer/commands/debug.rs index 7e85054d..1fa8db81 100644 --- a/vulkano/src/command_buffer/commands/debug.rs +++ b/vulkano/src/command_buffer/commands/debug.rs @@ -63,8 +63,12 @@ impl AutoCommandBufferBuilder { }); } + 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 AutoCommandBufferBuilder { }); } + 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 AutoCommandBufferBuilder { }); } + 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); } diff --git a/vulkano/src/command_buffer/commands/dynamic_state.rs b/vulkano/src/command_buffer/commands/dynamic_state.rs index 62fa2a7e..075c2a8a 100644 --- a/vulkano/src/command_buffer/commands/dynamic_state.rs +++ b/vulkano/src/command_buffer/commands/dynamic_state.rs @@ -75,8 +75,10 @@ impl AutoCommandBufferBuilder { ) -> 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 AutoCommandBufferBuilder { ) -> 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 AutoCommandBufferBuilder { // 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 AutoCommandBufferBuilder { ) -> 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { ) -> 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 AutoCommandBufferBuilder { ) -> 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 AutoCommandBufferBuilder { // 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { ) -> 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 AutoCommandBufferBuilder { // 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 AutoCommandBufferBuilder { ) -> 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { // 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { ) -> 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 AutoCommandBufferBuilder { // 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 AutoCommandBufferBuilder { ) -> 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 AutoCommandBufferBuilder { ) -> 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 AutoCommandBufferBuilder { ) -> 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 AutoCommandBufferBuilder { // 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 AutoCommandBufferBuilder { // 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 AutoCommandBufferBuilder { // 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { // 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 AutoCommandBufferBuilder { ) -> 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 AutoCommandBufferBuilder { ) -> 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); } diff --git a/vulkano/src/command_buffer/commands/image.rs b/vulkano/src/command_buffer/commands/image.rs index 331aa6eb..e766ff86 100644 --- a/vulkano/src/command_buffer/commands/image.rs +++ b/vulkano/src/command_buffer/commands/image.rs @@ -86,8 +86,10 @@ impl AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { 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); } diff --git a/vulkano/src/command_buffer/commands/pipeline.rs b/vulkano/src/command_buffer/commands/pipeline.rs index 6e8590de..ffc57983 100644 --- a/vulkano/src/command_buffer/commands/pipeline.rs +++ b/vulkano/src/command_buffer/commands/pipeline.rs @@ -70,8 +70,10 @@ impl AutoCommandBufferBuilder { } 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 AutoCommandBufferBuilder { &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); } diff --git a/vulkano/src/command_buffer/commands/query.rs b/vulkano/src/command_buffer/commands/query.rs index 42203786..4f247722 100644 --- a/vulkano/src/command_buffer/commands/query.rs +++ b/vulkano/src/command_buffer/commands/query.rs @@ -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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { // 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 AutoCommandBufferBuilder { } 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { } // 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 AutoCommandBufferBuilder { D: ?Sized + TypedBufferAccess, 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 AutoCommandBufferBuilder { 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); } diff --git a/vulkano/src/command_buffer/commands/render_pass.rs b/vulkano/src/command_buffer/commands/render_pass.rs index 1fde76a0..e9b91dd9 100644 --- a/vulkano/src/command_buffer/commands/render_pass.rs +++ b/vulkano/src/command_buffer/commands/render_pass.rs @@ -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 AutoCommandBufferBuilder { }); } + 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 AutoCommandBufferBuilder { } // 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 AutoCommandBufferBuilder { } // 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(()) } diff --git a/vulkano/src/command_buffer/commands/secondary.rs b/vulkano/src/command_buffer/commands/secondary.rs index dad5370a..70d289a7 100644 --- a/vulkano/src/command_buffer/commands/secondary.rs +++ b/vulkano/src/command_buffer/commands/secondary.rs @@ -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); } diff --git a/vulkano/src/command_buffer/commands/transfer.rs b/vulkano/src/command_buffer/commands/transfer.rs index 9900ba7d..1ffff080 100644 --- a/vulkano/src/command_buffer/commands/transfer.rs +++ b/vulkano/src/command_buffer/commands/transfer.rs @@ -63,10 +63,12 @@ impl AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { }); } - 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { }); } - 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 AutoCommandBufferBuilder { // 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { }); } - 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 AutoCommandBufferBuilder { // 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 AutoCommandBufferBuilder { 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 AutoCommandBufferBuilder { 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); } diff --git a/vulkano/src/command_buffer/mod.rs b/vulkano/src/command_buffer/mod.rs index 781a8b07..df8325a0 100644 --- a/vulkano/src/command_buffer/mod.rs +++ b/vulkano/src/command_buffer/mod.rs @@ -63,7 +63,7 @@ //! # let graphics_pipeline: std::sync::Arc = 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() diff --git a/vulkano/src/command_buffer/pool/mod.rs b/vulkano/src/command_buffer/pool/mod.rs index c7816880..1828cb48 100644 --- a/vulkano/src/command_buffer/pool/mod.rs +++ b/vulkano/src/command_buffer/pool/mod.rs @@ -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; - /// 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; } diff --git a/vulkano/src/command_buffer/pool/standard.rs b/vulkano/src/command_buffer/pool/standard.rs index f3750edb..ef46f633 100644 --- a/vulkano/src/command_buffer/pool/standard.rs +++ b/vulkano/src/command_buffer/pool/standard.rs @@ -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, - queue_family: QueueFamily, + queue_family_index: u32, ) -> Result { - 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 { } #[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() diff --git a/vulkano/src/command_buffer/pool/sys.rs b/vulkano/src/command_buffer/pool/sys.rs index ff08cea7..1f2698bc 100644 --- a/vulkano/src/command_buffer/pool/sys.rs +++ b/vulkano/src/command_buffer/pool/sys.rs @@ -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() }, ) diff --git a/vulkano/src/command_buffer/submit/bind_sparse.rs b/vulkano/src/command_buffer/submit/bind_sparse.rs index 33b1e13b..9b2a0381 100644 --- a/vulkano/src/command_buffer/submit/bind_sparse.rs +++ b/vulkano/src/command_buffer/submit/bind_sparse.rs @@ -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(); diff --git a/vulkano/src/command_buffer/synced/mod.rs b/vulkano/src/command_buffer/synced/mod.rs index a3cc2633..a9f3d7ab 100644 --- a/vulkano/src/command_buffer/synced/mod.rs +++ b/vulkano/src/command_buffer/synced/mod.rs @@ -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::>(); 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::>() @@ -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() diff --git a/vulkano/src/device/mod.rs b/vulkano/src/device/mod.rs index 249e74d3..5daed4b7 100644 --- a/vulkano/src/device/mod.rs +++ b/vulkano/src/device/mod.rs @@ -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, - physical_device: usize, + physical_device: Arc, // 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>, enabled_extensions: DeviceExtensions, enabled_features: Features, - active_queue_families: SmallVec<[u32; 2]>, + active_queue_family_indices: SmallVec<[u32; 2]>, allocation_count: Mutex, fence_pool: Mutex>, semaphore_pool: Mutex>, @@ -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, create_info: DeviceCreateInfo, ) -> Result<(Arc, impl ExactSizeIterator>), 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, - _ne: _, - } in &queue_create_infos - { - assert_eq!( - family.physical_device().internal_object(), - physical_device.internal_object() - ); + for queue_create_info in &queue_create_infos { + let &QueueCreateInfo { + queue_family_index, + ref queues, + _ne: _, + } = 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 { + &self.physical_device } /// Returns the instance used to create this device. #[inline] pub fn instance(&self) -> &Arc { - &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` in the future. - // TODO: ^ - #[inline] - pub fn active_queue_families(&self) -> impl ExactSizeIterator { - 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( self: &Arc, - queue_family: QueueFamily, + queue_family_index: u32, f: impl FnOnce(&Arc) -> T, ) -> Result { 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(&self, state: &mut H) { self.handle.hash(state); - self.instance.hash(state); + self.physical_device.hash(state); } } @@ -840,7 +848,7 @@ impl From 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>, + pub queue_create_infos: Vec, 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 for MemoryFdPropertiesError { pub struct Queue { handle: Mutex, device: Arc, - 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(&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() }, diff --git a/vulkano/src/device/physical.rs b/vulkano/src/device/physical.rs index aa004129..30fae885 100644 --- a/vulkano/src/device/physical.rs +++ b/vulkano/src/device/physical.rs @@ -12,7 +12,7 @@ use crate::{ device::{DeviceExtensions, Features, FeaturesFfi, Properties, PropertiesFfi}, format::{Format, FormatProperties}, image::{ImageCreateFlags, ImageFormatInfo, ImageFormatProperties, ImageUsage}, - instance::{Instance, InstanceCreationError}, + instance::Instance, macros::{vulkan_bitflags, vulkan_enum}, swapchain::{ ColorSpace, FullScreenExclusive, PresentMode, SupportedSurfaceTransforms, Surface, @@ -21,282 +21,17 @@ use crate::{ sync::{ExternalSemaphoreInfo, ExternalSemaphoreProperties, PipelineStage}, DeviceSize, OomError, RequirementNotMet, RequiresOneOf, Version, VulkanError, VulkanObject, }; +use bytemuck::cast_slice; use std::{ error::Error, - ffi::CStr, fmt::{Debug, Display, Error as FmtError, Formatter}, - hash::Hash, + hash::{Hash, Hasher}, mem::MaybeUninit, ptr, sync::Arc, }; -#[derive(Clone, Debug)] -pub(crate) struct PhysicalDeviceInfo { - handle: ash::vk::PhysicalDevice, - api_version: Version, - supported_extensions: DeviceExtensions, - supported_features: Features, - properties: Properties, - memory_properties: ash::vk::PhysicalDeviceMemoryProperties, - queue_families: Vec, -} - -pub(crate) fn init_physical_devices( - instance: &Instance, -) -> Result, InstanceCreationError> { - let fns = instance.fns(); - let instance_extensions = instance.enabled_extensions(); - - let handles = unsafe { - loop { - let mut count = 0; - (fns.v1_0.enumerate_physical_devices)( - instance.internal_object(), - &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)( - instance.internal_object(), - &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).into()), - } - } - }; - - handles - .into_iter() - .enumerate() - .map(|(_index, handle)| -> Result<_, InstanceCreationError> { - let api_version = unsafe { - let mut output = MaybeUninit::uninit(); - (fns.v1_0.get_physical_device_properties)(handle, output.as_mut_ptr()); - let api_version = Version::try_from(output.assume_init().api_version).unwrap(); - std::cmp::min(instance.max_api_version(), api_version) - }; - - let extension_properties = unsafe { - loop { - let mut count = 0; - (fns.v1_0.enumerate_device_extension_properties)( - handle, - ptr::null(), - &mut count, - ptr::null_mut(), - ) - .result() - .map_err(VulkanError::from)?; - - let mut properties = Vec::with_capacity(count as usize); - let result = (fns.v1_0.enumerate_device_extension_properties)( - handle, - ptr::null(), - &mut count, - properties.as_mut_ptr(), - ); - - match result { - ash::vk::Result::SUCCESS => { - properties.set_len(count as usize); - break properties; - } - ash::vk::Result::INCOMPLETE => (), - err => return Err(VulkanError::from(err).into()), - } - } - }; - - let supported_extensions = DeviceExtensions::from( - extension_properties - .iter() - .map(|property| unsafe { CStr::from_ptr(property.extension_name.as_ptr()) }), - ); - - let mut info = PhysicalDeviceInfo { - handle, - api_version, - supported_extensions, - supported_features: Default::default(), - properties: Default::default(), - memory_properties: Default::default(), - queue_families: Default::default(), - }; - - // Get the remaining infos. - // If possible, we use VK_KHR_get_physical_device_properties2. - if api_version >= Version::V1_1 - || instance_extensions.khr_get_physical_device_properties2 - { - init_info2(instance, &mut info) - } else { - init_info(instance, &mut info) - }; - - Ok(info) - }) - .collect::>() -} - -fn init_info(instance: &Instance, info: &mut PhysicalDeviceInfo) { - let fns = instance.fns(); - - info.supported_features = unsafe { - let mut output = FeaturesFfi::default(); - (fns.v1_0.get_physical_device_features)(info.handle, &mut output.head_as_mut().features); - Features::from(&output) - }; - - info.properties = unsafe { - let mut output = PropertiesFfi::default(); - output.make_chain( - info.api_version, - &info.supported_extensions, - instance.enabled_extensions(), - ); - (fns.v1_0.get_physical_device_properties)( - info.handle, - &mut output.head_as_mut().properties, - ); - Properties::from(&output) - }; - - info.memory_properties = unsafe { - let mut output = MaybeUninit::uninit(); - (fns.v1_0.get_physical_device_memory_properties)(info.handle, output.as_mut_ptr()); - output.assume_init() - }; - - info.queue_families = unsafe { - let mut num = 0; - (fns.v1_0.get_physical_device_queue_family_properties)( - info.handle, - &mut num, - ptr::null_mut(), - ); - - let mut families = Vec::with_capacity(num as usize); - (fns.v1_0.get_physical_device_queue_family_properties)( - info.handle, - &mut num, - families.as_mut_ptr(), - ); - families.set_len(num as usize); - families - }; -} - -// TODO: Query extension-specific physical device properties, once a new instance extension is supported. -fn init_info2(instance: &Instance, info: &mut PhysicalDeviceInfo) { - let fns = instance.fns(); - - info.supported_features = unsafe { - let mut output = FeaturesFfi::default(); - output.make_chain( - info.api_version, - &info.supported_extensions, - instance.enabled_extensions(), - ); - - if instance.api_version() >= Version::V1_1 { - (fns.v1_1.get_physical_device_features2)(info.handle, output.head_as_mut()); - } else { - (fns.khr_get_physical_device_properties2 - .get_physical_device_features2_khr)(info.handle, output.head_as_mut()); - } - - Features::from(&output) - }; - - info.properties = unsafe { - let mut output = PropertiesFfi::default(); - output.make_chain( - info.api_version, - &info.supported_extensions, - instance.enabled_extensions(), - ); - - if instance.api_version() >= Version::V1_1 { - (fns.v1_1.get_physical_device_properties2)(info.handle, output.head_as_mut()); - } else { - (fns.khr_get_physical_device_properties2 - .get_physical_device_properties2_khr)(info.handle, output.head_as_mut()); - } - - Properties::from(&output) - }; - - info.memory_properties = unsafe { - let mut output = ash::vk::PhysicalDeviceMemoryProperties2KHR::default(); - - if instance.api_version() >= Version::V1_1 { - (fns.v1_1.get_physical_device_memory_properties2)(info.handle, &mut output); - } else { - (fns.khr_get_physical_device_properties2 - .get_physical_device_memory_properties2_khr)(info.handle, &mut output); - } - - output.memory_properties - }; - - info.queue_families = unsafe { - let mut num = 0; - - if instance.api_version() >= Version::V1_1 { - (fns.v1_1.get_physical_device_queue_family_properties2)( - info.handle, - &mut num, - ptr::null_mut(), - ); - } else { - (fns.khr_get_physical_device_properties2 - .get_physical_device_queue_family_properties2_khr)( - info.handle, - &mut num, - ptr::null_mut(), - ); - } - - let mut families = vec![ash::vk::QueueFamilyProperties2::default(); num as usize]; - - if instance.api_version() >= Version::V1_1 { - (fns.v1_1.get_physical_device_queue_family_properties2)( - info.handle, - &mut num, - families.as_mut_ptr(), - ); - } else { - (fns.khr_get_physical_device_properties2 - .get_physical_device_queue_family_properties2_khr)( - info.handle, - &mut num, - families.as_mut_ptr(), - ); - } - - families - .into_iter() - .map(|family| family.queue_family_properties) - .collect() - }; -} - -/// Represents one of the available devices on this machine. -/// -/// This struct simply contains a pointer to an instance and a number representing the physical -/// device. You are therefore encouraged to pass this around by value instead of by reference. +/// Represents one of the available physical devices on this machine. /// /// # Example /// @@ -309,135 +44,349 @@ fn init_info2(instance: &Instance, info: &mut PhysicalDeviceInfo) { /// /// # let library = VulkanLibrary::new().unwrap(); /// # let instance = Instance::new(library, Default::default()).unwrap(); -/// for physical_device in PhysicalDevice::enumerate(&instance) { -/// print_infos(physical_device); +/// for physical_device in instance.enumerate_physical_devices().unwrap() { +/// print_infos(&physical_device); /// } /// -/// fn print_infos(dev: PhysicalDevice) { +/// fn print_infos(dev: &PhysicalDevice) { /// println!("Name: {}", dev.properties().device_name); /// } /// ``` -#[derive(Clone, Copy, Debug)] -pub struct PhysicalDevice<'a> { - instance: &'a Arc, - index: usize, - info: &'a PhysicalDeviceInfo, +#[derive(Clone, Debug)] +pub struct PhysicalDevice { + handle: ash::vk::PhysicalDevice, + instance: Arc, + + properties: Properties, + extension_properties: Vec, + memory_properties: MemoryProperties, + queue_family_properties: Vec, + + api_version: Version, + supported_extensions: DeviceExtensions, + supported_features: Features, } -impl<'a> PhysicalDevice<'a> { - /// Returns an iterator that enumerates the physical devices available. - /// - /// # Example - /// - /// ```no_run - /// # use vulkano::{ - /// # instance::{Instance, InstanceExtensions}, - /// # Version, VulkanLibrary, - /// # }; - /// use vulkano::device::physical::PhysicalDevice; - /// - /// # let library = VulkanLibrary::new().unwrap(); - /// # let instance = Instance::new(library, Default::default()).unwrap(); - /// for physical_device in PhysicalDevice::enumerate(&instance) { - /// println!("Available device: {}", physical_device.properties().device_name); - /// } - /// ``` - #[inline] - pub fn enumerate( - instance: &'a Arc, - ) -> impl ExactSizeIterator> { - instance - .physical_device_infos +impl PhysicalDevice { + pub unsafe fn from_handle( + handle: ash::vk::PhysicalDevice, + instance: Arc, + ) -> Result, VulkanError> { + let api_version = Self::get_api_version(handle, &instance); + let extension_properties = Self::get_extension_properties(handle, &instance)?; + let supported_extensions: DeviceExtensions = extension_properties .iter() - .enumerate() - .map(move |(index, info)| PhysicalDevice { - instance, - index, - info, - }) + .map(|property| property.extension_name.as_str()) + .collect(); + + let supported_features; + let properties; + let memory_properties; + let queue_family_properties; + + // Get the remaining infos. + // If possible, we use VK_KHR_get_physical_device_properties2. + if api_version >= Version::V1_1 + || instance + .enabled_extensions() + .khr_get_physical_device_properties2 + { + supported_features = + Self::get_features2(handle, &instance, api_version, &supported_extensions); + properties = + Self::get_properties2(handle, &instance, api_version, &supported_extensions); + memory_properties = Self::get_memory_properties2(handle, &instance); + queue_family_properties = Self::get_queue_family_properties2(handle, &instance); + } else { + supported_features = Self::get_features(handle, &instance); + properties = + Self::get_properties(handle, &instance, api_version, &supported_extensions); + memory_properties = Self::get_memory_properties(handle, &instance); + queue_family_properties = Self::get_queue_family_properties(handle, &instance); + }; + + Ok(Arc::new(PhysicalDevice { + handle, + instance, + + properties, + extension_properties, + memory_properties, + queue_family_properties, + + api_version, + supported_extensions, + supported_features, + })) } - /// Returns a physical device from its index. Returns `None` if out of range. - /// - /// Indices range from 0 to the number of devices. - /// - /// # Example - /// - /// ```no_run - /// # use vulkano::{ - /// # instance::{Instance, InstanceExtensions}, - /// # Version, VulkanLibrary, - /// # }; - /// use vulkano::device::physical::PhysicalDevice; - /// - /// # let library = VulkanLibrary::new().unwrap(); - /// # let instance = Instance::new(library, Default::default()).unwrap(); - /// let first_physical_device = PhysicalDevice::from_index(&instance, 0).unwrap(); - /// ``` + unsafe fn get_api_version(handle: ash::vk::PhysicalDevice, instance: &Instance) -> Version { + let fns = instance.fns(); + let mut output = MaybeUninit::uninit(); + (fns.v1_0.get_physical_device_properties)(handle, output.as_mut_ptr()); + let api_version = Version::try_from(output.assume_init().api_version).unwrap(); + std::cmp::min(instance.max_api_version(), api_version) + } + + unsafe fn get_extension_properties( + handle: ash::vk::PhysicalDevice, + instance: &Instance, + ) -> Result, VulkanError> { + let fns = instance.fns(); + + loop { + let mut count = 0; + (fns.v1_0.enumerate_device_extension_properties)( + handle, + ptr::null(), + &mut count, + ptr::null_mut(), + ) + .result() + .map_err(VulkanError::from)?; + + let mut output = Vec::with_capacity(count as usize); + let result = (fns.v1_0.enumerate_device_extension_properties)( + handle, + ptr::null(), + &mut count, + output.as_mut_ptr(), + ); + + match result { + ash::vk::Result::SUCCESS => { + output.set_len(count as usize); + return Ok(output.into_iter().map(Into::into).collect()); + } + ash::vk::Result::INCOMPLETE => (), + err => return Err(VulkanError::from(err)), + } + } + } + + unsafe fn get_features(handle: ash::vk::PhysicalDevice, instance: &Instance) -> Features { + let mut output = FeaturesFfi::default(); + + let fns = instance.fns(); + (fns.v1_0.get_physical_device_features)(handle, &mut output.head_as_mut().features); + + Features::from(&output) + } + + unsafe fn get_features2( + handle: ash::vk::PhysicalDevice, + instance: &Instance, + api_version: Version, + supported_extensions: &DeviceExtensions, + ) -> Features { + let mut output = FeaturesFfi::default(); + output.make_chain( + api_version, + supported_extensions, + instance.enabled_extensions(), + ); + + let fns = instance.fns(); + + if instance.api_version() >= Version::V1_1 { + (fns.v1_1.get_physical_device_features2)(handle, output.head_as_mut()); + } else { + (fns.khr_get_physical_device_properties2 + .get_physical_device_features2_khr)(handle, output.head_as_mut()); + } + + Features::from(&output) + } + + unsafe fn get_properties( + handle: ash::vk::PhysicalDevice, + instance: &Instance, + api_version: Version, + supported_extensions: &DeviceExtensions, + ) -> Properties { + let mut output = PropertiesFfi::default(); + output.make_chain( + api_version, + supported_extensions, + instance.enabled_extensions(), + ); + + let fns = instance.fns(); + (fns.v1_0.get_physical_device_properties)(handle, &mut output.head_as_mut().properties); + + Properties::from(&output) + } + + unsafe fn get_properties2( + handle: ash::vk::PhysicalDevice, + instance: &Instance, + api_version: Version, + supported_extensions: &DeviceExtensions, + ) -> Properties { + let mut output = PropertiesFfi::default(); + output.make_chain( + api_version, + supported_extensions, + instance.enabled_extensions(), + ); + + let fns = instance.fns(); + + if instance.api_version() >= Version::V1_1 { + (fns.v1_1.get_physical_device_properties2)(handle, output.head_as_mut()); + } else { + (fns.khr_get_physical_device_properties2 + .get_physical_device_properties2_khr)(handle, output.head_as_mut()); + } + + Properties::from(&output) + } + + unsafe fn get_memory_properties( + handle: ash::vk::PhysicalDevice, + instance: &Instance, + ) -> MemoryProperties { + let mut output = MaybeUninit::uninit(); + + let fns = instance.fns(); + (fns.v1_0.get_physical_device_memory_properties)(handle, output.as_mut_ptr()); + + output.assume_init().into() + } + + unsafe fn get_memory_properties2( + handle: ash::vk::PhysicalDevice, + instance: &Instance, + ) -> MemoryProperties { + let mut output = ash::vk::PhysicalDeviceMemoryProperties2KHR::default(); + + let fns = instance.fns(); + + if instance.api_version() >= Version::V1_1 { + (fns.v1_1.get_physical_device_memory_properties2)(handle, &mut output); + } else { + (fns.khr_get_physical_device_properties2 + .get_physical_device_memory_properties2_khr)(handle, &mut output); + } + + output.memory_properties.into() + } + + unsafe fn get_queue_family_properties( + handle: ash::vk::PhysicalDevice, + instance: &Instance, + ) -> Vec { + let fns = instance.fns(); + + let mut num = 0; + (fns.v1_0.get_physical_device_queue_family_properties)(handle, &mut num, ptr::null_mut()); + + let mut output = Vec::with_capacity(num as usize); + (fns.v1_0.get_physical_device_queue_family_properties)( + handle, + &mut num, + output.as_mut_ptr(), + ); + output.set_len(num as usize); + + output.into_iter().map(Into::into).collect() + } + + unsafe fn get_queue_family_properties2( + handle: ash::vk::PhysicalDevice, + instance: &Instance, + ) -> Vec { + let mut num = 0; + let fns = instance.fns(); + + if instance.api_version() >= Version::V1_1 { + (fns.v1_1.get_physical_device_queue_family_properties2)( + handle, + &mut num, + ptr::null_mut(), + ); + } else { + (fns.khr_get_physical_device_properties2 + .get_physical_device_queue_family_properties2_khr)( + handle, + &mut num, + ptr::null_mut(), + ); + } + + let mut output = vec![ash::vk::QueueFamilyProperties2::default(); num as usize]; + + if instance.api_version() >= Version::V1_1 { + (fns.v1_1.get_physical_device_queue_family_properties2)( + handle, + &mut num, + output.as_mut_ptr(), + ); + } else { + (fns.khr_get_physical_device_properties2 + .get_physical_device_queue_family_properties2_khr)( + handle, + &mut num, + output.as_mut_ptr(), + ); + } + + output + .into_iter() + .map(|family| family.queue_family_properties.into()) + .collect() + } + + /// Returns the instance that owns the physical device. #[inline] - pub fn from_index(instance: &'a Arc, index: usize) -> Option> { - instance - .physical_device_infos - .get(index) - .map(|info| PhysicalDevice { - instance, - index, - info, - }) + pub fn instance(&self) -> &Arc { + &self.instance } - /// Returns the instance corresponding to this physical device. - /// - /// # Example - /// - /// ```no_run - /// use vulkano::device::physical::PhysicalDevice; - /// - /// fn do_something(physical_device: PhysicalDevice) { - /// let _loaded_extensions = physical_device.instance().enabled_extensions(); - /// // ... - /// } - /// ``` - #[inline] - pub fn instance(&self) -> &'a Arc { - self.instance - } - - /// Returns the index of the physical device in the physical devices list. - /// - /// This index never changes and can be used later to retrieve a `PhysicalDevice` from an - /// instance and an index. - #[inline] - pub fn index(&self) -> usize { - self.index - } - - /// Returns the version of Vulkan supported by this device. + /// Returns the version of Vulkan supported by the physical device. /// /// Unlike the `api_version` property, which is the version reported by the device directly, /// this function returns the version the device can actually support, based on the instance's /// `max_api_version`. #[inline] pub fn api_version(&self) -> Version { - self.info.api_version + self.api_version } - /// Returns the extensions that are supported by this physical device. + /// Returns the properties reported by the physical device. #[inline] - pub fn supported_extensions(&self) -> &'a DeviceExtensions { - &self.info.supported_extensions + pub fn properties(&self) -> &Properties { + &self.properties } - /// Returns the properties reported by the device. + /// Returns the extension properties reported by the physical device. #[inline] - pub fn properties(&self) -> &'a Properties { - &self.info.properties + pub fn extension_properties(&self) -> &[ExtensionProperties] { + &self.extension_properties } - /// Returns the features that are supported by this physical device. + /// Returns the extensions that are supported by the physical device. #[inline] - pub fn supported_features(&self) -> &'a Features { - &self.info.supported_features + pub fn supported_extensions(&self) -> &DeviceExtensions { + &self.supported_extensions + } + + /// Returns the features that are supported by the physical device. + #[inline] + pub fn supported_features(&self) -> &Features { + &self.supported_features + } + + /// Returns the memory properties reported by the physical device. + #[inline] + pub fn memory_properties(&self) -> &MemoryProperties { + &self.memory_properties + } + + /// Returns the queue family properties reported by the physical device. + #[inline] + pub fn queue_family_properties(&self) -> &[QueueFamilyProperties] { + &self.queue_family_properties } /// Retrieves the external memory properties supported for buffers with a given configuration. @@ -445,10 +394,20 @@ impl<'a> PhysicalDevice<'a> { /// Instance API version must be at least 1.1, or the /// [`khr_external_memory_capabilities`](crate::instance::InstanceExtensions::khr_external_memory_capabilities) /// extension must be enabled on the instance. + #[inline] pub fn external_buffer_properties( &self, info: ExternalBufferInfo, ) -> Result { + self.validate_external_buffer_properties(&info)?; + + unsafe { Ok(self.external_buffer_properties_unchecked(info)) } + } + + fn validate_external_buffer_properties( + &self, + info: &ExternalBufferInfo, + ) -> Result<(), ExternalBufferPropertiesError> { if !(self.instance.api_version() >= Version::V1_1 || self .instance @@ -465,6 +424,30 @@ impl<'a> PhysicalDevice<'a> { }); } + let &ExternalBufferInfo { + handle_type, + usage, + sparse: _, + _ne: _, + } = info; + + // VUID-VkPhysicalDeviceExternalBufferInfo-usage-parameter + usage.validate_physical_device(self)?; + + // VUID-VkPhysicalDeviceExternalBufferInfo-usage-requiredbitmask + assert!(!usage.is_empty()); + + // VUID-VkPhysicalDeviceExternalBufferInfo-handleType-parameter + handle_type.validate_physical_device(self)?; + + Ok(()) + } + + #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] + pub unsafe fn external_buffer_properties_unchecked( + &self, + info: ExternalBufferInfo, + ) -> ExternalBufferProperties { /* Input */ let ExternalBufferInfo { @@ -474,14 +457,6 @@ impl<'a> PhysicalDevice<'a> { _ne: _, } = info; - // VUID-VkPhysicalDeviceExternalBufferInfo-usage-parameter - usage.validate_physical_device(self)?; - - assert!(!usage.is_empty()); - - // VUID-VkPhysicalDeviceExternalBufferInfo-handleType-parameter - handle_type.validate_physical_device(self)?; - let external_buffer_info = ash::vk::PhysicalDeviceExternalBufferInfo { flags: sparse.map(Into::into).unwrap_or_default(), usage: usage.into(), @@ -495,34 +470,148 @@ impl<'a> PhysicalDevice<'a> { /* Call */ - unsafe { - let fns = self.instance.fns(); + let fns = self.instance.fns(); - if self.instance.api_version() >= Version::V1_1 { - (fns.v1_1.get_physical_device_external_buffer_properties)( - self.info.handle, - &external_buffer_info, - &mut external_buffer_properties, - ) - } else { - (fns.khr_external_memory_capabilities - .get_physical_device_external_buffer_properties_khr)( - self.info.handle, - &external_buffer_info, - &mut external_buffer_properties, - ); - } + if self.instance.api_version() >= Version::V1_1 { + (fns.v1_1.get_physical_device_external_buffer_properties)( + self.handle, + &external_buffer_info, + &mut external_buffer_properties, + ) + } else { + (fns.khr_external_memory_capabilities + .get_physical_device_external_buffer_properties_khr)( + self.handle, + &external_buffer_info, + &mut external_buffer_properties, + ); } - Ok(ExternalBufferProperties { + ExternalBufferProperties { external_memory_properties: external_buffer_properties .external_memory_properties .into(), - }) + } + } + + /// Retrieves the external handle properties supported for semaphores with a given + /// configuration. + /// + /// The instance API version must be at least 1.1, or the + /// [`khr_external_semaphore_capabilities`](crate::instance::InstanceExtensions::khr_external_semaphore_capabilities) + /// extension must be enabled on the instance. + #[inline] + pub fn external_semaphore_properties( + &self, + info: ExternalSemaphoreInfo, + ) -> Result { + self.validate_external_semaphore_properties(&info)?; + + unsafe { Ok(self.external_semaphore_properties_unchecked(info)) } + } + + fn validate_external_semaphore_properties( + &self, + info: &ExternalSemaphoreInfo, + ) -> Result<(), ExternalSemaphorePropertiesError> { + if !(self.instance.api_version() >= Version::V1_1 + || self + .instance + .enabled_extensions() + .khr_external_semaphore_capabilities) + { + return Err(ExternalSemaphorePropertiesError::RequirementNotMet { + required_for: "`external_semaphore_properties`", + requires_one_of: RequiresOneOf { + api_version: Some(Version::V1_1), + instance_extensions: &["khr_external_semaphore_capabilities"], + ..Default::default() + }, + }); + } + + let &ExternalSemaphoreInfo { + handle_type, + _ne: _, + } = info; + + // VUID-VkPhysicalDeviceExternalSemaphoreInfo-handleType-parameter + handle_type.validate_physical_device(self)?; + + Ok(()) + } + + #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] + pub unsafe fn external_semaphore_properties_unchecked( + &self, + info: ExternalSemaphoreInfo, + ) -> ExternalSemaphoreProperties { + /* Input */ + + let ExternalSemaphoreInfo { + handle_type, + _ne: _, + } = info; + + let external_semaphore_info = ash::vk::PhysicalDeviceExternalSemaphoreInfo { + handle_type: handle_type.into(), + ..Default::default() + }; + + /* Output */ + + let mut external_semaphore_properties = ash::vk::ExternalSemaphoreProperties::default(); + + /* Call */ + + let fns = self.instance.fns(); + + if self.instance.api_version() >= Version::V1_1 { + (fns.v1_1.get_physical_device_external_semaphore_properties)( + self.handle, + &external_semaphore_info, + &mut external_semaphore_properties, + ) + } else { + (fns.khr_external_semaphore_capabilities + .get_physical_device_external_semaphore_properties_khr)( + self.handle, + &external_semaphore_info, + &mut external_semaphore_properties, + ); + } + + ExternalSemaphoreProperties { + exportable: external_semaphore_properties + .external_semaphore_features + .intersects(ash::vk::ExternalSemaphoreFeatureFlags::EXPORTABLE), + importable: external_semaphore_properties + .external_semaphore_features + .intersects(ash::vk::ExternalSemaphoreFeatureFlags::IMPORTABLE), + export_from_imported_handle_types: external_semaphore_properties + .export_from_imported_handle_types + .into(), + compatible_handle_types: external_semaphore_properties.compatible_handle_types.into(), + } } /// Retrieves the properties of a format when used by this physical device. + #[inline] pub fn format_properties(&self, format: Format) -> FormatProperties { + // TODO: self.validate_format_properties(format_properties)?; + + unsafe { self.format_properties_unchecked(format) } + } + + /* + TODO: + fn validate_format_properties(&self, format: Format) -> Result<(), ()> { + format.validate_physical_device(self)?; + } + */ + + #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] + pub unsafe fn format_properties_unchecked(&self, format: Format) -> FormatProperties { let mut format_properties2 = ash::vk::FormatProperties2::default(); let mut format_properties3 = if self.api_version() >= Version::V1_3 || self.supported_extensions().khr_format_feature_flags2 @@ -537,33 +626,31 @@ impl<'a> PhysicalDevice<'a> { format_properties2.p_next = next as *mut _ as *mut _; } - unsafe { - let fns = self.instance.fns(); + let fns = self.instance.fns(); - if self.api_version() >= Version::V1_1 { - (fns.v1_1.get_physical_device_format_properties2)( - self.info.handle, - format.into(), - &mut format_properties2, - ); - } else if self - .instance - .enabled_extensions() - .khr_get_physical_device_properties2 - { - (fns.khr_get_physical_device_properties2 - .get_physical_device_format_properties2_khr)( - self.info.handle, - format.into(), - &mut format_properties2, - ); - } else { - (fns.v1_0.get_physical_device_format_properties)( - self.internal_object(), - format.into(), - &mut format_properties2.format_properties, - ); - } + if self.api_version() >= Version::V1_1 { + (fns.v1_1.get_physical_device_format_properties2)( + self.handle, + format.into(), + &mut format_properties2, + ); + } else if self + .instance + .enabled_extensions() + .khr_get_physical_device_properties2 + { + (fns.khr_get_physical_device_properties2 + .get_physical_device_format_properties2_khr)( + self.handle, + format.into(), + &mut format_properties2, + ); + } else { + (fns.v1_0.get_physical_device_format_properties)( + self.internal_object(), + format.into(), + &mut format_properties2.format_properties, + ); } match format_properties3 { @@ -588,86 +675,6 @@ impl<'a> PhysicalDevice<'a> { } } - /// Retrieves the external handle properties supported for semaphores with a given - /// configuration. - /// - /// The instance API version must be at least 1.1, or the - /// [`khr_external_semaphore_capabilities`](crate::instance::InstanceExtensions::khr_external_semaphore_capabilities) - /// extension must be enabled on the instance. - pub fn external_semaphore_properties( - &self, - info: ExternalSemaphoreInfo, - ) -> Result { - if !(self.instance.api_version() >= Version::V1_1 - || self - .instance - .enabled_extensions() - .khr_external_semaphore_capabilities) - { - return Err(ExternalSemaphorePropertiesError::RequirementNotMet { - required_for: "`external_semaphore_properties`", - requires_one_of: RequiresOneOf { - api_version: Some(Version::V1_1), - instance_extensions: &["khr_external_semaphore_capabilities"], - ..Default::default() - }, - }); - } - - /* Input */ - - let ExternalSemaphoreInfo { - handle_type, - _ne: _, - } = info; - - // VUID-VkPhysicalDeviceExternalSemaphoreInfo-handleType-parameter - handle_type.validate_physical_device(self)?; - - let external_semaphore_info = ash::vk::PhysicalDeviceExternalSemaphoreInfo { - handle_type: handle_type.into(), - ..Default::default() - }; - - /* Output */ - - let mut external_semaphore_properties = ash::vk::ExternalSemaphoreProperties::default(); - - /* Call */ - - unsafe { - let fns = self.instance.fns(); - - if self.instance.api_version() >= Version::V1_1 { - (fns.v1_1.get_physical_device_external_semaphore_properties)( - self.info.handle, - &external_semaphore_info, - &mut external_semaphore_properties, - ) - } else { - (fns.khr_external_semaphore_capabilities - .get_physical_device_external_semaphore_properties_khr)( - self.info.handle, - &external_semaphore_info, - &mut external_semaphore_properties, - ); - } - } - - Ok(ExternalSemaphoreProperties { - exportable: external_semaphore_properties - .external_semaphore_features - .intersects(ash::vk::ExternalSemaphoreFeatureFlags::EXPORTABLE), - importable: external_semaphore_properties - .external_semaphore_features - .intersects(ash::vk::ExternalSemaphoreFeatureFlags::IMPORTABLE), - export_from_imported_handle_types: external_semaphore_properties - .export_from_imported_handle_types - .into(), - compatible_handle_types: external_semaphore_properties.compatible_handle_types.into(), - }) - } - /// Returns the properties supported for images with a given image configuration. /// /// `Some` is returned if the configuration is supported, `None` if it is not. @@ -675,22 +682,31 @@ impl<'a> PhysicalDevice<'a> { /// # Panics /// /// - Panics if `image_format_info.format` is `None`. + #[inline] pub fn image_format_properties( &self, image_format_info: ImageFormatInfo, ) -> Result, ImageFormatPropertiesError> { - /* Input */ - let ImageFormatInfo { - format, + self.validate_image_format_properties(&image_format_info)?; + + unsafe { Ok(self.image_format_properties_unchecked(image_format_info)?) } + } + + pub fn validate_image_format_properties( + &self, + image_format_info: &ImageFormatInfo, + ) -> Result<(), ImageFormatPropertiesError> { + let &ImageFormatInfo { + format: _, image_type, tiling, usage, external_memory_handle_type, image_view_type, - mutable_format, - cube_compatible, - array_2d_compatible, - block_texel_view_compatible, + mutable_format: _, + cube_compatible: _, + array_2d_compatible: _, + block_texel_view_compatible: _, _ne: _, } = image_format_info; @@ -706,23 +722,7 @@ impl<'a> PhysicalDevice<'a> { // VUID-VkPhysicalDeviceImageFormatInfo2-usage-parameter usage.validate_physical_device(self)?; - let flags = ImageCreateFlags { - mutable_format, - cube_compatible, - array_2d_compatible, - block_texel_view_compatible, - ..ImageCreateFlags::empty() - }; - - let mut format_info2 = ash::vk::PhysicalDeviceImageFormatInfo2::builder() - .format(format.unwrap().into()) - .ty(image_type.into()) - .tiling(tiling.into()) - .usage(usage.into()) - .flags(flags.into()); - - let mut external_image_format_info = if let Some(handle_type) = external_memory_handle_type - { + if let Some(handle_type) = external_memory_handle_type { if !(self.api_version() >= Version::V1_1 || self .instance() @@ -741,20 +741,9 @@ impl<'a> PhysicalDevice<'a> { // VUID-VkPhysicalDeviceExternalImageFormatInfo-handleType-parameter handle_type.validate_physical_device(self)?; - - Some( - ash::vk::PhysicalDeviceExternalImageFormatInfo::builder() - .handle_type(handle_type.into()), - ) - } else { - None - }; - - if let Some(next) = external_image_format_info.as_mut() { - format_info2 = format_info2.push_next(next); } - let mut image_view_image_format_info = if let Some(image_view_type) = image_view_type { + if let Some(image_view_type) = image_view_type { if !self.supported_extensions().ext_filter_cubic { return Err(ImageFormatPropertiesError::RequirementNotMet { required_for: "`image_format_info.image_view_type` is `Some`", @@ -767,19 +756,61 @@ impl<'a> PhysicalDevice<'a> { // VUID-VkPhysicalDeviceImageViewImageFormatInfoEXT-imageViewType-parameter image_view_type.validate_physical_device(self)?; + } - if !image_view_type.is_compatible_with(image_type) { - return Ok(None); - } + Ok(()) + } - Some( - ash::vk::PhysicalDeviceImageViewImageFormatInfoEXT::builder() - .image_view_type(image_view_type.into()), - ) - } else { - None + #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] + pub unsafe fn image_format_properties_unchecked( + &self, + image_format_info: ImageFormatInfo, + ) -> Result, VulkanError> { + /* Input */ + + let ImageFormatInfo { + format, + image_type, + tiling, + usage, + external_memory_handle_type, + image_view_type, + mutable_format, + cube_compatible, + array_2d_compatible, + block_texel_view_compatible, + _ne: _, + } = image_format_info; + + let flags = ImageCreateFlags { + mutable_format, + cube_compatible, + array_2d_compatible, + block_texel_view_compatible, + ..ImageCreateFlags::empty() }; + let mut format_info2 = ash::vk::PhysicalDeviceImageFormatInfo2::builder() + .format(format.unwrap().into()) + .ty(image_type.into()) + .tiling(tiling.into()) + .usage(usage.into()) + .flags(flags.into()); + + let mut external_image_format_info = external_memory_handle_type.map(|handle_type| { + ash::vk::PhysicalDeviceExternalImageFormatInfo::builder() + .handle_type(handle_type.into()) + }); + + if let Some(next) = external_image_format_info.as_mut() { + format_info2 = format_info2.push_next(next); + } + + let mut image_view_image_format_info = image_view_type.map(|image_view_type| { + ash::vk::PhysicalDeviceImageViewImageFormatInfoEXT::builder() + .image_view_type(image_view_type.into()) + }); + if let Some(next) = image_view_image_format_info.as_mut() { format_info2 = format_info2.push_next(next); } @@ -810,12 +841,12 @@ impl<'a> PhysicalDevice<'a> { image_format_properties2.p_next = next as *mut _ as *mut _; } - let result = unsafe { + let result = { let fns = self.instance.fns(); if self.api_version() >= Version::V1_1 { (fns.v1_1.get_physical_device_image_format_properties2)( - self.info.handle, + self.handle, &format_info2.build(), &mut image_format_properties2, ) @@ -826,7 +857,7 @@ impl<'a> PhysicalDevice<'a> { { (fns.khr_get_physical_device_properties2 .get_physical_device_image_format_properties2_khr)( - self.info.handle, + self.handle, &format_info2.build(), &mut image_format_properties2, ) @@ -837,7 +868,7 @@ impl<'a> PhysicalDevice<'a> { } (fns.v1_0.get_physical_device_image_format_properties)( - self.info.handle, + self.handle, format_info2.format, format_info2.ty, format_info2.tiling, @@ -866,94 +897,7 @@ impl<'a> PhysicalDevice<'a> { ..image_format_properties2.image_format_properties.into() })), Err(VulkanError::FormatNotSupported) => Ok(None), - Err(err) => Err(err.into()), - } - } - - /// Builds an iterator that enumerates all the memory types on this physical device. - #[inline] - pub fn memory_types(&self) -> impl ExactSizeIterator> { - let physical_device = *self; - self.info.memory_properties.memory_types - [0..self.info.memory_properties.memory_type_count as usize] - .iter() - .enumerate() - .map(move |(id, info)| MemoryType { - physical_device, - id: id as u32, - info, - }) - } - - /// Returns the memory type with the given index, or `None` if out of range. - #[inline] - pub fn memory_type_by_id(&self, id: u32) -> Option> { - if id < self.info.memory_properties.memory_type_count { - Some(MemoryType { - physical_device: *self, - id, - info: &self.info.memory_properties.memory_types[id as usize], - }) - } else { - None - } - } - - /// Builds an iterator that enumerates all the memory heaps on this physical device. - #[inline] - pub fn memory_heaps(&self) -> impl ExactSizeIterator> { - let physical_device = *self; - self.info.memory_properties.memory_heaps - [0..self.info.memory_properties.memory_heap_count as usize] - .iter() - .enumerate() - .map(move |(id, info)| MemoryHeap { - physical_device, - id: id as u32, - info, - }) - } - - /// Returns the memory heap with the given index, or `None` if out of range. - #[inline] - pub fn memory_heap_by_id(&self, id: u32) -> Option> { - if id < self.info.memory_properties.memory_heap_count { - Some(MemoryHeap { - physical_device: *self, - id, - info: &self.info.memory_properties.memory_heaps[id as usize], - }) - } else { - None - } - } - - /// Builds an iterator that enumerates all the queue families on this physical device. - #[inline] - pub fn queue_families(&self) -> impl ExactSizeIterator> { - let physical_device = *self; - self.info - .queue_families - .iter() - .enumerate() - .map(move |(id, properties)| QueueFamily { - physical_device, - id: id as u32, - properties, - }) - } - - /// Returns the queue family with the given index, or `None` if out of range. - #[inline] - pub fn queue_family_by_id(&self, id: u32) -> Option> { - if (id as usize) < self.info.queue_families.len() { - Some(QueueFamily { - physical_device: *self, - id, - properties: &self.info.queue_families[id as usize], - }) - } else { - None + Err(err) => Err(err), } } @@ -962,16 +906,57 @@ impl<'a> PhysicalDevice<'a> { /// # Panic /// /// - Panics if the physical device and the surface don't belong to the same instance. + #[inline] pub fn surface_capabilities( &self, surface: &Surface, surface_info: SurfaceInfo, ) -> Result { - assert_eq!( - self.instance.internal_object(), - surface.instance().internal_object(), - ); + self.validate_surface_capabilities(surface, &surface_info)?; + unsafe { Ok(self.surface_capabilities_unchecked(surface, surface_info)?) } + } + + fn validate_surface_capabilities( + &self, + surface: &Surface, + surface_info: &SurfaceInfo, + ) -> Result<(), SurfacePropertiesError> { + // VUID-vkGetPhysicalDeviceSurfaceCapabilities2KHR-commonparent + assert_eq!(self.instance(), surface.instance()); + + let &SurfaceInfo { + full_screen_exclusive, + win32_monitor, + _ne: _, + } = surface_info; + + // VUID-vkGetPhysicalDeviceSurfaceCapabilities2KHR-pSurfaceInfo-06210 + // TODO: + + if !self.supported_extensions().ext_full_screen_exclusive + && full_screen_exclusive != FullScreenExclusive::Default + { + return Err(SurfacePropertiesError::NotSupported); + } + + // VUID-VkPhysicalDeviceSurfaceInfo2KHR-pNext-02672 + if (surface.api() == SurfaceApi::Win32 + && full_screen_exclusive == FullScreenExclusive::ApplicationControlled) + != win32_monitor.is_some() + { + return Err(SurfacePropertiesError::NotSupported); + } + + Ok(()) + } + + #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] + pub unsafe fn surface_capabilities_unchecked( + &self, + surface: &Surface, + surface_info: SurfaceInfo, + ) -> Result { /* Input */ let SurfaceInfo { @@ -980,38 +965,21 @@ impl<'a> PhysicalDevice<'a> { _ne: _, } = surface_info; - let mut surface_full_screen_exclusive_info = - if self.supported_extensions().ext_full_screen_exclusive { - Some(ash::vk::SurfaceFullScreenExclusiveInfoEXT { - full_screen_exclusive: full_screen_exclusive.into(), - ..Default::default() - }) - } else { - if full_screen_exclusive != FullScreenExclusive::Default { - return Err(SurfacePropertiesError::NotSupported); - } + let mut surface_full_screen_exclusive_info = self + .supported_extensions() + .ext_full_screen_exclusive + .then(|| ash::vk::SurfaceFullScreenExclusiveInfoEXT { + full_screen_exclusive: full_screen_exclusive.into(), + ..Default::default() + }); - None - }; - - let mut surface_full_screen_exclusive_win32_info = if surface.api() == SurfaceApi::Win32 - && full_screen_exclusive == FullScreenExclusive::ApplicationControlled - { - if let Some(win32_monitor) = win32_monitor { - Some(ash::vk::SurfaceFullScreenExclusiveWin32InfoEXT { + let mut surface_full_screen_exclusive_win32_info = + win32_monitor.map( + |win32_monitor| ash::vk::SurfaceFullScreenExclusiveWin32InfoEXT { hmonitor: win32_monitor.0, ..Default::default() - }) - } else { - return Err(SurfacePropertiesError::NotSupported); - } - } else { - if win32_monitor.is_some() { - return Err(SurfacePropertiesError::NotSupported); - } else { - None - } - }; + }, + ); let mut surface_info2 = ash::vk::PhysicalDeviceSurfaceInfo2KHR { surface: surface.internal_object(), @@ -1052,32 +1020,30 @@ impl<'a> PhysicalDevice<'a> { surface_capabilities_full_screen_exclusive as *mut _ as *mut _; } - unsafe { - let fns = self.instance.fns(); + let fns = self.instance.fns(); - if self - .instance - .enabled_extensions() - .khr_get_surface_capabilities2 - { - (fns.khr_get_surface_capabilities2 - .get_physical_device_surface_capabilities2_khr)( - self.internal_object(), - &surface_info2, - &mut surface_capabilities2, - ) - .result() - .map_err(VulkanError::from)?; - } else { - (fns.khr_surface.get_physical_device_surface_capabilities_khr)( - self.internal_object(), - surface_info2.surface, - &mut surface_capabilities2.surface_capabilities, - ) - .result() - .map_err(VulkanError::from)?; - }; - } + if self + .instance + .enabled_extensions() + .khr_get_surface_capabilities2 + { + (fns.khr_get_surface_capabilities2 + .get_physical_device_surface_capabilities2_khr)( + self.internal_object(), + &surface_info2, + &mut surface_capabilities2, + ) + .result() + .map_err(VulkanError::from)?; + } else { + (fns.khr_surface.get_physical_device_surface_capabilities_khr)( + self.internal_object(), + surface_info2.surface, + &mut surface_capabilities2.surface_capabilities, + ) + .result() + .map_err(VulkanError::from)?; + }; Ok(SurfaceCapabilities { min_image_count: surface_capabilities2.surface_capabilities.min_image_count, @@ -1169,114 +1135,148 @@ impl<'a> PhysicalDevice<'a> { /// # Panic /// /// - Panics if the physical device and the surface don't belong to the same instance. + #[inline] pub fn surface_formats( &self, surface: &Surface, surface_info: SurfaceInfo, ) -> Result, SurfacePropertiesError> { - assert_eq!( - self.instance.internal_object(), - surface.instance().internal_object(), - ); + self.validate_surface_formats(surface, &surface_info)?; + + unsafe { Ok(self.surface_formats_unchecked(surface, surface_info)?) } + } + + fn validate_surface_formats( + &self, + surface: &Surface, + surface_info: &SurfaceInfo, + ) -> Result<(), SurfacePropertiesError> { + // VUID-vkGetPhysicalDeviceSurfaceFormats2KHR-commonparent + assert_eq!(self.instance(), surface.instance()); + + // VUID-vkGetPhysicalDeviceSurfaceFormats2KHR-pSurfaceInfo-06522 + // TODO: + + let &SurfaceInfo { + full_screen_exclusive, + win32_monitor, + _ne: _, + } = surface_info; if self .instance .enabled_extensions() .khr_get_surface_capabilities2 { - let SurfaceInfo { - full_screen_exclusive, - win32_monitor, - _ne: _, - } = surface_info; - - let mut surface_full_screen_exclusive_info = - if full_screen_exclusive != FullScreenExclusive::Default { - if !self.supported_extensions().ext_full_screen_exclusive { - return Err(SurfacePropertiesError::NotSupported); - } - - Some(ash::vk::SurfaceFullScreenExclusiveInfoEXT { - full_screen_exclusive: full_screen_exclusive.into(), - ..Default::default() - }) - } else { - None - }; - - let mut surface_full_screen_exclusive_win32_info = if surface.api() == SurfaceApi::Win32 - && full_screen_exclusive == FullScreenExclusive::ApplicationControlled + if !self.supported_extensions().ext_full_screen_exclusive + && full_screen_exclusive != FullScreenExclusive::Default { - if let Some(win32_monitor) = win32_monitor { - Some(ash::vk::SurfaceFullScreenExclusiveWin32InfoEXT { - hmonitor: win32_monitor.0, - ..Default::default() - }) - } else { - return Err(SurfacePropertiesError::NotSupported); - } - } else { - if win32_monitor.is_some() { - return Err(SurfacePropertiesError::NotSupported); - } else { - None - } - }; + return Err(SurfacePropertiesError::NotSupported); + } - let mut surface_info2 = ash::vk::PhysicalDeviceSurfaceInfo2KHR { - surface: surface.internal_object(), + // VUID-VkPhysicalDeviceSurfaceInfo2KHR-pNext-02672 + if (surface.api() == SurfaceApi::Win32 + && full_screen_exclusive == FullScreenExclusive::ApplicationControlled) + != win32_monitor.is_some() + { + return Err(SurfacePropertiesError::NotSupported); + } + } else { + if full_screen_exclusive != FullScreenExclusive::Default { + return Err(SurfacePropertiesError::NotSupported); + } + + if win32_monitor.is_some() { + return Err(SurfacePropertiesError::NotSupported); + } + } + + Ok(()) + } + + #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] + pub unsafe fn surface_formats_unchecked( + &self, + surface: &Surface, + surface_info: SurfaceInfo, + ) -> Result, VulkanError> { + let SurfaceInfo { + full_screen_exclusive, + win32_monitor, + _ne: _, + } = surface_info; + + let mut surface_full_screen_exclusive_info = (full_screen_exclusive + != FullScreenExclusive::Default) + .then(|| ash::vk::SurfaceFullScreenExclusiveInfoEXT { + full_screen_exclusive: full_screen_exclusive.into(), ..Default::default() - }; + }); - if let Some(surface_full_screen_exclusive_info) = - surface_full_screen_exclusive_info.as_mut() - { - surface_full_screen_exclusive_info.p_next = surface_info2.p_next as *mut _; - surface_info2.p_next = surface_full_screen_exclusive_info as *const _ as *const _; - } + let mut surface_full_screen_exclusive_win32_info = + win32_monitor.map( + |win32_monitor| ash::vk::SurfaceFullScreenExclusiveWin32InfoEXT { + hmonitor: win32_monitor.0, + ..Default::default() + }, + ); - if let Some(surface_full_screen_exclusive_win32_info) = - surface_full_screen_exclusive_win32_info.as_mut() - { - surface_full_screen_exclusive_win32_info.p_next = surface_info2.p_next as *mut _; - surface_info2.p_next = - surface_full_screen_exclusive_win32_info as *const _ as *const _; - } + let mut surface_info2 = ash::vk::PhysicalDeviceSurfaceInfo2KHR { + surface: surface.internal_object(), + ..Default::default() + }; - let fns = self.instance.fns(); + if let Some(surface_full_screen_exclusive_info) = + surface_full_screen_exclusive_info.as_mut() + { + surface_full_screen_exclusive_info.p_next = surface_info2.p_next as *mut _; + surface_info2.p_next = surface_full_screen_exclusive_info as *const _ as *const _; + } - let surface_format2s = unsafe { - loop { - let mut count = 0; - (fns.khr_get_surface_capabilities2 - .get_physical_device_surface_formats2_khr)( - self.internal_object(), - &surface_info2, - &mut count, - ptr::null_mut(), - ) - .result() - .map_err(VulkanError::from)?; + if let Some(surface_full_screen_exclusive_win32_info) = + surface_full_screen_exclusive_win32_info.as_mut() + { + surface_full_screen_exclusive_win32_info.p_next = surface_info2.p_next as *mut _; + surface_info2.p_next = surface_full_screen_exclusive_win32_info as *const _ as *const _; + } - let mut surface_format2s = - vec![ash::vk::SurfaceFormat2KHR::default(); count as usize]; - let result = (fns - .khr_get_surface_capabilities2 - .get_physical_device_surface_formats2_khr)( - self.internal_object(), - &surface_info2, - &mut count, - surface_format2s.as_mut_ptr(), - ); + let fns = self.instance.fns(); - match result { - ash::vk::Result::SUCCESS => { - surface_format2s.set_len(count as usize); - break surface_format2s; - } - ash::vk::Result::INCOMPLETE => (), - err => return Err(VulkanError::from(err).into()), + if self + .instance + .enabled_extensions() + .khr_get_surface_capabilities2 + { + let surface_format2s = loop { + let mut count = 0; + (fns.khr_get_surface_capabilities2 + .get_physical_device_surface_formats2_khr)( + self.internal_object(), + &surface_info2, + &mut count, + ptr::null_mut(), + ) + .result() + .map_err(VulkanError::from)?; + + let mut surface_format2s = + vec![ash::vk::SurfaceFormat2KHR::default(); count as usize]; + let result = (fns + .khr_get_surface_capabilities2 + .get_physical_device_surface_formats2_khr)( + self.internal_object(), + &surface_info2, + &mut count, + surface_format2s.as_mut_ptr(), + ); + + match result { + ash::vk::Result::SUCCESS => { + surface_format2s.set_len(count as usize); + break surface_format2s; } + ash::vk::Result::INCOMPLETE => (), + err => return Err(VulkanError::from(err)), } }; @@ -1288,40 +1288,32 @@ impl<'a> PhysicalDevice<'a> { }) .collect()) } else { - if surface_info != SurfaceInfo::default() { - return Ok(Vec::new()); - } + let surface_formats = loop { + let mut count = 0; + (fns.khr_surface.get_physical_device_surface_formats_khr)( + self.internal_object(), + surface.internal_object(), + &mut count, + ptr::null_mut(), + ) + .result() + .map_err(VulkanError::from)?; - let fns = self.instance.fns(); + let mut surface_formats = Vec::with_capacity(count as usize); + let result = (fns.khr_surface.get_physical_device_surface_formats_khr)( + self.internal_object(), + surface.internal_object(), + &mut count, + surface_formats.as_mut_ptr(), + ); - let surface_formats = unsafe { - loop { - let mut count = 0; - (fns.khr_surface.get_physical_device_surface_formats_khr)( - self.internal_object(), - surface.internal_object(), - &mut count, - ptr::null_mut(), - ) - .result() - .map_err(VulkanError::from)?; - - let mut surface_formats = Vec::with_capacity(count as usize); - let result = (fns.khr_surface.get_physical_device_surface_formats_khr)( - self.internal_object(), - surface.internal_object(), - &mut count, - surface_formats.as_mut_ptr(), - ); - - match result { - ash::vk::Result::SUCCESS => { - surface_formats.set_len(count as usize); - break surface_formats; - } - ash::vk::Result::INCOMPLETE => (), - err => return Err(VulkanError::from(err).into()), + match result { + ash::vk::Result::SUCCESS => { + surface_formats.set_len(count as usize); + break surface_formats; } + ash::vk::Result::INCOMPLETE => (), + err => return Err(VulkanError::from(err)), } }; @@ -1340,48 +1332,65 @@ impl<'a> PhysicalDevice<'a> { /// # Panic /// /// - Panics if the physical device and the surface don't belong to the same instance. + #[inline] pub fn surface_present_modes( &self, surface: &Surface, ) -> Result, SurfacePropertiesError> { - assert_eq!( - self.instance.internal_object(), - surface.instance().internal_object(), - ); + self.validate_surface_present_modes(surface)?; + unsafe { Ok(self.surface_present_modes_unchecked(surface)?) } + } + + fn validate_surface_present_modes( + &self, + surface: &Surface, + ) -> Result<(), SurfacePropertiesError> { + // VUID-vkGetPhysicalDeviceSurfacePresentModesKHR-commonparent + assert_eq!(self.instance(), surface.instance()); + + // VUID-vkGetPhysicalDeviceSurfacePresentModesKHR-surface-06525 + // TODO: + + Ok(()) + } + + #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] + pub unsafe fn surface_present_modes_unchecked( + &self, + surface: &Surface, + ) -> Result, VulkanError> { let fns = self.instance.fns(); - let modes = unsafe { - loop { - let mut count = 0; - (fns.khr_surface - .get_physical_device_surface_present_modes_khr)( - self.internal_object(), - surface.internal_object(), - &mut count, - ptr::null_mut(), - ) - .result() - .map_err(VulkanError::from)?; + let modes = loop { + let mut count = 0; + (fns.khr_surface + .get_physical_device_surface_present_modes_khr)( + self.internal_object(), + surface.internal_object(), + &mut count, + ptr::null_mut(), + ) + .result() + .map_err(VulkanError::from)?; - let mut modes = Vec::with_capacity(count as usize); - let result = (fns - .khr_surface - .get_physical_device_surface_present_modes_khr)( - self.internal_object(), - surface.internal_object(), - &mut count, - modes.as_mut_ptr(), - ); + let mut modes = Vec::with_capacity(count as usize); + let result = (fns + .khr_surface + .get_physical_device_surface_present_modes_khr)( + self.internal_object(), + surface.internal_object(), + &mut count, + modes.as_mut_ptr(), + ); - match result { - ash::vk::Result::SUCCESS => { - modes.set_len(count as usize); - break modes; - } - ash::vk::Result::INCOMPLETE => (), - err => return Err(VulkanError::from(err).into()), + match result { + ash::vk::Result::SUCCESS => { + modes.set_len(count as usize); + break modes; } + ash::vk::Result::INCOMPLETE => (), + err => return Err(VulkanError::from(err)), } }; @@ -1392,17 +1401,293 @@ impl<'a> PhysicalDevice<'a> { .into_iter() .filter_map(|mode_vk| mode_vk.try_into().ok())) } + + /// Returns whether queues of the given queue family can draw on the given surface. + #[inline] + pub fn surface_support( + &self, + queue_family_index: u32, + surface: &Surface, + ) -> Result { + self.validate_surface_support(queue_family_index, surface)?; + + unsafe { Ok(self.surface_support_unchecked(queue_family_index, surface)?) } + } + + fn validate_surface_support( + &self, + queue_family_index: u32, + _surface: &Surface, + ) -> Result<(), SurfacePropertiesError> { + // VUID-vkGetPhysicalDeviceSurfaceSupportKHR-queueFamilyIndex-01269 + if queue_family_index >= self.queue_family_properties.len() as u32 { + todo!() + } + + Ok(()) + } + + #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] + pub unsafe fn surface_support_unchecked( + &self, + queue_family_index: u32, + surface: &Surface, + ) -> Result { + let fns = self.instance.fns(); + + let mut output = MaybeUninit::uninit(); + (fns.khr_surface.get_physical_device_surface_support_khr)( + self.handle, + queue_family_index, + surface.internal_object(), + output.as_mut_ptr(), + ) + .result() + .map_err(VulkanError::from)?; + + Ok(output.assume_init() != 0) + } } -unsafe impl<'a> VulkanObject for PhysicalDevice<'a> { +unsafe impl VulkanObject for PhysicalDevice { type Object = ash::vk::PhysicalDevice; #[inline] fn internal_object(&self) -> ash::vk::PhysicalDevice { - self.info.handle + self.handle } } +impl PartialEq for PhysicalDevice { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.handle == other.handle && self.instance == other.instance + } +} + +impl Eq for PhysicalDevice {} + +impl Hash for PhysicalDevice { + #[inline] + fn hash(&self, state: &mut H) { + self.handle.hash(state); + self.instance.hash(state); + } +} + +/// Properties of an extension in the loader or a physical device. +#[derive(Clone, Debug)] +pub struct ExtensionProperties { + /// The name of the extension. + pub extension_name: String, + + /// The version of the extension. + pub spec_version: u32, +} + +impl From for ExtensionProperties { + #[inline] + fn from(val: ash::vk::ExtensionProperties) -> Self { + Self { + extension_name: { + let bytes = cast_slice(val.extension_name.as_slice()); + let end = bytes.iter().position(|&b| b == 0).unwrap_or(bytes.len()); + String::from_utf8_lossy(&bytes[0..end]).into() + }, + spec_version: val.spec_version, + } + } +} + +/// Properties of the memory in a physical device. +#[derive(Clone, Debug)] +#[non_exhaustive] +pub struct MemoryProperties { + /// The available memory types. + pub memory_types: Vec, + + /// The available memory heaps. + pub memory_heaps: Vec, +} + +impl From for MemoryProperties { + #[inline] + fn from(val: ash::vk::PhysicalDeviceMemoryProperties) -> Self { + Self { + memory_types: val.memory_types[0..val.memory_type_count as usize] + .iter() + .map(|vk_memory_type| MemoryType { + property_flags: vk_memory_type.property_flags.into(), + heap_index: vk_memory_type.heap_index, + }) + .collect(), + memory_heaps: val.memory_heaps[0..val.memory_heap_count as usize] + .iter() + .map(|vk_memory_heap| MemoryHeap { + size: vk_memory_heap.size, + flags: vk_memory_heap.flags.into(), + }) + .collect(), + } + } +} + +/// A memory type in a physical device. +#[derive(Clone, Debug)] +#[non_exhaustive] +pub struct MemoryType { + /// The properties of this memory type. + pub property_flags: MemoryPropertyFlags, + + /// The index of the memory heap that this memory type corresponds to. + pub heap_index: u32, +} + +vulkan_bitflags! { + /// Properties of a memory type. + #[non_exhaustive] + MemoryPropertyFlags = MemoryPropertyFlags(u32); + + /// The memory is located on the device. This usually means that it's efficient for the + /// device to access this memory. + device_local = DEVICE_LOCAL, + + /// The memory can be accessed by the host. + host_visible = HOST_VISIBLE, + + /// Modifications made by the host or the device on this memory type are + /// instantaneously visible to the other party. If memory does not have this flag, changes to + /// the memory are not visible until they are flushed or invalidated. + host_coherent = HOST_COHERENT, + + /// The memory is cached by the host. Host memory accesses to cached memory are faster than for + /// uncached memory, but the cache may not be coherent. + host_cached = HOST_CACHED, + + /// Allocations made from this memory type are lazy. + /// + /// This means that no actual allocation is performed. Instead memory is automatically + /// allocated by the Vulkan implementation based on need. + /// + /// Memory of this type can only be used on images created with a certain flag. Memory of this + /// type is never host-visible. + lazily_allocated = LAZILY_ALLOCATED, + + /// The memory can only be accessed by the device, and allows protected queue access. + /// + /// Memory of this type is never host visible, host coherent or host cached. + protected = PROTECTED { + api_version: V1_1, + }, +} + +/// A memory heap in a physical device. +#[derive(Clone, Debug)] +#[non_exhaustive] +pub struct MemoryHeap { + /// The size of the heap in bytes. + pub size: DeviceSize, + + /// Attributes of the heap. + pub flags: MemoryHeapFlags, +} + +vulkan_bitflags! { + /// Attributes of a memory heap. + #[non_exhaustive] + MemoryHeapFlags = MemoryHeapFlags(u32); + + /// The heap corresponds to device-local memory. + device_local = DEVICE_LOCAL, + + /// If used on a logical device that represents more than one physical device, allocations are + /// replicated across each physical device's instance of this heap. + multi_instance = MULTI_INSTANCE { + api_version: V1_1, + instance_extensions: [khr_device_group_creation], + }, +} + +/// Properties of a queue family in a physical device. +#[derive(Clone, Debug)] +#[non_exhaustive] +pub struct QueueFamilyProperties { + /// Attributes of the queue family. + pub queue_flags: QueueFlags, + + /// The number of queues available in this family. + /// + /// This guaranteed to be at least 1 (or else that family wouldn't exist). + pub queue_count: u32, + + /// If timestamps are supported, the number of bits supported by timestamp operations. + /// The returned value will be in the range 36..64. + /// + /// If timestamps are not supported, this is `None`. + pub timestamp_valid_bits: Option, + + /// The minimum granularity supported for image transfers, in terms of `[width, height, depth]`. + pub min_image_transfer_granularity: [u32; 3], +} + +impl QueueFamilyProperties { + /// Returns whether the queues of this family support a particular pipeline stage. + #[inline] + pub fn supports_stage(&self, stage: PipelineStage) -> bool { + ash::vk::QueueFlags::from(self.queue_flags).contains(stage.required_queue_flags()) + } +} + +impl From for QueueFamilyProperties { + #[inline] + fn from(val: ash::vk::QueueFamilyProperties) -> Self { + Self { + queue_flags: val.queue_flags.into(), + queue_count: val.queue_count, + timestamp_valid_bits: (val.timestamp_valid_bits != 0) + .then_some(val.timestamp_valid_bits), + min_image_transfer_granularity: [ + val.min_image_transfer_granularity.width, + val.min_image_transfer_granularity.height, + val.min_image_transfer_granularity.depth, + ], + } + } +} + +vulkan_bitflags! { + /// Attributes of a queue or queue family. + #[non_exhaustive] + QueueFlags = QueueFlags(u32); + + /// Queues of this family can execute graphics operations. + graphics = GRAPHICS, + + /// Queues of this family can execute compute operations. + compute = COMPUTE, + + /// Queues of this family can execute transfer operations. + transfer = TRANSFER, + + /// Queues of this family can execute sparse memory management operations. + sparse_binding = SPARSE_BINDING, + + /// Queues of this family can be created using the `protected` flag. + protected = PROTECTED { + api_version: V1_1, + }, + + /// Queues of this family can execute video decode operations. + video_decode = VIDEO_DECODE_KHR { + device_extensions: [khr_video_decode_queue], + }, + + /// Queues of this family can execute video encode operations. + video_encode = VIDEO_ENCODE_KHR { + device_extensions: [khr_video_encode_queue], + }, +} + vulkan_enum! { /// Type of a physical device. #[non_exhaustive] @@ -1431,265 +1716,6 @@ impl Default for PhysicalDeviceType { } } -/// Represents a memory type in a physical device. -#[derive(Debug, Copy, Clone)] -pub struct MemoryType<'a> { - physical_device: PhysicalDevice<'a>, - id: u32, - info: &'a ash::vk::MemoryType, -} - -impl<'a> MemoryType<'a> { - /// Returns the physical device associated to this memory type. - #[inline] - pub fn physical_device(&self) -> PhysicalDevice<'a> { - self.physical_device - } - - /// Returns the identifier of this memory type within the physical device. - #[inline] - pub fn id(&self) -> u32 { - self.id - } - - /// Returns the heap that corresponds to this memory type. - #[inline] - pub fn heap(&self) -> MemoryHeap<'a> { - self.physical_device - .memory_heap_by_id(self.info.heap_index) - .unwrap() - } - - /// Returns true if the memory type is located on the device, which means that it's the most - /// efficient for GPU accesses. - #[inline] - pub fn is_device_local(&self) -> bool { - self.info - .property_flags - .intersects(ash::vk::MemoryPropertyFlags::DEVICE_LOCAL) - } - - /// Returns true if the memory type can be accessed by the host. - #[inline] - pub fn is_host_visible(&self) -> bool { - self.info - .property_flags - .intersects(ash::vk::MemoryPropertyFlags::HOST_VISIBLE) - } - - /// Returns true if modifications made by the host or the GPU on this memory type are - /// instantaneously visible to the other party. False means that changes have to be flushed. - /// - /// You don't need to worry about this, as this library handles that for you. - #[inline] - pub fn is_host_coherent(&self) -> bool { - self.info - .property_flags - .intersects(ash::vk::MemoryPropertyFlags::HOST_COHERENT) - } - - /// Returns true if memory of this memory type is cached by the host. Host memory accesses to - /// cached memory is faster than for uncached memory. However you are not guaranteed that it - /// is coherent. - #[inline] - pub fn is_host_cached(&self) -> bool { - self.info - .property_flags - .intersects(ash::vk::MemoryPropertyFlags::HOST_CACHED) - } - - /// Returns true if allocations made to this memory type is lazy. - /// - /// This means that no actual allocation is performed. Instead memory is automatically - /// allocated by the Vulkan implementation. - /// - /// Memory of this type can only be used on images created with a certain flag. Memory of this - /// type is never host-visible. - #[inline] - pub fn is_lazily_allocated(&self) -> bool { - self.info - .property_flags - .intersects(ash::vk::MemoryPropertyFlags::LAZILY_ALLOCATED) - } - - /// Returns whether the memory type is protected. - #[inline] - pub fn is_protected(&self) -> bool { - self.info - .property_flags - .intersects(ash::vk::MemoryPropertyFlags::PROTECTED) - } -} - -/// Represents a memory heap in a physical device. -#[derive(Debug, Copy, Clone)] -pub struct MemoryHeap<'a> { - physical_device: PhysicalDevice<'a>, - id: u32, - info: &'a ash::vk::MemoryHeap, -} - -impl<'a> MemoryHeap<'a> { - /// Returns the physical device associated to this memory heap. - #[inline] - pub fn physical_device(&self) -> PhysicalDevice<'a> { - self.physical_device - } - - /// Returns the identifier of this memory heap within the physical device. - #[inline] - pub fn id(&self) -> u32 { - self.id - } - - /// Returns the size in bytes on this heap. - #[inline] - pub fn size(&self) -> DeviceSize { - self.info.size - } - - /// Returns true if the heap is local to the GPU. - #[inline] - pub fn is_device_local(&self) -> bool { - !(self.info.flags & ash::vk::MemoryHeapFlags::DEVICE_LOCAL).is_empty() - } - - /// Returns true if the heap is multi-instance enabled, that is allocation from such - /// heap will replicate to each physical-device's instance of heap. - #[inline] - pub fn is_multi_instance(&self) -> bool { - !(self.info.flags & ash::vk::MemoryHeapFlags::MULTI_INSTANCE).is_empty() - } -} - -/// Represents a queue family in a physical device. -/// -/// A queue family is group of one or multiple queues. All queues of one family have the same -/// characteristics. -#[derive(Debug, Copy, Clone)] -pub struct QueueFamily<'a> { - physical_device: PhysicalDevice<'a>, - id: u32, - properties: &'a ash::vk::QueueFamilyProperties, -} - -impl<'a> QueueFamily<'a> { - /// Returns the physical device associated to this queue family. - #[inline] - pub fn physical_device(&self) -> PhysicalDevice<'a> { - self.physical_device - } - - /// Returns the identifier of this queue family within the physical device. - #[inline] - pub fn id(&self) -> u32 { - self.id - } - - /// Returns the number of queues that belong to this family. - /// - /// Guaranteed to be at least 1 (or else that family wouldn't exist). - #[inline] - pub fn queues_count(&self) -> usize { - self.properties.queue_count as usize - } - - /// If timestamps are supported, returns the number of bits supported by timestamp operations. - /// The returned value will be in the range 36..64. - /// If timestamps are not supported, returns None. - #[inline] - pub fn timestamp_valid_bits(&self) -> Option { - let value = self.properties.timestamp_valid_bits; - if value == 0 { - None - } else { - Some(value) - } - } - - /// Returns the minimum granularity supported for image transfers in terms - /// of `[width, height, depth]` - #[inline] - pub fn min_image_transfer_granularity(&self) -> [u32; 3] { - let granularity = &self.properties.min_image_transfer_granularity; - [granularity.width, granularity.height, granularity.depth] - } - - /// Returns `true` if queues of this family can execute graphics operations. - #[inline] - pub fn supports_graphics(&self) -> bool { - self.properties - .queue_flags - .contains(ash::vk::QueueFlags::GRAPHICS) - } - - /// Returns `true` if queues of this family can execute compute operations. - #[inline] - pub fn supports_compute(&self) -> bool { - self.properties - .queue_flags - .contains(ash::vk::QueueFlags::COMPUTE) - } - - /// Returns `true` if queues of this family can execute transfer operations. - /// > **Note**: While all queues that can perform graphics or compute operations can implicitly perform - /// > transfer operations, graphics & compute queues only optionally indicate support for tranfers. - /// > Many discrete cards will have one queue family that exclusively sets the VK_QUEUE_TRANSFER_BIT - /// > to indicate a special relationship with the DMA module and more efficient transfers. - #[inline] - pub fn explicitly_supports_transfers(&self) -> bool { - self.properties - .queue_flags - .contains(ash::vk::QueueFlags::TRANSFER) - } - - /// Returns `true` if queues of this family can execute sparse resources binding operations. - #[inline] - pub fn supports_sparse_binding(&self) -> bool { - self.properties - .queue_flags - .contains(ash::vk::QueueFlags::SPARSE_BINDING) - } - - /// Returns `true` if the queues of this family support a particular pipeline stage. - #[inline] - pub fn supports_stage(&self, stage: PipelineStage) -> bool { - self.properties - .queue_flags - .contains(stage.required_queue_flags()) - } - - /// Returns whether queues of this family can draw on the given surface. - pub fn supports_surface( - &self, - surface: &Surface, - ) -> Result { - unsafe { - let fns = self.physical_device.instance.fns(); - - let mut output = MaybeUninit::uninit(); - (fns.khr_surface.get_physical_device_surface_support_khr)( - self.physical_device.internal_object(), - self.id, - surface.internal_object(), - output.as_mut_ptr(), - ) - .result() - .map_err(VulkanError::from)?; - Ok(output.assume_init() != 0) - } - } -} - -impl<'a> PartialEq for QueueFamily<'a> { - fn eq(&self, other: &Self) -> bool { - self.id == other.id - && self.physical_device.internal_object() == other.physical_device.internal_object() - } -} - -impl<'a> Eq for QueueFamily<'a> {} - /// The version of the Vulkan conformance test that a driver is conformant against. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct ConformanceVersion { @@ -1991,6 +2017,13 @@ pub enum SurfacePropertiesError { // The given `SurfaceInfo` values are not supported for the surface by the physical device. NotSupported, + + /// The provided `queue_family_index` was not less than the number of queue families in the + /// physical device. + QueueFamilyIndexOutOfRange { + queue_family_index: u32, + queue_family_count: u32, + }, } impl Error for SurfacePropertiesError { @@ -2006,15 +2039,28 @@ impl Error for SurfacePropertiesError { impl Display for SurfacePropertiesError { #[inline] fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { - write!( - f, - "{}", - match *self { - Self::OomError(_) => "not enough memory", - Self::SurfaceLost => "the surface is no longer valid", - Self::NotSupported => "the given `SurfaceInfo` values are not supported for the surface by the physical device", - } - ) + match self { + Self::OomError(_) => write!( + f, + "not enough memory", + ), + Self::SurfaceLost => write!( + f, + "the surface is no longer valid", + ), + Self::NotSupported => write!( + f, + "the given `SurfaceInfo` values are not supported for the surface by the physical device", + ), + Self::QueueFamilyIndexOutOfRange { + queue_family_index, + queue_family_count, + } => write!( + f, + "the provided `queue_family_index` ({}) was not less than the number of queue families in the physical device ({})", + queue_family_index, queue_family_count, + ), + } } } diff --git a/vulkano/src/image/attachment.rs b/vulkano/src/image/attachment.rs index bb085369..ed8b419e 100644 --- a/vulkano/src/image/attachment.rs +++ b/vulkano/src/image/attachment.rs @@ -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 diff --git a/vulkano/src/image/immutable.rs b/vulkano/src/image/immutable.rs index a6553a23..44326231 100644 --- a/vulkano/src/image/immutable.rs +++ b/vulkano/src/image/immutable.rs @@ -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( impl ImmutableImage { #[deprecated(note = "use ImmutableImage::uninitialized instead")] #[inline] - pub fn new<'a, I>( + pub fn new( device: Arc, dimensions: ImageDimensions, format: Format, - queue_families: I, - ) -> Result, ImmutableImageCreationError> - where - I: IntoIterator>, - { + queue_family_indices: impl IntoIterator, + ) -> Result, 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, dimensions: ImageDimensions, format: Format, - mip_levels: M, - queue_families: I, - ) -> Result, ImmutableImageCreationError> - where - I: IntoIterator>, - M: Into, - { + mip_levels: impl Into, + queue_family_indices: impl IntoIterator, + ) -> Result, 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, dimensions: ImageDimensions, format: Format, - mip_levels: M, + mip_levels: impl Into, usage: ImageUsage, flags: ImageCreateFlags, layout: ImageLayout, - queue_families: I, + queue_family_indices: impl IntoIterator, ) -> Result<(Arc, Arc), ImmutableImageCreationError> - where - I: IntoIterator>, - M: Into, { - let queue_families = queue_families - .into_iter() - .map(|f| f.id()) - .collect::>(); + 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)) diff --git a/vulkano/src/image/storage.rs b/vulkano/src/image/storage.rs index c9aad3d7..4dab1eb9 100644 --- a/vulkano/src/image/storage.rs +++ b/vulkano/src/image/storage.rs @@ -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, dimensions: ImageDimensions, format: Format, - queue_families: I, - ) -> Result, ImageCreationError> - where - I: IntoIterator>, - { + queue_family_indices: impl IntoIterator, + ) -> Result, 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, dimensions: ImageDimensions, format: Format, usage: ImageUsage, flags: ImageCreateFlags, - queue_families: I, - ) -> Result, ImageCreationError> - where - I: IntoIterator>, - { - let queue_families = queue_families - .into_iter() - .map(|f| f.id()) - .collect::>(); + queue_family_indices: impl IntoIterator, + ) -> Result, 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, dimensions: ImageDimensions, format: Format, usage: ImageUsage, flags: ImageCreateFlags, - queue_families: I, - ) -> Result, ImageCreationError> - where - I: IntoIterator>, - { - let queue_families = queue_families - .into_iter() - .map(|f| f.id()) - .collect::>(); + queue_family_indices: impl IntoIterator, + ) -> Result, 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(); } diff --git a/vulkano/src/image/sys.rs b/vulkano/src/image/sys.rs index 2ba84936..dbd3b841 100644 --- a/vulkano/src/image/sys.rs +++ b/vulkano/src/image/sys.rs @@ -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") diff --git a/vulkano/src/instance/mod.rs b/vulkano/src/instance/mod.rs index 11188c1f..b9bf9485 100644 --- a/vulkano/src/instance/mod.rs +++ b/vulkano/src/instance/mod.rs @@ -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, 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, + ) -> Result>, 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::>()?; + + 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 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()); - } } diff --git a/vulkano/src/lib.rs b/vulkano/src/lib.rs index 57a56222..0fb9674c 100644 --- a/vulkano/src/lib.rs +++ b/vulkano/src/lib.rs @@ -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 diff --git a/vulkano/src/library.rs b/vulkano/src/library.rs index 2b551204..33488228 100644 --- a/vulkano/src/library.rs +++ b/vulkano/src/library.rs @@ -142,11 +142,14 @@ impl VulkanLibrary { } }; - InstanceExtensions::from( - extension_properties - .iter() - .map(|property| CStr::from_ptr(property.extension_name.as_ptr())), - ) + extension_properties + .iter() + .map(|property| { + CStr::from_ptr(property.extension_name.as_ptr()) + .to_str() + .unwrap() + }) + .collect() }; Ok(Arc::new(VulkanLibrary { diff --git a/vulkano/src/macros.rs b/vulkano/src/macros.rs index 81605e4f..9969780d 100644 --- a/vulkano/src/macros.rs +++ b/vulkano/src/macros.rs @@ -9,7 +9,7 @@ macro_rules! vulkan_bitflags { { - $(#[doc = $ty_doc:literal])* + $(#[doc = $ty_doc:literal])* $ty:ident = $ty_ffi:ident($repr:ty); $( @@ -17,7 +17,7 @@ macro_rules! vulkan_bitflags { $flag_name:ident = $flag_name_ffi:ident, )+ } => { - $(#[doc = $ty_doc])* + $(#[doc = $ty_doc])* #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct $ty { $( @@ -131,27 +131,27 @@ macro_rules! vulkan_bitflags { } } - impl From<$ty> for ash::vk::$ty_ffi { - #[inline] - fn from(val: $ty) -> Self { - let mut result = ash::vk::$ty_ffi::empty(); - $( - if val.$flag_name { result |= ash::vk::$ty_ffi::$flag_name_ffi } - )+ - result - } - } + impl From<$ty> for ash::vk::$ty_ffi { + #[inline] + fn from(val: $ty) -> Self { + let mut result = ash::vk::$ty_ffi::empty(); + $( + if val.$flag_name { result |= ash::vk::$ty_ffi::$flag_name_ffi } + )+ + result + } + } impl From for $ty { - #[inline] - fn from(val: ash::vk::$ty_ffi) -> Self { + #[inline] + fn from(val: ash::vk::$ty_ffi) -> Self { Self { $( $flag_name: val.intersects(ash::vk::$ty_ffi::$flag_name_ffi), )+ } - } - } + } + } impl Default for $ty { #[inline] @@ -239,7 +239,7 @@ macro_rules! vulkan_bitflags { }; { - $(#[doc = $ty_doc:literal])* + $(#[doc = $ty_doc:literal])* #[non_exhaustive] $ty:ident = $ty_ffi:ident($repr:ty); @@ -254,7 +254,7 @@ macro_rules! vulkan_bitflags { , )+ } => { - $(#[doc = $ty_doc])* + $(#[doc = $ty_doc])* #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct $ty { $( @@ -452,28 +452,28 @@ macro_rules! vulkan_bitflags { } } - impl From<$ty> for ash::vk::$ty_ffi { - #[inline] - fn from(val: $ty) -> Self { - let mut result = ash::vk::$ty_ffi::empty(); - $( - if val.$flag_name { result |= ash::vk::$ty_ffi::$flag_name_ffi } - )+ - result - } - } + impl From<$ty> for ash::vk::$ty_ffi { + #[inline] + fn from(val: $ty) -> Self { + let mut result = ash::vk::$ty_ffi::empty(); + $( + if val.$flag_name { result |= ash::vk::$ty_ffi::$flag_name_ffi } + )+ + result + } + } impl From for $ty { - #[inline] - fn from(val: ash::vk::$ty_ffi) -> Self { + #[inline] + fn from(val: ash::vk::$ty_ffi) -> Self { Self { $( $flag_name: val.intersects(ash::vk::$ty_ffi::$flag_name_ffi), )+ _ne: crate::NonExhaustive(()), } - } - } + } + } impl Default for $ty { #[inline] @@ -555,7 +555,7 @@ macro_rules! vulkan_bitflags { macro_rules! vulkan_enum { { - $(#[doc = $ty_doc:literal])* + $(#[doc = $ty_doc:literal])* $ty:ident = $ty_ffi:ident($repr:ty); $( @@ -563,7 +563,7 @@ macro_rules! vulkan_enum { $flag_name:ident = $flag_name_ffi:ident, )+ } => { - $(#[doc = $ty_doc])* + $(#[doc = $ty_doc])* #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[repr($repr)] pub enum $ty { @@ -573,30 +573,30 @@ macro_rules! vulkan_enum { )+ } - impl From<$ty> for ash::vk::$ty_ffi { - #[inline] - fn from(val: $ty) -> Self { + impl From<$ty> for ash::vk::$ty_ffi { + #[inline] + fn from(val: $ty) -> Self { ash::vk::$ty_ffi::from_raw(val as $repr) - } - } + } + } impl TryFrom for $ty { type Error = (); - #[inline] - fn try_from(val: ash::vk::$ty_ffi) -> Result { + #[inline] + fn try_from(val: ash::vk::$ty_ffi) -> Result { Ok(match val { $( ash::vk::$ty_ffi::$flag_name_ffi => Self::$flag_name, )+ _ => return Err(()), }) - } - } + } + } }; { - $(#[doc = $ty_doc:literal])* + $(#[doc = $ty_doc:literal])* #[non_exhaustive] $ty:ident = $ty_ffi:ident($repr:ty); @@ -611,7 +611,7 @@ macro_rules! vulkan_enum { , )+ } => { - $(#[doc = $ty_doc])* + $(#[doc = $ty_doc])* #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[non_exhaustive] #[repr($repr)] @@ -733,30 +733,30 @@ macro_rules! vulkan_enum { _ => (), } - Ok(()) - } + Ok(()) } + } - impl From<$ty> for ash::vk::$ty_ffi { - #[inline] - fn from(val: $ty) -> Self { - ash::vk::$ty_ffi::from_raw(val as $repr) - } - } + impl From<$ty> for ash::vk::$ty_ffi { + #[inline] + fn from(val: $ty) -> Self { + ash::vk::$ty_ffi::from_raw(val as $repr) + } + } - impl TryFrom for $ty { - type Error = (); + impl TryFrom for $ty { + type Error = (); - #[inline] - fn try_from(val: ash::vk::$ty_ffi) -> Result { - Ok(match val { - $( - ash::vk::$ty_ffi::$flag_name_ffi => Self::$flag_name, - )+ - _ => return Err(()), - }) - } - } + #[inline] + fn try_from(val: ash::vk::$ty_ffi) -> Result { + Ok(match val { + $( + ash::vk::$ty_ffi::$flag_name_ffi => Self::$flag_name, + )+ + _ => return Err(()), + }) + } + } }; } diff --git a/vulkano/src/memory/device_memory.rs b/vulkano/src/memory/device_memory.rs index 56e4ea28..51a9d2ce 100644 --- a/vulkano/src/memory/device_memory.rs +++ b/vulkano/src/memory/device_memory.rs @@ -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 = 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 for DeviceMemoryExportError { /// /// # let device: std::sync::Arc = 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() }, ) diff --git a/vulkano/src/memory/mod.rs b/vulkano/src/memory/mod.rs index 25d97b50..c3e00fbd 100644 --- a/vulkano/src/memory/mod.rs +++ b/vulkano/src/memory/mod.rs @@ -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 = 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"); diff --git a/vulkano/src/memory/pool/host_visible.rs b/vulkano/src/memory/pool/host_visible.rs index 5e3fe706..f03d9418 100644 --- a/vulkano/src/memory/pool/host_visible.rs +++ b/vulkano/src/memory/pool/host_visible.rs @@ -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, - memory_type: u32, + memory_type_index: u32, // TODO: obviously very inefficient occupied: Mutex, Vec>)>>, } @@ -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, - memory_type: MemoryType, + memory_type_index: u32, ) -> Arc { - 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 } } diff --git a/vulkano/src/memory/pool/mod.rs b/vulkano/src/memory/pool/mod.rs index a909a48c..2155f87e 100644 --- a/vulkano/src/memory/pool/mod.rs +++ b/vulkano/src/memory/pool/mod.rs @@ -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, +fn choose_allocation_memory_type( + device: &Arc, 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( filter: F, ) -> Result, 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, 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() }, diff --git a/vulkano/src/memory/pool/non_host_visible.rs b/vulkano/src/memory/pool/non_host_visible.rs index 5db53316..1c3c164d 100644 --- a/vulkano/src/memory/pool/non_host_visible.rs +++ b/vulkano/src/memory/pool/non_host_visible.rs @@ -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, - memory_type: u32, + memory_type_index: u32, // TODO: obviously very inefficient occupied: Mutex, Vec>)>>, } @@ -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, - memory_type: MemoryType, + memory_type_index: u32, ) -> Arc { - 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 { - &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 } } diff --git a/vulkano/src/memory/pool/pool.rs b/vulkano/src/memory/pool/pool.rs index a040f3fe..d2dd38b1 100644 --- a/vulkano/src/memory/pool/pool.rs +++ b/vulkano/src/memory/pool/pool.rs @@ -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) -> Arc { - 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, - memory_type: MemoryType, + memory_type_index: u32, size: DeviceSize, alignment: DeviceSize, layout: AllocLayout, @@ -56,10 +60,19 @@ fn generic_allocation( ) -> Result { 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 { fn alloc_generic( &self, - memory_type: MemoryType, + memory_type_index: u32, size: DeviceSize, alignment: DeviceSize, layout: AllocLayout, map: MappingRequirement, ) -> Result { - generic_allocation(self.clone(), memory_type, size, alignment, layout, map) + generic_allocation( + self.clone(), + memory_type_index, + size, + alignment, + layout, + map, + ) } } diff --git a/vulkano/src/pipeline/compute.rs b/vulkano/src/pipeline/compute.rs index b7a5f59e..d89afae9 100644 --- a/vulkano/src/pipeline/compute.rs +++ b/vulkano/src/pipeline/compute.rs @@ -513,7 +513,7 @@ mod tests { let mut cbb = AutoCommandBufferBuilder::primary( device.clone(), - queue.family(), + queue.queue_family_index(), CommandBufferUsage::OneTimeSubmit, ) .unwrap(); diff --git a/vulkano/src/swapchain/display.rs b/vulkano/src/swapchain/display.rs index c3c97d75..9710e3dd 100644 --- a/vulkano/src/swapchain/display.rs +++ b/vulkano/src/swapchain/display.rs @@ -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, - physical_device: usize, + physical_device: Arc, index: u32, properties: ash::vk::DisplayPlanePropertiesKHR, supported_displays: Vec, @@ -55,17 +54,19 @@ pub struct DisplayPlane { impl DisplayPlane { /// See the docs of enumerate(). - pub fn enumerate_raw(device: PhysicalDevice) -> Result, OomError> { - let fns = device.instance().fns(); + pub fn enumerate_raw( + physical_device: Arc, + ) -> Result, 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::enumerate_raw(device).unwrap() + pub fn enumerate(physical_device: Arc) -> IntoIter { + 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 { + &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, - physical_device: usize, + physical_device: Arc, properties: Arc, // TODO: Arc because struct isn't clone } impl Display { /// See the docs of enumerate(). - pub fn enumerate_raw(device: PhysicalDevice) -> Result, OomError> { - let fns = device.instance().fns(); - assert!(device.instance().enabled_extensions().khr_display); // TODO: return error instead + pub fn enumerate_raw( + physical_device: Arc, + ) -> Result, 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::>() @@ -241,8 +241,8 @@ impl Display { /// // TODO: move iterator creation here from raw constructor? #[inline] - pub fn enumerate(device: PhysicalDevice) -> IntoIter { - Display::enumerate_raw(device).unwrap() + pub fn enumerate(physical_device: Arc) -> IntoIter { + 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 { + &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, OomError> { - let fns = self.instance.fns(); + let fns = self.physical_device.instance().fns(); let mode_properties = unsafe { loop { diff --git a/vulkano/src/swapchain/swapchain.rs b/vulkano/src/swapchain/swapchain.rs index 98dd4b6c..fa514608 100644 --- a/vulkano/src/swapchain/swapchain.rs +++ b/vulkano/src/swapchain/swapchain.rs @@ -452,19 +452,28 @@ impl Swapchain { 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 for SwapchainCreationError { SurfacePropertiesError::OomError(err) => Self::OomError(err), SurfacePropertiesError::SurfaceLost => Self::SurfaceLost, SurfacePropertiesError::NotSupported => unreachable!(), + SurfacePropertiesError::QueueFamilyIndexOutOfRange { .. } => unreachable!(), } } } diff --git a/vulkano/src/sync/mod.rs b/vulkano/src/sync/mod.rs index e4002fcc..f453e99c 100644 --- a/vulkano/src/sync/mod.rs +++ b/vulkano/src/sync/mod.rs @@ -152,7 +152,12 @@ impl<'a> From<&'a Arc> for SharingMode { impl<'a> From<&'a [&'a Arc]> for SharingMode { #[inline] fn from(queues: &'a [&'a Arc]) -> SharingMode { - SharingMode::Concurrent(queues.iter().map(|queue| queue.family().id()).collect()) + SharingMode::Concurrent( + queues + .iter() + .map(|queue| queue.queue_family_index()) + .collect(), + ) } } diff --git a/vulkano/src/sync/semaphore.rs b/vulkano/src/sync/semaphore.rs index e5bc6535..b9c44d32 100644 --- a/vulkano/src/sync/semaphore.rs +++ b/vulkano/src/sync/semaphore.rs @@ -501,9 +501,7 @@ impl From 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() }, ) { diff --git a/vulkano/src/tests.rs b/vulkano/src/tests.rs index 40d891de..69264dbe 100644 --- a/vulkano/src/tests.rs +++ b/vulkano/src/tests.rs @@ -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()