diff --git a/src/canvas.rs b/src/canvas.rs index 245cfa86..a6fdd4b6 100644 --- a/src/canvas.rs +++ b/src/canvas.rs @@ -51,31 +51,22 @@ it appears that renderpass is tied to the individual shader pub trait Vertex { fn position(&self) -> (f32, f32) { - (0.0,0.0) + (0.0, 0.0) } fn color(&self) -> Option<(f32, f32, f32, f32)> { - Some((0.,0.,0.,0.)) - } - - fn textured(&self) -> bool { - false + Some((0., 0., 0., 0.)) } } impl Vertex for ColoredVertex2D { - fn position(&self) -> (f32, f32) { - (0.0,0.0) + (0.0, 0.0) } fn color(&self) -> Option<(f32, f32, f32, f32)> { - Some((0.,0.,0.,0.)) - } - - fn textured(&self) -> bool { - false + Some((0., 0., 0., 0.)) } } @@ -86,54 +77,71 @@ pub trait Drawable { fn get_image_handle(&self) -> Option>; } -// Need three types of shaders. Solid, Textured, Compute +// Need three types of shaders. Solid, Textured, Image #[derive(PartialEq, Eq, Hash, Clone)] pub enum ShaderType { SOLID = 0, TEXTURED = 1, - COMPUTE = 2 + IMAGE = 2, } pub struct CanvasFrame { - colored_drawables : Vec, - textured_drawables: HashMap, Vec>, + colored_drawables: Vec, + textured_drawables: HashMap, Vec>>, + image_drawables: HashMap, Vec>>, } impl CanvasFrame { - + pub fn new() -> CanvasFrame { CanvasFrame { colored_drawables: vec![], - textured_drawables: Default::default() + textured_drawables: Default::default(), + image_drawables: Default::default() } } - // After done using this, need to call allocated vertex buffers + // Accumulates the drawables vertices and colors pub fn draw(&mut self, drawable: &dyn Drawable) { match drawable.get_texture_handle() { - Some(id) => { + Some(handle) => { self.textured_drawables - .entry(id.clone()) + .entry(handle.clone()) .or_insert(Vec::new()) - .extend(drawable.get_vertices().iter().map(|n| + .push(drawable.get_vertices().iter().map(|n| Vertex2D { position: [n.0, n.1], } - )); - - }, + ).collect::>()); + } None => { - let colors = drawable.get_color(); - self.colored_drawables.extend( - drawable.get_vertices().iter().map(|n| - ColoredVertex2D { - position: [n.0, n.1], - color: [colors.0, colors.1, colors.2, colors.3] - } - ) - ); + match drawable.get_image_handle() { + + Some(handle) => { + self.image_drawables + .entry(handle.clone()) + .or_insert(Vec::new()) + .push(drawable.get_vertices().iter().map(|n| + Vertex2D { + position: [n.0, n.1], + } + ).collect()); + } + None => { + let colors = drawable.get_color(); + + self.colored_drawables.extend( + drawable.get_vertices().iter().map(|n| + ColoredVertex2D { + position: [n.0, n.1], + color: [colors.0, colors.1, colors.2, colors.3], + } + ) + ); + } + } } } } @@ -142,31 +150,63 @@ impl CanvasFrame { #[derive(Clone)] pub struct Canvas { - - colored_drawables : Vec, - colored_vertex_buffer: Vec>, - - textured_drawables: HashMap, Vec>, - textured_vertex_buffer: HashMap, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>, - shader_kernels: HashMap, texture_store: HashMap>>, dynamic_state: DynamicState, + sampler: Arc, + // hold the image, texture, and shader buffers the same was as we do CompuState image_buffers: Vec>, image_buffer_handles: Vec>, + texture_buffers: Vec>>, + texture_buffer_handles: Vec>, + + shader_buffers: HashMap, + shader_buffer_handles: Vec>, + + // Hold onto the vertices we get from the Compu and Canvas Frames + // When the run comes around, push the vertices to the GPU + colored_drawables: Vec, + colored_vertex_buffer: Vec>, + + textured_drawables: HashMap, Vec>>, + textured_vertex_buffer: HashMap, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>, + + image_drawables: HashMap, Vec>>, + image_vertex_buffer: HashMap, Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync)>>, + // Looks like we gotta hold onto the queue for managing textures queue: Arc, - sampler: Arc, device: Arc, } impl Canvas { + // This method is called once during initialization, then again whenever the window is resized + pub fn window_size_dependent_setup(&mut self, images: &[Arc>]) + -> Vec> { + let dimensions = images[0].dimensions(); + + self.dynamic_state.viewports = + Some(vec![Viewport { + origin: [0.0, 0.0], + dimensions: [dimensions.width() as f32, dimensions.height() as f32], + depth_range: 0.0..1.0, + }]); + + images.iter().map(|image| { + Arc::new( + Framebuffer::start(self.shader_kernels.get(&ShaderType::SOLID).unwrap().render_pass.clone()) + .add(image.clone()).unwrap() + .build().unwrap() + ) as Arc + }).collect::>() + } + // needs to take in the texture list pub fn new(queue: Arc, device: Arc, @@ -176,33 +216,36 @@ impl Canvas { let solid_color_kernel = String::from("color-passthrough"); let texture_kernel = String::from("simple_texture"); - let shader_kernels = HashMap::from_iter(vec![ - (ShaderType::SOLID, ShaderKernels::new(solid_color_kernel, capabilities.clone(), queue.clone(), physical.clone(), device.clone())), - //(ShaderType::TEXTURED, ShaderKernels::new(texture_kernel, capabilities.clone(), queue.clone(), physical.clone(), device.clone())) - ]); + let shader_kernels : HashMap = HashMap::from_iter(vec![ + (ShaderType::SOLID, ShaderKernels::new(solid_color_kernel, capabilities.clone(), queue.clone(), physical.clone(), device.clone())), + (ShaderType::TEXTURED, ShaderKernels::new(texture_kernel, capabilities.clone(), queue.clone(), physical.clone(), device.clone())) + ]); + Canvas { + shader_kernels: Default::default(), + texture_store: Default::default(), + + dynamic_state: DynamicState { line_width: None, viewports: None, scissors: None }, + sampler: Sampler::new(device.clone(), Filter::Linear, Filter::Linear, + MipmapMode::Nearest, SamplerAddressMode::Repeat, SamplerAddressMode::Repeat, + SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, 0.0).unwrap(), + image_buffers: vec![], + image_buffer_handles: vec![], + texture_buffers: vec![], + texture_buffer_handles: vec![], + shader_buffers: Default::default(), + shader_buffer_handles: vec![], colored_drawables: vec![], colored_vertex_buffer: vec![], - textured_drawables: Default::default(), textured_vertex_buffer: Default::default(), + image_drawables: Default::default(), + image_vertex_buffer: Default::default(), - shader_kernels: shader_kernels, - texture_store: Default::default(), - - dynamic_state: DynamicState { line_width: None, viewports: None, scissors: None }, - - image_buffers: Vec::new(), - image_buffer_handles: Vec::new(), - - device: device.clone(), queue: queue.clone(), - sampler: Sampler::new(device.clone(), Filter::Linear, Filter::Linear, - MipmapMode::Nearest, SamplerAddressMode::Repeat, SamplerAddressMode::Repeat, - SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, 0.0).unwrap(), - + device: device.clone(), } } @@ -220,7 +263,6 @@ impl Canvas { // TODO Handle file not found gracefully fn get_texture_from_file(&self, image_filename: String) -> Arc> { - let project_root = std::env::current_dir() .expect("failed to get root directory"); @@ -255,14 +297,13 @@ impl Canvas { image_buffer.iter().cloned(), Dimensions::Dim2d { width: xy.0, height: xy.1 }, Format::R8G8B8A8Srgb, - self.queue.clone() + self.queue.clone(), ).unwrap(); texture } pub fn load_texture_from_filename(&mut self, filename: String) -> Arc> { - if self.texture_store.contains_key(&filename.clone()) { println!("{} Already exists, not going to replace it.", filename.clone()); self.texture_store.get(&filename.clone()).unwrap().clone() @@ -273,15 +314,25 @@ impl Canvas { } } + pub fn load_texture(&mut self, filename: String) -> Option> { + let texture_buffer = self.get_texture_from_file(filename.clone()); + self.texture_buffers.push(texture_buffer.clone()); + let id = Arc::new(self.texture_buffers.len() as u32); + self.texture_buffer_handles.push(id.clone()); + Some(id) + } + + // After done using this, need to call allocated vertex buffers pub fn draw(&mut self, canvas_frame: CanvasFrame) { self.textured_drawables = canvas_frame.textured_drawables; self.colored_drawables = canvas_frame.colored_drawables; - } + self.image_drawables = canvas_frame.image_drawables; + self.allocate_vertex_buffers(self.device.clone()); + } fn get_texture(&self, texture_id: String) -> Arc> { - if let Some(i) = self.texture_store.get(&texture_id) { return i.clone(); } else { @@ -290,9 +341,9 @@ impl Canvas { } pub fn allocate_vertex_buffers(&mut self, device: Arc) { - self.colored_vertex_buffer.clear(); self.textured_vertex_buffer.clear(); + self.image_vertex_buffer.clear(); //TODO should probably use cpu accessible buffer instead of recreating immutes each frame @@ -317,28 +368,26 @@ impl Canvas { v.iter().cloned(), BufferUsage::vertex_buffer(), self.queue.clone(), - ).unwrap().0 + ).unwrap().0, ); } } fn get_solid_color_descriptor_set(&self) -> Box { - println!("{}", self.shader_kernels.get(&ShaderType::SOLID).unwrap().clone().get_pipeline().clone().num_sets()); let o: Box = Box::new( PersistentDescriptorSet::start( - self.shader_kernels.get(&ShaderType::SOLID).unwrap().clone().get_pipeline().clone(), 0 + self.shader_kernels.get(&ShaderType::SOLID).unwrap().clone().get_pipeline().clone(), 0, ).build().unwrap()); o } fn get_textured_descriptor_set(&self, texture_id: String) - -> Box { - + -> Box { let o: Box = Box::new( PersistentDescriptorSet::start( - self.shader_kernels.get(&ShaderType::TEXTURED).unwrap().clone().get_pipeline().clone(), 0 + self.shader_kernels.get(&ShaderType::TEXTURED).unwrap().clone().get_pipeline().clone(), 0, ) .add_sampled_image(self.get_texture(texture_id), self.sampler.clone()).unwrap() .build().unwrap()); @@ -351,24 +400,19 @@ impl Canvas { fn get_compute_swap_descriptor_set(&mut self, device: Arc, compute_image: &ComputeImage) -> Box { - let sampler = Sampler::new(device.clone(), Filter::Linear, Filter::Linear, MipmapMode::Nearest, SamplerAddressMode::Repeat, SamplerAddressMode::Repeat, SamplerAddressMode::Repeat, 0.0, 1.0, 0.0, 0.0).unwrap(); - let o : Box = Box::new( + let o: Box = Box::new( PersistentDescriptorSet::start( - self.shader_kernels.get(&ShaderType::COMPUTE).clone().unwrap().clone().get_pipeline(), 0 + self.shader_kernels.get(&ShaderType::IMAGE).clone().unwrap().clone().get_pipeline(), 0, ) .add_image(compute_image.clone().get_swap_buffer().clone()).unwrap() .build().unwrap()); o } - /* - - - */ pub fn draw_commands(&self, mut command_buffer: AutoCommandBufferBuilder, framebuffers: Vec>, @@ -378,7 +422,7 @@ impl Canvas { let clear_values = vec!(ClearValue::Float([0.0, 0.0, 1.0, 1.0])); let mut command_buffer = command_buffer.begin_render_pass( - framebuffers[image_num].clone(), false, clear_values.clone() + framebuffers[image_num].clone(), false, clear_values.clone(), ).unwrap(); @@ -389,17 +433,19 @@ impl Canvas { kernel.clone().get_pipeline().clone(), &self.dynamic_state.clone(), self.colored_vertex_buffer.clone(), - (), () + (), (), ).unwrap(); - }, + } ShaderType::TEXTURED => { // command_buffer = command_buffer.draw( // kernel.clone().get_pipeline().clone(), // &dynamic_state.clone(), self.textured_vertex_buffer.clone(), // vec![self.get_textured_descriptor_set(String::from("funky-bird.jpg"))], () // ).unwrap(); - }, - ShaderType::COMPUTE => {}, + } + ShaderType::IMAGE => { + + } } } @@ -408,28 +454,6 @@ impl Canvas { .unwrap() } - /// This method is called once during initialization, then again whenever the window is resized - pub fn window_size_dependent_setup(&mut self, - images: &[Arc>], - ) -> Vec> { - - let dimensions = images[0].dimensions(); - - self.dynamic_state.viewports = - Some(vec![Viewport { - origin: [0.0, 0.0], - dimensions: [dimensions.width() as f32, dimensions.height() as f32], - depth_range: 0.0..1.0, - }]); - - images.iter().map(|image| { - Arc::new( - Framebuffer::start(self.shader_kernels.get(&ShaderType::SOLID).unwrap().render_pass.clone()) - .add(image.clone()).unwrap() - .build().unwrap() - ) as Arc - }).collect::>() - } } diff --git a/src/compu_wip.rs b/src/compu_wip.rs index 4a3c0b75..05b09fb2 100644 --- a/src/compu_wip.rs +++ b/src/compu_wip.rs @@ -130,9 +130,9 @@ impl CompuBuffers { pub fn get_descriptor_set(&self, compute_pipeline: std::sync::Arc>>) -> Arc>>, ((((), - PersistentDescriptorSetBuf>>), - PersistentDescriptorSetBuf>>), - PersistentDescriptorSetBuf>>)>> { + PersistentDescriptorSetBuf>>), + PersistentDescriptorSetBuf>>), + PersistentDescriptorSetBuf>>)>> { 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() @@ -182,6 +182,7 @@ impl CompuState { dimensions: (u32, u32), stride: u32, device: Arc) -> Arc { + self.compute_buffers.push( CompuBuffers::new(device.clone(), data, dimensions, stride)); @@ -213,17 +214,18 @@ impl CompuState { id } -} + pub fn compute(&mut self, compute_frame: ComputeFrame) { + + // i = (Buffer, Kernel) + for i in compute_frame.pure_compute { + + } + + } +} -/* - ComputeFrame accumulates combos of : - Buffers and Kernels - Buffers, Images and Kernels - Buffers, Buffers and Kernels - It will need to convert these into a logical list of command_buffer commands -*/ pub struct ComputeFrame { // Vec<(Buffer, Kernel)> pure_compute: Vec<(Arc, Arc)>, diff --git a/src/main.rs b/src/main.rs index c0603c5a..2a22204e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -44,10 +44,6 @@ Canvas works, but I want to use CPU accessible buffer instead of immutable buffe Texturing is broken -Compute is running in the background, but don't have a way to draw it. - Would like to draw it to a sprite??? - - 8/13 : Okay. So I've decided to keep compute image and compute kernel in their own 'canvas' @@ -193,9 +189,9 @@ fn main() { let mut window = surface.window(); let mut processor = vkprocessor::VkProcessor::new(&instance, &surface); - processor.compile_kernel(String::from("simple-edge.compute")); - processor.load_compute_image(String::from("background.jpg")); - processor.load_textures(String::from("funky-bird.jpg")); +// processor.compile_kernel(String::from("simple-edge.compute")); +// processor.load_compute_image(String::from("background.jpg")); +// processor.load_textures(String::from("funky-bird.jpg")); processor.create_swapchain(&surface); let mut timer = Timer::new(); @@ -231,6 +227,9 @@ fn main() { let compute_kernel = processor.get_kernel_handle(String::from("simple-edge.compute")) .expect("Can't find that kernel"); + + + while let Some(p) = window.get_position() { elapsed_time = timer.elap_time(); @@ -262,7 +261,7 @@ fn main() { match keyboard_input.virtual_keycode.unwrap() { VirtualKeyCode::A => { if keyboard_input.state == ElementState::Pressed { - processor.save_edges_image(); + // processor.save_edges_image(); } } _ => () diff --git a/src/vkprocessor.rs b/src/vkprocessor.rs index 7019f43a..6f8142bc 100644 --- a/src/vkprocessor.rs +++ b/src/vkprocessor.rs @@ -40,45 +40,6 @@ pub struct VkProcessor<'a> { impl<'a> VkProcessor<'a> { - pub fn preload_textures(&mut self) { - - } - pub fn preload_kernels(&mut self) { - - } - pub fn preload_shaders(&mut self) { - - } - - pub fn get_texture_handle(&self, texture_name: String) -> Option> { - None - } - pub fn get_kernel_handle(&self, kernel_name: String) -> Option> { - None - } - pub fn get_shader_handle(&self, shader_name: String) -> Option> { - None - } - - pub fn new_swap_image(&mut self, dimensions: (u32, u32)) -> Arc { - let mut usage = ImageUsage::none(); - usage.transfer_destination = true; - usage.storage = true; - - self.canvas.create_image(dimensions, usage) - } - - pub fn new_compute_buffer(&mut self, data: Vec, dimensions: (u32, u32), stride: u32) -> Arc { - self.compute_state.new_compute_buffer(data, dimensions, stride, self.device.clone()) - } - pub fn read_compute_buffer(&mut self, handle: Arc) -> Vec { - self.compute_state.read_compute_buffer(handle) - } - pub fn write_compute_buffer(&self, handle: Arc, data: Vec) { - self.compute_state.write_compute_buffer(handle, data) - } - - pub fn new(instance: &'a Arc, surface: &'a Arc>) -> VkProcessor<'a> { let physical = PhysicalDevice::enumerate(instance).next().unwrap(); @@ -117,10 +78,6 @@ impl<'a> VkProcessor<'a> { } } - pub fn compile_kernel(&mut self, filename: String) { - self.compute_kernel = Some(ComputeKernel::new(filename, self.device.clone())); - } - pub fn create_swapchain(&mut self, surface: &'a Arc>) { let (mut swapchain, images) = { let capabilities = surface.capabilities(self.physical).unwrap(); @@ -177,20 +134,45 @@ impl<'a> VkProcessor<'a> { self.swapchain_images = Some(new_images); } - pub fn load_compute_image(&mut self, image_filename: String) { - self.compute_image = Some(ComputeImage::new(self.device.clone(), image_filename.clone())); + pub fn preload_textures(&mut self) { + self.canvas.load_texture_from_filename(String::from("funky-bird.jpg")); } + pub fn preload_kernels(&mut self) { - pub fn load_textures(&mut self, image_filename: String) { - self.canvas.load_texture_from_filename(image_filename.clone()); } + pub fn preload_shaders(&mut self) { - pub fn save_edges_image(&mut self) { - self.compute_image.clone().unwrap().clone().save_image(); } - pub fn get_canvas(&mut self) -> &Canvas { - &self.canvas + pub fn get_texture_handle(&self, texture_name: String) -> Option> { + None + } + pub fn get_kernel_handle(&self, kernel_name: String) -> Option> { + None + } + pub fn get_shader_handle(&self, shader_name: String) -> Option> { + None + } + + // Create a new image which has the transfer usage + pub fn new_swap_image(&mut self, dimensions: (u32, u32)) -> Arc { + let mut usage = ImageUsage::none(); + usage.transfer_destination = true; + usage.storage = true; + + self.canvas.create_image(dimensions, usage) + } + + pub fn new_compute_buffer(&mut self, data: Vec, dimensions: (u32, u32), stride: u32) -> Arc { + self.compute_state.new_compute_buffer(data, dimensions, stride, self.device.clone()) + } + + pub fn read_compute_buffer(&mut self, handle: Arc) -> Vec { + self.compute_state.read_compute_buffer(handle) + } + + pub fn write_compute_buffer(&self, handle: Arc, data: Vec) { + self.compute_state.write_compute_buffer(handle, data) } pub fn run(&mut self, @@ -198,13 +180,14 @@ impl<'a> VkProcessor<'a> { mut frame_future: Box, canvas_frame: CanvasFrame, compute_frame: ComputeFrame, - ) -> Box { - + ) + -> Box { - - // + // take the canvas frame and create the vertex buffers self.canvas.draw(canvas_frame); - self.canvas.allocate_vertex_buffers(self.device.clone()); + + // ditto with the compuframe + self.compute_state.compute(compute_frame); let mut framebuffers = self.canvas.window_size_dependent_setup(&self.swapchain_images.clone().unwrap().clone());