saving working on key entry. going to do pallette now
This commit is contained in:
@@ -5,10 +5,12 @@ layout(set = 0, binding = 0) uniform sampler2D tex;
|
|||||||
layout(set = 0, binding = 1, rgba32ui) readonly uniform uimage2D img;
|
layout(set = 0, binding = 1, rgba32ui) readonly uniform uimage2D img;
|
||||||
void main() {
|
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;
|
float gamma = 0.5;
|
||||||
f_color.rgb = pow(f_color.rgb, vec3(1.0/gamma));
|
f_color.rgb = pow(f_color.rgb, vec3(1.0/gamma));
|
||||||
|
|
||||||
|
// f_color = texture(tex, tex_coords);
|
||||||
}
|
}
|
||||||
20
src/main.rs
20
src/main.rs
@@ -43,7 +43,7 @@ use vulkano::sync::GpuFuture;
|
|||||||
use shaderc::CompileOptions;
|
use shaderc::CompileOptions;
|
||||||
use shade_runner::CompileError;
|
use shade_runner::CompileError;
|
||||||
use crate::workpiece::{WorkpieceLoader, Workpiece};
|
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 winit::dpi::LogicalSize;
|
||||||
use vulkano_win::VkSurfaceBuild;
|
use vulkano_win::VkSurfaceBuild;
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ fn main() {
|
|||||||
|
|
||||||
|
|
||||||
let mut timer = Timer::new();
|
let mut timer = Timer::new();
|
||||||
let mut input = Input::new();
|
// let mut input = Input::new();
|
||||||
|
|
||||||
|
|
||||||
let step_size: f32 = 0.005;
|
let step_size: f32 = 0.005;
|
||||||
@@ -156,8 +156,8 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut exit = false;
|
let mut exit = false;
|
||||||
events_loop.poll_events(|ev| {
|
events_loop.poll_events(|event| {
|
||||||
match ev {
|
match event {
|
||||||
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } =>
|
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } =>
|
||||||
{
|
{
|
||||||
exit = true;
|
exit = true;
|
||||||
@@ -165,6 +165,17 @@ fn main() {
|
|||||||
Event::WindowEvent { event: WindowEvent::Resized(_), .. } => {
|
Event::WindowEvent { event: WindowEvent::Resized(_), .. } => {
|
||||||
processor.recreate_swapchain(&surface);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
s = processor.run(&surface, s);
|
s = processor.run(&surface, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -337,67 +337,23 @@ impl<'a> VkProcessor<'a> {
|
|||||||
|
|
||||||
println!("Allocating Buffers...");
|
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 = {
|
let vertex_buffer = {
|
||||||
vulkano::impl_vertex!(tVertex, position);
|
vulkano::impl_vertex!(tVertex, position);
|
||||||
|
|
||||||
CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::all(), [
|
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, 0.5 ] },
|
||||||
tVertex { position: [ 1.0, 1.0 ] },
|
tVertex { position: [ 0.5, 0.5 ] },
|
||||||
tVertex { position: [ 1.0, -1.0 ] },
|
tVertex { position: [ 0.5, 1.0 ] },
|
||||||
].iter().cloned()).unwrap()
|
].iter().cloned()).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
let vertex_buffer2 = {
|
let vertex_buffer2 = {
|
||||||
|
|
||||||
|
|
||||||
CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::all(), [
|
CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::all(), [
|
||||||
tVertex { position: [-1.0, -1.0 ] },
|
tVertex { position: [-1.0, -1.0 ] },
|
||||||
tVertex { position: [-1.0, -0.5 ] },
|
tVertex { position: [-1.0, -0.5 ] },
|
||||||
tVertex { position: [-0.5, 0.5 ] },
|
tVertex { position: [-0.5, -0.5 ] },
|
||||||
tVertex { position: [-0.5, -1.0 ] },
|
tVertex { position: [-0.5, -1.0 ] },
|
||||||
].iter().cloned()).unwrap()
|
].iter().cloned()).unwrap()
|
||||||
};
|
};
|
||||||
@@ -405,32 +361,15 @@ impl<'a> VkProcessor<'a> {
|
|||||||
self.vertex_buffer = Some(vertex_buffer);
|
self.vertex_buffer = Some(vertex_buffer);
|
||||||
self.vertex_buffer2 = Some(vertex_buffer2);
|
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());
|
let texture = VkProcessor::get_texture_from_file(image_filename.clone(), self.queue.clone());
|
||||||
|
|
||||||
self.textures.push(texture);
|
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.
|
// 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> {
|
fn get_image_set(&mut self) -> Box<DescriptorSet + Send + Sync> {
|
||||||
|
|
||||||
let sampler = Sampler::new(self.device.clone(), Filter::Linear, Filter::Linear,
|
let sampler = Sampler::new(self.device.clone(), Filter::Linear, Filter::Linear,
|
||||||
@@ -447,6 +386,27 @@ impl<'a> VkProcessor<'a> {
|
|||||||
o
|
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> {
|
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(),
|
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;
|
recreate_swapchain = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This function can block if no image is available. The parameter is an optional timeout
|
// This function can block if no image is available. The parameter is an optional timeout
|
||||||
// after which the function call will return an error.
|
// 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) {
|
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
|
// 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 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());
|
||||||
|
|
||||||
{
|
let mut v2 = Vec::new();
|
||||||
// In order to draw, we have to build a *command buffer*. The command buffer object holds
|
v2.push(self.vertex_buffer2.clone().unwrap().clone());
|
||||||
// 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();
|
let command_buffer =
|
||||||
v2.push(self.vertex_buffer2.clone().unwrap().clone());
|
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()
|
||||||
|
|
||||||
let command_buffer =
|
.copy_buffer_to_image(self.compute_image.clone().unwrap().clone().rw_buffers.get(0).unwrap().clone(),
|
||||||
AutoCommandBufferBuilder::primary_one_time_submit(self.device.clone(), self.queue.family())
|
self.compute_image.clone().unwrap().clone().get_swap_buffer().clone()).unwrap()
|
||||||
.unwrap()
|
|
||||||
|
|
||||||
.dispatch([self.xy.0, self.xy.1, 1],
|
.begin_render_pass(framebuffers[image_num].clone(), false, clear_values)
|
||||||
self.compute_pipeline.clone().unwrap().clone(),
|
.unwrap()
|
||||||
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(),
|
.draw(self.shader_kernels.clone().unwrap().graphics_pipeline.clone().unwrap().clone(),
|
||||||
self.compute_image.clone().unwrap().clone().get_swap_buffer().clone()).unwrap()
|
&self.dynamic_state.clone(), v,
|
||||||
|
vec![self.get_image_set()], ())
|
||||||
|
.unwrap()
|
||||||
|
|
||||||
.begin_render_pass(framebuffers[image_num].clone(), false, clear_values)
|
.draw(self.shader_kernels.clone().unwrap().graphics_pipeline.clone().unwrap().clone(),
|
||||||
.unwrap()
|
&self.dynamic_state.clone(), v2,
|
||||||
|
vec![self.get_gui_image_set()], ())
|
||||||
|
.unwrap()
|
||||||
|
|
||||||
.draw(self.shader_kernels.clone().unwrap().graphics_pipeline.clone().unwrap().clone(),
|
.end_render_pass()
|
||||||
&self.dynamic_state.clone(), v,
|
.unwrap()
|
||||||
vec![self.get_image_set()], ())
|
|
||||||
.unwrap()
|
|
||||||
|
|
||||||
// .draw(self.shader_kernels.clone().unwrap().graphics_pipeline.clone().unwrap().clone(),
|
.build().unwrap();
|
||||||
// &self.dynamic_state.clone(), v2,
|
|
||||||
// vec![self.get_image_set()], ())
|
|
||||||
// .unwrap()
|
|
||||||
|
|
||||||
.end_render_pass()
|
// Wait on the previous frame, then execute the command buffer and present the image
|
||||||
.unwrap()
|
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();
|
||||||
|
|
||||||
.build().unwrap();
|
match future {
|
||||||
|
Ok(future) => {
|
||||||
// Wait on the previous frame, then execute the command buffer and present the image
|
(Box::new(future) as Box<_>)
|
||||||
let future = frame_future.join(acquire_future)
|
}
|
||||||
.then_execute(self.queue.clone(), command_buffer).unwrap()
|
Err(FlushError::OutOfDate) => {
|
||||||
.then_swapchain_present(self.queue.clone(), self.shader_kernels.clone().unwrap().swapchain.clone(), image_num)
|
recreate_swapchain = true;
|
||||||
.then_signal_fence_and_flush();
|
(Box::new(sync::now(self.device.clone())) as Box<_>)
|
||||||
|
}
|
||||||
match future {
|
Err(e) => {
|
||||||
Ok(future) => {
|
println!("{:?}", e);
|
||||||
(Box::new(future) as Box<_>)
|
(Box::new(sync::now(self.device.clone())) 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()));
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ impl ComputeImage {
|
|||||||
device: device.clone(),
|
device: device.clone(),
|
||||||
compute_graphics_swap_buffer: compute_graphics_swap_buffer.unwrap(),
|
compute_graphics_swap_buffer: compute_graphics_swap_buffer.unwrap(),
|
||||||
image_buffer: image_buffer,
|
image_buffer: image_buffer,
|
||||||
xy: (0, 0),
|
xy: xy,
|
||||||
rw_buffers: vec![write_buffer, read_buffer],
|
rw_buffers: vec![write_buffer, read_buffer],
|
||||||
settings_buffer: settings_buffer
|
settings_buffer: settings_buffer
|
||||||
}
|
}
|
||||||
@@ -156,7 +156,7 @@ impl ComputeImage {
|
|||||||
self.compute_graphics_swap_buffer.clone()
|
self.compute_graphics_swap_buffer.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_read_buffer(&mut self) -> ImageBuffer<Rgba<u8>, Vec<u8>>{
|
pub fn read_read_buffer(&self) -> ImageBuffer<Rgba<u8>, Vec<u8>>{
|
||||||
|
|
||||||
let data_buffer_content = self.rw_buffers.get(0).unwrap().read().unwrap();
|
let data_buffer_content = self.rw_buffers.get(0).unwrap().read().unwrap();
|
||||||
ImageBuffer::from_fn(self.xy.0, self.xy.1, |x, y| {
|
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<ComputePipeline<PipelineLayout<shade_runner::layouts::ComputeLayout>>>)
|
pub fn get_descriptor_set(&self, compute_pipeline: std::sync::Arc<ComputePipeline<PipelineLayout<shade_runner::layouts::ComputeLayout>>>)
|
||||||
-> Arc<PersistentDescriptorSet<std::sync::Arc<ComputePipeline<PipelineLayout<shade_runner::layouts::ComputeLayout>>>, ((((),
|
-> Arc<PersistentDescriptorSet<std::sync::Arc<ComputePipeline<PipelineLayout<shade_runner::layouts::ComputeLayout>>>, ((((),
|
||||||
PersistentDescriptorSetBuf<std::sync::Arc<vulkano::buffer::cpu_access::CpuAccessibleBuffer<[u8]>>>),
|
PersistentDescriptorSetBuf<std::sync::Arc<vulkano::buffer::cpu_access::CpuAccessibleBuffer<[u8]>>>),
|
||||||
|
|||||||
Reference in New Issue
Block a user