-
Notifications
You must be signed in to change notification settings - Fork 54
ByteAddressableBuffer: allow reading from read-only buffer #17
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Conversation
330123c
to
f197b09
Compare
Does this have any effect on the shader side of things? It seems like a CPU-only change, as from my reading |
Not at all. |
Got it. So then I am interested in this for |
Just spit-balling here, but if we're going to break backwards compatibility, we could define the type as: pub struct ByteAddressableBuffer<T> {
inner: T
}
impl<'a> ByteAddressableBuffer<&'a [u32]> {
pub fn from_slice(s: &'a [u32]) -> Self {
Self{inner: s}
}
pub fn load<T>(&self, byte_index: u32) -> T {
todo!()
}
}
impl<'a> ByteAddressableBuffer<&'a mut [u32]> {
pub fn from_mut_slice(s: &'a mut [u32]) -> Self {
Self{inner: s}
}
pub fn store<T>(&mut self, byte_index: u32, t: T) {
todo!()
}
} That would cut out the new type and make fixing the callsites a bit easier, but it also makes discovering what |
f197b09
to
f78287a
Compare
I've actually thought about such a design already, but didn't knew how to express it properly in rust. Got stuck on trying to express it as |
@Firestar99 Yes, those functions would have to be defined in both pub struct ByteAddressableBuffer<T> {
inner: T,
}
impl<'a> ByteAddressableBuffer<&'a [u32]> {
pub fn from_slice(s: &'a [u32]) -> Self {
Self { inner: s }
}
pub fn load<T>(&self, byte_index: u32) -> T {
todo!()
}
}
impl<'a> ByteAddressableBuffer<&'a mut [u32]> {
pub fn from_mut_slice(s: &'a mut [u32]) -> Self {
Self { inner: s }
}
pub fn store<T>(&mut self, byte_index: u32, t: T) {
todo!()
}
/// Create a non-mutable `ByteAddressableBuffer` from this mutable one.
pub fn as_ref(&self) -> ByteAddressableBuffer<&[u32]> {
let buffer: ByteAddressableBuffer<&[u32]> = ByteAddressableBuffer { inner: self.inner };
buffer
}
pub fn load<T>(&self, byte_index: u32) -> T {
self.as_ref().load(byte_index)
}
}
#[cfg(test)]
mod test_buffer {
use super::*;
#[test]
fn buffer() {
let mut slab = [0u32; 36];
let mut buffer_mut = ByteAddressableBuffer::from_mut_slice(&mut slab);
buffer_mut.store(0, Some(123u64));
let _maybe_u64: Option<u64> = buffer_mut.load(0);
}
} It may be acceptable to add |
Added ❤️ |
ByteAddressableBuffer
currently has the major limitation of requiring a&mut [u32]
even if it's only used for reading data. This PR should serve as a place for discussion of how to resolve this issue.My currently proposed solution splits up
ByteAddressableBuffer
into the read-only variantByteAddressableBuffer
and the mutable variantMutByteAddressableBuffer
. This is obviously a breaking change and the names are up for discussion.I would also like to mention @eddyb's comment in EmbarkStudios/rust-gpu#1014 about adding
TypedBuffer
: