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
64
65
66
67
68
|
//! 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,
};
mod dedicated_image;
mod draw_buffers;
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;
/// Commit all changes to GPU memory, returning a handle to the GPU buffer
fn commit<'a>(
&'a mut self,
device: &DeviceT,
command_queue: &mut QueueT,
command_pool: &mut CommandPoolT,
) -> Result<&'a BufferT>;
}
|