|
|
@ -27,7 +27,7 @@ use std::io::Read;
|
|
|
|
use rusttype::{Font, PositionedGlyph, Scale, Rect, point, GlyphId, Line, Curve, Segment};
|
|
|
|
use rusttype::{Font, PositionedGlyph, Scale, Rect, point, GlyphId, Line, Curve, Segment};
|
|
|
|
use vulkano::pipeline::vertex::{VertexDefinition, Vertex};
|
|
|
|
use vulkano::pipeline::vertex::{VertexDefinition, Vertex};
|
|
|
|
use crate::canvas::managed::shader::dynamic_vertex::RuntimeVertexDef;
|
|
|
|
use crate::canvas::managed::shader::dynamic_vertex::RuntimeVertexDef;
|
|
|
|
use crate::canvas::managed::handles::{CanvasTextureHandle, CanvasImageHandle, CanvasFontHandle, CompiledShaderHandle, Handle, DrawableHandle};
|
|
|
|
use crate::canvas::managed::handles::{CanvasTextureHandle, CanvasImageHandle, CanvasFontHandle, CompiledShaderHandle, Handle, DrawableHandle, CompuBufferHandle, CompuKernelHandle};
|
|
|
|
use crate::canvas::managed::gpu_buffers::{CanvasImage, CanvasTexture, CanvasFont};
|
|
|
|
use crate::canvas::managed::gpu_buffers::{CanvasImage, CanvasTexture, CanvasFont};
|
|
|
|
use crate::canvas::managed::shader::shader_common::CompiledShader;
|
|
|
|
use crate::canvas::managed::shader::shader_common::CompiledShader;
|
|
|
|
use crate::canvas::managed::shader::generic_shader::GenericShader;
|
|
|
|
use crate::canvas::managed::shader::generic_shader::GenericShader;
|
|
|
@ -35,6 +35,9 @@ use crate::VertexTypeContainer;
|
|
|
|
use crate::util::vertex::{TextVertex3D, TextureVertex3D, ImageVertex3D, ColorVertex3D, CanvasFrameAllocation};
|
|
|
|
use crate::util::vertex::{TextVertex3D, TextureVertex3D, ImageVertex3D, ColorVertex3D, CanvasFrameAllocation};
|
|
|
|
use shade_runner::Input;
|
|
|
|
use shade_runner::Input;
|
|
|
|
use winit::window::Window;
|
|
|
|
use winit::window::Window;
|
|
|
|
|
|
|
|
use crate::canvas::managed::compu_buffer::CompuBuffers;
|
|
|
|
|
|
|
|
use crate::canvas::managed::compu_kernel::CompuKernel;
|
|
|
|
|
|
|
|
use crate::canvas::compu_frame::CompuFrame;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Canvas state is used for storage of texture and image buffers in addition to vertex buffers
|
|
|
|
/// Canvas state is used for storage of texture and image buffers in addition to vertex buffers
|
|
|
@ -58,6 +61,9 @@ pub struct CanvasState {
|
|
|
|
queue: Arc<Queue>,
|
|
|
|
queue: Arc<Queue>,
|
|
|
|
device: Arc<Device>,
|
|
|
|
device: Arc<Device>,
|
|
|
|
render_pass: Arc<dyn RenderPassAbstract + Send + Sync>,
|
|
|
|
render_pass: Arc<dyn RenderPassAbstract + Send + Sync>,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
compute_buffers: Vec<CompuBuffers>,
|
|
|
|
|
|
|
|
kernels: Vec<CompuKernel>,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -133,6 +139,9 @@ impl CanvasState {
|
|
|
|
|
|
|
|
|
|
|
|
CanvasState {
|
|
|
|
CanvasState {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
compute_buffers: vec![],
|
|
|
|
|
|
|
|
kernels: vec![],
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: Might need to move this
|
|
|
|
// TODO: Might need to move this
|
|
|
|
dynamic_state: DynamicState {
|
|
|
|
dynamic_state: DynamicState {
|
|
|
|
line_width: None,
|
|
|
|
line_width: None,
|
|
|
@ -167,6 +176,133 @@ impl CanvasState {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub fn read_compute_buffer(&mut self, handle: Arc<CompuBufferHandle>) -> Vec<u8> {
|
|
|
|
|
|
|
|
let mut buffer : &CompuBuffers = self.compute_buffers.get(handle.handle as usize).unwrap();
|
|
|
|
|
|
|
|
let v = buffer.read_output_buffer();
|
|
|
|
|
|
|
|
v.into_vec()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Write to the compute buffer, ostensibly overwriting what's already there
|
|
|
|
|
|
|
|
pub fn write_compute_buffer(&self, handle: Arc<CompuBufferHandle>, data: Vec<u8>) {
|
|
|
|
|
|
|
|
unimplemented!("read_compute_buffer is not implemented")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub fn new_kernel(&mut self,
|
|
|
|
|
|
|
|
filename: String,
|
|
|
|
|
|
|
|
device: Arc<Device>) -> Arc<CompuKernelHandle> {
|
|
|
|
|
|
|
|
let handle = Arc::new(CompuKernelHandle {
|
|
|
|
|
|
|
|
handle: self.kernels.len() as u32
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.kernels.push((CompuKernel::new(filename, device.clone(), handle.clone())));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handle
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub fn get_kernel_handle(&self, kernel_name: String) -> Option<Arc<CompuKernelHandle>> {
|
|
|
|
|
|
|
|
for i in self.kernels.clone() {
|
|
|
|
|
|
|
|
if i.get_name() == kernel_name {
|
|
|
|
|
|
|
|
return Some(i.get_handle());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
None
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub fn compute_commands(&mut self,
|
|
|
|
|
|
|
|
compute_frame: &CompuFrame,
|
|
|
|
|
|
|
|
mut command_buffer: &mut AutoCommandBufferBuilder) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// i = (Buffer, Kernel)
|
|
|
|
|
|
|
|
for i in &compute_frame.pure_compute {
|
|
|
|
|
|
|
|
let buffer_id = (*i.0).clone().get_handle() as usize;
|
|
|
|
|
|
|
|
let kernel_id = (*i.1).clone().get_handle() as usize;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let buffer = self.compute_buffers.get(buffer_id).unwrap();
|
|
|
|
|
|
|
|
let kernel = self.kernels.get(kernel_id).unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let pipeline = kernel.clone().get_pipeline();
|
|
|
|
|
|
|
|
let descriptorset = buffer.get_descriptor_set(kernel.clone().get_pipeline());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let size = buffer.get_size();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
command_buffer = command_buffer
|
|
|
|
|
|
|
|
.dispatch([size.0 / 8, size.1 / 8, 1], pipeline, descriptorset, ()).unwrap()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// i = (Buffer, Image, Kernel)
|
|
|
|
|
|
|
|
for i in &compute_frame.swapped_to_image {
|
|
|
|
|
|
|
|
let buffer_id = (*i.0).clone().get_handle() as usize;
|
|
|
|
|
|
|
|
let image_id = i.1.clone();
|
|
|
|
|
|
|
|
let kernel_id = (*i.2).clone().handle as usize;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let buffer = self.compute_buffers.get(buffer_id).unwrap();
|
|
|
|
|
|
|
|
let image = self.get_image(image_id);
|
|
|
|
|
|
|
|
let kernel = self.kernels.get(kernel_id).unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let p = kernel.clone().get_pipeline();
|
|
|
|
|
|
|
|
let d = buffer.get_descriptor_set(kernel.clone().get_pipeline());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let dimensions = image.dimensions();
|
|
|
|
|
|
|
|
let dimensions = (dimensions.width(), dimensions.height());
|
|
|
|
|
|
|
|
if dimensions != buffer.get_size() {
|
|
|
|
|
|
|
|
panic!("Buffer sizes not the same");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let size = buffer.get_size();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
command_buffer = command_buffer
|
|
|
|
|
|
|
|
.dispatch([size.0 / 8, size.1 / 8, 1], p, d, ()).unwrap()
|
|
|
|
|
|
|
|
.copy_buffer_to_image(buffer.get_output_buffer(), image).unwrap();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// i = (Input Buffer, Output Buffer, Kernel)
|
|
|
|
|
|
|
|
// Input buffer -> Kernel -> Output buffer
|
|
|
|
|
|
|
|
for i in &compute_frame.swapped_to_buffer {
|
|
|
|
|
|
|
|
let input_buffer_id = (*i.0).clone().get_handle() as usize;
|
|
|
|
|
|
|
|
let output_buffer_id = (*i.1).clone().get_handle() as usize;
|
|
|
|
|
|
|
|
let kernel_id = (*i.2).clone().handle as usize;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let input_buffer = self.compute_buffers.get(input_buffer_id).unwrap();
|
|
|
|
|
|
|
|
let output_buffer = self.compute_buffers.get(output_buffer_id).unwrap();
|
|
|
|
|
|
|
|
let kernel = self.kernels.get(kernel_id).unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let pipeline = kernel.clone().get_pipeline();
|
|
|
|
|
|
|
|
let descriptor_set = input_buffer.get_descriptor_set(kernel.clone().get_pipeline());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if input_buffer.get_size() != output_buffer.get_size() {
|
|
|
|
|
|
|
|
panic!("Buffer sizes not the same");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
let size = input_buffer.get_size();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
command_buffer = command_buffer
|
|
|
|
|
|
|
|
// .dispatch([size.0/8, size.1/8,1], pipeline, descriptor_set, ()).unwrap()
|
|
|
|
|
|
|
|
.copy_buffer(
|
|
|
|
|
|
|
|
input_buffer.get_output_buffer(),
|
|
|
|
|
|
|
|
output_buffer.get_input_buffer()).unwrap();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Creates a 2d compute buffer from incoming data
|
|
|
|
|
|
|
|
pub fn new_compute_buffer(&mut self,
|
|
|
|
|
|
|
|
data: Vec<u8>,
|
|
|
|
|
|
|
|
dimensions: (u32, u32),
|
|
|
|
|
|
|
|
stride: u32,
|
|
|
|
|
|
|
|
device: Arc<Device>) -> Arc<CompuBufferHandle> {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let handle = Arc::new(CompuBufferHandle {
|
|
|
|
|
|
|
|
handle: self.compute_buffers.len() as u32
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.compute_buffers.push(
|
|
|
|
|
|
|
|
(CompuBuffers::new(device.clone(), data, dimensions, stride, handle.clone())));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
handle
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Using the dimensions and suggested usage, load a CanvasImage and return it's handle
|
|
|
|
/// Using the dimensions and suggested usage, load a CanvasImage and return it's handle
|
|
|
|
pub fn create_image(&mut self, dimensions: (u32, u32), usage: ImageUsage) -> Arc<CanvasImageHandle> {
|
|
|
|
pub fn create_image(&mut self, dimensions: (u32, u32), usage: ImageUsage) -> Arc<CanvasImageHandle> {
|
|
|
|
let handle = Arc::new(CanvasImageHandle { handle: self.image_buffers.len() as u32 });
|
|
|
|
let handle = Arc::new(CanvasImageHandle { handle: self.image_buffers.len() as u32 });
|
|
|
|