diff --git a/resources/images/test.png b/resources/images/test.png new file mode 100644 index 00000000..b3def253 Binary files /dev/null and b/resources/images/test.png differ diff --git a/src/main.rs b/src/main.rs index ff73d571..3ea31290 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,7 +20,7 @@ use sfml::system::Vector2 as sfVec2; use sfml::window::*; use sfml::window::{Event, Key, Style}; -use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer}; +use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, DeviceLocalBuffer, ImmutableBuffer, BufferAccess}; use vulkano::command_buffer::AutoCommandBufferBuilder; use vulkano::descriptor::descriptor_set::PersistentDescriptorSet; use vulkano::device::{Device, DeviceExtensions}; @@ -31,6 +31,7 @@ use vulkano::sync; use std::sync::Arc; use std::fs; use std::path::PathBuf; +use std::result; use crate::input::Input; use crate::slider::Slider; @@ -127,30 +128,6 @@ impl<'t> Effect for Edge<'t> { } // ================================================= -fn surrounding_pixels(x: u32, y: u32, img: &DynamicImage) -> Vec> { - - let mut pixels: Vec> = Vec::new(); - - if img.in_bounds(x+1, y+1) {pixels.push(img.get_pixel(x+1, y+1))} - if img.in_bounds(x+1, y) {pixels.push(img.get_pixel(x+1, y))} - if img.in_bounds(x, y+1) {pixels.push(img.get_pixel(x, y+1))} - - if x > 0 { - if img.in_bounds(x-1, y+1) {pixels.push(img.get_pixel(x-1, y+1))} - if img.in_bounds(x-1, y) {pixels.push(img.get_pixel(x-1, y))} - } - - if y > 0 { - if img.in_bounds(x+1, y-1) {pixels.push(img.get_pixel(x+1, y-1))} - if img.in_bounds(x, y-1) {pixels.push(img.get_pixel(x, y-1))} - if x > 0 { - if img.in_bounds(x - 1, y - 1) { pixels.push(img.get_pixel(x - 1, y - 1)) } - } - } - - pixels -} - fn main() { // Create the vulkan instance, device, and device queue @@ -162,6 +139,7 @@ fn main() { &DeviceExtensions::none(), [(queue_family, 0.5)].iter().cloned()).unwrap(); let queue = queues.next().unwrap(); + println!("Device initialized"); let project_root = std::env::current_dir().expect("failed to get root directory"); @@ -187,39 +165,47 @@ fn main() { }); // Load up the input image, determine some details - let mut img = image::open("resources/images/funky-bird.jpg").unwrap(); + let mut img = image::open("resources/images/test.png").unwrap(); let xy = img.dimensions(); let data_length = xy.0*xy.1*4; - let mut image_buffer = Vec::new(); + let pixel_count = img.raw_pixels().len(); + println!("Pixel count {}", pixel_count); - for i in img.raw_pixels().iter() { - if (image_buffer.len() + 1) % 4 == 0 { - image_buffer.push(255); + let mut image_buffer = Vec::new(); + if pixel_count != data_length as usize { + for i in img.raw_pixels().iter() { + if (image_buffer.len() + 1) % 4 == 0 { + image_buffer.push(255); + } + image_buffer.push(*i); } - image_buffer.push(*i); + image_buffer.push(255); + } + else { + image_buffer = img.raw_pixels(); } - image_buffer.push(255); - println!("Buffer length {}", data_length); println!("Buffer length {}", image_buffer.len()); println!("Size {:?}", xy); + println!("Allocating Buffers..."); { - // Pull out the image data and place it in a sync'd CPU<->GPU buffer - let data_buffer = { - - let mut buff = image_buffer.iter(); - let data_iter = (0 .. data_length).map(|n| *(buff.next().unwrap())); - CpuAccessibleBuffer::from_iter(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 q = ImmutableBuffer::from_data(image_buffer.clone(), BufferUsage::all(), queue.clone()).unwrap(); + q.1.flush(); + q.0 }; - let out_buffer = { + // 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 = image_buffer.iter(); let data_iter = (0 .. data_length).map(|n| *(buff.next().unwrap())); - CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), data_iter).unwrap() + CpuAccessibleBuffer::from_data(device.clone(), BufferUsage::all(), image_buffer.clone()).unwrap() }; + // A buffer to hold many i32 values to use as settings let settings_buffer = { let vec = vec![xy.0, xy.1]; let mut buff = vec.iter(); @@ -227,14 +213,16 @@ fn main() { CpuAccessibleBuffer::from_iter(device.clone(), BufferUsage::all(), data_iter).unwrap() }; + println!("Done"); // Create the data descriptor set for our previously created shader pipeline let mut set = Arc::new(PersistentDescriptorSet::start(pipeline.clone(), 0) - .add_buffer(data_buffer.clone()).unwrap() - .add_buffer(out_buffer.clone()).unwrap() + .add_buffer(read_buffer).unwrap() + .add_buffer(write_buffer.clone()).unwrap() .add_buffer(settings_buffer.clone()).unwrap() .build().unwrap() ); + println!("Running Kernel..."); // The command buffer I think pretty much serves to define what runs where for how many times let command_buffer = AutoCommandBufferBuilder::primary_one_time_submit(device.clone(), queue.family()).unwrap() .dispatch([xy.0, xy.1, 1], pipeline.clone(), set.clone(), ()).unwrap() @@ -248,9 +236,13 @@ fn main() { // I think this is redundant and returns immediately future.wait(None).unwrap(); + println!("Done running kernel"); // The buffer is sync'd so we can just read straight from the handle - let data_buffer_content = data_buffer.read().unwrap(); + let data_buffer_content = write_buffer.read().unwrap(); + + let p = image::load_from_memory(data_buffer_content.as_slice()).unwrap(); + println!("done2"); for y in 0 .. xy.1 { for x in 0 .. xy.0 { @@ -269,6 +261,7 @@ fn main() { } } + println!("done3"); img.save(format!("output/{}.png", SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs())); println!("Stdddwafasddfqwefaarting");