got everything worked out in the loop. I guess next will be to swap the compute buffer to the image buffer

master
mitchellhansen 6 years ago
parent 3f79b276a9
commit 5751965ce3

@ -15,7 +15,7 @@ use sfml::graphics::{
Color, RenderTarget, RenderWindow, Color, RenderTarget, RenderWindow,
}; };
use sfml::system::*; use sfml::system::*;
use sfml::window::{Event, Key, Style}; use sfml::window::{Key, Style};
use sfml::window::mouse::*; use sfml::window::mouse::*;
use sfml::window::mouse; use sfml::window::mouse;
@ -43,9 +43,10 @@ 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}; use winit::{EventsLoop, WindowBuilder, WindowEvent, Event};
use vulkano_win::VkSurfaceBuild; use vulkano_win::VkSurfaceBuild;
mod slider; mod slider;
mod timer; mod timer;
mod input; mod input;
@ -90,6 +91,15 @@ fn main() {
let mut mouse_xy = Vector2i::new(0,0); let mut mouse_xy = Vector2i::new(0,0);
let mut s = Box::new(sync::now(processor.device.clone())) as Box<dyn GpuFuture>;
while let Some(p) = window.get_position() { while let Some(p) = window.get_position() {
// Event::MouseButtonPressed { button, x, y} => { // Event::MouseButtonPressed { button, x, y} => {
@ -124,9 +134,25 @@ fn main() {
accumulator_time -= step_size; accumulator_time -= step_size;
} }
processor.run_loop(&surface); let mut exit = false;
print!("adosfijqwe"); events_loop.poll_events(|ev| {
match ev {
Event::WindowEvent { event: WindowEvent::CloseRequested, .. } =>
{
exit = true;
},
Event::WindowEvent { event: WindowEvent::Resized(_), .. } => {
processor.recreate_swapchain(&surface);
},
_ => ()
}
});
if exit {
return;
}
s = processor.run(&surface, s);
} }
} }

