iv/src/renderer/pipeline/attachement.rs
Steins7 dd1d214a4a Started implementing triangle pipeline
+ Pipeline new() and drop()
+ Attachement new(() and drop()
+ draw_triangle_frame
! crashes at pipeline creation
2021-01-30 12:05:48 +01:00

136 lines
4.0 KiB
Rust

#[allow(unused_imports)]
use log::{debug, error, info, trace, warn};
use std::mem::ManuallyDrop;
use crate::renderer::gpu::Gpu;
//--Attachement implementation----------------------------------------------------------------------
#[derive(Debug)]
pub struct Attachement<B: gfx_hal::Backend> {
buffer: ManuallyDrop<B::Buffer>,
memory: ManuallyDrop<B::Memory>,
size: u64,
}
impl<B> Attachement<B>
where
B: gfx_hal::Backend,
{
pub fn drop(mut self, gpu: &mut Gpu<B>) {
use std::ptr::read;
use gfx_hal::device::Device;
debug!("Dropping Attachement...");
unsafe {
gpu.device()
.free_memory(ManuallyDrop::into_inner(read(&mut self.memory)));
gpu.device()
.destroy_buffer(ManuallyDrop::into_inner(read(&mut self.buffer)));
}
}
pub fn new(gpu: &mut Gpu<B>) -> Result<Attachement<B>, &'static str> {
use std::mem::size_of;
use gfx_hal::{
device::Device,
adapter::PhysicalDevice,
buffer::Usage,
};
debug!("Creating attachement...");
let mut buffer = unsafe {
gpu.device()
.create_buffer((size_of::<f32>()*2*3) as u64, Usage::VERTEX)
.map_err(|_| "Could not create buffer")?
};
trace!("Creating underlying attachement memory...");
let (memory, size) = {
use gfx_hal::{
memory::Properties,
MemoryTypeId,
};
let requirements = unsafe {
gpu.device().get_buffer_requirements(&buffer)
};
let memory_type = gpu.adapter()
.physical_device
.memory_properties()
.memory_types
.iter()
.enumerate()
.find(|&(id, memory_type)| {
requirements.type_mask & (1 << id) != 0 &&
memory_type.properties.contains(Properties::CPU_VISIBLE)})
.map(|(id, _)| MemoryTypeId(id))
.ok_or("Could not find a suitable memory type to allocate attachement memory")?;
(
unsafe {
gpu.device()
.allocate_memory(memory_type, requirements.size)
.map_err(|_| "Could not allocate buffer memory...")?
},
requirements.size,
)};
trace!("Binding memory to buffer...");
unsafe {
gpu.device()
.bind_buffer_memory(&memory, 0, &mut buffer)
.map_err(|__| "Could not bind memory to buffer")?;
}
Ok( Attachement {
buffer: ManuallyDrop::new(buffer),
memory: ManuallyDrop::new(memory),
size,
})
}
pub fn get_buffer(&self) -> &B::Buffer {
//manual deref for ManuallyDrop to not cause troubles
&self.buffer
}
pub fn write_buffer(&self, gpu: &Gpu<B>, data: Vec<f32>) -> Result<(), &'static str>
{
use gfx_hal::{
device::Device,
memory::Segment,
};
trace!("writing data to buffer...");
unsafe {
let mapped_memory = gpu.device()
.map_memory(&self.memory, Segment::ALL)
.map_err(|_| "Could not map buffer memory")?;
//debug!("before : {}", std::ptr::read(mapped_memory as *mut f32));
std::ptr::copy_nonoverlapping(data.as_ptr() as *const u8,
mapped_memory, self.size as usize);
//debug!("after : {}", std::ptr::read(mapped_memory as *mut f32));
//manual deref for ManuallyDrop to not cause troubles
let memory_ref: &B::Memory = &self.memory;
gpu.device()
.flush_mapped_memory_ranges(std::iter::once((memory_ref, Segment::ALL)))
.map_err(|_| "Could not flush mapped buffer memory")?;
gpu.device().unmap_memory(&self.memory);
}
Ok(())
}
}