pub use self::device_memory::{
DeviceMemory, DeviceMemoryError, ExternalMemoryHandleType, ExternalMemoryHandleTypes,
MappedDeviceMemory, MemoryAllocateFlags, MemoryAllocateInfo, MemoryImportInfo, MemoryMapError,
};
use crate::{
buffer::{sys::RawBuffer, BufferAccess},
image::{sys::RawImage, ImageAccess, ImageAspects},
macros::vulkan_bitflags,
sync::Semaphore,
DeviceSize,
};
use std::{num::NonZeroU64, sync::Arc};
pub mod allocator;
mod device_memory;
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct MemoryProperties {
pub memory_types: Vec<MemoryType>,
pub memory_heaps: Vec<MemoryHeap>,
}
impl From<ash::vk::PhysicalDeviceMemoryProperties> for MemoryProperties {
#[inline]
fn from(val: ash::vk::PhysicalDeviceMemoryProperties) -> Self {
Self {
memory_types: val.memory_types[0..val.memory_type_count as usize]
.iter()
.map(|vk_memory_type| MemoryType {
property_flags: vk_memory_type.property_flags.into(),
heap_index: vk_memory_type.heap_index,
})
.collect(),
memory_heaps: val.memory_heaps[0..val.memory_heap_count as usize]
.iter()
.map(|vk_memory_heap| MemoryHeap {
size: vk_memory_heap.size,
flags: vk_memory_heap.flags.into(),
})
.collect(),
}
}
}
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct MemoryType {
pub property_flags: MemoryPropertyFlags,
pub heap_index: u32,
}
vulkan_bitflags! {
#[non_exhaustive]
MemoryPropertyFlags = MemoryPropertyFlags(u32);
device_local = DEVICE_LOCAL,
host_visible = HOST_VISIBLE,
host_coherent = HOST_COHERENT,
host_cached = HOST_CACHED,
lazily_allocated = LAZILY_ALLOCATED,
protected = PROTECTED {
api_version: V1_1,
},
device_coherent = DEVICE_COHERENT_AMD {
device_extensions: [amd_device_coherent_memory],
},
device_uncached = DEVICE_UNCACHED_AMD {
device_extensions: [amd_device_coherent_memory],
},
rdma_capable = RDMA_CAPABLE_NV {
device_extensions: [nv_external_memory_rdma],
},
}
#[derive(Clone, Debug)]
#[non_exhaustive]
pub struct MemoryHeap {
pub size: DeviceSize,
pub flags: MemoryHeapFlags,
}
vulkan_bitflags! {
#[non_exhaustive]
MemoryHeapFlags = MemoryHeapFlags(u32);
device_local = DEVICE_LOCAL,
multi_instance = MULTI_INSTANCE {
api_version: V1_1,
instance_extensions: [khr_device_group_creation],
},
}
#[derive(Clone, Copy, Debug)]
pub struct MemoryRequirements {
pub size: DeviceSize,
pub alignment: DeviceSize,
pub memory_type_bits: u32,
pub prefers_dedicated_allocation: bool,
pub requires_dedicated_allocation: bool,
}
#[derive(Clone, Copy, Debug)]
pub enum DedicatedAllocation<'a> {
Buffer(&'a RawBuffer),
Image(&'a RawImage),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum DedicatedTo {
Buffer(NonZeroU64),
Image(NonZeroU64),
}
impl From<DedicatedAllocation<'_>> for DedicatedTo {
fn from(dedicated_allocation: DedicatedAllocation<'_>) -> Self {
match dedicated_allocation {
DedicatedAllocation::Buffer(buffer) => Self::Buffer(buffer.id()),
DedicatedAllocation::Image(image) => Self::Image(image.id()),
}
}
}
#[derive(Clone, Debug, Default)]
#[non_exhaustive]
pub struct ExternalMemoryProperties {
pub dedicated_only: bool,
pub exportable: bool,
pub importable: bool,
pub export_from_imported_handle_types: ExternalMemoryHandleTypes,
pub compatible_handle_types: ExternalMemoryHandleTypes,
}
impl From<ash::vk::ExternalMemoryProperties> for ExternalMemoryProperties {
#[inline]
fn from(val: ash::vk::ExternalMemoryProperties) -> Self {
Self {
dedicated_only: val
.external_memory_features
.intersects(ash::vk::ExternalMemoryFeatureFlags::DEDICATED_ONLY),
exportable: val
.external_memory_features
.intersects(ash::vk::ExternalMemoryFeatureFlags::EXPORTABLE),
importable: val
.external_memory_features
.intersects(ash::vk::ExternalMemoryFeatureFlags::IMPORTABLE),
export_from_imported_handle_types: val.export_from_imported_handle_types.into(),
compatible_handle_types: val.compatible_handle_types.into(),
}
}
}
#[derive(Clone, Debug)]
pub struct BindSparseInfo {
pub wait_semaphores: Vec<Arc<Semaphore>>,
pub buffer_binds: Vec<(Arc<dyn BufferAccess>, Vec<SparseBufferMemoryBind>)>,
pub image_opaque_binds: Vec<(Arc<dyn ImageAccess>, Vec<SparseImageOpaqueMemoryBind>)>,
pub image_binds: Vec<(Arc<dyn ImageAccess>, Vec<SparseImageMemoryBind>)>,
pub signal_semaphores: Vec<Arc<Semaphore>>,
pub _ne: crate::NonExhaustive,
}
impl Default for BindSparseInfo {
#[inline]
fn default() -> Self {
Self {
wait_semaphores: Vec::new(),
buffer_binds: Vec::new(),
image_opaque_binds: Vec::new(),
image_binds: Vec::new(),
signal_semaphores: Vec::new(),
_ne: crate::NonExhaustive(()),
}
}
}
#[derive(Clone, Debug, Default)]
pub struct SparseBufferMemoryBind {
pub offset: DeviceSize,
pub size: DeviceSize,
pub memory: Option<(Arc<DeviceMemory>, DeviceSize)>,
}
#[derive(Clone, Debug, Default)]
pub struct SparseImageOpaqueMemoryBind {
pub offset: DeviceSize,
pub size: DeviceSize,
pub memory: Option<(Arc<DeviceMemory>, DeviceSize)>,
pub metadata: bool,
}
#[derive(Clone, Debug, Default)]
pub struct SparseImageMemoryBind {
pub aspects: ImageAspects,
pub mip_level: u32,
pub array_layer: u32,
pub offset: [u32; 3],
pub extent: [u32; 3],
pub memory: Option<(Arc<DeviceMemory>, DeviceSize)>,
}