diff --git a/crates/renderer/src/commands.rs b/crates/renderer/src/commands.rs index daac485..07ee5f8 100644 --- a/crates/renderer/src/commands.rs +++ b/crates/renderer/src/commands.rs @@ -64,6 +64,7 @@ impl SingleUseCommandPool { } /// get the underlying pool, bypassing the mutex + #[allow(dead_code)] pub unsafe fn pool(&self) -> vk::CommandPool { self.pool.data_ptr().read() } @@ -129,6 +130,8 @@ pub enum CommandBufferState { #[derive(Debug)] #[repr(transparent)] struct CommandBufferState2(AtomicU8); + +#[allow(dead_code)] impl CommandBufferState2 { fn initial() -> Self { Self(AtomicU8::new(CommandBufferState::Initial as u8)) @@ -188,11 +191,13 @@ impl !Sync for SingleUseCommand {} impl SingleUseCommand { pub fn new(device: Device, pool: Arc) -> VkResult { let buffer = unsafe { - let alloc_info = vk::CommandBufferAllocateInfo::default() - .command_buffer_count(1) - .command_pool(pool.pool()) - .level(vk::CommandBufferLevel::PRIMARY); - let buffer = device.dev().allocate_command_buffers(&alloc_info)?[0]; + let buffer = pool.pool.with_locked(|pool| { + let alloc_info = vk::CommandBufferAllocateInfo::default() + .command_buffer_count(1) + .command_pool(*pool) + .level(vk::CommandBufferLevel::PRIMARY); + Ok(device.dev().allocate_command_buffers(&alloc_info)?[0]) + })?; device.dev().begin_command_buffer( buffer, diff --git a/crates/renderer/src/images.rs b/crates/renderer/src/images.rs index 6e98988..fa6da7d 100644 --- a/crates/renderer/src/images.rs +++ b/crates/renderer/src/images.rs @@ -1,4 +1,8 @@ -use std::{borrow::Cow, collections::HashMap, sync::Arc}; +use std::{ + borrow::Cow, + collections::HashMap, + sync::{Arc, Weak}, +}; use crate::{ define_device_owned_handle, @@ -128,8 +132,8 @@ define_device_owned_handle! { format: vk::Format, views: Mutex>, aliases: Mutex>>, - parent: Option>, - is_swapchain_image:bool, + parent: Option>, + is_swapchain_image: bool, } => |this| if !this.is_swapchain_image { unsafe { for &view in this.views.lock().values() { @@ -266,20 +270,19 @@ impl Image { self.size.depth } - fn get_parent(self: &Arc) -> Arc { - self.parent.clone().unwrap_or_else(|| self.clone()) - } - - fn get_alloc(&self) -> Option<&vk_mem::Allocation> { - self.alloc + fn get_parent_or_self(self: &Arc) -> Arc { + self.parent .as_ref() - .or(self.parent.as_ref().and_then(|image| image.get_alloc())) + .map(|weak| weak.upgrade().unwrap()) + .unwrap_or_else(|| self.clone()) } pub unsafe fn get_alias(self: &Arc, desc: ImageDesc) -> VkResult> { - self.get_parent().get_alias_inner(desc) + self.get_parent_or_self().get_alias_inner(desc) } + /// must only be called on the primogenitor of an image. + /// get the primogenitor with [`Self::get_parent_or_self()`] unsafe fn get_alias_inner(self: Arc, desc: ImageDesc) -> VkResult> { use std::collections::hash_map::Entry::*; match self.aliases.lock().entry(desc.clone()) { @@ -327,7 +330,8 @@ impl Image { .mip_levels(mip_levels); let alloc = self - .get_alloc() + .alloc + .as_ref() .expect("no alloc associated with image. is this the framebuffer?"); let image = unsafe { @@ -342,7 +346,6 @@ impl Image { image }; - let parent = self.parent.clone().unwrap_or(self.clone()); let alias = Self::construct( self.device().clone(), image, @@ -352,8 +355,8 @@ impl Image { format, Mutex::new(HashMap::new()), Mutex::new(HashMap::new()), - Some(parent.clone()), - parent.is_swapchain_image, + Some(Arc::downgrade(&self)), + self.is_swapchain_image, )?; Ok(vacant.insert(Arc::new(alias)).clone()) }