summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.rs108
1 files changed, 73 insertions, 35 deletions
diff --git a/src/main.rs b/src/main.rs
index e45e49f..c7e12a6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,6 @@
 #![deny(unsafe_code)]
 use std::cell::OnceCell;
-use vulkanalia::{ Entry, Instance };
+use vulkanalia::{ Entry, Instance, Version };
 use vulkanalia::loader::{ LibloadingLoader, LIBRARY };
 use vulkanalia::vk::{ self, HasBuilder,
                       ApplicationInfo, InstanceCreateInfo,
@@ -94,6 +94,9 @@ fn ignore_errors(mut body: impl FnMut() -> Result<()>) -> () {
 }
 
 
+const VULKAN_FIRST_PORTABILITY_VERSION: Version = Version::new(1, 3, 216);
+
+
 struct Surreality {
   window: OnceCell<Window>,
   entry: OnceCell<Entry>,
@@ -109,51 +112,86 @@ impl Surreality {
     }
   }
 
-  fn init_if_needed(&mut self, event_loop: &ActiveEventLoop) -> Result<()> {
+  fn init(&mut self, event_loop: &ActiveEventLoop) -> Result<()> {
     if self.window.get().is_none() {
-      let window_attributes = WindowAttributes::default()
-              .with_title("Love, Curiosity, Justice")
-              .with_inner_size(LogicalSize::new(1024, 768));
-      let window: Window = event_loop.create_window(window_attributes)?;
-      let _ = self.window.set(window);
+      self.init_window(event_loop)?;
     }
 
     if self.entry.get().is_none() {
-      #[allow(unsafe_code)]
-      let loader = unsafe { LibloadingLoader::new(LIBRARY)? };
-      #[allow(unsafe_code)]
-      let entry = unsafe { Entry::new(loader)? };
-      let _ = self.entry.set(entry);
+      self.init_entry()?;
     }
 
     if self.instance.get().is_none() {
-      let application_info = ApplicationInfo::builder()
-        .application_name(b"Surreality\0")
-        .application_version(vk::make_version(1, 0, 0))
-        .engine_name(b"Surreality\0")
-        .engine_version(vk::make_version(1, 0, 0))
-        .api_version(vk::make_version(1, 0, 0));
-
-      let extensions = vulkanalia::window::get_required_instance_extensions(
-                           self.window.get().unwrap())
-          .iter().map(|item| item.as_ptr()).collect::<Vec<_>>();
-
-      let instance_create_info = InstanceCreateInfo::builder()
-        .application_info(&application_info)
-        .enabled_extension_names(&extensions);
-
-      #[allow(unsafe_code)]
-      let instance = unsafe {
-        let entry = self.entry.get().unwrap();
-        entry.create_instance(&instance_create_info, None)?
-      };
-
-      let _ = self.instance.set(instance);
+      self.init_instance()?;
     }
 
     Ok(())
   }
 
+  fn init_window(&mut self, event_loop: &ActiveEventLoop) -> Result<()> {
+    let window_attributes = WindowAttributes::default()
+            .with_title("Love, Curiosity, Justice")
+            .with_inner_size(LogicalSize::new(1024, 768));
+
+    let window: Window = event_loop.create_window(window_attributes)?;
+
+    let _ = self.window.set(window);
+
+    Ok(())
+  }
+
+  fn init_entry(&mut self) -> Result<()> {
+    #[allow(unsafe_code)]
+    let loader = unsafe { LibloadingLoader::new(LIBRARY)? };
+    #[allow(unsafe_code)]
+    let entry = unsafe { Entry::new(loader)? };
+
+    let _ = self.entry.set(entry);
+
+    Ok(())
+  }
+
+  fn init_instance(&mut self) -> Result<()> {
+    let entry = self.entry.get().unwrap();
+
+    let application_info = ApplicationInfo::builder()
+      .application_name(b"Surreality\0")
+      .application_version(vk::make_version(1, 0, 0))
+      .engine_name(b"Surreality\0")
+      .engine_version(vk::make_version(1, 0, 0))
+      .api_version(vk::make_version(1, 0, 0));
+
+    let mut extensions = vulkanalia::window::get_required_instance_extensions(
+                         self.window.get().unwrap())
+        .iter().map(|item| item.as_ptr()).collect::<Vec<_>>();
+
+    let mut flags = vk::InstanceCreateFlags::empty();
+    if entry.version()? >= VULKAN_FIRST_PORTABILITY_VERSION {
+      if cfg!(target_os = "macos") {
+        // Vulkan on the Mac is not fully conforming.
+        extensions.push(
+            vk::KHR_GET_PHYSICAL_DEVICE_PROPERTIES2_EXTENSION.name.as_ptr());
+        extensions.push(
+            vk::KHR_PORTABILITY_ENUMERATION_EXTENSION.name.as_ptr());
+        flags.insert(vk::InstanceCreateFlags::ENUMERATE_PORTABILITY_KHR);
+      }
+    }
+
+    let instance_create_info = InstanceCreateInfo::builder()
+      .application_info(&application_info)
+      .enabled_extension_names(&extensions)
+      .flags(flags);
+
+    #[allow(unsafe_code)]
+    let instance = unsafe {
+      entry.create_instance(&instance_create_info, None)?
+    };
+
+    let _ = self.instance.set(instance);
+
+    Ok(())
+  }
+
   fn render(&mut self, window_id: WindowId) -> Result<()> {
     if let Some(window) = self.window.get()
        && window_id == window.id()
@@ -171,7 +209,7 @@ impl ApplicationHandler for Surreality {
   fn resumed(&mut self, event_loop: &ActiveEventLoop) {
     ignore_errors(move || {
       println!("resumed");
-      self.init_if_needed(event_loop)?;
+      self.init(event_loop)?;
 
       Ok(())
     });