demo_vk/graphics/vulkan/allocator/
owned_block.rs1use {
2 crate::{
3 graphics::vulkan::{raii, Allocator, Block},
4 trace,
5 },
6 anyhow::{Context, 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 = raii::Image::new(
29 "Allocated Image",
30 allocator.logical_device.clone(),
31 image_create_info,
32 )
33 .with_context(trace!("Unable to create image!"))?;
34
35 let (requirements, dedicated) = {
36 let mut dedicated = vk::MemoryDedicatedRequirements::default();
37 let requirements = unsafe {
38 let mut out = vk::MemoryRequirements2::default()
39 .push_next(&mut dedicated);
40
41 allocator.logical_device.get_image_memory_requirements2(
42 &vk::ImageMemoryRequirementsInfo2 {
43 image: image.raw,
44 ..Default::default()
45 },
46 &mut out,
47 );
48
49 out.memory_requirements
50 };
51 (
52 requirements,
53 dedicated.prefers_dedicated_allocation == vk::TRUE
54 || dedicated.requires_dedicated_allocation == vk::TRUE,
55 )
56 };
57
58 let block = allocator
59 .allocate_memory(
60 &requirements,
61 memory_property_flags,
62 vk::MemoryAllocateFlags::empty(),
63 dedicated,
64 )
65 .with_context(trace!("Unable to allocate memory for image!"))?;
66
67 unsafe {
68 allocator
69 .logical_device
70 .bind_image_memory(image.raw, block.memory(), block.offset())
71 .with_context(trace!("Unable to bind image memory!"))?;
72 };
73
74 Ok((Self { block, allocator }, image))
75 }
76
77 pub fn allocate_buffer(
82 allocator: Arc<Allocator>,
83 buffer_create_info: &vk::BufferCreateInfo,
84 memory_property_flags: vk::MemoryPropertyFlags,
85 ) -> Result<(OwnedBlock, raii::Buffer)> {
86 let buffer = raii::Buffer::new(
87 "Allocated Buffer",
88 allocator.logical_device.clone(),
89 buffer_create_info,
90 )
91 .with_context(trace!("Unable to create buffer!"))?;
92
93 let (requirements, dedicated) = {
94 let mut dedicated = vk::MemoryDedicatedRequirements::default();
95 let requirements = unsafe {
96 let mut out = vk::MemoryRequirements2::default()
97 .push_next(&mut dedicated);
98
99 allocator.logical_device.get_buffer_memory_requirements2(
100 &vk::BufferMemoryRequirementsInfo2 {
101 buffer: buffer.raw,
102 ..Default::default()
103 },
104 &mut out,
105 );
106
107 out.memory_requirements
108 };
109 (
110 requirements,
111 dedicated.prefers_dedicated_allocation == vk::TRUE
112 || dedicated.requires_dedicated_allocation == vk::TRUE,
113 )
114 };
115
116 let memory_allocate_flags = if buffer_create_info
117 .usage
118 .contains(vk::BufferUsageFlags::SHADER_DEVICE_ADDRESS)
119 {
120 vk::MemoryAllocateFlags::DEVICE_ADDRESS
121 } else {
122 vk::MemoryAllocateFlags::empty()
123 };
124
125 let block = allocator
126 .allocate_memory(
127 &requirements,
128 memory_property_flags,
129 memory_allocate_flags,
130 dedicated,
131 )
132 .with_context(trace!("Unable to allocate memory for buffer!"))?;
133
134 unsafe {
135 allocator
136 .logical_device
137 .bind_buffer_memory(buffer.raw, block.memory(), block.offset())
138 .with_context(trace!("Unable to bind buffer to memory!"))?;
139 };
140
141 Ok((Self { block, allocator }, buffer))
142 }
143}
144
145impl std::ops::Deref for OwnedBlock {
146 type Target = Block;
147
148 fn deref(&self) -> &Self::Target {
149 &self.block
150 }
151}
152
153impl Drop for OwnedBlock {
154 fn drop(&mut self) {
155 self.allocator.free(&self.block);
156 }
157}