aboutsummaryrefslogtreecommitdiff
path: root/rendy-memory/src/mapping/write.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rendy-memory/src/mapping/write.rs')
-rw-r--r--rendy-memory/src/mapping/write.rs73
1 files changed, 73 insertions, 0 deletions
diff --git a/rendy-memory/src/mapping/write.rs b/rendy-memory/src/mapping/write.rs
new file mode 100644
index 0000000..d067a61
--- /dev/null
+++ b/rendy-memory/src/mapping/write.rs
@@ -0,0 +1,73 @@
+use std::ptr::copy_nonoverlapping;
+
+/// Trait for memory region suitable for host writes.
+pub trait Write<T: Copy> {
+ /// Get mutable slice of `T` bound to mapped range.
+ ///
+ /// # Safety
+ ///
+ /// * Returned slice should not be read.
+ unsafe fn slice(&mut self) -> &mut [T];
+
+ /// Write data into mapped memory sub-region.
+ ///
+ /// # Panic
+ ///
+ /// Panics if `data.len()` is greater than this sub-region len.
+ fn write(&mut self, data: &[T]) {
+ unsafe {
+ let slice = self.slice();
+ assert!(data.len() <= slice.len());
+ copy_nonoverlapping(data.as_ptr(), slice.as_mut_ptr(), data.len());
+ }
+ }
+}
+
+#[derive(Debug)]
+pub(super) struct WriteFlush<'a, T, F: FnOnce() + 'a> {
+ pub(super) slice: &'a mut [T],
+ pub(super) flush: Option<F>,
+}
+
+impl<'a, T, F> Drop for WriteFlush<'a, T, F>
+where
+ T: 'a,
+ F: FnOnce() + 'a,
+{
+ fn drop(&mut self) {
+ if let Some(f) = self.flush.take() {
+ f();
+ }
+ }
+}
+
+impl<'a, T, F> Write<T> for WriteFlush<'a, T, F>
+where
+ T: Copy + 'a,
+ F: FnOnce() + 'a,
+{
+ /// # Safety
+ ///
+ /// [See doc comment for trait method](trait.Write#method.slice)
+ unsafe fn slice(&mut self) -> &mut [T] {
+ self.slice
+ }
+}
+
+#[warn(dead_code)]
+#[derive(Debug)]
+pub(super) struct WriteCoherent<'a, T> {
+ pub(super) slice: &'a mut [T],
+}
+
+impl<'a, T> Write<T> for WriteCoherent<'a, T>
+where
+ T: Copy + 'a,
+{
+ /// # Safety
+ ///
+ /// [See doc comment for trait method](trait.Write#method.slice)
+ unsafe fn slice(&mut self) -> &mut [T] {
+ self.slice
+ }
+}