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
|
/// get the underlying pool, bypassing the mutex
|
||||||
|
#[allow(dead_code)]
|
||||||
pub unsafe fn pool(&self) -> vk::CommandPool {
|
pub unsafe fn pool(&self) -> vk::CommandPool {
|
||||||
self.pool.data_ptr().read()
|
self.pool.data_ptr().read()
|
||||||
}
|
}
|
||||||
|
@ -129,6 +130,8 @@ pub enum CommandBufferState {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
struct CommandBufferState2(AtomicU8);
|
struct CommandBufferState2(AtomicU8);
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
impl CommandBufferState2 {
|
impl CommandBufferState2 {
|
||||||
fn initial() -> Self {
|
fn initial() -> Self {
|
||||||
Self(AtomicU8::new(CommandBufferState::Initial as u8))
|
Self(AtomicU8::new(CommandBufferState::Initial as u8))
|
||||||
|
@ -188,11 +191,13 @@ impl !Sync for SingleUseCommand {}
|
||||||
impl SingleUseCommand {
|
impl SingleUseCommand {
|
||||||
pub fn new(device: Device, pool: Arc<SingleUseCommandPool>) -> VkResult<Self> {
|
pub fn new(device: Device, pool: Arc<SingleUseCommandPool>) -> VkResult<Self> {
|
||||||
let buffer = unsafe {
|
let buffer = unsafe {
|
||||||
let alloc_info = vk::CommandBufferAllocateInfo::default()
|
let buffer = pool.pool.with_locked(|pool| {
|
||||||
.command_buffer_count(1)
|
let alloc_info = vk::CommandBufferAllocateInfo::default()
|
||||||
.command_pool(pool.pool())
|
.command_buffer_count(1)
|
||||||
.level(vk::CommandBufferLevel::PRIMARY);
|
.command_pool(*pool)
|
||||||
let buffer = device.dev().allocate_command_buffers(&alloc_info)?[0];
|
.level(vk::CommandBufferLevel::PRIMARY);
|
||||||
|
Ok(device.dev().allocate_command_buffers(&alloc_info)?[0])
|
||||||
|
})?;
|
||||||
|
|
||||||
device.dev().begin_command_buffer(
|
device.dev().begin_command_buffer(
|
||||||
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::{
|
use crate::{
|
||||||
define_device_owned_handle,
|
define_device_owned_handle,
|
||||||
|
@ -128,8 +132,8 @@ define_device_owned_handle! {
|
||||||
format: vk::Format,
|
format: vk::Format,
|
||||||
views: Mutex<HashMap<ImageViewDesc, vk::ImageView>>,
|
views: Mutex<HashMap<ImageViewDesc, vk::ImageView>>,
|
||||||
aliases: Mutex<HashMap<ImageDesc, Arc<Image>>>,
|
aliases: Mutex<HashMap<ImageDesc, Arc<Image>>>,
|
||||||
parent: Option<Arc<Image>>,
|
parent: Option<Weak<Image>>,
|
||||||
is_swapchain_image:bool,
|
is_swapchain_image: bool,
|
||||||
} => |this| if !this.is_swapchain_image {
|
} => |this| if !this.is_swapchain_image {
|
||||||
unsafe {
|
unsafe {
|
||||||
for &view in this.views.lock().values() {
|
for &view in this.views.lock().values() {
|
||||||
|
@ -266,20 +270,19 @@ impl Image {
|
||||||
self.size.depth
|
self.size.depth
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_parent(self: &Arc<Self>) -> Arc<Image> {
|
fn get_parent_or_self(self: &Arc<Self>) -> Arc<Image> {
|
||||||
self.parent.clone().unwrap_or_else(|| self.clone())
|
self.parent
|
||||||
}
|
|
||||||
|
|
||||||
fn get_alloc(&self) -> Option<&vk_mem::Allocation> {
|
|
||||||
self.alloc
|
|
||||||
.as_ref()
|
.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>> {
|
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>> {
|
unsafe fn get_alias_inner(self: Arc<Self>, desc: ImageDesc) -> VkResult<Arc<Image>> {
|
||||||
use std::collections::hash_map::Entry::*;
|
use std::collections::hash_map::Entry::*;
|
||||||
match self.aliases.lock().entry(desc.clone()) {
|
match self.aliases.lock().entry(desc.clone()) {
|
||||||
|
@ -327,7 +330,8 @@ impl Image {
|
||||||
.mip_levels(mip_levels);
|
.mip_levels(mip_levels);
|
||||||
|
|
||||||
let alloc = self
|
let alloc = self
|
||||||
.get_alloc()
|
.alloc
|
||||||
|
.as_ref()
|
||||||
.expect("no alloc associated with image. is this the framebuffer?");
|
.expect("no alloc associated with image. is this the framebuffer?");
|
||||||
|
|
||||||
let image = unsafe {
|
let image = unsafe {
|
||||||
|
@ -342,7 +346,6 @@ impl Image {
|
||||||
image
|
image
|
||||||
};
|
};
|
||||||
|
|
||||||
let parent = self.parent.clone().unwrap_or(self.clone());
|
|
||||||
let alias = Self::construct(
|
let alias = Self::construct(
|
||||||
self.device().clone(),
|
self.device().clone(),
|
||||||
image,
|
image,
|
||||||
|
@ -352,8 +355,8 @@ impl Image {
|
||||||
format,
|
format,
|
||||||
Mutex::new(HashMap::new()),
|
Mutex::new(HashMap::new()),
|
||||||
Mutex::new(HashMap::new()),
|
Mutex::new(HashMap::new()),
|
||||||
Some(parent.clone()),
|
Some(Arc::downgrade(&self)),
|
||||||
parent.is_swapchain_image,
|
self.is_swapchain_image,
|
||||||
)?;
|
)?;
|
||||||
Ok(vacant.insert(Arc::new(alias)).clone())
|
Ok(vacant.insert(Arc::new(alias)).clone())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue