use crate::vulkan::vk_surface::VkSurface; use ash::vk; use crate::vulkan::LOG_TARGET; pub struct VkPhysicalDevice { // Vulkan properties pub(super) handle: vk::PhysicalDevice, pub properties: vk::PhysicalDeviceProperties, pub features: vk::PhysicalDeviceFeatures, pub queue_family_properties: Vec, } impl VkPhysicalDevice { pub fn new(instance: &ash::Instance, physical_device: vk::PhysicalDevice) -> Self { log::debug!(target: LOG_TARGET, "New physical device"); let device_properties = unsafe { instance.get_physical_device_properties(physical_device) }; log::debug!(target: LOG_TARGET, "{device_properties:#?}"); let device_features = unsafe { instance.get_physical_device_features(physical_device) }; log::debug!(target: LOG_TARGET, "{device_features:#?}"); let device_queue_families = unsafe { instance.get_physical_device_queue_family_properties(physical_device) }; log::debug!(target: LOG_TARGET, "{device_queue_families:#?}"); Self { 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 } } }