pub use rendy_core::hal::buffer::*;
use {
crate::{
core::{device_owned, Device, DeviceId},
memory::{Block, Heaps, MappedRange, MemoryBlock, MemoryUsage},
CreationError,
},
relevant::Relevant,
rendy_core::hal::{device::Device as _, Backend},
};
#[derive(Clone, Copy, Debug)]
pub struct BufferInfo {
pub size: u64,
pub usage: Usage,
}
#[derive(Debug)]
pub struct Buffer<B: Backend> {
device: DeviceId,
raw: B::Buffer,
block: MemoryBlock<B>,
info: BufferInfo,
relevant: Relevant,
}
device_owned!(Buffer<B>);
pub type BufferCreationError = CreationError<rendy_core::hal::buffer::CreationError>;
impl<B> Buffer<B>
where
B: Backend,
{
pub unsafe fn create(
device: &Device<B>,
heaps: &mut Heaps<B>,
info: BufferInfo,
memory_usage: impl MemoryUsage,
) -> Result<Self, BufferCreationError> {
log::trace!("{:#?}@{:#?}", info, memory_usage);
assert_ne!(info.size, 0);
let mut buf = device
.create_buffer(info.size, info.usage)
.map_err(CreationError::Create)?;
let reqs = device.get_buffer_requirements(&buf);
let block = heaps
.allocate(
device,
reqs.type_mask as u32,
memory_usage,
reqs.size,
reqs.alignment,
)
.map_err(CreationError::Allocate)?;
device
.bind_buffer_memory(block.memory(), block.range().start, &mut buf)
.map_err(CreationError::Bind)?;
Ok(Buffer {
device: device.id(),
raw: buf,
block,
info,
relevant: Relevant,
})
}
pub unsafe fn dispose(self, device: &Device<B>, heaps: &mut Heaps<B>) {
self.assert_device_owner(device);
device.destroy_buffer(self.raw);
heaps.free(device, self.block);
self.relevant.dispose();
}
pub fn raw(&self) -> &B::Buffer {
&self.raw
}
pub unsafe fn raw_mut(&mut self) -> &mut B::Buffer {
&mut self.raw
}
pub fn block(&self) -> &MemoryBlock<B> {
&self.block
}
pub unsafe fn block_mut(&mut self) -> &mut MemoryBlock<B> {
&mut self.block
}
pub fn info(&self) -> &BufferInfo {
&self.info
}
pub fn visible(&self) -> bool {
self.block
.properties()
.contains(rendy_core::hal::memory::Properties::CPU_VISIBLE)
}
pub fn map<'a>(
&'a mut self,
device: &Device<B>,
range: std::ops::Range<u64>,
) -> Result<MappedRange<'a, B>, rendy_core::hal::device::MapError> {
self.block.map(device, range)
}
pub fn size(&self) -> u64 {
self.info().size
}
}