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

master
mitchellhansen 5 years ago
parent 3f79b276a9
commit 5751965ce3

@ -15,7 +15,7 @@ use sfml::graphics::{
Color, RenderTarget, RenderWindow,
};
use sfml::system::*;
use sfml::window::{Event, Key, Style};
use sfml::window::{Key, Style};
use sfml::window::mouse::*;
use sfml::window::mouse;
@ -43,9 +43,10 @@ use vulkano::sync::GpuFuture;
use shaderc::CompileOptions;
use shade_runner::CompileError;
use crate::workpiece::{WorkpieceLoader, Workpiece};
use winit::{EventsLoop, WindowBuilder};
use winit::{EventsLoop, WindowBuilder, WindowEvent, Event};
use vulkano_win::VkSurfaceBuild;
mod slider;
mod timer;
mod input;
@ -90,6 +91,15 @@ fn main() {
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() {
// Event::MouseButtonPressed { button, x, y} => {
@ -124,9 +134,25 @@ fn main() {
accumulator_time -= step_size;
}
processor.run_loop(&surface);
print!("adosfijqwe");
let mut exit = false;
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 vertex_buffer: Option<Arc<(dyn BufferAccess + std::marker::Send + std::marker::Sync + 'static)>>,
pub dynamic_state: DynamicState,
pub previous_frame: Box<dyn GpuFuture>,
}
impl<'a> VkProcessor<'a> {
@ -134,7 +135,7 @@ impl<'a> VkProcessor<'a> {
physical: physical.clone(),
pipeline: Option::None,
compute_pipeline: Option::None,
device: device,
device: device.clone(),
queue: queue,
queues: queues,
set: Option::None,
@ -147,6 +148,7 @@ impl<'a> VkProcessor<'a> {
render_pass: Option::None,
vertex_buffer: Option::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(),
self.render_pass.clone().unwrap().clone(),
@ -381,140 +383,90 @@ impl<'a> VkProcessor<'a> {
let mut recreate_swapchain = false;
// In the loop below we are going to submit commands to the GPU. Submitting a command produces
// an object that implements the `GpuFuture` trait, which holds the resources for as long as
// 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.
// In this example that includes the swapchain, the framebuffers and the dynamic state viewport.
if recreate_swapchain {
self.recreate_swapchain(surface);
framebuffers = window_size_dependent_setup(&self.images.clone().unwrap().clone(),
self.render_pass.clone().unwrap().clone(),
&mut self.dynamic_state);
recreate_swapchain = false;
// The docs said to call this on each loop.
frame_future.cleanup_finished();
// 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.
if recreate_swapchain {
self.recreate_swapchain(surface);
framebuffers = window_size_dependent_setup(&self.images.clone().unwrap().clone(),
self.render_pass.clone().unwrap().clone(),
&mut self.dynamic_state);
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.swapchain.clone().unwrap().clone(), None) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
recreate_swapchain = true;
//continue;
panic!("Weird thing");
}
Err(err) => panic!("{:?}", err)
};
// Specify the color to clear the framebuffer with i.e. blue
let clear_values = vec!([0.0, 0.0, 1.0, 1.0].into());
// 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.
{
// 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.
//
// 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.swapchain.clone().unwrap().clone(), None) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
// 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 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.set.clone().unwrap().clone(), ()).unwrap()
.begin_render_pass(framebuffers[image_num].clone(), false, clear_values)
.unwrap()
.draw(self.pipeline.clone().unwrap().clone(), &self.dynamic_state, v, (), ())
.unwrap()
.end_render_pass()
.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.swapchain.clone().unwrap().clone(), image_num)
.then_signal_fence_and_flush();
match future {
Ok(future) => {
(Box::new(future) as Box<_>)
}
Err(FlushError::OutOfDate) => {
recreate_swapchain = true;
//continue;
panic!("Weird thing");
(Box::new(sync::now(self.device.clone())) as Box<_>)
}
Err(err) => panic!("{:?}", err)
};
// Specify the color to clear the framebuffer with i.e. blue
let clear_values = vec!([0.0, 0.0, 1.0, 1.0].into());
{
// 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 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.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)
.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, (), ())
.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()
.unwrap()
// Finish building the command buffer by calling `build`.
.build().unwrap();
let future = previous_frame_end.join(acquire_future)
.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_signal_fence_and_flush();
match future {
Ok(future) => {
previous_frame_end = Box::new(future) as Box<_>;
}
Err(FlushError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Box::new(sync::now(self.device.clone())) as Box<_>;
}
Err(e) => {
println!("{:?}", e);
previous_frame_end = Box::new(sync::now(self.device.clone())) as Box<_>;
}
Err(e) => {
println!("{:?}", e);
(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)
{
let project_root =

Loading…
Cancel
Save