vulkan: only use coherency functions for non-coherent memory
This commit is contained in:
parent
1f169a0d7b
commit
fe8238421f
2 changed files with 20 additions and 11 deletions
|
|
@ -4,7 +4,7 @@ use {
|
||||||
utils::{numcell::NumCell, ptr_ext::MutPtrExt},
|
utils::{numcell::NumCell, ptr_ext::MutPtrExt},
|
||||||
},
|
},
|
||||||
ash::vk::{DeviceMemory, DeviceSize, MemoryRequirements},
|
ash::vk::{DeviceMemory, DeviceSize, MemoryRequirements},
|
||||||
gpu_alloc::{Config, GpuAllocator, MemoryBlock, Request, UsageFlags},
|
gpu_alloc::{Config, GpuAllocator, MemoryBlock, MemoryPropertyFlags, Request, UsageFlags},
|
||||||
gpu_alloc_ash::AshMemoryDevice,
|
gpu_alloc_ash::AshMemoryDevice,
|
||||||
std::{
|
std::{
|
||||||
cell::{Cell, UnsafeCell},
|
cell::{Cell, UnsafeCell},
|
||||||
|
|
@ -25,6 +25,7 @@ pub struct VulkanAllocation {
|
||||||
pub(super) offset: DeviceSize,
|
pub(super) offset: DeviceSize,
|
||||||
pub(super) mem: Option<*mut u8>,
|
pub(super) mem: Option<*mut u8>,
|
||||||
pub(super) size: DeviceSize,
|
pub(super) size: DeviceSize,
|
||||||
|
pub(super) coherency_mask: Option<u64>,
|
||||||
block: Cell<Option<MemoryBlock<DeviceMemory>>>,
|
block: Cell<Option<MemoryBlock<DeviceMemory>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -111,6 +112,10 @@ impl VulkanAllocator {
|
||||||
offset: block.offset(),
|
offset: block.offset(),
|
||||||
mem: ptr,
|
mem: ptr,
|
||||||
size: block.size(),
|
size: block.size(),
|
||||||
|
coherency_mask: match block.props().contains(MemoryPropertyFlags::HOST_COHERENT) {
|
||||||
|
true => None,
|
||||||
|
false => Some(self.non_coherent_atom_mask),
|
||||||
|
},
|
||||||
block: Cell::new(Some(block)),
|
block: Cell::new(Some(block)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,27 +72,31 @@ impl VulkanStagingBuffer {
|
||||||
F: FnOnce(*mut u8, usize) -> T,
|
F: FnOnce(*mut u8, usize) -> T,
|
||||||
{
|
{
|
||||||
let t = f(self.allocation.mem.unwrap(), self.size as usize);
|
let t = f(self.allocation.mem.unwrap(), self.size as usize);
|
||||||
let range = self.range();
|
if let Some(mask) = self.allocation.coherency_mask {
|
||||||
let res = unsafe { self.device.device.flush_mapped_memory_ranges(&[range]) };
|
let range = self.incoherent_range(mask);
|
||||||
res.map_err(VulkanError::FlushMemory).map(|_| t)
|
let res = unsafe { self.device.device.flush_mapped_memory_ranges(&[range]) };
|
||||||
|
res.map_err(VulkanError::FlushMemory)?;
|
||||||
|
}
|
||||||
|
Ok(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn download<T, F>(&self, f: F) -> Result<T, VulkanError>
|
pub fn download<T, F>(&self, f: F) -> Result<T, VulkanError>
|
||||||
where
|
where
|
||||||
F: FnOnce(*const u8, usize) -> T,
|
F: FnOnce(*const u8, usize) -> T,
|
||||||
{
|
{
|
||||||
let range = self.range();
|
if let Some(mask) = self.allocation.coherency_mask {
|
||||||
let res = unsafe { self.device.device.invalidate_mapped_memory_ranges(&[range]) };
|
let range = self.incoherent_range(mask);
|
||||||
res.map_err(VulkanError::FlushMemory)?;
|
let res = unsafe { self.device.device.invalidate_mapped_memory_ranges(&[range]) };
|
||||||
|
res.map_err(VulkanError::FlushMemory)?;
|
||||||
|
}
|
||||||
Ok(f(self.allocation.mem.unwrap(), self.size as usize))
|
Ok(f(self.allocation.mem.unwrap(), self.size as usize))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn range(&self) -> MappedMemoryRange {
|
fn incoherent_range(&self, mask: u64) -> MappedMemoryRange {
|
||||||
let atom_mask = self.allocation.allocator.non_coherent_atom_mask;
|
|
||||||
MappedMemoryRange::default()
|
MappedMemoryRange::default()
|
||||||
.memory(self.allocation.memory)
|
.memory(self.allocation.memory)
|
||||||
.offset(self.allocation.offset & !atom_mask)
|
.offset(self.allocation.offset & !mask)
|
||||||
.size((self.allocation.size + atom_mask) & !atom_mask)
|
.size((self.allocation.size + mask) & !mask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue