mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-25 08:14:20 +00:00
Don't always map memory (#699)
This commit is contained in:
parent
beb1ddc200
commit
5e78de73e2
@ -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<T: ?Sized> CpuAccessibleBuffer<T> {
|
||||
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())?;
|
||||
|
@ -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<T, A> CpuBufferPool<T, A>
|
||||
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())?;
|
||||
|
@ -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<T: ?Sized> DeviceLocalBuffer<T> {
|
||||
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())?;
|
||||
|
||||
|
@ -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<T: ?Sized> ImmutableBuffer<T> {
|
||||
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())?;
|
||||
|
||||
|
@ -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<F> AttachmentImage<F> {
|
||||
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())?;
|
||||
|
@ -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<F> ImmutableImage<F> {
|
||||
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())?;
|
||||
|
@ -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<F> StorageImage<F> {
|
||||
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())?;
|
||||
|
@ -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<Device>, memory_type: MemoryType) -> Arc<StdHostVisibleMemoryTypePool> {
|
||||
@ -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(),
|
||||
|
@ -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<Self::Alloc, DeviceMemoryAllocError>;
|
||||
fn alloc(&self, ty: MemoryType, size: usize, alignment: usize, layout: AllocLayout,
|
||||
map: MappingRequirement) -> Result<Self::Alloc, DeviceMemoryAllocError>;
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
|
@ -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<Device>,
|
||||
|
||||
// For each memory type index, stores the associated pool.
|
||||
pools: Mutex<HashMap<(u32, AllocLayout), Pool, BuildHasherDefault<FnvHasher>>>,
|
||||
pools: Mutex<HashMap<(u32, AllocLayout, MappingRequirement), Pool, BuildHasherDefault<FnvHasher>>>,
|
||||
}
|
||||
|
||||
impl StdMemoryPool {
|
||||
@ -52,11 +53,14 @@ impl StdMemoryPool {
|
||||
unsafe impl MemoryPool for Arc<StdMemoryPool> {
|
||||
type Alloc = StdMemoryPoolAlloc;
|
||||
|
||||
fn alloc(&self, memory_type: MemoryType, size: usize, alignment: usize, layout: AllocLayout)
|
||||
-> Result<StdMemoryPoolAlloc, DeviceMemoryAllocError> {
|
||||
fn alloc(&self, memory_type: MemoryType, size: usize, alignment: usize, layout: AllocLayout,
|
||||
map: MappingRequirement) -> Result<StdMemoryPoolAlloc, DeviceMemoryAllocError> {
|
||||
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<StdMemoryPool> {
|
||||
},
|
||||
|
||||
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(),
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user