summary refs log tree commit diff
path: root/src/graphics/permanent.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/graphics/permanent.rs')
-rw-r--r--src/graphics/permanent.rs52
1 files changed, 47 insertions, 5 deletions
diff --git a/src/graphics/permanent.rs b/src/graphics/permanent.rs
index beda3fe..f359dbd 100644
--- a/src/graphics/permanent.rs
+++ b/src/graphics/permanent.rs
@@ -75,6 +75,14 @@ pub struct PermanentGraphicsState {
   // concerns, which have a tendency to defeat optimizations. Alas.
   pub graphics_queue: vk::Queue,
   pub presentation_queue: vk::Queue,
+
+  //   A command pool is an object from which command buffers are allocated.
+  // Our command pools are permanent, but none of the actual buffers are,
+  // those are all managed elsewhere. Lifecycle operations on Permanent
+  // require all the command-buffer lifecycle stuff to have already been dealt
+  // with.
+  pub primary_command_pool: vk::CommandPool,
+  pub transient_command_pool: vk::CommandPool,
 }
 
 
@@ -130,9 +138,13 @@ impl PermanentGraphicsState {
 
     let descriptor_set_layout = init_descriptor_set_layout(&device)?;
 
+    let (primary_command_pool, transient_command_pool)
+            = init_command_pools(&device, &indices)?;
+
     Ok((PermanentGraphicsState {
       window, entry, instance, debug_messager, surface, device,
-      graphics_queue, presentation_queue
+      graphics_queue, presentation_queue,
+      primary_command_pool, transient_command_pool,
     }, GraphicsStateForReinit {
       indices, sample_count, descriptor_set_layout,
     }, enable_anisotropy, enable_swapchain))
@@ -140,9 +152,17 @@ impl PermanentGraphicsState {
 
   #[allow(unsafe_code)]
   pub fn destroy(self) -> () {
-    unsafe { self.device.destroy_device(None) };
+    let device = self.device;
+    let instance = self.instance;
+
+    //   Notice that we rely on the assumption any command buffers in the
+    // pools have already been freed.
+    unsafe { device.destroy_command_pool(self.primary_command_pool, None) };
+    unsafe { device.destroy_command_pool(self.transient_command_pool, None) };
+
+    unsafe { device.destroy_device(None) };
 
-    unsafe { self.instance.destroy_surface_khr(self.surface, None) };
+    unsafe { instance.destroy_surface_khr(self.surface, None) };
 
     //   Everything but the instance itself should already be destroyed,
     // before we destroy the debug messager. The special hook to get debug
@@ -151,11 +171,11 @@ impl PermanentGraphicsState {
     // shouldn't after this point, we'd miss out on diagnostics.
     if let Some(debug_messager) = self.debug_messager {
       unsafe {
-        self.instance.destroy_debug_utils_messenger_ext(debug_messager, None);
+        instance.destroy_debug_utils_messenger_ext(debug_messager, None);
       }
     }
 
-    unsafe { self.instance.destroy_instance(None) };
+    unsafe { instance.destroy_instance(None) };
   }
 
   //   We expect our caller to have already verified that the device supports
@@ -573,6 +593,28 @@ fn init_descriptor_set_layout(device: &Device)
 
 
 
+#[allow(unsafe_code)]
+fn init_command_pools(device: &Device, indices: &QueueFamilyIndices)
+    -> Result<(vk::CommandPool, vk::CommandPool)>
+{
+  let command_pool_info = vk::CommandPoolCreateInfo::builder()
+          .flags(vk::CommandPoolCreateFlags::TRANSIENT
+                 | vk::CommandPoolCreateFlags::RESET_COMMAND_BUFFER)
+          .queue_family_index(indices.graphics);
+
+  let primary = unsafe {
+    device.create_command_pool(&command_pool_info, None)
+  }?;
+
+  command_pool_info.flags(vk::CommandPoolCreateFlags::TRANSIENT);
+  let transient = unsafe {
+    device.create_command_pool(&command_pool_info, None)
+  }?;
+
+  Ok((primary, transient))
+}
+
+
 //   To Vulkan, a "physical" device is the actual GPU, and a "logical"
 // device is per-process state that represents a connection to the GPU.
 // Before we can create a logical device, we must choose which physical