demo_vk/graphics/vulkan/allocator/
owned_block.rs1use {
2 crate::{
3 graphics::vulkan::{raii, Allocator, Block},
4 unwrap_here,
5 },
6 anyhow::Result,
7 ash::vk,
8 std::sync::Arc,
9};
10
11#[derive(Debug)]
13pub struct OwnedBlock {
14 block: Block,
15 allocator: Arc<Allocator>,
16}
17
18impl OwnedBlock {
19 pub fn allocate_image(
24 allocator: Arc<Allocator>,
25 image_create_info: &vk::ImageCreateInfo,
26 memory_property_flags: vk::MemoryPropertyFlags,
27 ) -> Result<(Self, raii::Image)> {
28 let image = unwrap_here!(
29 "Create Vulkan image",
30 raii::Image::new(
31 "Allocated Image",
32 allocator.logical_device.clone(),
33 image_create_info,
34 )
35 );
36
37 let (requirements, dedicated) = {
38 let mut dedicated = vk::MemoryDedicatedRequirements::default();
39 let requirements = unsafe {
40 let mut out = vk::MemoryRequirements2::default()
41 .push_next(&mut dedicated);
42
43 allocator.logical_device.get_image_memory_requirements2(
44 &vk::ImageMemoryRequirementsInfo2 {
45 image: image.raw,
46 ..Default::default()
47 },
48 &mut out,
49 );
50
51 out.memory_requirements
52 };
53 (
54 requirements,
55 dedicated.prefers_dedicated_allocation == vk::TRUE
56 || dedicated.requires_dedicated_allocation == vk::TRUE,
57 )
58 };
59
60 let block = unwrap_here!(
61 "Allocate memory for Vulkan image",
62 allocator.allocate_memory(
63 &requirements,
64 memory_property_flags,
65 vk::MemoryAllocateFlags::empty(),
66 dedicated,
67 )
68 );
69
70 unwrap_here!("Bind memory to Vulkan image", unsafe {
71 allocator.logical_device.bind_image_memory(
72 image.raw,
73 block.memory(),
74 block.offset(),
75 )
76 });
77
78 Ok((Self { block, allocator }, image))
79 }
80
81 pub fn allocate_buffer(
86 allocator: Arc<Allocator>,
87 buffer_create_info: &vk::BufferCreateInfo,
88 memory_property_flags: vk::MemoryPropertyFlags,
89 ) -> Result<(OwnedBlock, raii::Buffer)> {
90 let buffer = unwrap_here!(
91 "Create Vulkan buffer",
92 raii::Buffer::new(
93 "Allocated Buffer",
94 allocator.logical_device.clone(),
95 buffer_create_info,
96 )
97 );
98
99 let (requirements, dedicated) = {
100 let mut dedicated = vk::MemoryDedicatedRequirements::default();
101 let requirements = unsafe {
102 let mut out = vk::MemoryRequirements2::default()
103 .push_next(&mut dedicated);
104
105 allocator.logical_device.get_buffer_memory_requirements2(
106 &vk::BufferMemoryRequirementsInfo2 {
107 buffer: buffer.raw,
108 ..Default::default()
109 },
110 &mut out,
111 );
112
113 out.memory_requirements
114 };
115 (
116 requirements,
117 dedicated.prefers_dedicated_allocation == vk::TRUE
118 || dedicated.requires_dedicated_allocation == vk::TRUE,
119 )
120 };
121
122 let memory_allocate_flags = if buffer_create_info
123 .usage
124 .contains(vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS)
125 {
126 vk::MemoryAllocateFlags::DEVICE_ADDRESS
127 } else {
128 vk::MemoryAllocateFlags::empty()
129 };
130
131 let block = unwrap_here!(
132 "Allocate memory for Vulkan buffer",
133 allocator.allocate_memory(
134 &requirements,
135 memory_property_flags,
136 memory_allocate_flags,
137 dedicated,
138 )
139 );
140
141 unwrap_here!("Bind memory to Vulkan buffer", unsafe {
142 allocator.logical_device.bind_buffer_memory(
143 buffer.raw,
144 block.memory(),
145 block.offset(),
146 )
147 });
148
149 Ok((Self { block, allocator }, buffer))
150 }
151}
152
153impl std::ops::Deref for OwnedBlock {
154 type Target = Block;
155
156 fn deref(&self) -> &Self::Target {
157 &self.block
158 }
159}
160
161impl Drop for OwnedBlock {
162 fn drop(&mut self) {
163 self.allocator.free(&self.block);
164 }
165}