demo_vk/graphics/vulkan/buffers/
cpu_buffer.rs1use {
2 crate::{
3 graphics::vulkan::{raii, OwnedBlock, VulkanContext},
4 unwrap_here,
5 },
6 anyhow::{bail, Result},
7 ash::vk,
8 std::marker::PhantomData,
9};
10
11#[derive(Debug)]
16pub struct CPUBuffer<DataT: Sized + Copy> {
17 buffer: raii::Buffer,
18 block: OwnedBlock,
19 count: usize,
20 _phantom_data: PhantomData<DataT>,
21}
22
23impl<DataT> CPUBuffer<DataT>
24where
25 DataT: Sized + Copy,
26{
27 pub fn allocate(
31 cxt: &VulkanContext,
32 count: usize,
33 usage: vk::BufferUsageFlags,
34 ) -> Result<Self> {
35 let buffer_size_in_bytes = (count * size_of::<DataT>()) as u64;
36
37 let (block, buffer) = unwrap_here!(
38 "Allocate host visible and coherent memory",
39 OwnedBlock::allocate_buffer(
40 cxt.allocator.clone(),
41 &vk::BufferCreateInfo {
42 size: buffer_size_in_bytes,
43 usage,
44 sharing_mode: vk::SharingMode::EXCLUSIVE,
45 queue_family_index_count: 1,
46 p_queue_family_indices: &cxt.graphics_queue_family_index,
47 ..Default::default()
48 },
49 vk::MemoryPropertyFlags::HOST_VISIBLE
50 | vk::MemoryPropertyFlags::HOST_COHERENT,
51 )
52 );
53
54 Ok(Self {
55 buffer,
56 block,
57 count,
58 _phantom_data: PhantomData,
59 })
60 }
61
62 pub fn buffer(&self) -> vk::Buffer {
64 self.buffer.raw
65 }
66
67 pub fn size_in_bytes(&self) -> u64 {
69 (self.count * size_of::<DataT>()) as u64
70 }
71
72 pub fn capacity(&self) -> usize {
74 self.count
75 }
76
77 pub unsafe fn write_data(
84 &mut self,
85 start_index: usize,
86 data: &[DataT],
87 ) -> Result<()> {
88 if start_index + data.len() > self.count {
89 bail!(
90 "Out of bounds write attempted! {}/{}",
91 start_index + data.len(),
92 self.count
93 );
94 }
95
96 std::ptr::copy_nonoverlapping(
97 data.as_ptr(),
98 (self.block.mapped_ptr() as *mut DataT).add(start_index),
99 data.len(),
100 );
101
102 Ok(())
103 }
104}