summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.rs48
1 files changed, 27 insertions, 21 deletions
diff --git a/src/main.rs b/src/main.rs
index e181e46..44e92bd 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -45,6 +45,7 @@ impl<T> Acceptable<T> {
     if let Acceptable::Rejected(_) = self { true } else { false }
   }
 
+  #[allow(unused)]
   fn unwrap(self) -> T {
     if let Acceptable::Accepted(result) = self {
       result
@@ -480,14 +481,8 @@ impl Surreality {
       -> Result<(vk::PhysicalDevice, Device, QueueFamilyIndices, vk::Queue,
                  vk::Queue, EnableSwapchain)>
   {
-    let physical_device = Self::pick_vulkan_device(instance, surface)?;
-
-    //   We already did the check in score_vulkan_device(), so if it fails
-    // this second time, that's our own bug and we don't need to explain it
-    // to our users.
-    // TODO looks sus though
-    let indices = Self::find_device_queue_family_indices(
-                      instance, surface, &physical_device)?.unwrap();
+    let (physical_device, indices)
+            = Self::pick_vulkan_device(instance, surface)?;
 
     //   We enumerate the device extensions here so they can inform
     // configuration. We already did this in score_vulkan_device(), but here
@@ -1019,23 +1014,26 @@ impl Surreality {
   // device to connect it to.
   #[allow(unsafe_code)]
   fn pick_vulkan_device(instance: &Instance, surface: &vk::SurfaceKHR)
-      -> Result<vk::PhysicalDevice>
+      -> Result<(vk::PhysicalDevice, QueueFamilyIndices)>
   {
     let mut best_device = None;
     let mut best_score = None;
+    let mut best_indices = None;
     let mut rejected = BTreeMap::new();
 
     for device in unsafe { instance.enumerate_physical_devices() }? {
       match Self::score_vulkan_device(instance, surface, &device)? {
-        Acceptable::Accepted(new_score) => {
+        Acceptable::Accepted((new_score, new_indices)) => {
           if let Some(old_score) = best_score {
             if new_score > old_score {
               best_device = Some(device);
               best_score = Some(new_score);
+              best_indices = Some(new_indices);
             }
           } else {
             best_device = Some(device);
             best_score = Some(new_score);
+            best_indices = Some(new_indices);
           }
         }
         Acceptable::Rejected(reason) => {
@@ -1050,8 +1048,8 @@ impl Surreality {
       }
     }
 
-    if let Some(device) = best_device {
-      Ok(device)
+    if let (Some(device), Some(indices)) = (best_device, best_indices) {
+      Ok((device, indices))
     } else if rejected.is_empty() {
       Err(Error {
         message: "The system has no GPUs of any kind.".to_string()
@@ -1074,21 +1072,29 @@ impl Surreality {
   // will want to print explanations, but otherwise it'll want to be quiet. So
   // the outer Result is whether we successfully evaluated the device, and the
   // inner Acceptable is whether we approve of it.
+  //
+  //   In the event that we find the device acceptable, we also return the
+  // queue family indices we'd be using if we ultimately go with it. While
+  // this is not strictly necessary, it's better to return them from here
+  // than to recompute them later on the assumption it'll work out the same.
   #[allow(unsafe_code)]
   fn score_vulkan_device(instance: &Instance, surface: &vk::SurfaceKHR,
                          physical_device: &vk::PhysicalDevice)
-      -> Result<Acceptable<u64>>
+      -> Result<Acceptable<(u64, QueueFamilyIndices)>>
   {
     //   Not all devices support graphics, and not all devices support
     // presenting to any given surface. We check whether this one is suitable
-    // by looking up the indices of the queue families we would use, though
-    // we ignore the actual values and recompute them later.
-    if let Acceptable::Rejected(rationale)
-           = Self::find_device_queue_family_indices(
-                 instance, surface, physical_device)?
+    // by looking up the indices of the queue families we would use. If we
+    // ultimately use this device, we'll need these, so we make sure to return
+    // them.
+    let indices = match Self::find_device_queue_family_indices(
+                            instance, surface, physical_device)?
     {
-      return Ok(Acceptable::Rejected(rationale));
-    }
+      Acceptable::Rejected(rationale) => {
+        return Ok(Acceptable::Rejected(rationale));
+      }
+      Acceptable::Accepted(indices) => indices
+    };
 
     //   At this point we know the device meets our high-level requirements,
     // so it's just a question of scoring.
@@ -1145,7 +1151,7 @@ impl Surreality {
       // selected.
     }
 
-    Ok(Acceptable::Accepted(score))
+    Ok(Acceptable::Accepted((score, indices)))
   }
 
   #[allow(unsafe_code)]