@ -108,6 +108,7 @@ pub struct VkProcessor<'a> {
pub render_pass: Option<Arc<RenderPassAbstract + Send + Sync>>, pub render_pass: Option<Arc<RenderPassAbstract + Send + Sync>>,
pub vertex_buffer: Option<Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync + 'static)>>, pub vertex_buffer: Option<Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync + 'static)>>,
pub dynamic_state: DynamicState, pub dynamic_state: DynamicState,
pub previous_frame: Box<dyn GpuFuture>,
} }
impl<'a> VkProcessor<'a> { impl<'a> VkProcessor<'a> {
@ -134,7 +135,7 @@ impl<'a> VkProcessor<'a> {
physical: physical.clone(), physical: physical.clone(),
pipeline: Option::None, pipeline: Option::None,
compute_pipeline: Option::None, compute_pipeline: Option::None,
device: device, device: device.clone(),
queue: queue, queue: queue,
queues: queues, queues: queues,
set: Option::None, set: Option::None,
@ -147,6 +148,7 @@ impl<'a> VkProcessor<'a> {
render_pass: Option::None, render_pass: Option::None,
vertex_buffer: Option::None, vertex_buffer: Option::None,
dynamic_state: DynamicState { line_width: None, viewports: None, scissors: None }, dynamic_state: DynamicState { line_width: None, viewports: None, scissors: None },
previous_frame: Box::new(sync::now(device.clone())) as Box<dyn GpuFuture>,
} }
} }
@ -373,7 +375,7 @@ impl<'a> VkProcessor<'a> {
} }
pub fn run_loop(&mut self, surface: &'a Arc<Surface<Window>>) { 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.images.clone().unwrap().clone(), let mut framebuffers = window_size_dependent_setup(&self.images.clone().unwrap().clone(),
self.render_pass.clone().unwrap().clone(), self.render_pass.clone().unwrap().clone(),
@ -381,21 +383,8 @@ impl<'a> VkProcessor<'a> {
let mut recreate_swapchain = false; let mut recreate_swapchain = false;
// In the loop below we are going to submit commands to the GPU. Submitting a command produces // The docs said to call this on each loop.
// an object that implements the `GpuFuture` trait, which holds the resources for as long as frame_future.cleanup_finished();
// they are in use by the GPU.
//
// Destroying the `GpuFuture` blocks until the GPU is finished executing it. In order to avoid
// that, we store the submission of the previous frame here.
let mut previous_frame_end = Box::new(sync::now(self.device.clone())) as Box<dyn GpuFuture>;
// loop {
// It is important to call this function from time to time, otherwise resources will keep
// accumulating and you will eventually reach an out of memory error.
// Calling this function polls various fences in order to determine what the GPU has
// already processed, and frees the resources that are no longer needed.
// already processed, and frees the resources that are no longer needed.
previous_frame_end.cleanup_finished();
// Whenever the window resizes we need to recreate everything dependent on the window size. // Whenever the window resizes we need to recreate everything dependent on the window size.
// In this example that includes the swapchain, the framebuffers and the dynamic state viewport. // In this example that includes the swapchain, the framebuffers and the dynamic state viewport.
@ -407,11 +396,7 @@ impl<'a> VkProcessor<'a> {
recreate_swapchain = false; recreate_swapchain = false;
} }
// Before we can draw on the output, we have to *acquire* an image from the swapchain. If
// no image is available (which happens if you submit draw commands too quickly), then the
// function will block.
// This operation returns the index of the image that we are allowed to draw upon.
//
// 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.swapchain.clone().unwrap().clone(), None) { let (image_num, acquire_future) = match vulkano::swapchain::acquire_next_image(self.swapchain.clone().unwrap().clone(), None) {
@ -448,73 +433,40 @@ impl<'a> VkProcessor<'a> {
.dispatch([self.xy.0, self.xy.1, 1], .dispatch([self.xy.0, self.xy.1, 1],
self.compute_pipeline.clone().unwrap().clone(), self.compute_pipeline.clone().unwrap().clone(),
self.set.clone().unwrap().clone(), ()).unwrap() self.set.clone().unwrap().clone(), ()).unwrap()
// Before we can draw, we have to *enter a render pass*. There are two methods to do
// this: `draw_inline` and `draw_secondary`. The latter is a bit more advanced and is
// not covered here.
//
// The third parameter builds the list of values to clear the attachments with. The API
// is similar to the list of attachments when building the framebuffers, except that
// only the attachments that use `load: Clear` appear in the list.
.begin_render_pass(framebuffers[image_num].clone(), false, clear_values) .begin_render_pass(framebuffers[image_num].clone(), false, clear_values)
.unwrap() .unwrap()
// We are now inside the first subpass of the render pass. We add a draw command.
//
// The last two parameters contain the list of resources to pass to the shaders.
// Since we used an `EmptyPipeline` object, the objects have to be `()`.
.draw(self.pipeline.clone().unwrap().clone(), &self.dynamic_state, v, (), ()) .draw(self.pipeline.clone().unwrap().clone(), &self.dynamic_state, v, (), ())
.unwrap() .unwrap()
// We leave the render pass by calling `draw_end`. Note that if we had multiple
// subpasses we could have called `next_inline` (or `next_secondary`) to jump to the
// next subpass.
.end_render_pass() .end_render_pass()
.unwrap() .unwrap()
// Finish building the command buffer by calling `build`.
.build().unwrap(); .build().unwrap();
let future = previous_frame_end.join(acquire_future) // 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_execute(self.queue.clone(), command_buffer).unwrap()
// The color output is now expected to contain our triangle. But in order to show it on
// the screen, we have to *present* the image by calling `present`.
//
// This function does not actually present the image immediately. Instead it submits a
// present command at the end of the queue. This means that it will only be presented once
// the GPU has finished executing the command buffer that draws the triangle.
.then_swapchain_present(self.queue.clone(), self.swapchain.clone().unwrap().clone(), image_num) .then_swapchain_present(self.queue.clone(), self.swapchain.clone().unwrap().clone(), image_num)
.then_signal_fence_and_flush(); .then_signal_fence_and_flush();
match future { match future {
Ok(future) => { Ok(future) => {
previous_frame_end = Box::new(future) as Box<_>; (Box::new(future) as Box<_>)
} }
Err(FlushError::OutOfDate) => { Err(FlushError::OutOfDate) => {
recreate_swapchain = true; recreate_swapchain = true;
previous_frame_end = Box::new(sync::now(self.device.clone())) as Box<_>; (Box::new(sync::now(self.device.clone())) as Box<_>)
} }
Err(e) => { Err(e) => {
println!("{:?}", e); println!("{:?}", e);
previous_frame_end = Box::new(sync::now(self.device.clone())) as Box<_>; (Box::new(sync::now(self.device.clone())) as Box<_>)
} }
} }
} }
// Handling the window events in order to close the program when the user wants to close
// it.
let mut done = true;
// events_loop.poll_events(|ev| {
// match ev {
// Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => done = true,
// Event::WindowEvent { event: WindowEvent::Resized(_), .. } => recreate_swapchain = true,
// _ => ()
// }
// });
if done { return; }
//}
} }
pub fn load_buffers(&mut self, image_filename: String) pub fn load_buffers(&mut self, image_filename: String)
{ {
let project_root = let project_root =

Loading…
Cancel
Save