Commit f8e6bc3e5529
tarball2 files changed+45-0
@@ -116,6 +116,7 @@ pub(super) fn stage_rows<'a>(
116116
for i in 0..h {117117
dst[i * line..(i + 1) * line].copy_from_slice(row(region.loc.y as usize + i));118118
}119
+ staging.flush()?;119120
Ok(staging)120121
}121122
@@ -25,13 +25,23 @@ struct Pooled {
2525
pub(crate) struct StagingPool {2626
shared: Arc<Shared>,2727
free: Mutex<Vec<Pooled>>,28
+ /// Granularity of flushes and invalidations of non-coherent memory.29
+ atom: u64,2830
}2931
3032
impl StagingPool {3133
pub fn new(shared: &Arc<Shared>) -> Arc<Self> {34
+ let limits = unsafe {35
+ shared36
+ .device37
+ .instance38
+ .get_physical_device_properties(shared.device.physical)39
+ }40
+ .limits;3241
Arc::new(Self {3342
shared: shared.clone(),3443
free: Mutex::new(Vec::new()),44
+ atom: limits.non_coherent_atom_size.max(1),3545
})3646
}3747
@@ -149,13 +159,47 @@ impl Staging {
149159
})150160
}151161
162
+ /// The mapped bytes, with whatever the GPU wrote to them made visible.152163
pub fn bytes(&self) -> Result<&[u8], Error> {164
+ self.host_sync(false)?;153165
self.allocation154166
.as_ref()155167
.and_then(|a| a.mapped_slice())156168
.ok_or(Error::StagingUnmapped)157169
}158170
171
+ /// Makes what the host wrote through `bytes_mut` visible to the GPU.172
+ pub fn flush(&self) -> Result<(), Error> {173
+ self.host_sync(true)174
+ }175
+176
+ /// Flushes or invalidates the mapping. Coherent memory needs neither.177
+ fn host_sync(&self, flush: bool) -> Result<(), Error> {178
+ let Some(allocation) = self.allocation.as_ref() else {179
+ return Ok(());180
+ };181
+ if allocation182
+ .memory_properties()183
+ .contains(vk::MemoryPropertyFlags::HOST_COHERENT)184
+ {185
+ return Ok(());186
+ }187
+ let atom = self.pool.atom;188
+ let range = [vk::MappedMemoryRange::default()189
+ .memory(unsafe { allocation.memory() })190
+ .offset(allocation.offset() / atom * atom)191
+ .size(vk::WHOLE_SIZE)];192
+ let d = &self.pool.shared.device.device;193
+ unsafe {194
+ if flush {195
+ d.flush_mapped_memory_ranges(&range)?;196
+ } else {197
+ d.invalidate_mapped_memory_ranges(&range)?;198
+ }199
+ }200
+ Ok(())201
+ }202
+159203
pub fn bytes_mut(&mut self) -> Result<&mut [u8], Error> {160204
self.allocation161205
.as_mut()