vulkano_ecs/src/vulkan/vk_physical_device.rs
2024-11-15 23:16:18 +01:00

87 lines
3.2 KiB
Rust

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<vk::QueueFamilyProperties>,
}
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<vk::QueueFlags>,
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<VkPhysicalDevice>,
queue_flags: Option<vk::QueueFlags>,
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
}
}
}