From 8c56bda87a3d87a895f1ad83802536225a49f9ab Mon Sep 17 00:00:00 2001 From: mitchellhansen Date: Sat, 6 Jul 2019 16:12:39 -0700 Subject: [PATCH] struggling with the borrow checker --- resources/images/test2.png | Bin 4073 -> 1683 bytes src/main.rs | 8 ++- src/vkprocessor.rs | 129 ++++++++++++++++++++++--------------- 3 files changed, 82 insertions(+), 55 deletions(-) diff --git a/resources/images/test2.png b/resources/images/test2.png index 7b6efa96e33b3ef752d1d94ad276406bb6d2fffd..02dbe9da1bcb313b28b32a138775ac3d725052c2 100644 GIT binary patch literal 1683 zcmeAS@N?(olHy`uVBq!ia0y~yV4MKL9Be?5hW%z|fD~teM`SSr1Gg{;GcwGYBLNg- zFY)wsWq-`h!pf^S&r8J^C?uO15>euupPQSSR|4cRFgO>bCYGe8D3oWGWGJ|M`Ua%v zrLr?HuyK02IEGZ*dVBYDQImm0!^I;X|H?=1$|w{GoIHX1LUG!z!ds^{oOtdZkj#GWFs=K!%#^Lix9Oa6VlCj)OJr0~VE9sOd+FdY z3Fn@VPmON;nQ=OqL2bfy=DmO9UPY-qJO1oGql3ddwVwQCnMLBF4Gk@iRvuDe`f#3k zl2zpl7lvP_Z@IkRt1+D|<;X^+84hJBr(;9konZQLoRKkM|0cb}opV?kI9VF%ggxH5 zY%G;Oq-NE?xunClgn?1B&*7xX#?&Il2P}-7iY>R_UVEC)U=it1q$W6-y`f>xT&-(P zM)ql+7+$Ei2`u{=`tP24kDmII_ZB`z4D2%;YSOJ58bW$G8GdhlshxXW?Dt|H0kb=d zY^+c2E}5{~V7ZUXR`FjyEnQg_6g$}I{#wahbZ)7Z^lb)pjuS->^&_u%f49u?;rSN9 zz{axV>fNCG|E@p&d~MI0ltqjh(`&@T)`q`3&9PMH(dqj)jSezguv9RO+nGNzA3#8@z)VM~YmIgv+~L=W^a z1r@zq@l@@{r;4PW@A8+~9i&gbXO66U@@si{dw<2%|8FgiGA9H$TvM7P)g9Jde(HM% z2T;w;=^Ki~o?J2K%IiI`;yIf^qln%uQ@fCjsV)pRA{}(@FvQGZVqjrmU<5`FgMa`C zv9L7Ud-tCC>Df0Eg956;t*93g*4;AodULj);yRu!2X7Nk!n1MK`4O> z_Yu|QMk59oo5V)w5lsf9@PbDQjS?NPt|H$3cvKRTupU&@F>u}ZXD~HjDi5f(@O1Ta JS?83{1OTD(R?q+d literal 4073 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 aPj=v%6qiT!|2EHZ@J&uzcy}Fq6aE($Z0w!@ diff --git a/src/main.rs b/src/main.rs index b8813e5f..15af7479 100644 --- a/src/main.rs +++ b/src/main.rs @@ -51,7 +51,10 @@ mod vkprocessor; fn main() { - let processor = vkprocessor::VkProcessor::new(); + let mut processor = vkprocessor::VkProcessor::new(); + processor.compile_kernel(); + processor.load_buffers(); + let mut window = RenderWindow::new( @@ -66,8 +69,9 @@ fn main() { let font = Font::from_file("resources/fonts/sansation.ttf").unwrap(); + let xy = processor.img.unwrap().dimensions(); let mut bg_texture = Texture::new(xy.0, xy.1).unwrap(); - bg_texture.update_from_pixels(image_buffer.as_slice(), xy.0, xy.1, 0, 0); + bg_texture.update_from_pixels(processor.image_buffer.as_slice(), xy.0, xy.1, 0, 0); let mut background_sprite = Sprite::with_texture(&bg_texture); background_sprite.set_position((0., 0.)); diff --git a/src/vkprocessor.rs b/src/vkprocessor.rs index 87d00718..8bc596c7 100644 --- a/src/vkprocessor.rs +++ b/src/vkprocessor.rs @@ -1,6 +1,6 @@ use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, DeviceLocalBuffer, ImmutableBuffer, BufferAccess}; use vulkano::command_buffer::AutoCommandBufferBuilder; -use vulkano::descriptor::descriptor_set::PersistentDescriptorSet; +use vulkano::descriptor::descriptor_set::{PersistentDescriptorSet, StdDescriptorPoolAlloc}; use vulkano::device::{Device, DeviceExtensions, QueuesIter, Queue}; use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice, QueueFamily}; use vulkano::pipeline::ComputePipeline; @@ -12,21 +12,30 @@ use std::ffi::CStr; use std::path::PathBuf; use shade_runner as sr; use image::DynamicImage; +use image::GenericImageView; +use vulkano::descriptor::pipeline_layout::PipelineLayout; +use image::GenericImage; +use shade_runner::ComputeLayout; +use vulkano::descriptor::descriptor_set::PersistentDescriptorSetBuf; pub struct VkProcessor<'a> { - instance: Arc, - physical: PhysicalDevice<'a>, - queue_family: QueueFamily<'a>, - device: Arc, - queues: QueuesIter, - queue: Arc, - img: Option, - image_buffer: Vec, - buffers: Vec:: + pub instance: Arc, + pub physical: PhysicalDevice<'a>, + pub queue_family: QueueFamily<'a>, + pub pipeline: Option>>>, + pub device: Arc, + pub queues: QueuesIter, + pub queue: Arc, + pub set: Option>>, ((((), PersistentDescriptorSetBuf>>), PersistentDescriptorSetBuf>>), PersistentDescriptorSetBuf>>)>>>, + pub img: Option, + pub image_buffer: Vec, + pub img_buffers: Vec>>, + pub settings_buffer: Option>>, } -impl VkProcessor { - pub fn new() -> VkProcessor { +impl<'a> VkProcessor<'a> { + pub fn new() -> VkProcessor<'a> { + let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap(); let physical = PhysicalDevice::enumerate(&instance).next().unwrap(); let queue_family = physical.queue_families().find(|&q| q.supports_compute()).unwrap(); @@ -34,17 +43,23 @@ impl VkProcessor { physical.supported_features(), &DeviceExtensions::none(), [(queue_family, 0.5)].iter().cloned()).unwrap(); + + // Self referential struct problem VkProcessor { - instance: instance, - physical: physical, - queue_family: queue_family, + instance: instance.clone(), + physical: physical.clone(), + queue_family: physical.queue_families().find(|&q| q.supports_compute()).unwrap(), + pipeline: Option::None, device: device, queues: queues, queue: queues.next().unwrap(), img: Option::None, + set: Option::None, image_buffer: Vec::new(), - buffers: Vec::new(), + img_buffers: Vec::new(), + settings_buffer: Option::None, } + } pub fn compile_kernel(&mut self) { @@ -68,20 +83,21 @@ impl VkProcessor { ).unwrap() } }); + } pub fn load_buffers(&mut self) { self.img = Option::Some(image::open("resources/images/funky-bird.jpg").unwrap()); - let xy = self.img.dimensions(); + let xy = self.img.unwrap().dimensions(); let data_length = xy.0 * xy.1 * 4; - let pixel_count = self.img.raw_pixels().len(); + let pixel_count = self.img.unwrap().raw_pixels().len(); println!("Pixel count {}", pixel_count); if pixel_count != data_length as usize { println!("Creating apha channel..."); - for i in self.img.raw_pixels().iter() { + for i in self.img.unwrap().raw_pixels().iter() { if (self.image_buffer.len() + 1) % 4 == 0 { self.image_buffer.push(255); } @@ -89,58 +105,63 @@ impl VkProcessor { } self.image_buffer.push(255); } else { - self.image_buffer = self.img.raw_pixels(); + self.image_buffer = self.img.unwrap().raw_pixels(); } println!("Buffer length {}", self.image_buffer.len()); println!("Size {:?}", xy); 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 = 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 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() - }; - - // 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(); - let data_iter = (0..2).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 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() + }; + self.img_buffers.push(write_buffer); + + // 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() + }; + self.img_buffers.push(read_buffer); + + // 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(); + let data_iter = (0..2).map(|n| *(buff.next().unwrap())); + CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::all(), data_iter).unwrap() + }; + self.settings_buffer = Some(settings_buffer); println!("Done"); // Create the data descriptor set for our previously created shader pipeline - let mut set = PersistentDescriptorSet::start(pipeline.clone(), 0) + let mut set = PersistentDescriptorSet::start(self.pipeline.unwrap().clone(), 0) .add_buffer(write_buffer.clone()).unwrap() .add_buffer(read_buffer.clone()).unwrap() .add_buffer(settings_buffer.clone()).unwrap(); - let mut set = Arc::new(set.build().unwrap()); +// self.set = Some(Arc::new(set.build().unwrap())); } pub fn run_kernel(&mut self) { + println!("Running Kernel..."); + let xy = self.img.unwrap().dimensions(); + // 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() + let command_buffer = AutoCommandBufferBuilder::primary_one_time_submit(self.device.clone(), self.queue.family()).unwrap() + .dispatch([xy.0, xy.1, 1], self.pipeline.unwrap().clone(), self.set.unwrap().clone(), ()).unwrap() .build().unwrap(); // Create a future for running the command buffer and then just fence it - let future = sync::now(device.clone()) - .then_execute(queue.clone(), command_buffer).unwrap() + let future = sync::now(self.device.clone()) + .then_execute(self.queue.clone(), command_buffer).unwrap() .then_signal_fence_and_flush().unwrap(); // I think this is redundant and returns immediately @@ -148,10 +169,12 @@ impl VkProcessor { println!("Done running kernel"); } - pub fn read_image() -> Vec { + pub fn read_image(&self) -> Vec { + + let xy = self.img.unwrap().dimensions(); // The buffer is sync'd so we can just read straight from the handle - let mut data_buffer_content = write_buffer.read().unwrap(); + let mut data_buffer_content = self.img_buffers.get(0).unwrap().read().unwrap(); println!("Reading output"); @@ -170,7 +193,7 @@ impl VkProcessor { image_buffer.push(b); image_buffer.push(a); - img.put_pixel(x, y, image::Rgba([r, g, b, a])) + self.img.unwrap().put_pixel(x, y, image::Rgba([r, g, b, a])) } } @@ -179,7 +202,7 @@ impl VkProcessor { pub fn save_image(&self) { println!("Saving output"); - img.save(format!("output/{}.png", SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs())); + self.img.unwrap().save(format!("output/{}.png", SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs())); } }