format source
[kazan.git] / vulkan-driver / src / device_memory.rs
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 // Copyright 2018 Jacob Lifshay
3 use api;
4 use enum_map::EnumMap;
5 use std::alloc;
6 use std::fmt::{self, Debug, Display};
7 use std::ops::{Deref, DerefMut};
8 use std::ptr::NonNull;
9
10 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Enum)]
11 #[repr(u32)]
12 pub enum DeviceMemoryType {
13 Main = 0,
14 }
15
16 impl DeviceMemoryType {
17 pub fn from_index(index: u32) -> Option<Self> {
18 for (enumerant, _) in EnumMap::<Self, ()>::from(|_| {}).iter() {
19 if enumerant as u32 == index {
20 return Some(enumerant);
21 }
22 }
23 None
24 }
25 pub fn heap(self) -> DeviceMemoryHeap {
26 match self {
27 DeviceMemoryType::Main => DeviceMemoryHeap::Main,
28 }
29 }
30 pub fn flags(self) -> api::VkMemoryPropertyFlags {
31 match self {
32 DeviceMemoryType::Main => {
33 api::VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
34 | api::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
35 | api::VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
36 | api::VK_MEMORY_PROPERTY_HOST_CACHED_BIT
37 }
38 }
39 }
40 pub fn to_bits(self) -> u32 {
41 1 << (self as u32)
42 }
43 }
44
45 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
46 pub struct DeviceMemoryTypes(EnumMap<DeviceMemoryType, bool>);
47
48 impl Default for DeviceMemoryTypes {
49 fn default() -> Self {
50 DeviceMemoryTypes(enum_map! {_ => false})
51 }
52 }
53
54 impl DeviceMemoryTypes {
55 #[allow(dead_code)]
56 pub fn to_bits(self) -> u32 {
57 let mut retval = 0;
58 for (enumerant, value) in self.iter() {
59 if *value {
60 retval |= enumerant.to_bits();
61 }
62 }
63 retval
64 }
65 }
66
67 impl From<EnumMap<DeviceMemoryType, bool>> for DeviceMemoryTypes {
68 fn from(v: EnumMap<DeviceMemoryType, bool>) -> Self {
69 DeviceMemoryTypes(v)
70 }
71 }
72
73 impl From<DeviceMemoryType> for DeviceMemoryTypes {
74 fn from(v: DeviceMemoryType) -> Self {
75 DeviceMemoryTypes(EnumMap::from(|i| i == v))
76 }
77 }
78
79 impl Deref for DeviceMemoryTypes {
80 type Target = EnumMap<DeviceMemoryType, bool>;
81 fn deref(&self) -> &Self::Target {
82 &self.0
83 }
84 }
85
86 impl DerefMut for DeviceMemoryTypes {
87 fn deref_mut(&mut self) -> &mut Self::Target {
88 &mut self.0
89 }
90 }
91
92 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Enum)]
93 #[repr(u32)]
94 pub enum DeviceMemoryHeap {
95 Main = 0,
96 }
97
98 impl DeviceMemoryHeap {
99 pub fn flags(self) -> api::VkMemoryHeapFlags {
100 match self {
101 DeviceMemoryHeap::Main => api::VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
102 }
103 }
104 #[allow(dead_code)]
105 pub fn to_bits(self) -> u32 {
106 1 << (self as u32)
107 }
108 #[allow(dead_code)]
109 pub fn from_index(index: u32) -> Option<Self> {
110 for (enumerant, _) in EnumMap::<Self, ()>::from(|_| {}).iter() {
111 if enumerant as u32 == index {
112 return Some(enumerant);
113 }
114 }
115 None
116 }
117 }
118
119 #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
120 pub struct DeviceMemoryHeaps(EnumMap<DeviceMemoryHeap, bool>);
121
122 impl Default for DeviceMemoryHeaps {
123 fn default() -> Self {
124 DeviceMemoryHeaps(enum_map! {_ => false})
125 }
126 }
127
128 impl DeviceMemoryHeaps {
129 #[allow(dead_code)]
130 pub fn to_bits(self) -> u32 {
131 let mut retval = 0;
132 for (enumerant, value) in self.iter() {
133 if *value {
134 retval |= enumerant.to_bits();
135 }
136 }
137 retval
138 }
139 }
140
141 impl From<EnumMap<DeviceMemoryHeap, bool>> for DeviceMemoryHeaps {
142 fn from(v: EnumMap<DeviceMemoryHeap, bool>) -> Self {
143 DeviceMemoryHeaps(v)
144 }
145 }
146
147 impl From<DeviceMemoryHeap> for DeviceMemoryHeaps {
148 fn from(v: DeviceMemoryHeap) -> Self {
149 DeviceMemoryHeaps(EnumMap::from(|i| i == v))
150 }
151 }
152
153 impl Deref for DeviceMemoryHeaps {
154 type Target = EnumMap<DeviceMemoryHeap, bool>;
155 fn deref(&self) -> &Self::Target {
156 &self.0
157 }
158 }
159
160 impl DerefMut for DeviceMemoryHeaps {
161 fn deref_mut(&mut self) -> &mut Self::Target {
162 &mut self.0
163 }
164 }
165
166 #[derive(Copy, Clone, Debug)]
167 pub struct DeviceMemoryLayout {
168 pub size: usize,
169 pub alignment: usize,
170 }
171
172 impl DeviceMemoryLayout {
173 pub fn calculate(required_size: usize, required_alignment: usize) -> Self {
174 assert!(required_alignment.is_power_of_two());
175 assert_ne!(required_size, 0);
176 Self {
177 size: (required_size + required_alignment - 1) & !(required_alignment - 1),
178 alignment: required_alignment,
179 }
180 }
181 }
182
183 pub trait DeviceMemoryAllocation: 'static + Send + Sync + Debug {
184 unsafe fn get(&self) -> NonNull<u8>;
185 fn layout(&self) -> DeviceMemoryLayout;
186 fn size(&self) -> usize {
187 self.layout().size
188 }
189 }
190
191 #[derive(Debug)]
192 pub struct DefaultDeviceMemoryAllocation {
193 memory: NonNull<u8>,
194 layout: alloc::Layout,
195 }
196
197 #[derive(Debug)]
198 pub struct DefaultDeviceMemoryAllocationFailure;
199
200 impl Display for DefaultDeviceMemoryAllocationFailure {
201 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
202 f.write_str("device memory allocation failed with default allocator")
203 }
204 }
205
206 impl DefaultDeviceMemoryAllocation {
207 pub fn new(layout: DeviceMemoryLayout) -> Result<Self, DefaultDeviceMemoryAllocationFailure> {
208 unsafe {
209 let layout = alloc::Layout::from_size_align(layout.size, layout.alignment).unwrap();
210 Ok(Self {
211 memory: NonNull::new(alloc::alloc(layout))
212 .ok_or(DefaultDeviceMemoryAllocationFailure)?,
213 layout: layout,
214 })
215 }
216 }
217 }
218
219 unsafe impl Send for DefaultDeviceMemoryAllocation {}
220
221 unsafe impl Sync for DefaultDeviceMemoryAllocation {}
222
223 impl DeviceMemoryAllocation for DefaultDeviceMemoryAllocation {
224 unsafe fn get(&self) -> NonNull<u8> {
225 self.memory
226 }
227 fn layout(&self) -> DeviceMemoryLayout {
228 DeviceMemoryLayout {
229 size: self.layout.size(),
230 alignment: self.layout.align(),
231 }
232 }
233 }
234
235 impl Drop for DefaultDeviceMemoryAllocation {
236 fn drop(&mut self) {
237 unsafe {
238 alloc::dealloc(self.memory.as_ptr(), self.layout);
239 }
240 }
241 }
242
243 #[derive(Debug)]
244 pub enum DeviceMemory {
245 Default(DefaultDeviceMemoryAllocation),
246 #[allow(dead_code)]
247 Special(Box<dyn DeviceMemoryAllocation>),
248 }
249
250 impl DeviceMemory {
251 pub fn allocate_from_default_heap(
252 layout: DeviceMemoryLayout,
253 ) -> Result<Self, DefaultDeviceMemoryAllocationFailure> {
254 Ok(DeviceMemory::Default(DefaultDeviceMemoryAllocation::new(
255 layout,
256 )?))
257 }
258 }
259
260 impl DeviceMemoryAllocation for DeviceMemory {
261 unsafe fn get(&self) -> NonNull<u8> {
262 match self {
263 DeviceMemory::Default(memory) => memory.get(),
264 DeviceMemory::Special(memory) => memory.as_ref().get(),
265 }
266 }
267 fn layout(&self) -> DeviceMemoryLayout {
268 match self {
269 DeviceMemory::Default(memory) => memory.layout(),
270 DeviceMemory::Special(memory) => memory.as_ref().layout(),
271 }
272 }
273 }