got everything worked out in the loop. I guess next will be to swap the compute buffer to the image buffer
This commit is contained in:
34
src/main.rs
34
src/main.rs
@@ -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,140 +383,90 @@ 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 {
|
// Whenever the window resizes we need to recreate everything dependent on the window size.
|
||||||
// It is important to call this function from time to time, otherwise resources will keep
|
// In this example that includes the swapchain, the framebuffers and the dynamic state viewport.
|
||||||
// accumulating and you will eventually reach an out of memory error.
|
if recreate_swapchain {
|
||||||
// Calling this function polls various fences in order to determine what the GPU has
|
self.recreate_swapchain(surface);
|
||||||
// already processed, and frees the resources that are no longer needed.
|
framebuffers = window_size_dependent_setup(&self.images.clone().unwrap().clone(),
|
||||||
// already processed, and frees the resources that are no longer needed.
|
self.render_pass.clone().unwrap().clone(),
|
||||||
previous_frame_end.cleanup_finished();
|
&mut self.dynamic_state);
|
||||||
|
recreate_swapchain = false;
|
||||||
|
}
|
||||||
|
|
||||||
// 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.
|
// This function can block if no image is available. The parameter is an optional timeout
|
||||||
if recreate_swapchain {
|
// after which the function call will return an error.
|
||||||
self.recreate_swapchain(surface);
|
let (image_num, acquire_future) = match vulkano::swapchain::acquire_next_image(self.swapchain.clone().unwrap().clone(), None) {
|
||||||
framebuffers = window_size_dependent_setup(&self.images.clone().unwrap().clone(),
|
Ok(r) => r,
|
||||||
self.render_pass.clone().unwrap().clone(),
|
Err(AcquireError::OutOfDate) => {
|
||||||
&mut self.dynamic_state);
|
recreate_swapchain = true;
|
||||||
recreate_swapchain = false;
|
//continue;
|
||||||
|
panic!("Weird thing");
|
||||||
}
|
}
|
||||||
|
Err(err) => panic!("{:?}", err)
|
||||||
|
};
|
||||||
|
|
||||||
// Before we can draw on the output, we have to *acquire* an image from the swapchain. If
|
// Specify the color to clear the framebuffer with i.e. blue
|
||||||
// no image is available (which happens if you submit draw commands too quickly), then the
|
let clear_values = vec!([0.0, 0.0, 1.0, 1.0].into());
|
||||||
// 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
|
// Building a command buffer is an expensive operation (usually a few hundred
|
||||||
// after which the function call will return an error.
|
// microseconds), but it is known to be a hot path in the driver and is expected to be
|
||||||
let (image_num, acquire_future) = match vulkano::swapchain::acquire_next_image(self.swapchain.clone().unwrap().clone(), None) {
|
// optimized.
|
||||||
Ok(r) => r,
|
//
|
||||||
Err(AcquireError::OutOfDate) => {
|
// Note that we have to pass a queue family when we create the command buffer. The command
|
||||||
recreate_swapchain = true;
|
// buffer will only be executable on that given queue family.
|
||||||
//continue;
|
let mut v = Vec::new();
|
||||||
panic!("Weird thing");
|
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(err) => panic!("{:?}", err)
|
Err(FlushError::OutOfDate) => {
|
||||||
};
|
recreate_swapchain = true;
|
||||||
|
(Box::new(sync::now(self.device.clone())) as Box<_>)
|
||||||
// Specify the color to clear the framebuffer with i.e. blue
|
}
|
||||||
let clear_values = vec!([0.0, 0.0, 1.0, 1.0].into());
|
Err(e) => {
|
||||||
|
println!("{:?}", e);
|
||||||
|
(Box::new(sync::now(self.device.clone())) as Box<_>)
|
||||||
{
|
|
||||||
// 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<_>;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// 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 =
|
||||||
|
|||||||
Reference in New Issue
Block a user