merge Texture and Image structs, add image aliasing
This commit is contained in:
parent
e76055860d
commit
0627556051
|
@ -1,13 +1,14 @@
|
|||
use std::borrow::Cow;
|
||||
use std::{borrow::Cow, collections::HashMap, sync::Arc};
|
||||
|
||||
use crate::{
|
||||
define_device_owned_handle,
|
||||
device::{DeviceOwned, QueueFlags},
|
||||
device::{self, DeviceOwned, QueueFlags},
|
||||
};
|
||||
|
||||
use super::Device;
|
||||
use ash::{prelude::*, vk};
|
||||
use itertools::Itertools;
|
||||
use parking_lot::Mutex;
|
||||
use vk_mem::Alloc;
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -83,11 +84,18 @@ impl Default for ImageDesc {
|
|||
define_device_owned_handle! {
|
||||
#[derive(Debug)]
|
||||
pub Image(vk::Image) {
|
||||
alloc: vk_mem::Allocation,
|
||||
alloc: Option<vk_mem::Allocation>,
|
||||
size: vk::Extent3D,
|
||||
format: vk::Format,
|
||||
views: Mutex<HashMap<ImageViewDesc, vk::ImageView>>,
|
||||
aliased: Option<Arc<Image>>,
|
||||
} => |this| unsafe {
|
||||
this.inner.dev().alloc().destroy_image(this.handle(), &mut this.alloc);
|
||||
for &view in this.views.lock().values() {
|
||||
this.inner.dev().dev().destroy_image_view(view, None);
|
||||
}
|
||||
if this.aliased.is_none() {
|
||||
this.inner.dev().alloc().destroy_image(this.handle(), this.alloc.as_mut().unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,7 +148,16 @@ impl Image {
|
|||
|
||||
let (handle, alloc) = unsafe { device.alloc().create_image(info, alloc_info)? };
|
||||
|
||||
Self::construct(device, handle, name, alloc, extent, format)
|
||||
Self::construct(
|
||||
device,
|
||||
handle,
|
||||
name,
|
||||
Some(alloc),
|
||||
extent,
|
||||
format,
|
||||
Mutex::new(HashMap::new()),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn format(&self) -> vk::Format {
|
||||
|
@ -168,7 +185,110 @@ impl Image {
|
|||
self.size.depth
|
||||
}
|
||||
|
||||
pub fn view(&self, desc: ImageViewDesc) -> VkResult<ImageView> {
|
||||
fn get_alloc(&self) -> Option<&vk_mem::Allocation> {
|
||||
self.alloc
|
||||
.as_ref()
|
||||
.or(self.aliased.as_ref().and_then(|image| image.get_alloc()))
|
||||
}
|
||||
|
||||
pub unsafe fn alias(self: Arc<Self>, desc: ImageDesc) -> VkResult<Image> {
|
||||
let ImageDesc {
|
||||
flags,
|
||||
name,
|
||||
format,
|
||||
kind,
|
||||
mip_levels,
|
||||
array_layers,
|
||||
samples,
|
||||
extent,
|
||||
tiling,
|
||||
usage,
|
||||
queue_families,
|
||||
layout,
|
||||
mem_usage,
|
||||
alloc_flags,
|
||||
} = desc;
|
||||
|
||||
let queue_families = self
|
||||
.device()
|
||||
.queue_families()
|
||||
.family_indices(queue_families);
|
||||
|
||||
let sharing_mode = if queue_families.len() > 1 {
|
||||
vk::SharingMode::CONCURRENT
|
||||
} else {
|
||||
vk::SharingMode::EXCLUSIVE
|
||||
};
|
||||
|
||||
let info = &vk::ImageCreateInfo::default()
|
||||
.flags(flags)
|
||||
.image_type(kind)
|
||||
.format(format)
|
||||
.extent(extent)
|
||||
.samples(samples)
|
||||
.initial_layout(layout)
|
||||
.tiling(tiling)
|
||||
.usage(usage)
|
||||
.sharing_mode(sharing_mode)
|
||||
.queue_family_indices(&queue_families)
|
||||
.array_layers(array_layers)
|
||||
.mip_levels(mip_levels);
|
||||
|
||||
let alloc = self.get_alloc().unwrap();
|
||||
|
||||
let image = unsafe {
|
||||
let image = self.device().dev().create_image(info, None)?;
|
||||
|
||||
let req = self.device().dev().get_image_memory_requirements(image);
|
||||
if self.device().alloc().get_allocation_info(alloc).size < req.size {
|
||||
return Err(vk::Result::ERROR_MEMORY_MAP_FAILED);
|
||||
}
|
||||
|
||||
self.device().alloc().bind_image_memory(alloc, image)?;
|
||||
image
|
||||
};
|
||||
|
||||
Self::construct(
|
||||
self.device().clone(),
|
||||
image,
|
||||
name,
|
||||
None,
|
||||
extent,
|
||||
format,
|
||||
Mutex::new(HashMap::new()),
|
||||
Some(self.aliased.clone().unwrap_or(self)),
|
||||
)
|
||||
}
|
||||
|
||||
/// technically, this ImageView belongs to the image and is managed by it.
|
||||
pub fn get_view(&self, desc: ImageViewDesc) -> VkResult<vk::ImageView> {
|
||||
use std::collections::hash_map::Entry::*;
|
||||
match self.views.lock().entry(desc.hash_eq_copy()) {
|
||||
Occupied(occupied) => Ok(*occupied.get()),
|
||||
Vacant(vacant) => {
|
||||
let view = unsafe {
|
||||
let create_info = vk::ImageViewCreateInfo::default()
|
||||
.flags(desc.flags)
|
||||
.image(self.image())
|
||||
.view_type(vk::ImageViewType::TYPE_2D)
|
||||
.format(desc.format)
|
||||
.components(desc.components)
|
||||
.subresource_range(
|
||||
vk::ImageSubresourceRange::default()
|
||||
.aspect_mask(desc.aspect)
|
||||
.base_mip_level(desc.mip_range.0)
|
||||
.level_count(desc.mip_range.count())
|
||||
.base_array_layer(desc.layer_range.0)
|
||||
.layer_count(desc.layer_range.count()),
|
||||
);
|
||||
self.device().dev().create_image_view(&create_info, None)?
|
||||
};
|
||||
Ok(*vacant.insert(view))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_view(&self, desc: ImageViewDesc) -> VkResult<ImageView> {
|
||||
let create_info = vk::ImageViewCreateInfo::default()
|
||||
.flags(desc.flags)
|
||||
.image(self.image())
|
||||
|
@ -202,6 +322,32 @@ pub struct ImageViewDesc {
|
|||
pub layer_range: MipRange,
|
||||
}
|
||||
|
||||
impl ImageViewDesc {
|
||||
pub fn hash_eq_copy(&self) -> Self {
|
||||
let &Self {
|
||||
flags,
|
||||
kind,
|
||||
format,
|
||||
components,
|
||||
aspect,
|
||||
mip_range,
|
||||
layer_range,
|
||||
..
|
||||
} = self;
|
||||
|
||||
Self {
|
||||
flags,
|
||||
name: None,
|
||||
kind,
|
||||
format,
|
||||
components,
|
||||
aspect,
|
||||
mip_range,
|
||||
layer_range,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct MipRange(u32, u32);
|
||||
|
||||
|
|
|
@ -47,51 +47,14 @@ mod util;
|
|||
use device::{Device, DeviceOwned, DeviceQueueFamilies};
|
||||
|
||||
mod texture {
|
||||
use std::{
|
||||
collections::{hash_map::Entry, BTreeMap, HashMap},
|
||||
sync::Arc,
|
||||
};
|
||||
use std::{collections::BTreeMap, sync::Arc};
|
||||
|
||||
use ash::prelude::VkResult;
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use crate::{
|
||||
def_monotonic_id,
|
||||
images::{Image, ImageView},
|
||||
Device,
|
||||
};
|
||||
use crate::{def_monotonic_id, images::Image, Device};
|
||||
|
||||
def_monotonic_id!(pub TextureId);
|
||||
|
||||
pub struct Texture {
|
||||
id: TextureId,
|
||||
image: Arc<Image>,
|
||||
views: Mutex<HashMap<crate::images::ImageViewDesc, Arc<ImageView>>>,
|
||||
}
|
||||
|
||||
impl Texture {
|
||||
pub fn id(&self) -> TextureId {
|
||||
self.id
|
||||
}
|
||||
pub fn image(&self) -> Arc<Image> {
|
||||
self.image.clone()
|
||||
}
|
||||
pub fn view(&self, desc: crate::images::ImageViewDesc) -> VkResult<Arc<ImageView>> {
|
||||
let mut views = self.views.lock();
|
||||
let view = match views.entry(desc) {
|
||||
Entry::Occupied(entry) => entry.get().clone(),
|
||||
Entry::Vacant(entry) => {
|
||||
let view = Arc::new(self.image.view(entry.key().clone())?);
|
||||
entry.insert(view).clone()
|
||||
}
|
||||
};
|
||||
|
||||
Ok(view)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TextureManager {
|
||||
pub textures: BTreeMap<TextureId, Arc<Texture>>,
|
||||
pub textures: BTreeMap<TextureId, Arc<Image>>,
|
||||
#[allow(unused)]
|
||||
dev: Device,
|
||||
}
|
||||
|
@ -104,22 +67,20 @@ mod texture {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn insert_image(&mut self, image: Arc<Image>) -> TextureId {
|
||||
let id = TextureId::new();
|
||||
self.textures.insert(id, image);
|
||||
id
|
||||
}
|
||||
pub fn insert_image_with_id(&mut self, id: TextureId, image: Arc<Image>) {
|
||||
self.textures.insert(
|
||||
id,
|
||||
Arc::new(Texture {
|
||||
id,
|
||||
image,
|
||||
views: Mutex::new(HashMap::new()),
|
||||
}),
|
||||
);
|
||||
self.textures.insert(id, image);
|
||||
}
|
||||
|
||||
pub fn remove_texture(&mut self, id: TextureId) -> Option<Arc<Texture>> {
|
||||
pub fn remove_texture(&mut self, id: TextureId) -> Option<Arc<Image>> {
|
||||
self.textures.remove(&id)
|
||||
}
|
||||
|
||||
pub fn get_texture(&self, id: TextureId) -> Option<Arc<Texture>> {
|
||||
pub fn get_texture(&self, id: TextureId) -> Option<Arc<Image>> {
|
||||
self.textures.get(&id).cloned()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue