Skip to main content

vk/
memory.rs

1//! Checked memory selection, separate storage and explicit pooled buffers.
2//!
3//! Allocator operations do not submit or wait. GPU completion, resource
4//! destruction and host/GPU access ordering remain caller responsibilities.
5
6mod allocation;
7mod allocator;
8mod block;
9mod selector;
10mod tlsf;
11pub mod virtual_block;
12
13pub use allocation::Allocation;
14pub use allocator::{
15	Allocator, allocate, close, create_buffer, create_buffer_with_options, destroy_buffer, flush,
16	free, invalidate, map, mapped_pointer, statistics, unmap,
17};
18pub use selector::MemoryTypeSelector;
19pub use virtual_block::{
20	PlacementStrategy, VirtualAllocation, VirtualAllocationInfo, VirtualBlock, VirtualBlockStats,
21};
22
23use crate::{core as vk, load::CallError};
24
25#[derive(Debug, PartialEq)]
26pub enum AllocError {
27	NoCompatibleMemoryType,
28	InvalidProperties(&'static str),
29	InvalidRequest(&'static str),
30	InvalidRange,
31	UnknownAllocation,
32	WrongAllocator,
33	AlreadyMapped,
34	NotMapped,
35	NotHostVisible,
36	SerialExhausted,
37	HostAllocationFailed,
38	AllocationLimit,
39	OutOfSpace,
40	AllocationTooLarge { requested: u64, limit: u64 },
41	UnsupportedCapability(&'static str),
42	WrongResource,
43	LiveAllocations,
44	Closed,
45	Call(CallError),
46}
47
48impl std::fmt::Display for AllocError {
49	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50		write!(f, "allocation error: {self:?}")
51	}
52}
53
54impl std::error::Error for AllocError {}
55
56impl From<CallError> for AllocError {
57	fn from(error: CallError) -> Self {
58		Self::Call(error)
59	}
60}
61
62pub struct AllocRequest {
63	pub size: u64,
64	pub alignment: u64,
65	pub memory_type_bits: u32,
66	pub required_flags: vk::MemoryPropertyFlags,
67	pub preferred_flags: vk::MemoryPropertyFlags,
68}
69
70/// Buffer storage policy. Required or preferred native dedication takes precedence.
71#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
72pub enum AllocationPolicy {
73	#[default]
74	Separate,
75	/// Reuse ordinary buffer blocks with this exact native size. No block shrinking.
76	/// Requests larger than the block use separate storage.
77	Pooled { block_size: u64 },
78}
79
80/// Managed-buffer policy; not a Vulkan ABI record or an arbitrary allocation chain.
81#[derive(Clone, Copy, Debug)]
82pub struct AllocationCreateInfo {
83	pub required_flags: vk::MemoryPropertyFlags,
84	pub preferred_flags: vk::MemoryPropertyFlags,
85	/// Intersected with queried native requirements; zero admits no memory types.
86	pub memory_type_bits: u32,
87	pub strategy: PlacementStrategy,
88	pub policy: AllocationPolicy,
89	/// Retain a mapping until explicit allocation release. Requires host-visible storage.
90	pub persistent_map: bool,
91}
92
93impl Default for AllocationCreateInfo {
94	fn default() -> Self {
95		Self {
96			required_flags: vk::MemoryPropertyFlags::empty(),
97			preferred_flags: vk::MemoryPropertyFlags::empty(),
98			memory_type_bits: u32::MAX,
99			strategy: PlacementStrategy::Default,
100			policy: AllocationPolicy::Separate,
101			persistent_map: false,
102		}
103	}
104}
105
106/// Local accounting snapshot; excludes allocations made by other allocators/raw calls.
107#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
108pub struct AllocatorStats {
109	pub allocation_count: usize,
110	pub native_allocation_count: usize,
111	pub pooled_block_count: usize,
112	/// Sum of native requirements sizes of live regions.
113	pub allocation_bytes: u64,
114	/// Includes cache-atom padding reserved to live pooled regions.
115	pub reserved_bytes: u64,
116	pub native_bytes: u64,
117	pub mapped_native_count: usize,
118}
119
120#[cfg(test)]
121#[path = "../../test/rs/memory/test_host_allocator.rs"]
122pub(crate) mod test_host_allocator;