made buffer loading much faster

master
mitchellhansen 6 years ago
parent d5350a04ff
commit 4b85f6dd1f

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

@ -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<image::Rgba<u8>> {
let mut pixels: Vec<image::Rgba<u8>> = 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");

Loading…
Cancel
Save