use std::sync::Arc; use super::{VkInstance, VkSurface}; use ash::vk; pub struct VkPhysicalDevice { instance: Arc, pub handle: vk::PhysicalDevice, pub properties: vk::PhysicalDeviceProperties, pub features: vk::PhysicalDeviceFeatures, pub queue_family_properties: Vec, } impl VkPhysicalDevice { pub fn new(instance: &Arc, physical_device: vk::PhysicalDevice) -> Self { log::debug!("New physical device"); let device_properties = unsafe { instance.handle.get_physical_device_properties(physical_device) }; log::debug!("{device_properties:#?}"); let device_features = unsafe { instance.handle.get_physical_device_features(physical_device) }; log::debug!("{device_features:#?}"); let device_queue_families = unsafe { instance.handle.get_physical_device_queue_family_properties(physical_device) }; log::debug!("{device_queue_families:#?}"); Self { instance: Arc::clone(instance), handle: physical_device, properties: device_properties, features: device_features, queue_family_properties: device_queue_families, } } pub fn find_queue_family_by( &self, queue_flags: Option, surface: Option<&VkSurface>, ) -> Option<(u32, &vk::QueueFamilyProperties)> { self.queue_family_properties.iter().enumerate().find_map( |(index, queue_family_property)| { let surface_check_passed = match surface { Some(surface) => surface .physical_device_queue_supported(self, index as u32) .unwrap_or(false), None => true, }; let queue_flags_check_passed = match queue_flags { Some(queue_flags) => queue_family_property.queue_flags.contains(queue_flags), None => true, }; if surface_check_passed && queue_flags_check_passed { Some((index as u32, queue_family_property)) } else { None } }, ) } pub fn pick_physical_device_and_queue_by<'a>( physical_devices: &'a Vec, queue_flags: Option, surface: Option<&VkSurface>, ) -> Option<(&'a VkPhysicalDevice, u32, &'a vk::QueueFamilyProperties)> { physical_devices.iter().find_map(|physical_device| { physical_device .find_queue_family_by(queue_flags, surface) .and_then(|(queue_index, queue_family_properties)| { Some((physical_device, queue_index, queue_family_properties)) }) }) } pub fn priority(&self) -> usize { match self.properties.device_type { vk::PhysicalDeviceType::CPU => 1, vk::PhysicalDeviceType::VIRTUAL_GPU => 2, vk::PhysicalDeviceType::INTEGRATED_GPU => 3, vk::PhysicalDeviceType::DISCRETE_GPU => 4, _ => 0, } } }