Add logical device struct and surface handling for Vulkan
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 0s

Introduce the VkLogicalDevice struct and add surface creation logic in VkInstance. Also, import necessary extensions and refine Vulkan physical device and window handling. Included a dependency on 'anyhow' for error management.
This commit is contained in:
Florian RICHER 2024-11-10 18:18:59 +01:00
parent 4048937a6c
commit da0be47b14
Signed by: florian.richer
GPG key ID: C73D37CBED7BFC77
14 changed files with 258 additions and 153 deletions

View file

@ -1,7 +1,10 @@
use std::ffi::CString;
use std::ffi::{c_char, CString};
use std::fmt::{Display, Formatter};
use ash::{Instance, vk, Entry};
use winit::raw_window_handle::{HasDisplayHandle};
use ash::khr::surface;
use winit::raw_window_handle::{HasDisplayHandle, HasWindowHandle};
use crate::vulkan::utils::use_layers;
use crate::vulkan::vk_surface::VkSurface;
use crate::vulkan::VkPhysicalDevice;
pub struct VkInstance {
@ -10,7 +13,9 @@ pub struct VkInstance {
}
impl VkInstance {
pub fn new(window: &impl HasDisplayHandle) -> Self {
pub fn new(
required_extensions: &Vec<*const c_char>,
) -> Self {
let entry = Entry::linked();
// Layers
@ -21,19 +26,6 @@ impl VkInstance {
]);
let layers_raw = layers.iter().map(|s| s.as_ptr()).collect::<Vec<_>>();
// Extensions
let mut extension_names =
ash_window::enumerate_required_extensions(window.display_handle().expect("No display handle").as_raw())
.unwrap()
.to_vec();
#[cfg(any(target_os = "macos", target_os = "ios"))]
{
extension_names.push(ash::khr::portability_enumeration::NAME.as_ptr());
// Enabling this extension is a requirement when using `VK_KHR_portability_subset`
extension_names.push(ash::khr::get_physical_device_properties2::NAME.as_ptr());
}
// App Info
let app_name = CString::new("VulkanTriangle").unwrap();
let appinfo = vk::ApplicationInfo::default()
@ -53,7 +45,7 @@ impl VkInstance {
let create_info = vk::InstanceCreateInfo::default()
.application_info(&appinfo)
.enabled_layer_names(&layers_raw)
.enabled_extension_names(&extension_names)
.enabled_extension_names(&required_extensions)
.flags(create_flags);
let instance: Instance = unsafe {
@ -75,6 +67,31 @@ impl VkInstance {
.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 {
@ -83,4 +100,10 @@ impl Drop for VkInstance {
self.handle.destroy_instance(None);
}
}
}
impl Display for VkInstance {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "Vulkan Version:")
}
}