diff options
| author | Irene Knapp <ireneista@irenes.space> | 2026-08-09 17:10:03 -0700 |
|---|---|---|
| committer | Irene Knapp <ireneista@irenes.space> | 2026-08-09 17:10:03 -0700 |
| commit | 4158fed109ae789cb3ca7ff53c2790797a3b4087 (patch) | |
| tree | 4e264225e211faaacc8259997dff207378c50e39 /src/graphics/permanent.rs | |
| parent | 4b877079872248d3a4c17312b18599c6084e1e2d (diff) | |
refactor Texture into its own thing
as part of this, the command pools are moved from window dressing to permanent note also how mip count is a value computed by loading the texture, and used when creating the sampler, which is part of the window dressing. the assumption about how it's computed will have to change when we support multiple textures, but for now we settle for just pushing the assumption to the top level. Force-Push: yes Change-Id: I545c53feedc99628fbe943120798fe66fe9e065b
Diffstat (limited to 'src/graphics/permanent.rs')
| -rw-r--r-- | src/graphics/permanent.rs | 52 |
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 |