aliases stored along side views in-line
This commit is contained in:
		
							parent
							
								
									d66071f7bb
								
							
						
					
					
						commit
						32ce6e9140
					
				|  | @ -30,6 +30,45 @@ pub struct ImageDesc { | |||
|     pub alloc_flags: vk_mem::AllocationCreateFlags, | ||||
| } | ||||
| 
 | ||||
| impl std::hash::Hash for ImageDesc { | ||||
|     fn hash<H: std::hash::Hasher>(&self, state: &mut H) { | ||||
|         self.flags.hash(state); | ||||
|         self.name.hash(state); | ||||
|         self.format.hash(state); | ||||
|         self.kind.hash(state); | ||||
|         self.mip_levels.hash(state); | ||||
|         self.array_layers.hash(state); | ||||
|         self.samples.hash(state); | ||||
|         self.extent.hash(state); | ||||
|         self.tiling.hash(state); | ||||
|         self.usage.hash(state); | ||||
|         self.queue_families.hash(state); | ||||
|         self.layout.hash(state); | ||||
|         self.mem_usage.hash(state); | ||||
|         self.alloc_flags.bits().hash(state); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Eq for ImageDesc {} | ||||
| impl PartialEq for ImageDesc { | ||||
|     fn eq(&self, other: &Self) -> bool { | ||||
|         self.flags == other.flags | ||||
|             && self.name == other.name | ||||
|             && self.format == other.format | ||||
|             && self.kind == other.kind | ||||
|             && self.mip_levels == other.mip_levels | ||||
|             && self.array_layers == other.array_layers | ||||
|             && self.samples == other.samples | ||||
|             && self.extent == other.extent | ||||
|             && self.tiling == other.tiling | ||||
|             && self.usage == other.usage | ||||
|             && self.queue_families == other.queue_families | ||||
|             && self.layout == other.layout | ||||
|             && self.mem_usage == other.mem_usage | ||||
|             && self.alloc_flags.bits() == other.alloc_flags.bits() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'a> std::fmt::Debug for ImageDesc { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|         f.debug_struct("ImageDesc") | ||||
|  | @ -88,13 +127,18 @@ define_device_owned_handle! { | |||
|         size: vk::Extent3D, | ||||
|         format: vk::Format, | ||||
|         views: Mutex<HashMap<ImageViewDesc, vk::ImageView>>, | ||||
|         aliased: Option<Arc<Image>>, | ||||
|         aliases: Mutex<HashMap<ImageDesc, Arc<Image>>>, | ||||
|         parent: Option<Arc<Image>>, | ||||
|     } => |this|  unsafe { | ||||
|         for &view in this.views.lock().values() { | ||||
|             this.inner.dev().dev().destroy_image_view(view, None); | ||||
|         } | ||||
|         if this.aliased.is_none() { | ||||
|         if this.parent.is_none() { | ||||
|             // destroy image handle and allocation
 | ||||
|             this.inner.dev().alloc().destroy_image(this.handle(), this.alloc.as_mut().unwrap()); | ||||
|         } else { | ||||
|             // destroy image handle
 | ||||
|             this.inner.dev().dev().destroy_image(this.handle(), None); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -156,7 +200,8 @@ impl Image { | |||
|             extent, | ||||
|             format, | ||||
|             Mutex::new(HashMap::new()), | ||||
|             None, | ||||
|             Mutex::new(HashMap::new()), | ||||
|             None, // aliased
 | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|  | @ -185,79 +230,94 @@ impl Image { | |||
|         self.size.depth | ||||
|     } | ||||
| 
 | ||||
|     fn get_parent(self: Arc<Self>) -> Arc<Image> { | ||||
|         self.parent.clone().unwrap_or(self) | ||||
|     } | ||||
| 
 | ||||
|     fn get_alloc(&self) -> Option<&vk_mem::Allocation> { | ||||
|         self.alloc | ||||
|             .as_ref() | ||||
|             .or(self.aliased.as_ref().and_then(|image| image.get_alloc())) | ||||
|             .or(self.parent.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; | ||||
|     pub unsafe fn get_alias(self: Arc<Self>, desc: ImageDesc) -> VkResult<Arc<Self>> { | ||||
|         self.get_parent().get_alias_inner(desc) | ||||
|     } | ||||
| 
 | ||||
|         let queue_families = self | ||||
|             .device() | ||||
|             .queue_families() | ||||
|             .family_indices(queue_families); | ||||
|     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()) { | ||||
|             Occupied(occupied) => Ok(occupied.get().clone()), | ||||
|             Vacant(vacant) => { | ||||
|                 let ImageDesc { | ||||
|                     flags, | ||||
|                     name, | ||||
|                     format, | ||||
|                     kind, | ||||
|                     mip_levels, | ||||
|                     array_layers, | ||||
|                     samples, | ||||
|                     extent, | ||||
|                     tiling, | ||||
|                     usage, | ||||
|                     queue_families, | ||||
|                     layout, | ||||
|                     .. | ||||
|                 } = desc; | ||||
| 
 | ||||
|         let sharing_mode = if queue_families.len() > 1 { | ||||
|             vk::SharingMode::CONCURRENT | ||||
|         } else { | ||||
|             vk::SharingMode::EXCLUSIVE | ||||
|         }; | ||||
|                 let queue_families = self | ||||
|                     .device() | ||||
|                     .queue_families() | ||||
|                     .family_indices(queue_families); | ||||
| 
 | ||||
|         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 sharing_mode = if queue_families.len() > 1 { | ||||
|                     vk::SharingMode::CONCURRENT | ||||
|                 } else { | ||||
|                     vk::SharingMode::EXCLUSIVE | ||||
|                 }; | ||||
| 
 | ||||
|         let alloc = self.get_alloc().unwrap(); | ||||
|                 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 image = unsafe { | ||||
|             let image = self.device().dev().create_image(info, None)?; | ||||
|                 let alloc = self.get_alloc().unwrap(); | ||||
| 
 | ||||
|             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); | ||||
|                 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 | ||||
|                 }; | ||||
| 
 | ||||
|                 let alias = Self::construct( | ||||
|                     self.device().clone(), | ||||
|                     image, | ||||
|                     name, | ||||
|                     None, | ||||
|                     extent, | ||||
|                     format, | ||||
|                     Mutex::new(HashMap::new()), | ||||
|                     Mutex::new(HashMap::new()), | ||||
|                     Some(self.parent.clone().unwrap_or(self.clone())), | ||||
|                 )?; | ||||
|                 Ok(vacant.insert(Arc::new(alias)).clone()) | ||||
|             } | ||||
| 
 | ||||
|             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.
 | ||||
|  |  | |||
|  | @ -81,7 +81,7 @@ pub struct EguiPrePass { | |||
|         BTreeMap<egui::TextureId, (RenderGraphResourceId, texture::TextureId, ResourceAccess)>, | ||||
|     staging_image: Arc<Image>, | ||||
|     staging_buffer: Arc<Buffer>, | ||||
|     aliased_images: BTreeMap<egui::TextureId, (usize, usize, [usize; 2], Image)>, | ||||
|     aliased_images: BTreeMap<egui::TextureId, (usize, usize, [usize; 2], Arc<Image>)>, | ||||
|     tessellated: Vec<egui::ClippedPrimitive>, | ||||
|     texture_data: BTreeMap<egui::TextureId, egui::epaint::ImageDelta>, | ||||
| } | ||||
|  | @ -224,7 +224,7 @@ impl EguiPrePass { | |||
|                         unsafe { | ||||
|                             let alias = staging_image | ||||
|                                 .clone() | ||||
|                                 .alias(ImageDesc { | ||||
|                                 .get_alias(ImageDesc { | ||||
|                                     name: Some( | ||||
|                                         format!("egui-prepass-staging-aliased-{id:?}").into(), | ||||
|                                     ), | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue