|
|
|
@ -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<DescriptorSet + Send + Sync> {
|
|
|
|
|
|
|
|
|
|
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<DescriptorSet + Send + Sync> {
|
|
|
|
|
|
|
|
|
|
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<DescriptorSet + Send + Sync> = 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<Surface<Window>>, mut frame_future: Box<dyn GpuFuture>) -> Box<dyn GpuFuture> {
|
|
|
|
|
|
|
|
|
|
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<u8> {
|
|
|
|
|
//
|
|
|
|
|
// // 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()));
|
|
|
|
|
// }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|