librashader/librashader-runtime-vk/tests/hello_triangle/physicaldevice.rs
2023-02-16 00:39:36 -05:00

145 lines
4.2 KiB
Rust

use ash::vk;
use std::ffi::CStr;
pub struct QueueFamilyIndices {
graphics_family: Option<u32>,
}
impl QueueFamilyIndices {
pub fn is_complete(&self) -> bool {
self.graphics_family.is_some()
}
pub fn graphics_family(&self) -> u32 {
self.graphics_family.unwrap()
}
}
pub(crate) fn pick_physical_device(instance: &ash::Instance) -> vk::PhysicalDevice {
let physical_devices = unsafe {
instance
.enumerate_physical_devices()
.expect("Failed to enumerate Physical Devices!")
};
let mut result = None;
for &physical_device in physical_devices.iter() {
if is_physical_device_suitable(instance, physical_device) && result.is_none() {
result = Some(physical_device)
}
}
match result {
None => panic!("Failed to find a suitable GPU!"),
Some(physical_device) => physical_device,
}
}
fn is_physical_device_suitable(
instance: &ash::Instance,
physical_device: vk::PhysicalDevice,
) -> bool {
let device_properties = unsafe { instance.get_physical_device_properties(physical_device) };
let device_features = unsafe { instance.get_physical_device_features(physical_device) };
let device_queue_families =
unsafe { instance.get_physical_device_queue_family_properties(physical_device) };
let device_type = match device_properties.device_type {
vk::PhysicalDeviceType::CPU => "Cpu",
vk::PhysicalDeviceType::INTEGRATED_GPU => "Integrated GPU",
vk::PhysicalDeviceType::DISCRETE_GPU => "Discrete GPU",
vk::PhysicalDeviceType::VIRTUAL_GPU => "Virtual GPU",
vk::PhysicalDeviceType::OTHER => "Unknown",
_ => panic!(),
};
let device_name = unsafe { CStr::from_ptr(device_properties.device_name.as_ptr()) };
let device_name = device_name.to_string_lossy();
println!(
"\tDevice Name: {}, id: {}, type: {}",
device_name, device_properties.device_id, device_type
);
println!("\tAPI Version: {}", device_properties.api_version);
println!("\tSupport Queue Family: {}", device_queue_families.len());
println!("\t\tQueue Count | Graphics, Compute, Transfer, Sparse Binding");
for queue_family in device_queue_families.iter() {
let is_graphics_support = if queue_family.queue_flags.contains(vk::QueueFlags::GRAPHICS) {
"support"
} else {
"unsupport"
};
let is_compute_support = if queue_family.queue_flags.contains(vk::QueueFlags::COMPUTE) {
"support"
} else {
"unsupport"
};
let is_transfer_support = if queue_family.queue_flags.contains(vk::QueueFlags::TRANSFER) {
"support"
} else {
"unsupport"
};
let is_sparse_support = if queue_family
.queue_flags
.contains(vk::QueueFlags::SPARSE_BINDING)
{
"support"
} else {
"unsupport"
};
println!(
"\t\t{}\t | {}, {}, {}, {}",
queue_family.queue_count,
is_graphics_support,
is_compute_support,
is_transfer_support,
is_sparse_support
);
}
// there are plenty of features
println!(
"\tGeometry Shader support: {}",
if device_features.geometry_shader == 1 {
"support"
} else {
"unsupported"
}
);
let indices = find_queue_family(instance, physical_device);
indices.is_complete()
}
pub fn find_queue_family(
instance: &ash::Instance,
physical_device: vk::PhysicalDevice,
) -> QueueFamilyIndices {
let queue_families =
unsafe { instance.get_physical_device_queue_family_properties(physical_device) };
let mut queue_family_indices = QueueFamilyIndices {
graphics_family: None,
};
let mut index = 0;
for queue_family in queue_families.iter() {
if queue_family.queue_count > 0
&& queue_family.queue_flags.contains(vk::QueueFlags::GRAPHICS)
{
queue_family_indices.graphics_family = Some(index);
}
if queue_family_indices.is_complete() {
break;
}
index += 1;
}
queue_family_indices
}