demo_vk/graphics/vulkan/buffers/
cpu_buffer.rs1use {
2 crate::{
3 graphics::vulkan::{raii, OwnedBlock, VulkanContext},
4 trace,
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) = OwnedBlock::allocate_buffer(
38 cxt.allocator.clone(),
39 &vk::BufferCreateInfo {
40 size: buffer_size_in_bytes,
41 usage,
42 sharing_mode: vk::SharingMode::EXCLUSIVE,
43 queue_family_index_count: 1,
44 p_queue_family_indices: &cxt.graphics_queue_family_index,
45 ..Default::default()
46 },
47 vk::MemoryPropertyFlags::HOST_VISIBLE
48 | vk::MemoryPropertyFlags::HOST_COHERENT,
49 )?;
50
51 Ok(Self {
52 buffer,
53 block,
54 count,
55 _phantom_data: PhantomData,
56 })
57 }
58
59 pub fn buffer(&self) -> vk::Buffer {
61 self.buffer.raw
62 }
63
64 pub fn size_in_bytes(&self) -> u64 {
66 (self.count * size_of::<DataT>()) as u64
67 }
68
69 pub fn capacity(&self) -> usize {
71 self.count
72 }
73
74 pub unsafe fn write_data(
81 &mut self,
82 start_index: usize,
83 data: &[DataT],
84 ) -> Result<()> {
85 if start_index + data.len() > self.count {
86 bail!(trace!(
87 "Out of bounds write attempted! {}/{}",
88 start_index + data.len(),
89 self.count
90 )());
91 }
92
93 std::ptr::copy_nonoverlapping(
94 data.as_ptr(),
95 (self.block.mapped_ptr() as *mut DataT).add(start_index),
96 data.len(),
97 );
98
99 Ok(())
100 }
101}