diff --git a/resources/shaders/simple_texture.fragment b/resources/shaders/simple_texture.fragment index 63fa5753..ebf3c254 100644 --- a/resources/shaders/simple_texture.fragment +++ b/resources/shaders/simple_texture.fragment @@ -5,10 +5,12 @@ layout(set = 0, binding = 0) uniform sampler2D tex; layout(set = 0, binding = 1, rgba32ui) readonly uniform uimage2D img; void main() { - ivec2 size = ivec2(gl_FragCoord.x, gl_FragCoord.y); + ivec2 pos = ivec2(gl_FragCoord.x, gl_FragCoord.y); - f_color = imageLoad(img, size) / (255.0); + f_color = imageLoad(img, ivec2(pos)) / (255.0); float gamma = 0.5; f_color.rgb = pow(f_color.rgb, vec3(1.0/gamma)); + + // f_color = texture(tex, tex_coords); } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index e5e94fd8..71010605 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,7 +43,7 @@ use vulkano::sync::GpuFuture; use shaderc::CompileOptions; use shade_runner::CompileError; use crate::workpiece::{WorkpieceLoader, Workpiece}; -use winit::{EventsLoop, WindowBuilder, WindowEvent, Event}; +use winit::{EventsLoop, WindowBuilder, WindowEvent, Event, DeviceEvent, VirtualKeyCode, ElementState}; use winit::dpi::LogicalSize; use vulkano_win::VkSurfaceBuild; @@ -101,7 +101,7 @@ fn main() { let mut timer = Timer::new(); - let mut input = Input::new(); + // let mut input = Input::new(); let step_size: f32 = 0.005; @@ -156,8 +156,8 @@ fn main() { } let mut exit = false; - events_loop.poll_events(|ev| { - match ev { + events_loop.poll_events(|event| { + match event { Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => { exit = true; @@ -165,6 +165,17 @@ fn main() { Event::WindowEvent { event: WindowEvent::Resized(_), .. } => { processor.recreate_swapchain(&surface); }, + Event::DeviceEvent { event: DeviceEvent::Key(keyboard_input), .. } => { + + match keyboard_input.virtual_keycode.unwrap() { + VirtualKeyCode::A => { + if keyboard_input.state == ElementState::Pressed { + processor.save_edges_image(); + } + } + _ => () + } + }, _ => () } }); @@ -173,6 +184,7 @@ fn main() { return; } + s = processor.run(&surface, s); } } diff --git a/src/vkprocessor.rs b/src/vkprocessor.rs index 409d7de5..941c256e 100644 --- a/src/vkprocessor.rs +++ b/src/vkprocessor.rs @@ -337,67 +337,23 @@ impl<'a> VkProcessor<'a> { println!("Allocating Buffers..."); - // Pull out the image data and place it in a buffer for the kernel to write to and for us to read from - let write_buffer = { - let mut buff = self.image_buffer.iter(); - let data_iter = (0..data_length).map(|n| *(buff.next().unwrap())); - CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::all(), data_iter).unwrap() - }; - - - // Pull out the image data and place it in a buffer for the kernel to read from - let read_buffer = { - let mut buff = self.image_buffer.iter(); - let data_iter = (0..data_length).map(|n| *(buff.next().unwrap())); - CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::all(), data_iter).unwrap() - }; - - - // A buffer to hold many i32 values to use as settings - let settings_buffer = { - let vec = vec![self.xy.0, self.xy.1]; - let mut buff = vec.iter(); - let data_iter = - (0..2).map(|n| *(buff.next().unwrap())); - CpuAccessibleBuffer::from_iter(self.device.clone(), - BufferUsage::all(), - data_iter).unwrap() - }; - - println!("Done"); - - // Create the data descriptor set for our previously created shader pipeline - let mut set = - PersistentDescriptorSet::start(self.compute_pipeline.clone().unwrap().clone(), 0) - .add_buffer(write_buffer.clone()).unwrap() - .add_buffer(read_buffer.clone()).unwrap() - .add_buffer(settings_buffer.clone()).unwrap(); - - self.compute_set = Some(Arc::new(set.build().unwrap())); - - self.compute_image_buffers.push(write_buffer); - self.compute_image_buffers.push(read_buffer); - self.settings_buffer = Some(settings_buffer); - - let vertex_buffer = { vulkano::impl_vertex!(tVertex, position); CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::all(), [ - tVertex { position: [-1.0, -1.0 ] }, - tVertex { position: [-1.0, 1.0 ] }, - tVertex { position: [ 1.0, 1.0 ] }, - tVertex { position: [ 1.0, -1.0 ] }, + tVertex { position: [ 1.0, 1.0 ] }, + tVertex { position: [ 1.0, 0.5 ] }, + tVertex { position: [ 0.5, 0.5 ] }, + tVertex { position: [ 0.5, 1.0 ] }, ].iter().cloned()).unwrap() }; let vertex_buffer2 = { - CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::all(), [ tVertex { position: [-1.0, -1.0 ] }, tVertex { position: [-1.0, -0.5 ] }, - tVertex { position: [-0.5, 0.5 ] }, + tVertex { position: [-0.5, -0.5 ] }, tVertex { position: [-0.5, -1.0 ] }, ].iter().cloned()).unwrap() }; @@ -405,32 +361,15 @@ impl<'a> VkProcessor<'a> { self.vertex_buffer = Some(vertex_buffer); self.vertex_buffer2 = Some(vertex_buffer2); - let compute_transfer_image = { - - let mut usage = ImageUsage::none(); - usage.transfer_destination = true; - usage.storage = true; - - AttachmentImage::with_usage( - self.device.clone(), - [self.xy.0, self.xy.1], - Format::R8G8B8A8Uint, - usage) - }; - - self.graphics_image_swap_buffer = Some(compute_transfer_image.clone().unwrap()); - let texture = VkProcessor::get_texture_from_file(image_filename.clone(), self.queue.clone()); - self.textures.push(texture); - - + let texture1 = VkProcessor::get_texture_from_file(String::from("button.png"), self.queue.clone()); + self.textures.push(texture1); } // The image set is the containing object for all texture and image hooks. - // todo, make this pull from the image_buffer_store fn get_image_set(&mut self) -> Box { let sampler = Sampler::new(self.device.clone(), Filter::Linear, Filter::Linear, @@ -447,6 +386,27 @@ impl<'a> VkProcessor<'a> { o } + // The image set is the containing object for all texture and image hooks. + fn get_gui_image_set(&mut self) -> Box { + + let sampler = Sampler::new(self.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( + PersistentDescriptorSet::start( + self.shader_kernels.clone().unwrap().graphics_pipeline.clone().unwrap().clone(), 0 + ) + .add_sampled_image(self.textures.get(1).unwrap().clone(), sampler.clone()).unwrap() + .add_image(self.compute_image.clone().unwrap().clone().get_swap_buffer().clone()).unwrap() + .build().unwrap()); + o + } + + pub fn save_edges_image(&mut self){ + self.compute_image.clone().unwrap().clone().save_image(); + } + pub fn run(&mut self, surface: &'a Arc>, mut frame_future: Box) -> Box { let mut framebuffers = window_size_dependent_setup(&self.shader_kernels.clone().unwrap().swapchain_images.clone(), @@ -468,7 +428,6 @@ impl<'a> VkProcessor<'a> { recreate_swapchain = false; } - // This function can block if no image is available. The parameter is an optional timeout // after which the function call will return an error. let (image_num, acquire_future) = match vulkano::swapchain::acquire_next_image(self.shader_kernels.clone().unwrap().swapchain.clone(), None) { @@ -484,120 +443,62 @@ impl<'a> VkProcessor<'a> { // Specify the color to clear the framebuffer with i.e. blue let clear_values = vec!([0.0, 0.0, 1.0, 1.0].into()); + let mut v = Vec::new(); + v.push(self.vertex_buffer.clone().unwrap().clone()); - { - // In order to draw, we have to build a *command buffer*. The command buffer object holds - // the list of commands that are going to be executed. - // - // Building a command buffer is an expensive operation (usually a few hundred - // microseconds), but it is known to be a hot path in the driver and is expected to be - // optimized. - // - // Note that we have to pass a queue family when we create the command buffer. The command - // buffer will only be executable on that given queue family. - let mut v = Vec::new(); - v.push(self.vertex_buffer.clone().unwrap().clone()); - - let mut v2 = Vec::new(); - v2.push(self.vertex_buffer2.clone().unwrap().clone()); + let mut v2 = Vec::new(); + v2.push(self.vertex_buffer2.clone().unwrap().clone()); + let command_buffer = + AutoCommandBufferBuilder::primary_one_time_submit(self.device.clone(), self.queue.family()) + .unwrap() - let command_buffer = - AutoCommandBufferBuilder::primary_one_time_submit(self.device.clone(), self.queue.family()) - .unwrap() + .dispatch([self.xy.0, self.xy.1, 1], + self.compute_pipeline.clone().unwrap().clone(), + self.compute_image.clone().unwrap().clone().get_descriptor_set(self.compute_pipeline.clone().unwrap().clone()).clone(), ()).unwrap() + //self.compute_set.clone().unwrap().clone(), ()).unwrap() - .dispatch([self.xy.0, self.xy.1, 1], - self.compute_pipeline.clone().unwrap().clone(), - self.compute_image.clone().unwrap().clone().get_descriptor_set(self.compute_pipeline.clone().unwrap().clone()).clone(), ()).unwrap() - //self.compute_set.clone().unwrap().clone(), ()).unwrap() + .copy_buffer_to_image(self.compute_image.clone().unwrap().clone().rw_buffers.get(0).unwrap().clone(), + self.compute_image.clone().unwrap().clone().get_swap_buffer().clone()).unwrap() - .copy_buffer_to_image(self.compute_image.clone().unwrap().clone().rw_buffers.get(0).unwrap().clone(), - self.compute_image.clone().unwrap().clone().get_swap_buffer().clone()).unwrap() + .begin_render_pass(framebuffers[image_num].clone(), false, clear_values) + .unwrap() - .begin_render_pass(framebuffers[image_num].clone(), false, clear_values) - .unwrap() + .draw(self.shader_kernels.clone().unwrap().graphics_pipeline.clone().unwrap().clone(), + &self.dynamic_state.clone(), v, + vec![self.get_image_set()], ()) + .unwrap() - .draw(self.shader_kernels.clone().unwrap().graphics_pipeline.clone().unwrap().clone(), - &self.dynamic_state.clone(), v, - vec![self.get_image_set()], ()) - .unwrap() + .draw(self.shader_kernels.clone().unwrap().graphics_pipeline.clone().unwrap().clone(), + &self.dynamic_state.clone(), v2, + vec![self.get_gui_image_set()], ()) + .unwrap() -// .draw(self.shader_kernels.clone().unwrap().graphics_pipeline.clone().unwrap().clone(), -// &self.dynamic_state.clone(), v2, -// vec![self.get_image_set()], ()) -// .unwrap() + .end_render_pass() + .unwrap() - .end_render_pass() - .unwrap() + .build().unwrap(); - .build().unwrap(); + // Wait on the previous frame, then execute the command buffer and present the image + let future = frame_future.join(acquire_future) + .then_execute(self.queue.clone(), command_buffer).unwrap() + .then_swapchain_present(self.queue.clone(), self.shader_kernels.clone().unwrap().swapchain.clone(), image_num) + .then_signal_fence_and_flush(); - // Wait on the previous frame, then execute the command buffer and present the image - let future = frame_future.join(acquire_future) - .then_execute(self.queue.clone(), command_buffer).unwrap() - .then_swapchain_present(self.queue.clone(), self.shader_kernels.clone().unwrap().swapchain.clone(), image_num) - .then_signal_fence_and_flush(); - - match future { - Ok(future) => { - (Box::new(future) as Box<_>) - } - Err(FlushError::OutOfDate) => { - recreate_swapchain = true; - (Box::new(sync::now(self.device.clone())) as Box<_>) - } - Err(e) => { - println!("{:?}", e); - (Box::new(sync::now(self.device.clone())) as Box<_>) - } + match future { + Ok(future) => { + (Box::new(future) as Box<_>) + } + Err(FlushError::OutOfDate) => { + recreate_swapchain = true; + (Box::new(sync::now(self.device.clone())) as Box<_>) + } + Err(e) => { + println!("{:?}", e); + (Box::new(sync::now(self.device.clone())) as Box<_>) } } } - -// pub fn read_image(&self) -> Vec { -// -// // The buffer is sync'd so we can just read straight from the handle -// let mut data_buffer_content = self.img_buffers.get(0).unwrap().read().unwrap(); -// -// println!("Reading output"); -// -// let mut image_buffer = Vec::new(); -// -// for y in 0..self.xy.1 { -// for x in 0..self.xy.0 { -// -// let r = data_buffer_content[((self.xy.0 * y + x) * 4 + 0) as usize] as u8; -// let g = data_buffer_content[((self.xy.0 * y + x) * 4 + 1) as usize] as u8; -// let b = data_buffer_content[((self.xy.0 * y + x) * 4 + 2) as usize] as u8; -// let a = data_buffer_content[((self.xy.0 * y + x) * 4 + 3) as usize] as u8; -// -// image_buffer.push(r); -// image_buffer.push(g); -// image_buffer.push(b); -// image_buffer.push(a); -// } -// } -// -// image_buffer -// } - -// pub fn save_image(&self) { -// println!("Saving output"); -// -// let img_data = self.read_image(); -// -// let img = ImageBuffer::from_fn(self.xy.0, self.xy.1, |x, y| { -// -// let r = img_data[((self.xy.0 * y + x) * 4 + 0) as usize] as u8; -// let g = img_data[((self.xy.0 * y + x) * 4 + 1) as usize] as u8; -// let b = img_data[((self.xy.0 * y + x) * 4 + 2) as usize] as u8; -// let a = img_data[((self.xy.0 * y + x) * 4 + 3) as usize] as u8; -// -// image::Rgba([r, g, b, a]) -// }); -// -// img.save(format!("output/{}.png", SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs())); -// } } diff --git a/src/vkprocessor/compute_image.rs b/src/vkprocessor/compute_image.rs index 78daac67..73347e0c 100644 --- a/src/vkprocessor/compute_image.rs +++ b/src/vkprocessor/compute_image.rs @@ -146,7 +146,7 @@ impl ComputeImage { device: device.clone(), compute_graphics_swap_buffer: compute_graphics_swap_buffer.unwrap(), image_buffer: image_buffer, - xy: (0, 0), + xy: xy, rw_buffers: vec![write_buffer, read_buffer], settings_buffer: settings_buffer } @@ -156,7 +156,7 @@ impl ComputeImage { self.compute_graphics_swap_buffer.clone() } - pub fn read_read_buffer(&mut self) -> ImageBuffer, Vec>{ + pub fn read_read_buffer(&self) -> ImageBuffer, Vec>{ let data_buffer_content = self.rw_buffers.get(0).unwrap().read().unwrap(); ImageBuffer::from_fn(self.xy.0, self.xy.1, |x, y| { @@ -169,6 +169,10 @@ impl ComputeImage { }) } + pub fn save_image(&self) { + self.read_read_buffer().save(format!("output/{}.jpg", SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs())); + } + pub fn get_descriptor_set(&self, compute_pipeline: std::sync::Arc>>) -> Arc>>, ((((), PersistentDescriptorSetBuf>>),