#[repr(C)]
pub struct Subbuffer<T: ?Sized> { /* private fields */ }
Expand description

A subpart of a buffer.

This type doesn’t correspond to any Vulkan object, it exists for API convenience. Most Vulkan functions that work with buffers take the buffer as argument as well as an offset and size within the buffer, which we can represent with a single subbuffer instead.

Subbuffer also has a type parameter, which is a hint for how the data is going to be interpreted by the host or device (or both). This is useful so that we can allocate (sub)buffers that are correctly aligned and have the correct size for their content, and for type-safety. For example, when reading/writing a subbuffer from the host, you can use Subbuffer::read/Subbuffer::write without worrying about the alignment and size being correct and about converting your data from/to raw bytes.

There are two ways to get a Subbuffer:

  • By using the functions on Buffer, which create a new buffer and memory allocation each time, and give you a Subbuffer that has an entire Buffer dedicated to it.
  • By using the SubbufferAllocator, which creates Subbuffers by suballocating existing Buffers such that the Buffers can keep being reused.

Alternatively, you can also create a Buffer manually and convert it to a Subbuffer<[u8]>.

Implementations§

source§

impl<T: ?Sized> Subbuffer<T>

source

pub fn offset(&self) -> DeviceSize

Returns the offset of the subbuffer, in bytes, relative to the buffer.

source

pub fn size(&self) -> DeviceSize

Returns the size of the subbuffer in bytes.

source

pub fn buffer(&self) -> &Arc<Buffer>

Returns the buffer that this subbuffer is a part of.

source

pub fn mapped_slice(&self) -> Result<NonNull<[u8]>, HostAccessError>

Returns the mapped pointer to the range of memory of self.

The subbuffer must fall within the range of the memory mapping given to DeviceMemory::map.

See MappingState::slice for the safety invariants of the returned pointer.

source

pub fn device_address( &self ) -> Result<NonNullDeviceAddress, Box<ValidationError>>

Returns the device address for this subbuffer.

source

pub fn into_bytes(self) -> Subbuffer<[u8]>

Casts the subbuffer to a slice of raw bytes.

source

pub fn as_bytes(&self) -> &Subbuffer<[u8]>

Same as into_bytes, except it works with a reference to the subbuffer.

source§

impl<T> Subbuffer<T>where T: BufferContents + ?Sized,

source

pub fn reinterpret<U>(self) -> Subbuffer<U>where U: BufferContents + ?Sized,

Changes the T generic parameter of the subbuffer to the desired type.

Panics
  • Panics if the memory offset of the subbuffer is not a multiple of the alignment of U.
  • If U is sized, then panics if the subbuffer size doesn’t match the size of U exactly.
  • If U is unsized, then panics if
    • the subbuffer size isn’t greater than the size of the head (sized part) of U,
    • the subbuffer would have slop when reinterpreted as U, meaning that the subbuffer size minus the the size of the head of U isn’t divisible by the element size of U, or
    • the subbuffer size isn’t a multiple of the alignment of U.
source

pub fn reinterpret_ref<U>(&self) -> &Subbuffer<U>where U: BufferContents + ?Sized,

Same as reinterpret, except it works with a reference to the subbuffer.

source

pub fn read(&self) -> Result<BufferReadGuard<'_, T>, HostAccessError>

Locks the subbuffer in order to read its content from the host.

If the subbuffer is currently used in exclusive mode by the device, this function will return an error. Similarly if you called write on the buffer and haven’t dropped the lock, this function will return an error as well.

After this function successfully locks the subbuffer, any attempt to submit a command buffer that uses it in exclusive mode will fail. You can still submit this subbuffer for non-exclusive accesses (ie. reads).

If the memory backing the buffer is not host-coherent, then this function will lock a range that is potentially larger than the subbuffer, because the range given to invalidate_range must be aligned to the non_coherent_atom_size. This means that for example if your Vulkan implementation reports an atom size of 64, and you tried to put 2 subbuffers of size 32 in the same buffer, one at offset 0 and one at offset 32, while the buffer is backed by non-coherent memory, then invalidating one subbuffer would also invalidate the other subbuffer. This can lead to data races and is therefore not allowed. What you should do in that case is ensure that each subbuffer is aligned to the non-coherent atom size, so in this case one would be at offset 0 and the other at offset 64. SubbufferAllocator does this automatically.

source

pub fn write(&self) -> Result<BufferWriteGuard<'_, T>, HostAccessError>

Locks the subbuffer in order to write its content from the host.

If the subbuffer is currently in use by the device, this function will return an error. Similarly if you called read on the subbuffer and haven’t dropped the lock, this function will return an error as well.

After this function successfully locks the buffer, any attempt to submit a command buffer that uses it and any attempt to call read will return an error.

