gpu_alloc/lib.rs
1//!
2//! Implementation agnostic memory allocator for Vulkan like APIs.
3//!
4//! This crate is intended to be used as part of safe API implementations.\
5//! Use with caution. There are unsafe functions all over the place.
6//!
7//! # Usage
8//!
9//! Start with fetching `DeviceProperties` from `gpu-alloc-<backend>` crate for the backend of choice.\
10//! Then create `GpuAllocator` instance and use it for all device memory allocations.\
11//! `GpuAllocator` will take care for all necessary bookkeeping like memory object count limit,
12//! heap budget and memory mapping.
13//!
14//! ### Backends implementations
15//!
16//! Backend supporting crates should not depend on this crate.\
17//! Instead they should depend on `gpu-alloc-types` which is much more stable,
18//! allowing to upgrade `gpu-alloc` version without `gpu-alloc-<backend>` upgrade.
19//!
20
21#![cfg_attr(not(feature = "std"), no_std)]
22
23extern crate alloc;
24
25#[cfg(feature = "tracing")]
26macro_rules! report_error_on_drop {
27 ($($tokens:tt)*) => {{
28 #[cfg(feature = "std")]
29 {
30 if std::thread::panicking() {
31 return;
32 }
33 }
34
35 tracing::error!($($tokens)*)
36 }};
37}
38
39#[cfg(all(not(feature = "tracing"), feature = "std"))]
40macro_rules! report_error_on_drop {
41 ($($tokens:tt)*) => {{
42 if std::thread::panicking() {
43 return;
44 }
45 eprintln!($($tokens)*)
46 }};
47}
48
49#[cfg(all(not(feature = "tracing"), not(feature = "std")))]
50macro_rules! report_error_on_drop {
51 ($($tokens:tt)*) => {{
52 panic!($($tokens)*)
53 }};
54}
55
56mod allocator;
57mod block;
58mod buddy;
59mod config;
60mod error;
61mod freelist;
62mod heap;
63mod slab;
64mod usage;
65mod util;
66
67pub use {
68 self::{allocator::*, block::MemoryBlock, config::*, error::*, usage::*},
69 gpu_alloc_types::*,
70};
71
72/// Memory request for allocator.
73#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
74pub struct Request {
75 /// Minimal size of memory block required.
76 /// Returned block may have larger size,
77 /// use `MemoryBlock::size` to learn actual size of returned block.
78 pub size: u64,
79
80 /// Minimal alignment mask required.
81 /// Returned block may have larger alignment,
82 /// use `MemoryBlock::align` to learn actual alignment of returned block.
83 pub align_mask: u64,
84
85 /// Intended memory usage.
86 /// Returned block may support additional usages,
87 /// use `MemoryBlock::props` to learn memory properties of returned block.
88 pub usage: UsageFlags,
89
90 /// Bitset for memory types.
91 /// Returned block will be from memory type corresponding to one of set bits,
92 /// use `MemoryBlock::memory_type` to learn memory type index of returned block.
93 pub memory_types: u32,
94}
95
96/// Aligns `value` up to `align_mask`
97/// Returns smallest integer not lesser than `value` aligned by `align_mask`.
98/// Returns `None` on overflow.
99pub(crate) fn align_up(value: u64, align_mask: u64) -> Option<u64> {
100 Some(value.checked_add(align_mask)? & !align_mask)
101}
102
103/// Align `value` down to `align_mask`
104/// Returns largest integer not bigger than `value` aligned by `align_mask`.
105pub(crate) fn align_down(value: u64, align_mask: u64) -> u64 {
106 value & !align_mask
107}
108
109#[cfg(debug_assertions)]
110#[allow(unused_unsafe)]
111unsafe fn unreachable_unchecked() -> ! {
112 unreachable!()
113}
114
115#[cfg(not(debug_assertions))]
116unsafe fn unreachable_unchecked() -> ! {
117 core::hint::unreachable_unchecked()
118}
119
120// #[cfg(feature = "tracing")]
121use core::fmt::Debug as MemoryBounds;
122
123// #[cfg(not(feature = "tracing"))]
124// use core::any::Any as MemoryBounds;