1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
//! All sorts of buffers
use std::ops::IndexMut;
use crate::{error::EnvironmentError, types::*};
use anyhow::{Context, Result};
use hal::{
buffer::Usage,
memory::{Properties, SparseFlags},
MemoryTypeId,
};
pub mod dedicated_image;
pub mod draw_buffers;
pub mod staged;
pub use dedicated_image::DedicatedLoadedImage;
pub use draw_buffers::DrawBuffers;
pub use staged::StagedBuffer;
/// Create a buffer of the given specifications, allocating more device memory.
// TODO: Use a different memory allocator?
pub(crate) fn create_buffer(
device: &mut DeviceT,
adapter: &Adapter,
usage: Usage,
properties: Properties,
size: u64,
) -> Result<(BufferT, MemoryT)> {
let mut buffer = unsafe { device.create_buffer(size, usage, SparseFlags::empty()) }
.context("Error creating buffer")?;
let requirements = unsafe { device.get_buffer_requirements(&buffer) };
let memory_type_id = adapter
.physical_device
.memory_properties()
.memory_types
.iter()
.enumerate()
.find(|&(id, memory_type)| {
requirements.type_mask & (1 << id) != 0 && memory_type.properties.contains(properties)
})
.map(|(id, _)| MemoryTypeId(id))
.ok_or(EnvironmentError::NoMemoryTypes)?;
let memory = unsafe { device.allocate_memory(memory_type_id, requirements.size) }
.context("Error allocating memory")?;
unsafe { device.bind_buffer_memory(&memory, 0, &mut buffer) }
.context("Error binding memory to buffer")?;
Ok((buffer, memory))
}
/// A buffer that can be modified by the CPU
pub trait ModifiableBuffer: IndexMut<usize> {
/// Get a handle to the underlying GPU buffer
fn get_buffer(&mut self) -> &BufferT;
/// Record the command(s) required to commit changes to this buffer to the given command buffer.
fn record_commit_cmds<'a>(&'a mut self, cmd_buffer: &mut CommandBufferT) -> Result<()>;
}
|