Skip to content

Commit dfdc21b

Browse files
Merge branch 'main' into bootcamp0b10
2 parents 7d8c453 + 07657e9 commit dfdc21b

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

gpu/src/metal/abstractions/state.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,21 @@ impl MetalState {
9595
/// Returns a vector of a copy of the data that `buffer` holds, interpreting it into a specific
9696
/// type `T`.
9797
///
98-
/// BEWARE: this function uses an unsafe function for retrieveing the data, if the buffer's
98+
/// SAFETY: this function uses an unsafe function for retrieveing the data, if the buffer's
9999
/// contents don't match the specified `T`, expect undefined behaviour. Always make sure the
100100
/// buffer you are retreiving from holds data of type `T`.
101101
pub fn retrieve_contents<T: Clone>(buffer: &Buffer) -> Vec<T> {
102102
let ptr = buffer.contents() as *const T;
103103
let len = buffer.length() as usize / mem::size_of::<T>();
104-
let slice = unsafe { std::slice::from_raw_parts(ptr, len) };
105-
106-
slice.to_vec()
104+
let mut contents = Vec::with_capacity(len);
105+
for i in 0..len {
106+
// 1. Read possibly unaligned data producing a bitwise copy
107+
let val = unsafe { ptr.add(i).read_unaligned() };
108+
// 2. Clone into the vector to avoid both `contents` and `buffer` dropping it
109+
contents.push(val.clone());
110+
// 3. Forget the bitwise copy to avoid both `val` and `buffer` dropping it
111+
core::mem::forget(val);
112+
}
113+
contents
107114
}
108115
}

0 commit comments

Comments
 (0)