You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
4.1 KiB
104 lines
4.1 KiB
use std::sync::Arc;
|
|
use vulkano::device::Device;
|
|
use vulkano::buffer::{CpuAccessibleBuffer, BufferUsage};
|
|
use vulkano::pipeline::ComputePipeline;
|
|
use vulkano::descriptor::pipeline_layout::PipelineLayout;
|
|
use vulkano::descriptor::descriptor_set::{PersistentDescriptorSet, PersistentDescriptorSetBuf};
|
|
use image::ImageBuffer;
|
|
use image::Rgba;
|
|
use shade_runner::Layout;
|
|
use crate::compute::managed::handles::CompuBufferHandle;
|
|
|
|
|
|
#[derive(Clone)]
|
|
pub struct CompuBuffers {
|
|
dimensions: (u32, u32),
|
|
device: Arc<Device>,
|
|
handle: Arc<CompuBufferHandle>,
|
|
|
|
io_buffers: Vec<Arc<CpuAccessibleBuffer<[u8]>>>,
|
|
settings_buffer: Arc<CpuAccessibleBuffer<[u32]>>,
|
|
}
|
|
|
|
impl CompuBuffers {
|
|
pub fn new(device: Arc<Device>, data: Vec<u8>,
|
|
dimensions: (u32, u32), stride: u32,
|
|
handle: Arc<CompuBufferHandle>) -> CompuBuffers {
|
|
|
|
let data_length = dimensions.0 * dimensions.1 * stride;
|
|
|
|
let input_buffer = {
|
|
let mut buff = data.iter();
|
|
let data_iter = (0..data_length).map(|n| *(buff.next().unwrap()));
|
|
CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), data_iter).unwrap()
|
|
};
|
|
|
|
let output_buffer = {
|
|
let mut buff = data.iter();
|
|
let data_iter = (0..data_length).map(|n| *(buff.next().unwrap()));
|
|
CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), data_iter).unwrap()
|
|
};
|
|
|
|
// Settings buffer which holds i32's
|
|
// TODO: Compile macros into the kernel eventually to index them
|
|
let settings_buffer = {
|
|
let vec = vec![dimensions.0, dimensions.1];
|
|
let mut buff = vec.iter();
|
|
let data_iter =
|
|
(0..2).map(|n| *(buff.next().unwrap()));
|
|
CpuAccessibleBuffer::from_iter(device.clone(),
|
|
BufferUsage::all(),
|
|
data_iter).unwrap()
|
|
};
|
|
|
|
CompuBuffers {
|
|
dimensions: dimensions,
|
|
device: device.clone(),
|
|
|
|
handle: handle,
|
|
io_buffers: vec![input_buffer, output_buffer],
|
|
settings_buffer: settings_buffer,
|
|
}
|
|
}
|
|
|
|
pub fn get_size(&self) -> (u32, u32) {
|
|
self.dimensions
|
|
}
|
|
|
|
pub fn get_descriptor_set(&self, compute_pipeline: std::sync::Arc<ComputePipeline<PipelineLayout<Layout>>>)
|
|
-> Arc<PersistentDescriptorSet<std::sync::Arc<ComputePipeline<PipelineLayout<Layout>>>, ((((),
|
|
PersistentDescriptorSetBuf<std::sync::Arc<vulkano::buffer::cpu_access::CpuAccessibleBuffer<[u8]>>>),
|
|
PersistentDescriptorSetBuf<std::sync::Arc<vulkano::buffer::cpu_access::CpuAccessibleBuffer<[u8]>>>),
|
|
PersistentDescriptorSetBuf<std::sync::Arc<vulkano::buffer::cpu_access::CpuAccessibleBuffer<[u32]>>>)>> {
|
|
|
|
Arc::new(PersistentDescriptorSet::start(compute_pipeline.clone(), 0)
|
|
.add_buffer(self.io_buffers.get(0).unwrap().clone()).unwrap()
|
|
.add_buffer(self.io_buffers.get(1).unwrap().clone()).unwrap()
|
|
.add_buffer(self.settings_buffer.clone()).unwrap()
|
|
.build().unwrap())
|
|
}
|
|
|
|
pub fn read_output_buffer(&self) -> ImageBuffer<Rgba<u8>, Vec<u8>> {
|
|
let xy = self.get_size();
|
|
|
|
self.io_buffers.get(1).unwrap().write().unwrap().map(|x| x);
|
|
let data_buffer_content = self.io_buffers.get(1).unwrap().read().unwrap();
|
|
ImageBuffer::from_fn(xy.0, xy.1, |x, y| {
|
|
let r = data_buffer_content[((xy.0 * y + x) * 4 + 0) as usize] as u8;
|
|
let g = data_buffer_content[((xy.0 * y + x) * 4 + 1) as usize] as u8;
|
|
let b = data_buffer_content[((xy.0 * y + x) * 4 + 2) as usize] as u8;
|
|
let a = data_buffer_content[((xy.0 * y + x) * 4 + 3) as usize] as u8;
|
|
|
|
image::Rgba([r, g, b, a])
|
|
})
|
|
}
|
|
|
|
pub fn get_input_buffer(&self) -> Arc<CpuAccessibleBuffer<[u8]>> {
|
|
self.io_buffers.get(0).unwrap().clone()
|
|
}
|
|
|
|
pub fn get_output_buffer(&self) -> Arc<CpuAccessibleBuffer<[u8]>> {
|
|
self.io_buffers.get(1).unwrap().clone()
|
|
}
|
|
}
|