diff --git a/src/app.rs b/src/app.rs index 4084fe0..4bf9be4 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,14 +1,57 @@ -use anyhow::Result; +use anyhow::{anyhow, Result}; +use vulkanalia::loader::{LibloadingLoader, LIBRARY}; +use vulkanalia::prelude::v1_0::*; +use vulkanalia::window as vk_window; use winit::window::Window; +unsafe fn create_instance(window: &Window, entry: &Entry) -> Result { + let application_info = vk::ApplicationInfo::builder() + .application_name(b"Vulkan Tutorial\0") + .application_version(vk::make_version(1, 0, 0)) + .engine_name(b"No Engine\0") + .engine_version(vk::make_version(1, 0, 0)) + .api_version(vk::make_version(1, 0, 0)); + + let mut extensions = vk_window::get_required_instance_extensions(window) + .iter() + .map(|e| e.as_ptr()) + .collect::>(); + + // Compatibility extension for macOS + let flags = if entry + .enumerate_instance_extension_properties(None)? + .iter() + .any(|e| e.extension_name == vk::KHR_PORTABILITY_ENUMERATION_EXTENSION.name) + { + extensions.push(vk::KHR_PORTABILITY_ENUMERATION_EXTENSION.name.as_ptr()); + vk::InstanceCreateFlags::ENUMERATE_PORTABILITY_KHR + } else { + vk::InstanceCreateFlags::empty() + }; + + let info = vk::InstanceCreateInfo::builder() + .application_info(&application_info) + .enabled_extension_names(&extensions) + .flags(flags); + + Ok(entry.create_instance(&info, None)?) +} + /// Our Vulkan app. #[derive(Clone, Debug)] -pub struct App {} +pub struct App { + entry: Entry, + instance: Instance, +} impl App { /// Creates our Vulkan app. pub unsafe fn create(window: &Window) -> Result { - Ok(Self {}) + let loader = LibloadingLoader::new(LIBRARY)?; + let entry = Entry::new(loader).map_err(|b| anyhow!("{}", b))?; + let instance = create_instance(window, &entry)?; + + Ok(Self { entry, instance }) } /// Renders a frame for our Vulkan app. @@ -17,7 +60,9 @@ impl App { } /// Destroys our Vulkan app. - pub unsafe fn destroy(&mut self) {} + pub unsafe fn destroy(&mut self) { + self.instance.destroy_instance(None); + } } /// The Vulkan handles and associated properties used by our Vulkan app. diff --git a/src/main.rs b/src/main.rs index 4c07e3c..68b3184 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,7 @@ use anyhow::Result; use winit::dpi::LogicalSize; use winit::event::{Event, WindowEvent}; use winit::event_loop::{ControlFlow, EventLoop}; -use winit::window::{Window, WindowBuilder}; +use winit::window::WindowBuilder; fn main() -> Result<()> { pretty_env_logger::init(); @@ -26,18 +26,18 @@ fn main() -> Result<()> { // App let mut app = unsafe { App::create(&window)? }; - let mut destorying = false; + let mut destroying = false; event_loop.run(move |event, _, control_flow| { *control_flow = ControlFlow::Poll; match event { // Render a frame if our Vulkan app is not being destroyed - Event::MainEventsCleared if !destorying => unsafe { app.render(&window) }.unwrap(), + Event::MainEventsCleared if !destroying => unsafe { app.render(&window) }.unwrap(), // Destroy our Vulkan app. Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => { - destorying = true; + destroying = true; *control_flow = ControlFlow::Exit; unsafe { app.destroy();