If the memory backing the buffer is not host-coherent, then this function will lock a range that is potentially larger than the subbuffer, because the range given to flush_range must be aligned to the non_coherent_atom_size. This means that for example if your Vulkan implementation reports an atom size of 64, and you tried to put 2 subbuffers of size 32 in the same buffer, one at offset 0 and one at offset 32, while the buffer is backed by non-coherent memory, then flushing one subbuffer would also flush the other subbuffer. This can lead to data races and is therefore not allowed. What you should do in that case is ensure that each subbuffer is aligned to the non-coherent atom size, so in this case one would be at offset 0 and the other at offset 64. SubbufferAllocator does this automatically.

source§

impl<T> Subbuffer<T>

source

pub fn into_slice(self) -> Subbuffer<[T]>

Converts the subbuffer to a slice of one element.

source

pub fn as_slice(&self) -> &Subbuffer<[T]>

Same as into_slice, except it works with a reference to the subbuffer.

source§

impl<T> Subbuffer<[T]>

source

pub fn len(&self) -> DeviceSize

Returns the number of elements in the slice.

source

pub fn index(self, index: DeviceSize) -> Subbuffer<T>

Reduces the subbuffer to just one element of the slice.

Panics
  • Panics if index is out of bounds.
source

pub fn slice(self, range: impl RangeBounds<DeviceSize>) -> Subbuffer<[T]>

Reduces the subbuffer to just a range of the slice.

Panics
  • Panics if range is out of bounds.
  • Panics if range is empty.
source

pub fn split_at(self, mid: DeviceSize) -> (Subbuffer<[T]>, Subbuffer<[T]>)

Splits the subbuffer into two at an index.

Panics
  • Panics if mid is not greater than 0.
  • Panics if mid is not less than self.len().
source§

impl Subbuffer<[u8]>

source

pub fn new(buffer: Arc<Buffer>) -> Self

Creates a new Subbuffer<[u8]> spanning the whole buffer.

source

pub fn cast_aligned<T>(self) -> Subbuffer<[T]>where T: BufferContents,

Casts the slice to a different element type while ensuring correct alignment for the type.

The offset of the subbuffer is rounded up to the alignment of T and the size abjusted for the padding, then the size is rounded down to the nearest multiple of T’s size.

Panics
  • Panics if the aligned offset would be out of bounds.
source

pub fn align_to(self, layout: DeviceLayout) -> Subbuffer<[u8]>

Aligns the subbuffer to the given layout by rounding the offset up to layout.alignment() and adjusting the size for the padding, and then rounding the size down to the nearest multiple of layout.size().

Panics
  • Panics if the aligned offset would be out of bounds.
  • Panics if layout.alignment() exceeds 64.

Trait Implementations§

source§

impl<T: ?Sized> Clone for Subbuffer<T>

source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug + ?Sized> Debug for Subbuffer<T>

source§

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

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

impl<T: ?Sized> DeviceOwned for Subbuffer<T>

source§

fn device(&self) -> &Arc<Device>

Returns the device that owns self.
source§

impl From<Arc<Buffer>> for Subbuffer<[u8]>

source§

fn from(buffer: Arc<Buffer>) -> Self

Converts to this type from the input type.
source§

impl From<Subbuffer<[AccelerationStructureInstance]>> for AccelerationStructureGeometryInstancesDataType

source§

fn from(value: Subbuffer<[AccelerationStructureInstance]>) -> Self

Converts to this type from the input type.
source§

impl From<Subbuffer<[u16]>> for IndexBuffer

source§

fn from(value: Subbuffer<[u16]>) -> Self

Converts to this type from the input type.
source§

impl From<Subbuffer<[u32]>> for IndexBuffer

source§

fn from(value: Subbuffer<[u32]>) -> Self

Converts to this type from the input type.
source§

impl From<Subbuffer<[u64]>> for AccelerationStructureGeometryInstancesDataType

source§

fn from(value: Subbuffer<[DeviceSize]>) -> Self

Converts to this type from the input type.
source§

impl From<Subbuffer<[u8]>> for IndexBuffer

source§

fn from(value: Subbuffer<[u8]>) -> Self

Converts to this type from the input type.
source§

impl<T: ?Sized> Hash for Subbuffer<T>

source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<T: ?Sized> PartialEq for Subbuffer<T>

source§

fn eq(&self, other: &Self) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<T: ?Sized> VertexBuffersCollection for Subbuffer<T>

source§

fn into_vec(self) -> Vec<Subbuffer<[u8]>>

Converts self into a list of buffers.
source§

impl<T: ?Sized> Eq for Subbuffer<T>

Auto Trait Implementations§

§

impl<T> !RefUnwindSafe for Subbuffer<T>

§

impl<T: ?Sized> Send for Subbuffer<T>where T: Send + Sync,

§

impl<T: ?Sized> Sync for Subbuffer<T>where T: Send + Sync,

§

impl<T: ?Sized> Unpin for Subbuffer<T>

§

impl<T> !UnwindSafe for Subbuffer<T>

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere 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 Twhere 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> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

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

§

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 Twhere U: TryFrom<T>,

§

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.