mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-22 14:56:42 +00:00
Add configuration for custom memory_type_bits
masks (#2311)
This commit is contained in:
parent
c74eedbdf4
commit
e1daac6690
@ -612,6 +612,12 @@ pub struct AllocationCreateInfo {
|
|||||||
/// The default value is [`MemoryTypeFilter::PREFER_DEVICE`].
|
/// The default value is [`MemoryTypeFilter::PREFER_DEVICE`].
|
||||||
pub memory_type_filter: MemoryTypeFilter,
|
pub memory_type_filter: MemoryTypeFilter,
|
||||||
|
|
||||||
|
/// Allows you to further constrain the possible choices of memory types, by only allowing the
|
||||||
|
/// memory type indices that have a corresponding bit at the same index set to 1.
|
||||||
|
///
|
||||||
|
/// The default value is [`u32::MAX`].
|
||||||
|
pub memory_type_bits: u32,
|
||||||
|
|
||||||
/// How eager the allocator should be to allocate [`DeviceMemory`].
|
/// How eager the allocator should be to allocate [`DeviceMemory`].
|
||||||
///
|
///
|
||||||
/// The default value is [`MemoryAllocatePreference::Unknown`].
|
/// The default value is [`MemoryAllocatePreference::Unknown`].
|
||||||
@ -625,6 +631,7 @@ impl Default for AllocationCreateInfo {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
AllocationCreateInfo {
|
AllocationCreateInfo {
|
||||||
memory_type_filter: MemoryTypeFilter::PREFER_DEVICE,
|
memory_type_filter: MemoryTypeFilter::PREFER_DEVICE,
|
||||||
|
memory_type_bits: u32::MAX,
|
||||||
allocate_preference: MemoryAllocatePreference::Unknown,
|
allocate_preference: MemoryAllocatePreference::Unknown,
|
||||||
_ne: crate::NonExhaustive(()),
|
_ne: crate::NonExhaustive(()),
|
||||||
}
|
}
|
||||||
@ -734,6 +741,24 @@ pub type StandardMemoryAllocator = GenericMemoryAllocator<Arc<FreeListAllocator>
|
|||||||
impl StandardMemoryAllocator {
|
impl StandardMemoryAllocator {
|
||||||
/// Creates a new `StandardMemoryAllocator` with default configuration.
|
/// Creates a new `StandardMemoryAllocator` with default configuration.
|
||||||
pub fn new_default(device: Arc<Device>) -> Self {
|
pub fn new_default(device: Arc<Device>) -> Self {
|
||||||
|
let memory_types = &device.physical_device().memory_properties().memory_types;
|
||||||
|
|
||||||
|
let mut memory_type_bits = u32::MAX;
|
||||||
|
|
||||||
|
for (index, MemoryType { property_flags, .. }) in memory_types.iter().enumerate() {
|
||||||
|
if property_flags.intersects(
|
||||||
|
MemoryPropertyFlags::LAZILY_ALLOCATED
|
||||||
|
| MemoryPropertyFlags::PROTECTED
|
||||||
|
| MemoryPropertyFlags::DEVICE_COHERENT
|
||||||
|
| MemoryPropertyFlags::RDMA_CAPABLE,
|
||||||
|
) {
|
||||||
|
// VUID-VkMemoryAllocateInfo-memoryTypeIndex-01872
|
||||||
|
// VUID-vkAllocateMemory-deviceCoherentMemory-02790
|
||||||
|
// Lazily allocated memory would just cause problems for suballocation in general.
|
||||||
|
memory_type_bits &= !(1 << index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::erasing_op, clippy::identity_op)]
|
#[allow(clippy::erasing_op, clippy::identity_op)]
|
||||||
let create_info = GenericMemoryAllocatorCreateInfo {
|
let create_info = GenericMemoryAllocatorCreateInfo {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
@ -741,6 +766,7 @@ impl StandardMemoryAllocator {
|
|||||||
(0 * B, 64 * M),
|
(0 * B, 64 * M),
|
||||||
(1 * G, 256 * M),
|
(1 * G, 256 * M),
|
||||||
],
|
],
|
||||||
|
memory_type_bits,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -859,6 +885,7 @@ impl<S: Suballocator> GenericMemoryAllocator<S> {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
let GenericMemoryAllocatorCreateInfo {
|
let GenericMemoryAllocatorCreateInfo {
|
||||||
block_sizes,
|
block_sizes,
|
||||||
|
memory_type_bits,
|
||||||
allocation_type,
|
allocation_type,
|
||||||
dedicated_allocation,
|
dedicated_allocation,
|
||||||
export_handle_types,
|
export_handle_types,
|
||||||
@ -872,6 +899,7 @@ impl<S: Suballocator> GenericMemoryAllocator<S> {
|
|||||||
} = device.physical_device().memory_properties();
|
} = device.physical_device().memory_properties();
|
||||||
|
|
||||||
let mut pools = ArrayVec::new(memory_types.len(), [Self::EMPTY_POOL; MAX_MEMORY_TYPES]);
|
let mut pools = ArrayVec::new(memory_types.len(), [Self::EMPTY_POOL; MAX_MEMORY_TYPES]);
|
||||||
|
|
||||||
for (i, memory_type) in memory_types.iter().enumerate() {
|
for (i, memory_type) in memory_types.iter().enumerate() {
|
||||||
pools[i].memory_type = ash::vk::MemoryType {
|
pools[i].memory_type = ash::vk::MemoryType {
|
||||||
property_flags: memory_type.property_flags.into(),
|
property_flags: memory_type.property_flags.into(),
|
||||||
@ -913,22 +941,6 @@ impl<S: Suballocator> GenericMemoryAllocator<S> {
|
|||||||
device_address &=
|
device_address &=
|
||||||
device.api_version() >= Version::V1_1 || device.enabled_extensions().khr_device_group;
|
device.api_version() >= Version::V1_1 || device.enabled_extensions().khr_device_group;
|
||||||
|
|
||||||
let mut memory_type_bits = u32::MAX;
|
|
||||||
for (index, MemoryType { property_flags, .. }) in memory_types.iter().enumerate() {
|
|
||||||
if property_flags.intersects(
|
|
||||||
MemoryPropertyFlags::LAZILY_ALLOCATED
|
|
||||||
| MemoryPropertyFlags::PROTECTED
|
|
||||||
| MemoryPropertyFlags::DEVICE_COHERENT
|
|
||||||
| MemoryPropertyFlags::DEVICE_UNCACHED
|
|
||||||
| MemoryPropertyFlags::RDMA_CAPABLE,
|
|
||||||
) {
|
|
||||||
// VUID-VkMemoryAllocateInfo-memoryTypeIndex-01872
|
|
||||||
// VUID-vkAllocateMemory-deviceCoherentMemory-02790
|
|
||||||
// Lazily allocated memory would just cause problems for suballocation in general.
|
|
||||||
memory_type_bits &= !(1 << index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let flags = if device_address {
|
let flags = if device_address {
|
||||||
MemoryAllocateFlags::DEVICE_ADDRESS
|
MemoryAllocateFlags::DEVICE_ADDRESS
|
||||||
} else {
|
} else {
|
||||||
@ -1236,8 +1248,12 @@ unsafe impl<S: Suballocator> MemoryAllocator for GenericMemoryAllocator<S> {
|
|||||||
requires_dedicated_allocation,
|
requires_dedicated_allocation,
|
||||||
} = requirements;
|
} = requirements;
|
||||||
|
|
||||||
|
memory_type_bits &= self.memory_type_bits;
|
||||||
|
memory_type_bits &= create_info.memory_type_bits;
|
||||||
|
|
||||||
let AllocationCreateInfo {
|
let AllocationCreateInfo {
|
||||||
memory_type_filter,
|
memory_type_filter,
|
||||||
|
memory_type_bits: _,
|
||||||
allocate_preference,
|
allocate_preference,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
} = create_info;
|
} = create_info;
|
||||||
@ -1249,7 +1265,6 @@ unsafe impl<S: Suballocator> MemoryAllocator for GenericMemoryAllocator<S> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let size = layout.size();
|
let size = layout.size();
|
||||||
memory_type_bits &= self.memory_type_bits;
|
|
||||||
|
|
||||||
let mut memory_type_index = self
|
let mut memory_type_index = self
|
||||||
.find_memory_type_index(memory_type_bits, memory_type_filter)
|
.find_memory_type_index(memory_type_bits, memory_type_filter)
|
||||||
@ -1485,6 +1500,19 @@ pub struct GenericMemoryAllocatorCreateInfo<'b, 'e> {
|
|||||||
/// The default value is `&[]`, which must be overridden.
|
/// The default value is `&[]`, which must be overridden.
|
||||||
pub block_sizes: &'b [(Threshold, BlockSize)],
|
pub block_sizes: &'b [(Threshold, BlockSize)],
|
||||||
|
|
||||||
|
/// Lets you configure the allocator's global mask of memory type indices. Only the memory type
|
||||||
|
/// indices that have a corresponding bit at the same index set will be allocated from when
|
||||||
|
/// calling [`allocate`], otherwise [`MemoryAllocatorError::FindMemoryType`] is returned.
|
||||||
|
///
|
||||||
|
/// You may use this to disallow problematic memory types, for instance ones with the
|
||||||
|
/// [`PROTECTED`] flag, or any other flags you don't want.
|
||||||
|
///
|
||||||
|
/// The default value is [`u32::MAX`].
|
||||||
|
///
|
||||||
|
/// [`allocate`]: struct.GenericMemoryAllocator.html#method.allocate
|
||||||
|
/// [`PROTECTED`]: MemoryPropertyFlags::DEVICE_COHERENT
|
||||||
|
pub memory_type_bits: u32,
|
||||||
|
|
||||||
/// The allocation type that should be used for root allocations.
|
/// The allocation type that should be used for root allocations.
|
||||||
///
|
///
|
||||||
/// You only need to worry about this if you're using [`PoolAllocator`] as the suballocator, as
|
/// You only need to worry about this if you're using [`PoolAllocator`] as the suballocator, as
|
||||||
@ -1563,6 +1591,7 @@ impl GenericMemoryAllocatorCreateInfo<'_, '_> {
|
|||||||
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
|
||||||
let &Self {
|
let &Self {
|
||||||
block_sizes,
|
block_sizes,
|
||||||
|
memory_type_bits: _,
|
||||||
allocation_type: _,
|
allocation_type: _,
|
||||||
dedicated_allocation: _,
|
dedicated_allocation: _,
|
||||||
export_handle_types,
|
export_handle_types,
|
||||||
@ -1621,6 +1650,7 @@ impl Default for GenericMemoryAllocatorCreateInfo<'_, '_> {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
GenericMemoryAllocatorCreateInfo {
|
GenericMemoryAllocatorCreateInfo {
|
||||||
block_sizes: &[],
|
block_sizes: &[],
|
||||||
|
memory_type_bits: u32::MAX,
|
||||||
allocation_type: AllocationType::Unknown,
|
allocation_type: AllocationType::Unknown,
|
||||||
dedicated_allocation: true,
|
dedicated_allocation: true,
|
||||||
export_handle_types: &[],
|
export_handle_types: &[],
|
||||||
|
Loading…
Reference in New Issue
Block a user