Add logical device struct and surface handling for Vulkan

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
src/display

View file

@ -1,52 +1,70 @@
use std::fmt::{Display, Formatter};
use winit::{
application::ApplicationHandler, event::WindowEvent, event_loop::ActiveEventLoop, raw_window_handle::{HasDisplayHandle, DisplayHandle, HandleError}, window::{Window, WindowId}
};
use winit::window::WindowAttributes;
use crate::vulkan::VkInstance;
use ash::vk::QueueFlags;
use winit::application::ApplicationHandler;
use winit::event::WindowEvent;
use winit::event_loop::ActiveEventLoop;
use winit::window::{WindowId};
use crate::display::window::Window;
use crate::vulkan::{VkInstance, VkPhysicalDevice};
pub struct App {
window_attributes: WindowAttributes,
window: Option<Window>,
instance: Option<VkInstance>,
window: Window,
instance: Option<VkInstance>
}
impl App {
pub fn new(window_attributes: WindowAttributes) -> Self {
pub fn new(window: Window) -> Self {
Self {
window_attributes,
window: None,
instance: None,
window,
instance: None
}
}
}
impl HasDisplayHandle for App {
fn display_handle(&self) -> Result<DisplayHandle<'_>, HandleError> {
self.window.as_ref()
.ok_or_else(|| HandleError::Unavailable)?
.display_handle()
fn init_vulkan(&mut self) {
let required_extensions = self.window
.required_extensions()
.expect("Unable to get required required extensions");
log::info!("Initializing Vulkan instance");
let instance = VkInstance::new(&required_extensions);
log::info!("Vulkan instance created");
log::info!("\t{}", instance);
let surface = instance.create_surface(&self.window)
.expect("Unable to create surface");
let mut physical_devices = instance.get_physical_devices();
physical_devices.sort_by(|a, b| b.priority().cmp(&a.priority()));
let (physical_device, queue_family_index) = physical_devices
.iter()
.find_map(|physical_device| {
physical_device.queue_family_properties
.iter()
.enumerate()
.find_map(|(index, queue_family_property)| {
if surface.physical_device_queue_supported(physical_device, index as u32).unwrap_or(false) {
Some((physical_device, index as u32))
} else {
None
}
})
})
.expect("Unable to find suitable device");
self.instance = Some(instance);
}
}
impl ApplicationHandler for App {
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
self.window = event_loop
.create_window(self.window_attributes.clone())
.ok();
self.window.create_window(event_loop)
.map_err(|err| format!("Failed to create window: {}", err))
.unwrap();
self.instance = self.window
.as_ref()
.and_then(|w| Some(VkInstance::new(w)));
if let Some(instance) = self.instance.as_ref() {
let physical_devices = instance.get_physical_devices();
log::info!("Physical Devices:");
for physical_device in physical_devices {
log::info!("{}", physical_device)
}
}
self.init_vulkan();
}
fn window_event(&mut self, event_loop: &ActiveEventLoop, id: WindowId, event: WindowEvent) {
@ -55,10 +73,7 @@ impl ApplicationHandler for App {
log::info!("The close button was pressed; stopping");
event_loop.exit();
}
WindowEvent::RedrawRequested => {
self.window.as_ref().unwrap().request_redraw();
}
_ => (),
_ => self.window.window_event(event_loop, id, event),
}
}
}