-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ByteAddressableBuffer: allow reading from read-only buffer #17
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
: