rust_vulkan_test/src/vulkan/vk_instance.rs
Florian RICHER b91571e777
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 0s
Enhance vulkan instance and physical device display formatting
Refactor Vulkan instance and physical device formatting for better clarity. Added formatter utilities to encapsulate version and property formatting. Updated logging to use the new formatted output for improved debug readability.
2024-11-10 21:27:03 +01:00

129 lines
No EOL
3.9 KiB
Rust

use std::ffi::{c_char, CString};
use std::fmt::{Debug, Display, Formatter};
use ash::{Instance, vk, Entry};
use ash::khr::surface;
use winit::raw_window_handle::{HasDisplayHandle, HasWindowHandle};
use crate::vulkan::utils::formatter::format_instance_layer;
use crate::vulkan::utils::layers::{use_layers, LayersSelector};
use crate::vulkan::vk_surface::VkSurface;
use crate::vulkan::VkPhysicalDevice;
pub struct VkInstance {
entry: Entry,
handle: Instance,
}
impl VkInstance {
pub fn new(
required_extensions: &Vec<*const c_char>,
) -> Self {
let entry = Entry::linked();
// Layers
let layers = use_layers(
&entry,
LayersSelector::SpecificLayers(vec![
"VK_LAYER_KHRONOS_validation",
"VK_LAYER_MANGOHUD_overlay_x86_64",
"VK_LAYER_NV_optimus"
])
);
let layers_raw = layers.iter().map(|s| s.as_ptr()).collect::<Vec<_>>();
// App Info
let app_name = CString::new("VulkanTriangle").unwrap();
let appinfo = vk::ApplicationInfo::default()
.application_name(app_name.as_c_str())
.application_version(0)
.engine_name(app_name.as_c_str())
.engine_version(0)
.api_version(vk::make_api_version(0, 1, 0, 0));
let create_flags = if cfg!(any(target_os = "macos", target_os = "ios")) {
vk::InstanceCreateFlags::ENUMERATE_PORTABILITY_KHR
} else {
vk::InstanceCreateFlags::default()
};
// Instance Info
let create_info = vk::InstanceCreateInfo::default()
.application_info(&appinfo)
.enabled_layer_names(&layers_raw)
.enabled_extension_names(&required_extensions)
.flags(create_flags);
let instance: Instance = unsafe {
entry
.create_instance(&create_info, None)
.expect("Instance creation error")
};
Self {
entry,
handle: instance
}
}
pub fn get_physical_devices(&self) -> Vec<VkPhysicalDevice> {
let physical_devices = unsafe { self.handle.enumerate_physical_devices() };
physical_devices
.unwrap_or_default()
.iter().map(|physical_device| VkPhysicalDevice::new(&self.handle, *physical_device))
.collect()
}
pub fn create_surface(
&self,
window: &crate::display::Window
) -> anyhow::Result<VkSurface> {
let window_handle = window.handle()
.ok_or_else(|| anyhow::anyhow!("Window handle is not available."))?;
let surface_loader = surface::Instance::new(&self.entry, &self.handle);
let surface = unsafe {
ash_window::create_surface(
&self.entry,
&self.handle,
window_handle.display_handle()?.as_raw(),
window_handle.window_handle()?.as_raw(),
None,
)?
};
Ok(VkSurface::new(
surface_loader,
surface,
))
}
}
impl Drop for VkInstance {
fn drop(&mut self) {
unsafe {
self.handle.destroy_instance(None);
}
}
}
impl Display for VkInstance {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
writeln!(f, "")?;
let instance_layers = unsafe { self.entry.enumerate_instance_layer_properties().unwrap_or_default() };
writeln!(f, "Instance layers ({}) :", instance_layers.len())?;
for instance_layer in &instance_layers {
writeln!(f, "{}", format_instance_layer(instance_layer))?;
}
writeln!(f, "")?;
let physical_devices = self.get_physical_devices();
writeln!(f, "Physical Devices ({}) :", physical_devices.len())?;
for physical_device in physical_devices {
writeln!(f, "{physical_device}")?;
}
writeln!(f, "")?;
Ok(())
}
}