From 5e78de73e213d8c3dc6e4313f732bfe050fbbd68 Mon Sep 17 00:00:00 2001 From: tomaka Date: Sun, 30 Jul 2017 09:03:24 +0200 Subject: [PATCH] Don't always map memory (#699) --- vulkano/src/buffer/cpu_access.rs | 4 +- vulkano/src/buffer/cpu_pool.rs | 4 +- vulkano/src/buffer/device_local.rs | 4 +- vulkano/src/buffer/immutable.rs | 4 +- vulkano/src/image/attachment.rs | 4 +- vulkano/src/image/immutable.rs | 4 +- vulkano/src/image/storage.rs | 4 +- vulkano/src/memory/pool/host_visible.rs | 2 + vulkano/src/memory/pool/mod.rs | 14 ++++++- vulkano/src/memory/pool/pool.rs | 55 +++++++++++++------------ 10 files changed, 63 insertions(+), 36 deletions(-) diff --git a/vulkano/src/buffer/cpu_access.rs b/vulkano/src/buffer/cpu_access.rs index a6d1e0b6..0d35753c 100644 --- a/vulkano/src/buffer/cpu_access.rs +++ b/vulkano/src/buffer/cpu_access.rs @@ -46,6 +46,7 @@ use memory::Content; use memory::CpuAccess as MemCpuAccess; use memory::DeviceMemoryAllocError; use memory::pool::AllocLayout; +use memory::pool::MappingRequirement; use memory::pool::MemoryPool; use memory::pool::MemoryPoolAlloc; use memory::pool::StdMemoryPoolAlloc; @@ -226,7 +227,8 @@ impl CpuAccessibleBuffer { mem_ty, mem_reqs.size, mem_reqs.alignment, - AllocLayout::Linear)?; + AllocLayout::Linear, + MappingRequirement::Map)?; debug_assert!((mem.offset() % mem_reqs.alignment) == 0); debug_assert!(mem.mapped_memory().is_some()); buffer.bind_memory(mem.memory(), mem.offset())?; diff --git a/vulkano/src/buffer/cpu_pool.rs b/vulkano/src/buffer/cpu_pool.rs index fbc4b2be..116c726e 100644 --- a/vulkano/src/buffer/cpu_pool.rs +++ b/vulkano/src/buffer/cpu_pool.rs @@ -34,6 +34,7 @@ use device::DeviceOwned; use device::Queue; use instance::QueueFamily; use memory::pool::AllocLayout; +use memory::pool::MappingRequirement; use memory::pool::MemoryPool; use memory::pool::MemoryPoolAlloc; use memory::pool::StdMemoryPool; @@ -352,7 +353,8 @@ impl CpuBufferPool mem_ty, mem_reqs.size, mem_reqs.alignment, - AllocLayout::Linear)?; + AllocLayout::Linear, + MappingRequirement::Map)?; debug_assert!((mem.offset() % mem_reqs.alignment) == 0); debug_assert!(mem.mapped_memory().is_some()); buffer.bind_memory(mem.memory(), mem.offset())?; diff --git a/vulkano/src/buffer/device_local.rs b/vulkano/src/buffer/device_local.rs index d9bd33df..50ab4e1d 100644 --- a/vulkano/src/buffer/device_local.rs +++ b/vulkano/src/buffer/device_local.rs @@ -31,6 +31,7 @@ use device::DeviceOwned; use device::Queue; use instance::QueueFamily; use memory::pool::AllocLayout; +use memory::pool::MappingRequirement; use memory::pool::MemoryPool; use memory::pool::MemoryPoolAlloc; use memory::pool::StdMemoryPoolAlloc; @@ -144,7 +145,8 @@ impl DeviceLocalBuffer { mem_ty, mem_reqs.size, mem_reqs.alignment, - AllocLayout::Linear)?; + AllocLayout::Linear, + MappingRequirement::DoNotMap)?; debug_assert!((mem.offset() % mem_reqs.alignment) == 0); buffer.bind_memory(mem.memory(), mem.offset())?; diff --git a/vulkano/src/buffer/immutable.rs b/vulkano/src/buffer/immutable.rs index ee249456..e249100d 100644 --- a/vulkano/src/buffer/immutable.rs +++ b/vulkano/src/buffer/immutable.rs @@ -43,6 +43,7 @@ use device::DeviceOwned; use device::Queue; use instance::QueueFamily; use memory::pool::AllocLayout; +use memory::pool::MappingRequirement; use memory::pool::MemoryPool; use memory::pool::MemoryPoolAlloc; use memory::pool::StdMemoryPoolAlloc; @@ -268,7 +269,8 @@ impl ImmutableBuffer { mem_ty, mem_reqs.size, mem_reqs.alignment, - AllocLayout::Linear)?; + AllocLayout::Linear, + MappingRequirement::DoNotMap)?; debug_assert!((mem.offset() % mem_reqs.alignment) == 0); buffer.bind_memory(mem.memory(), mem.offset())?; diff --git a/vulkano/src/image/attachment.rs b/vulkano/src/image/attachment.rs index 1ef0e6c7..51bde6ee 100644 --- a/vulkano/src/image/attachment.rs +++ b/vulkano/src/image/attachment.rs @@ -32,6 +32,7 @@ use image::traits::ImageClearValue; use image::traits::ImageContent; use image::traits::ImageViewAccess; use memory::pool::AllocLayout; +use memory::pool::MappingRequirement; use memory::pool::MemoryPool; use memory::pool::MemoryPoolAlloc; use memory::pool::StdMemoryPoolAlloc; @@ -228,7 +229,8 @@ impl AttachmentImage { mem_ty, mem_reqs.size, mem_reqs.alignment, - AllocLayout::Optimal)?; + AllocLayout::Optimal, + MappingRequirement::DoNotMap)?; debug_assert!((mem.offset() % mem_reqs.alignment) == 0); unsafe { image.bind_memory(mem.memory(), mem.offset())?; diff --git a/vulkano/src/image/immutable.rs b/vulkano/src/image/immutable.rs index 7f4b4494..62da1615 100644 --- a/vulkano/src/image/immutable.rs +++ b/vulkano/src/image/immutable.rs @@ -39,6 +39,7 @@ use image::traits::ImageContent; use image::traits::ImageViewAccess; use instance::QueueFamily; use memory::pool::AllocLayout; +use memory::pool::MappingRequirement; use memory::pool::MemoryPool; use memory::pool::MemoryPoolAlloc; use memory::pool::StdMemoryPoolAlloc; @@ -153,7 +154,8 @@ impl ImmutableImage { mem_ty, mem_reqs.size, mem_reqs.alignment, - AllocLayout::Optimal)?; + AllocLayout::Optimal, + MappingRequirement::DoNotMap)?; debug_assert!((mem.offset() % mem_reqs.alignment) == 0); unsafe { image.bind_memory(mem.memory(), mem.offset())?; diff --git a/vulkano/src/image/storage.rs b/vulkano/src/image/storage.rs index 65bdf56e..d1bf2ee5 100644 --- a/vulkano/src/image/storage.rs +++ b/vulkano/src/image/storage.rs @@ -31,6 +31,7 @@ use image::traits::ImageContent; use image::traits::ImageViewAccess; use instance::QueueFamily; use memory::pool::AllocLayout; +use memory::pool::MappingRequirement; use memory::pool::MemoryPool; use memory::pool::MemoryPoolAlloc; use memory::pool::StdMemoryPool; @@ -131,7 +132,8 @@ impl StorageImage { mem_ty, mem_reqs.size, mem_reqs.alignment, - AllocLayout::Optimal)?; + AllocLayout::Optimal, + MappingRequirement::DoNotMap)?; debug_assert!((mem.offset() % mem_reqs.alignment) == 0); unsafe { image.bind_memory(mem.memory(), mem.offset())?; diff --git a/vulkano/src/memory/pool/host_visible.rs b/vulkano/src/memory/pool/host_visible.rs index 5c07b221..1b580b6a 100644 --- a/vulkano/src/memory/pool/host_visible.rs +++ b/vulkano/src/memory/pool/host_visible.rs @@ -34,6 +34,7 @@ impl StdHostVisibleMemoryTypePool { /// # Panic /// /// - Panics if the `device` and `memory_type` don't belong to the same physical device. + /// - Panics if the memory type is not host-visible. /// #[inline] pub fn new(device: Arc, memory_type: MemoryType) -> Arc { @@ -41,6 +42,7 @@ impl StdHostVisibleMemoryTypePool { &**memory_type.physical_device().instance() as *const Instance); assert_eq!(device.physical_device().index(), memory_type.physical_device().index()); + assert!(memory_type.is_host_visible()); Arc::new(StdHostVisibleMemoryTypePool { device: device.clone(), diff --git a/vulkano/src/memory/pool/mod.rs b/vulkano/src/memory/pool/mod.rs index 8c8a71f0..c73628ac 100644 --- a/vulkano/src/memory/pool/mod.rs +++ b/vulkano/src/memory/pool/mod.rs @@ -40,11 +40,12 @@ pub unsafe trait MemoryPool { /// /// - Panics if `memory_type` doesn't belong to the same physical device as the device which /// was used to create this pool. + /// - Panics if the memory type is not host-visible and `map` is `MappingRequirement::Map`. /// - Panics if `size` is 0. /// - Panics if `alignment` is 0. /// - fn alloc(&self, ty: MemoryType, size: usize, alignment: usize, layout: AllocLayout) - -> Result; + fn alloc(&self, ty: MemoryType, size: usize, alignment: usize, layout: AllocLayout, + map: MappingRequirement) -> Result; } /// Object that represents a single allocation. Its destructor should free the chunk. @@ -61,6 +62,15 @@ pub unsafe trait MemoryPoolAlloc { fn offset(&self) -> usize; } +/// Whether an allocation should map the memory or not. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum MappingRequirement { + /// Should map. + Map, + /// Shouldn't map. + DoNotMap, +} + /// Layout of the object being allocated. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum AllocLayout { diff --git a/vulkano/src/memory/pool/pool.rs b/vulkano/src/memory/pool/pool.rs index cadbd227..e1aa6971 100644 --- a/vulkano/src/memory/pool/pool.rs +++ b/vulkano/src/memory/pool/pool.rs @@ -20,6 +20,7 @@ use memory::DeviceMemory; use memory::MappedDeviceMemory; use memory::DeviceMemoryAllocError; use memory::pool::AllocLayout; +use memory::pool::MappingRequirement; use memory::pool::MemoryPool; use memory::pool::MemoryPoolAlloc; use memory::pool::StdHostVisibleMemoryTypePool; @@ -32,7 +33,7 @@ pub struct StdMemoryPool { device: Arc, // For each memory type index, stores the associated pool. - pools: Mutex>>, + pools: Mutex>>, } impl StdMemoryPool { @@ -52,11 +53,14 @@ impl StdMemoryPool { unsafe impl MemoryPool for Arc { type Alloc = StdMemoryPoolAlloc; - fn alloc(&self, memory_type: MemoryType, size: usize, alignment: usize, layout: AllocLayout) - -> Result { + fn alloc(&self, memory_type: MemoryType, size: usize, alignment: usize, layout: AllocLayout, + map: MappingRequirement) -> Result { let mut pools = self.pools.lock().unwrap(); - match pools.entry((memory_type.id(), layout)) { + let memory_type_host_visible = memory_type.is_host_visible(); + assert!(memory_type_host_visible || map == MappingRequirement::DoNotMap); + + match pools.entry((memory_type.id(), layout, map)) { Entry::Occupied(entry) => { match entry.get() { &Pool::HostVisible(ref pool) => { @@ -79,29 +83,26 @@ unsafe impl MemoryPool for Arc { }, Entry::Vacant(entry) => { - match memory_type.is_host_visible() { - true => { - let pool = StdHostVisibleMemoryTypePool::new(self.device.clone(), - memory_type); - entry.insert(Pool::HostVisible(pool.clone())); - let alloc = StdHostVisibleMemoryTypePool::alloc(&pool, size, alignment)?; - let inner = StdMemoryPoolAllocInner::HostVisible(alloc); - Ok(StdMemoryPoolAlloc { - inner: inner, - pool: self.clone(), - }) - }, - false => { - let pool = StdNonHostVisibleMemoryTypePool::new(self.device.clone(), - memory_type); - entry.insert(Pool::NonHostVisible(pool.clone())); - let alloc = StdNonHostVisibleMemoryTypePool::alloc(&pool, size, alignment)?; - let inner = StdMemoryPoolAllocInner::NonHostVisible(alloc); - Ok(StdMemoryPoolAlloc { - inner: inner, - pool: self.clone(), - }) - }, + if memory_type_host_visible { + let pool = StdHostVisibleMemoryTypePool::new(self.device.clone(), + memory_type); + entry.insert(Pool::HostVisible(pool.clone())); + let alloc = StdHostVisibleMemoryTypePool::alloc(&pool, size, alignment)?; + let inner = StdMemoryPoolAllocInner::HostVisible(alloc); + Ok(StdMemoryPoolAlloc { + inner: inner, + pool: self.clone(), + }) + } else { + let pool = StdNonHostVisibleMemoryTypePool::new(self.device.clone(), + memory_type); + entry.insert(Pool::NonHostVisible(pool.clone())); + let alloc = StdNonHostVisibleMemoryTypePool::alloc(&pool, size, alignment)?; + let inner = StdMemoryPoolAllocInner::NonHostVisible(alloc); + Ok(StdMemoryPoolAlloc { + inner: inner, + pool: self.clone(), + }) } }, }