images+commands: sync
- lock pool when allocating command buffers - store image parent as weak arc in order to not create cycles
This commit is contained in:
parent
260275d694
commit
0f96689079
|
@ -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<SingleUseCommandPool>) -> VkResult<Self> {
|
||||
let buffer = unsafe {
|
||||
let buffer = pool.pool.with_locked(|pool| {
|
||||
let alloc_info = vk::CommandBufferAllocateInfo::default()
|
||||
.command_buffer_count(1)
|
||||
.command_pool(pool.pool())
|
||||
.command_pool(*pool)
|
||||
.level(vk::CommandBufferLevel::PRIMARY);
|
||||
let buffer = device.dev().allocate_command_buffers(&alloc_info)?[0];
|
||||
Ok(device.dev().allocate_command_buffers(&alloc_info)?[0])
|
||||
})?;
|
||||
|
||||
device.dev().begin_command_buffer(
|
||||
buffer,
|
||||
|
|
|
@ -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,7 +132,7 @@ define_device_owned_handle! {
|
|||
format: vk::Format,
|
||||
views: Mutex<HashMap<ImageViewDesc, vk::ImageView>>,
|
||||
aliases: Mutex<HashMap<ImageDesc, Arc<Image>>>,
|
||||
parent: Option<Arc<Image>>,
|
||||
parent: Option<Weak<Image>>,
|
||||
is_swapchain_image: bool,
|
||||
} => |this| if !this.is_swapchain_image {
|
||||
unsafe {
|
||||
|
@ -266,20 +270,19 @@ impl Image {
|
|||
self.size.depth
|
||||
}
|
||||
|
||||
fn get_parent(self: &Arc<Self>) -> Arc<Image> {
|
||||
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<Self>) -> Arc<Image> {
|
||||
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<Self>, desc: ImageDesc) -> VkResult<Arc<Self>> {
|
||||
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<Self>, desc: ImageDesc) -> VkResult<Arc<Image>> {
|
||||
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())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue