Skip to main content

WriteOnly

Struct WriteOnly 

Source
pub struct WriteOnly<'a, T: ?Sized> { /* private fields */ }
Expand description

Like &'a mut T, but allows only write operations.

This pointer type is obtained from BufferViewMut and QueueWriteBufferView. It is an unfortunate necessity due to the fact that mapped GPU memory may be write combining, which means it cannot work normally with all of the things that Rust &mut access allows you to do.

(WriteOnly can also be used as an interface to write to uninitialized memory, but this is not a feature which wgpu currently offers for GPU buffers.)

The methods of WriteOnly<[T]> are similar to those available for slice references, &mut [T], with some changes to ownership intended to minimize the pain of explicit reborrowing.

Implementations§

Source§

impl<'a, T: ?Sized> WriteOnly<'a, T>

Source

pub unsafe fn new(ptr: NonNull<T>) -> Self

Constructs a WriteOnly pointer from a raw pointer.

§Safety

By calling WriteOnly::new(), you are giving safe code the opportunity to write to this memory if it is given the resulting WriteOnly. Therefore:

  • ptr must be valid for ordinary, non-volatile, writes. (It need not be valid for reads, including reads that occur as part of atomic operations — that’s the whole point.)
  • ptr must be aligned to at least the alignment of the type T.
  • No other accesses to the memory pointed to by ptr may be performed until the lifetime 'a ends. (Similar to the conditions to construct &'a mut T.)

The memory pointed to need not contain a valid T, but if it does, it still will after the WriteOnly pointer is used; that is, safe (or sound unsafe) use of WriteOnly will not “de-initialize” the memory.

Source

pub fn from_mut(reference: &mut T) -> Self

Constructs a WriteOnly pointer from an ordinary read-write &mut reference.

This may be used to write code which can write either to a mapped GPU buffer or normal memory.

§Example
fn write_numbers(slice: wgpu::WriteOnly<[u32]>) {
    for (i, mut elem) in slice.into_iter().enumerate() {
        elem.write(i as u32);
    }
}

let mut buf: [u32; 4] = [0; 4];
write_numbers(wgpu::WriteOnly::from_mut(&mut buf));
assert_eq!(buf, [0, 1, 2, 3]);
Source

pub fn write(self, value: T)
where T: Copy,

Writes value into the memory pointed to by self.

This can only be used when T is a Sized type. For slices, use copy_from_slice() or write_iter() instead.

Source

pub fn as_raw_ptr(&mut self) -> NonNull<T>

Returns a raw pointer to the memory this WriteOnly refers to.

This operation may be used to manually perform writes in situations where the safe API of WriteOnly is not sufficient, e.g. for random access from multiple threads.

You must take care when using this pointer:

  • The WriteOnly type makes no guarantee that the memory pointed to by this pointer is readable or initialized. Therefore, it must not be converted to &mut T, nor read any other way.
  • You may not write an invalid value unless you also overwrite it with a valid value later. That is, you may not make the memory less initialized than it already was.

See also as_raw_element_ptr(), which returns a pointer to the first element of a slice.

Source§

impl<'a, T> WriteOnly<'a, [T]>

Methods for write-only references to slices.

Source

pub const fn len(&self) -> usize

Returns the length of the referenced slice; the number of elements that may be written.

§Example
let example_slice: &mut [u8] = &mut [0; 10];
assert_eq!(wgpu::WriteOnly::from_mut(example_slice).len(), example_slice.len());
Source

pub const fn is_empty(&self) -> bool

Returns true if the referenced slice has a length of 0.

Source

pub fn slice<'b, S: RangeBounds<usize>>( &'b mut self, bounds: S, ) -> WriteOnly<'b, [T]>

Returns another slice reference borrowing from this one, covering a sub-range and with a shorter lifetime.

You can also use .slice(..) to perform an explicit reborrow without shrinking.

See also into_slice() when the same lifetime is needed.

§Example
// Ordinarily you would get a `WriteOnly` from `wgpu::Buffer` instead.
let mut data: [u8; 9] = [0; 9];
let mut wo = wgpu::WriteOnly::from_mut(data.as_mut_slice());

wo.slice(..3).copy_from_slice(&[1, 2, 3]);
wo.slice(3..6).copy_from_slice(&[4, 5, 6]);
wo.slice(6..).copy_from_slice(&[7, 8, 9]);

assert_eq!(data, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
Source

pub fn into_slice<S: RangeBounds<usize>>(self, bounds: S) -> Self

Shrinks this slice reference in the same way as slice(), but consumes self and returns a slice reference with the same lifetime, instead of a shorter lifetime.

Source

pub fn write_iter<I>(self, iter: I)
where T: Copy, I: IntoIterator<Item = T>,

Writes the items of iter into self.

The iterator must produce exactly self.len() items.

If the items are in a slice, use copy_from_slice() instead.

§Panics

Panics if iter produces more or fewer items than self.len().

§Example
// Ordinarily you would get a `WriteOnly` from `wgpu::Buffer` instead.
let mut buf: [u8; 10] = [0; 10];
let wo = wgpu::WriteOnly::from_mut(buf.as_mut_slice());

wo.write_iter((1..).take(10));

assert_eq!(buf, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
Source

pub fn fill(&mut self, value: T)
where T: Copy + 'static,

Writes copies of value to every element of self.

§Example
// Ordinarily you would get a `WriteOnly` from `wgpu::Buffer` instead.
let mut buf = vec![0; 10];
let mut wo = wgpu::WriteOnly::from_mut(buf.as_mut_slice());

wo.fill(1);

assert_eq!(buf, [1; 10]);
Source

pub fn copy_from_slice(&mut self, src: &[T])
where T: Copy,

Copies all elements from src into self.

§Panics

Panics if the length of src is not the same as self.

§Example
// Ordinarily you would get a `WriteOnly` from `wgpu::Buffer` instead.
let mut buf = vec![0; 5];
let mut wo = wgpu::WriteOnly::from_mut(buf.as_mut_slice());

wo.copy_from_slice(&[2, 3, 5, 7, 11]);

assert_eq!(*buf, [2, 3, 5, 7, 11]);
Source

pub fn into_chunks<const N: usize>( self, ) -> (WriteOnly<'a, [[T; N]]>, WriteOnly<'a, [T]>)

Splits this slice reference into N-element arrays, starting at the beginning of the slice, and a reference to the remainder with length strictly less than N.

This method is analogous to <[T]>::as_chunks_mut() but for WriteOnly<[T]> access. (It takes ownership instead of &mut self in order to avoid reborrowing issues. Use .slice(..) first if reborrowing is needed.)

§Panics

Panics if N is zero.

§Example

into_chunks() is useful for writing a sequence of elements from CPU memory to GPU memory when a transformation is required. (If a transformation is not required, use WriteOnly::copy_from_slice().)

fn write_text_as_chars(text: &str, output: wgpu::WriteOnly<[u8]>) {
    let (mut output, _remainder) = output.into_chunks::<{ size_of::<u32>() }>();
    output.write_iter(text.chars().map(|ch| (ch as u32).to_ne_bytes()));
}
Source

pub fn split_at(self, mid: usize) -> (WriteOnly<'a, [T]>, WriteOnly<'a, [T]>)

Divides one write-only slice reference into two at an index.

The first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

§Panics

Panics if mid > len.

Source

pub fn split_at_checked(self, mid: usize) -> Result<(Self, Self), Self>

Divides one write-only slice reference into two at an index, returning Err if the slice is too short.

If mid ≤ len, returns a pair of slices where the first will contain all indices from [0, mid) (excluding the index mid itself) and the second will contain all indices from [mid, len) (excluding the index len itself).

Otherwise, if mid > len, returns Err with the original slice.

Source

pub fn split_off<R>(&mut self, range: R) -> Option<Self>
where R: RangeBounds<usize>,

Removes the subslice corresponding to the given range and returns a mutable reference to it.

Returns None and does not modify the slice if the given range is out of bounds.

§Panics

Panics if R is not a one-sided range such as ..n or n...

Source

pub fn split_off_first(&mut self) -> Option<WriteOnly<'a, T>>

Shrinks self to no longer refer to its first element, and returns a reference to that element.

Returns None if self is empty.

Source

pub fn split_off_last(&mut self) -> Option<WriteOnly<'a, T>>

Shrinks self to no longer refer to its last element, and returns a reference to that element.

Returns None if self is empty.

Source

pub unsafe fn cast_elements<U>(self) -> WriteOnly<'a, [U]>

Reinterprets a reference to [T] as a reference to [U].

This may be used, for example, to copy a slice of structs into a [u8] buffer.

This method is unsafe, can easily be used incorrectly, and its use is often not necessary; consider converting your data to bytes explicitly instead. Consider using .into_chunks() instead if possible. When this method is used, consider wrapping it in a function that provides a narrower type signature that can be safe.

§Safety

All values of type U must also be valid values of type T.

Note that this is a requirement which is significant even if T = [u8; N]. For example, if T contains any padding (uninitialized) bytes, then it is not valid to interpret those bytes as u8s, and such a cast is unsound.

A way to ensure soundness of this operation is to ensure that T and U satisfy traits from a helper library, such as T: bytemuck::AnyBitPattern, U: bytemuck::NoUninit.

§Panics

Panics if the size of type U does not equal the size of type T, or if the alignment of type U is greater than the alignment of type T.

This panic occurs regardless of the run-time length or alignment of the slice; any call to cast_elements() with a particular type T and typ U will either always succeed or always fail.

Source

pub fn as_raw_element_ptr(&mut self) -> NonNull<T>

Returns a raw pointer to the first element of this WriteOnly slice reference.

See WriteOnly::as_raw_ptr() for information on how this pointer is, or is not, sound to use.

Trait Implementations§

Source§

impl<T> Debug for WriteOnly<'_, [T]>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Debug for WriteOnly<'_, T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a, T> Default for WriteOnly<'a, [T]>

Source§

fn default() -> Self

Returns an empty slice reference, just like <&mut [T]>::default() would.

This may be used as a placeholder value for operations like mem::take(). It is equivalent to WriteOnly::from_mut(&mut []).

Source§

impl<'a, T> Default for WriteOnly<'a, [T; 0]>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'a, 'b: 'a, T: ?Sized> From<&'b mut T> for WriteOnly<'a, T>

Source§

fn from(reference: &'a mut T) -> WriteOnly<'a, T>

Equivalent to WriteOnly::from_mut().

Source§

impl<'a, 'b: 'a, T, const N: usize> From<WriteOnly<'b, [T; N]>> for WriteOnly<'a, [T]>

Source§

fn from(array_wo: WriteOnly<'b, [T; N]>) -> WriteOnly<'a, [T]>

Converts to this type from the input type.
Source§

impl<'a, T> IntoIterator for WriteOnly<'a, [T]>

Source§

fn into_iter(self) -> Self::IntoIter

Produces an iterator over WriteOnly<T> for each element of this WriteOnly<[T]>.

See also WriteOnly::write_iter() for the case where you already have an iterator of data to write.

Source§

type Item = WriteOnly<'a, T>

The type of the elements being iterated over.
Source§

type IntoIter = WriteOnlyIter<'a, T>

Which kind of iterator are we turning this into?
Source§

impl<'a, T, const N: usize> IntoIterator for WriteOnly<'a, [T; N]>

Source§

type Item = WriteOnly<'a, T>

The type of the elements being iterated over.
Source§

type IntoIter = WriteOnlyIter<'a, T>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
Source§

impl<T: Send> Send for WriteOnly<'_, T>

Source§

impl<T: ?Sized> Sync for WriteOnly<'_, T>

Auto Trait Implementations§

§

impl<'a, T> Freeze for WriteOnly<'a, T>
where T: ?Sized,

§

impl<'a, T> RefUnwindSafe for WriteOnly<'a, T>
where T: RefUnwindSafe + ?Sized,

§

impl<'a, T> Unpin for WriteOnly<'a, T>
where T: ?Sized,

§

impl<'a, T> UnsafeUnpin for WriteOnly<'a, T>
where T: ?Sized,

§

impl<'a, T> !UnwindSafe for WriteOnly<'a, T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.