mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-21 22:34:43 +00:00
Improve clarity of MemoryTypeFilter
docs (#2428)
* Make the combination disclaimers **impossible** to miss * Add headings to the examples for improved visibility * Update vulkano/src/memory/allocator/mod.rs Co-authored-by: Rua <ruawhitepaw@gmail.com> --------- Co-authored-by: Rua <ruawhitepaw@gmail.com>
This commit is contained in:
parent
6afe4792df
commit
648f3ce715
@ -367,6 +367,8 @@ impl Debug for dyn MemoryAllocator {
|
|||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
/// #### Direct device access only
|
||||||
|
///
|
||||||
/// For resources that the device frequently accesses, e.g. textures, render targets, or
|
/// For resources that the device frequently accesses, e.g. textures, render targets, or
|
||||||
/// intermediary buffers, you want device-local memory without any host access:
|
/// intermediary buffers, you want device-local memory without any host access:
|
||||||
///
|
///
|
||||||
@ -396,8 +398,10 @@ impl Debug for dyn MemoryAllocator {
|
|||||||
/// .unwrap();
|
/// .unwrap();
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// #### Sequential writes from host, indirect device access
|
||||||
|
///
|
||||||
/// For staging, the resource is only ever written to sequentially. Also, since the device will
|
/// For staging, the resource is only ever written to sequentially. Also, since the device will
|
||||||
/// only read the staging resourse once, it would yield no benefit to place it in device-local
|
/// only read the staging resource once, it would yield no benefit to place it in device-local
|
||||||
/// memory, in fact it would be wasteful. Therefore, it's best to put it in host-local memory:
|
/// memory, in fact it would be wasteful. Therefore, it's best to put it in host-local memory:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -425,6 +429,8 @@ impl Debug for dyn MemoryAllocator {
|
|||||||
/// # let staging_buffer: vulkano::buffer::Subbuffer<u32> = staging_buffer;
|
/// # let staging_buffer: vulkano::buffer::Subbuffer<u32> = staging_buffer;
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// #### Sequential writes from host, direct device access
|
||||||
|
///
|
||||||
/// For resources that the device accesses directly, aka a buffer/image used for anything other
|
/// For resources that the device accesses directly, aka a buffer/image used for anything other
|
||||||
/// than transfers, it's probably best to put it in device-local memory:
|
/// than transfers, it's probably best to put it in device-local memory:
|
||||||
///
|
///
|
||||||
@ -453,6 +459,8 @@ impl Debug for dyn MemoryAllocator {
|
|||||||
/// # let uniform_buffer: vulkano::buffer::Subbuffer<u32> = uniform_buffer;
|
/// # let uniform_buffer: vulkano::buffer::Subbuffer<u32> = uniform_buffer;
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// #### Readback to host
|
||||||
|
///
|
||||||
/// For readback, e.g. getting the results of a compute shader back to the host:
|
/// For readback, e.g. getting the results of a compute shader back to the host:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -487,7 +495,9 @@ pub struct MemoryTypeFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MemoryTypeFilter {
|
impl MemoryTypeFilter {
|
||||||
/// Prefers picking a memory type with the [`DEVICE_LOCAL`] flag.
|
/// Prefers picking a memory type with the [`DEVICE_LOCAL`] flag. **It does not affect whether
|
||||||
|
/// the memory is host-visible**. You need to combine this with either the
|
||||||
|
/// [`HOST_SEQUENTIAL_WRITE`] or [`HOST_RANDOM_ACCESS`] filter for that.
|
||||||
///
|
///
|
||||||
/// Memory being device-local means that it is fastest to access for the device. However,
|
/// Memory being device-local means that it is fastest to access for the device. However,
|
||||||
/// for dedicated GPUs, getting memory in and out of VRAM requires to go through the PCIe bus,
|
/// for dedicated GPUs, getting memory in and out of VRAM requires to go through the PCIe bus,
|
||||||
@ -514,22 +524,22 @@ impl MemoryTypeFilter {
|
|||||||
/// memory types that are not `HOST_VISIBLE`, which makes sense since it's all system RAM. In
|
/// memory types that are not `HOST_VISIBLE`, which makes sense since it's all system RAM. In
|
||||||
/// that case you wouldn't need to do staging.
|
/// that case you wouldn't need to do staging.
|
||||||
///
|
///
|
||||||
/// Don't use this together with [`PREFER_HOST`], that makes no sense. If you need host access,
|
/// Don't use this together with [`PREFER_HOST`], that makes no sense.
|
||||||
/// make sure you combine this with either the [`HOST_SEQUENTIAL_WRITE`] or
|
|
||||||
/// [`HOST_RANDOM_ACCESS`] filter.
|
|
||||||
///
|
///
|
||||||
/// [`DEVICE_LOCAL`]: MemoryPropertyFlags::DEVICE_LOCAL
|
/// [`DEVICE_LOCAL`]: MemoryPropertyFlags::DEVICE_LOCAL
|
||||||
/// [`HOST_VISIBLE`]: MemoryPropertyFlags::HOST_VISIBLE
|
|
||||||
/// [`PREFER_HOST`]: Self::PREFER_HOST
|
|
||||||
/// [`HOST_SEQUENTIAL_WRITE`]: Self::HOST_SEQUENTIAL_WRITE
|
/// [`HOST_SEQUENTIAL_WRITE`]: Self::HOST_SEQUENTIAL_WRITE
|
||||||
/// [`HOST_RANDOM_ACCESS`]: Self::HOST_RANDOM_ACCESS
|
/// [`HOST_RANDOM_ACCESS`]: Self::HOST_RANDOM_ACCESS
|
||||||
|
/// [`HOST_VISIBLE`]: MemoryPropertyFlags::HOST_VISIBLE
|
||||||
|
/// [`PREFER_HOST`]: Self::PREFER_HOST
|
||||||
pub const PREFER_DEVICE: Self = Self {
|
pub const PREFER_DEVICE: Self = Self {
|
||||||
required_flags: MemoryPropertyFlags::empty(),
|
required_flags: MemoryPropertyFlags::empty(),
|
||||||
preferred_flags: MemoryPropertyFlags::DEVICE_LOCAL,
|
preferred_flags: MemoryPropertyFlags::DEVICE_LOCAL,
|
||||||
not_preferred_flags: MemoryPropertyFlags::empty(),
|
not_preferred_flags: MemoryPropertyFlags::empty(),
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Prefers picking a memory type without the [`DEVICE_LOCAL`] flag.
|
/// Prefers picking a memory type without the [`DEVICE_LOCAL`] flag. **It does not affect
|
||||||
|
/// whether the memory is host-visible**. You need to combine this with either the
|
||||||
|
/// [`HOST_SEQUENTIAL_WRITE`] or [`HOST_RANDOM_ACCESS`] filter for that.
|
||||||
///
|
///
|
||||||
/// This option is best suited for resources that the host does access, but device doesn't
|
/// This option is best suited for resources that the host does access, but device doesn't
|
||||||
/// access directly, such as staging buffers and readback buffers.
|
/// access directly, such as staging buffers and readback buffers.
|
||||||
@ -544,28 +554,29 @@ impl MemoryTypeFilter {
|
|||||||
/// still prefer host-local memory if the memory is rarely used, such as for manually paging
|
/// still prefer host-local memory if the memory is rarely used, such as for manually paging
|
||||||
/// parts of device-local memory out in order to free up space on the device.
|
/// parts of device-local memory out in order to free up space on the device.
|
||||||
///
|
///
|
||||||
/// Don't use this together with [`PREFER_DEVICE`], that makes no sense. If you need host
|
/// Don't use this together with [`PREFER_DEVICE`], that makes no sense.
|
||||||
/// access, make sure you combine this with either the [`HOST_SEQUENTIAL_WRITE`] or
|
|
||||||
/// [`HOST_RANDOM_ACCESS`] filter.
|
|
||||||
///
|
///
|
||||||
/// [`DEVICE_LOCAL`]: MemoryPropertyFlags::DEVICE_LOCAL
|
/// [`DEVICE_LOCAL`]: MemoryPropertyFlags::DEVICE_LOCAL
|
||||||
/// [`PREFER_DEVICE`]: Self::PREFER_DEVICE
|
|
||||||
/// [`HOST_SEQUENTIAL_WRITE`]: Self::HOST_SEQUENTIAL_WRITE
|
/// [`HOST_SEQUENTIAL_WRITE`]: Self::HOST_SEQUENTIAL_WRITE
|
||||||
/// [`HOST_RANDOM_ACCESS`]: Self::HOST_RANDOM_ACCESS
|
/// [`HOST_RANDOM_ACCESS`]: Self::HOST_RANDOM_ACCESS
|
||||||
|
/// [`PREFER_DEVICE`]: Self::PREFER_DEVICE
|
||||||
pub const PREFER_HOST: Self = Self {
|
pub const PREFER_HOST: Self = Self {
|
||||||
required_flags: MemoryPropertyFlags::empty(),
|
required_flags: MemoryPropertyFlags::empty(),
|
||||||
preferred_flags: MemoryPropertyFlags::empty(),
|
preferred_flags: MemoryPropertyFlags::empty(),
|
||||||
not_preferred_flags: MemoryPropertyFlags::DEVICE_LOCAL,
|
not_preferred_flags: MemoryPropertyFlags::DEVICE_LOCAL,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This guarantees picking a memory type that has the [`HOST_VISIBLE`] flag. Using this filter
|
/// This guarantees picking a memory type that has the [`HOST_VISIBLE`] flag. **It does not
|
||||||
/// allows the allocator to pick a memory type that is uncached and write-combined, which is
|
/// affect whether the memory is device-local or host-local**. You need to combine this with
|
||||||
/// ideal for sequential writes. However, this optimization might lead to poor performance for
|
/// either the [`PREFER_DEVICE`] or [`PREFER_HOST`] filter for that.
|
||||||
/// anything else. What counts as a sequential write is any kind of loop that writes memory
|
///
|
||||||
/// locations in order, such as iterating over a slice while writing each element in order, or
|
/// Using this filter allows the allocator to pick a memory type that is uncached and
|
||||||
/// equivalently using [`slice::copy_from_slice`]. Copying sized data also counts, as rustc
|
/// write-combined, which is ideal for sequential writes. However, this optimization might lead
|
||||||
/// should write the memory locations in order. If you have a struct, make sure you write it
|
/// to poor performance for anything else. What counts as a sequential write is any kind of
|
||||||
/// member-by-member.
|
/// loop that writes memory locations in order, such as iterating over a slice while writing
|
||||||
|
/// each element in order, or equivalently using [`slice::copy_from_slice`]. Copying sized data
|
||||||
|
/// also counts, as rustc should write the memory locations in order. If you have a struct,
|
||||||
|
/// make sure you write it member-by-member.
|
||||||
///
|
///
|
||||||
/// Example use cases include staging buffers, as well as any other kind of buffer that you
|
/// Example use cases include staging buffers, as well as any other kind of buffer that you
|
||||||
/// only write to from the host, like a uniform or vertex buffer.
|
/// only write to from the host, like a uniform or vertex buffer.
|
||||||
@ -576,7 +587,8 @@ impl MemoryTypeFilter {
|
|||||||
/// to get the most performance out, if that's possible.
|
/// to get the most performance out, if that's possible.
|
||||||
///
|
///
|
||||||
/// [`HOST_VISIBLE`]: MemoryPropertyFlags::HOST_VISIBLE
|
/// [`HOST_VISIBLE`]: MemoryPropertyFlags::HOST_VISIBLE
|
||||||
/// [`HOST_COHERENT`]: MemoryPropertyFlags::HOST_COHERENT
|
/// [`PREFER_DEVICE`]: Self::PREFER_DEVICE
|
||||||
|
/// [`PREFER_HOST`]: Self::PREFER_HOST
|
||||||
/// [`HOST_RANDOM_ACCESS`]: Self::HOST_RANDOM_ACCESS
|
/// [`HOST_RANDOM_ACCESS`]: Self::HOST_RANDOM_ACCESS
|
||||||
pub const HOST_SEQUENTIAL_WRITE: Self = Self {
|
pub const HOST_SEQUENTIAL_WRITE: Self = Self {
|
||||||
required_flags: MemoryPropertyFlags::HOST_VISIBLE,
|
required_flags: MemoryPropertyFlags::HOST_VISIBLE,
|
||||||
@ -585,7 +597,9 @@ impl MemoryTypeFilter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// This guarantees picking a memory type that has the [`HOST_VISIBLE`] and [`HOST_CACHED`]
|
/// This guarantees picking a memory type that has the [`HOST_VISIBLE`] and [`HOST_CACHED`]
|
||||||
/// flags, which is best suited for readback and/or random access.
|
/// flags, which is best suited for readback and/or random access. **It does not affect whether
|
||||||
|
/// the memory is device-local or host-local**. You need to combine this with either the
|
||||||
|
/// [`PREFER_DEVICE`] or [`PREFER_HOST`] filter for that.
|
||||||
///
|
///
|
||||||
/// Example use cases include using the device for things other than rendering and getting the
|
/// Example use cases include using the device for things other than rendering and getting the
|
||||||
/// results back to the host. That might be compute shading, or image or video manipulation, or
|
/// results back to the host. That might be compute shading, or image or video manipulation, or
|
||||||
@ -597,6 +611,8 @@ impl MemoryTypeFilter {
|
|||||||
///
|
///
|
||||||
/// [`HOST_VISIBLE`]: MemoryPropertyFlags::HOST_VISIBLE
|
/// [`HOST_VISIBLE`]: MemoryPropertyFlags::HOST_VISIBLE
|
||||||
/// [`HOST_CACHED`]: MemoryPropertyFlags::HOST_CACHED
|
/// [`HOST_CACHED`]: MemoryPropertyFlags::HOST_CACHED
|
||||||
|
/// [`PREFER_DEVICE`]: Self::PREFER_DEVICE
|
||||||
|
/// [`PREFER_HOST`]: Self::PREFER_HOST
|
||||||
/// [`HOST_SEQUENTIAL_WRITE`]: Self::HOST_SEQUENTIAL_WRITE
|
/// [`HOST_SEQUENTIAL_WRITE`]: Self::HOST_SEQUENTIAL_WRITE
|
||||||
pub const HOST_RANDOM_ACCESS: Self = Self {
|
pub const HOST_RANDOM_ACCESS: Self = Self {
|
||||||
required_flags: MemoryPropertyFlags::HOST_VISIBLE.union(MemoryPropertyFlags::HOST_CACHED),
|
required_flags: MemoryPropertyFlags::HOST_VISIBLE.union(MemoryPropertyFlags::HOST_CACHED),
|
||||||
|
Loading…
Reference in New Issue
Block a user