That's it. Fifo present mode halts until the next time the screen is refreshed. Mailbox will replace the lined up image if the refresh period has not been reached

This commit is contained in:
2019-09-05 23:26:25 -07:00
parent 9135d9ec84
commit 711e678969
2 changed files with 53 additions and 36 deletions

View File

@@ -175,7 +175,8 @@ fn main() {
//canvas.draw(&compu_sprite1); //canvas.draw(&compu_sprite1);
{ {
let g = hprof::enter("Run"); let g = hprof::enter("Run");
(frame_future) = processor.run(&surface, frame_future, processor.run(&surface,
//frame_future,
canvas, canvas,
compu_frame); compu_frame);
} }

View File

@@ -15,6 +15,7 @@ use crate::canvas::{CanvasState, CanvasTextureHandle, CanvasShaderHandle, Canvas
use crate::canvas_frame::CanvasFrame; use crate::canvas_frame::CanvasFrame;
use crate::compu_kernel::{CompuKernel, CompuKernelHandle}; use crate::compu_kernel::{CompuKernel, CompuKernelHandle};
use crate::compu_buffer::{CompuBuffers, CompuBufferHandle}; use crate::compu_buffer::{CompuBuffers, CompuBufferHandle};
use std::time::Duration;
pub struct VkProcessor<'a> { pub struct VkProcessor<'a> {
// Vulkan state fields // Vulkan state fields
@@ -94,7 +95,7 @@ impl<'a> VkProcessor<'a> {
Swapchain::new(self.device.clone(), Swapchain::new(self.device.clone(),
surface.clone(), surface.clone(),
capabilities.min_image_count, // number of attachment images capabilities.min_image_count + 10, // number of attachment images
format, format,
initial_dimensions, initial_dimensions,
1, // Layers 1, // Layers
@@ -102,13 +103,12 @@ impl<'a> VkProcessor<'a> {
&self.queue, &self.queue,
SurfaceTransform::Identity, SurfaceTransform::Identity,
alpha, alpha,
PresentMode::Fifo, true, None).unwrap() PresentMode::Mailbox, true, None).unwrap()
}; };
self.swapchain = Some(swapchain); self.swapchain = Some(swapchain);
self.swapchain_images = Some(images); self.swapchain_images = Some(images);
} }
// On resizes we have to recreate the swapchain // On resizes we have to recreate the swapchain
pub fn recreate_swapchain(&mut self, surface: &'a Arc<Surface<Window>>) { pub fn recreate_swapchain(&mut self, surface: &'a Arc<Surface<Window>>) {
let dimensions = if let Some(dimensions) = surface.window().get_inner_size() { let dimensions = if let Some(dimensions) = surface.window().get_inner_size() {
@@ -174,22 +174,23 @@ impl<'a> VkProcessor<'a> {
pub fn run(&mut self, pub fn run(&mut self,
surface: &'a Arc<Surface<Window>>, surface: &'a Arc<Surface<Window>>,
mut frame_future: Box<dyn GpuFuture>, // mut frame_future: Box<dyn GpuFuture>,
canvas_frame: CanvasFrame, canvas_frame: CanvasFrame,
compute_frame: CompuFrame, compute_frame: CompuFrame,
) )
-> Box<dyn GpuFuture> { // -> Box<dyn GpuFuture> {
{
{ {
let g = hprof::enter("Waiting at queue"); let g = hprof::enter("Waiting at queue");
self.queue.wait(); self.queue.wait();
} }
let g = hprof::enter("Frame buffer, future, swapchain recreate");
let mut framebuffers = let mut framebuffers =
self.canvas.window_size_dependent_setup(&self.swapchain_images.clone().unwrap().clone()); self.canvas.window_size_dependent_setup(&self.swapchain_images.clone().unwrap().clone());
// The docs said to call this on each loop. // The docs said to call this on each loop.
frame_future.cleanup_finished(); // frame_future.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.
@@ -200,18 +201,29 @@ impl<'a> VkProcessor<'a> {
self.swapchain_recreate_needed = false; self.swapchain_recreate_needed = 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.swapchain.clone().unwrap().clone(), None) { let (image_num, acquire_future) =
Ok(r) => r, match vulkano::swapchain::acquire_next_image(
Err(AcquireError::OutOfDate) => { self.swapchain.clone().unwrap().clone(),
self.swapchain_recreate_needed = true; //Some(Duration::from_millis(3)),
return Box::new(sync::now(self.device.clone())) as Box<_>; None,
} ) {
Err(err) => panic!("{:?}", err) Ok(r) => r,
}; Err(AcquireError::OutOfDate) => {
self.swapchain_recreate_needed = true;
//return Box::new(sync::now(self.device.clone())) as Box<_>;
return;
}
Err(err) => panic!("{:?}", err)
};
drop(g);
let g = hprof::enter("Joining the future");
// let future = frame_future.join(acquire_future);
drop(g);
let future = frame_future.join(acquire_future);
{ {
let g = hprof::enter("Canvas creates GPU buffers"); let g = hprof::enter("Canvas creates GPU buffers");
// take the canvas frame and create the vertex buffers // take the canvas frame and create the vertex buffers
@@ -224,36 +236,41 @@ impl<'a> VkProcessor<'a> {
let g = hprof::enter("Push compute commands to command buffer"); let g = hprof::enter("Push compute commands to command buffer");
// Add the compute commands // Add the compute commands
// let mut command_buffer = self.compute_state.compute_commands(compute_frame, command_buffer, &self.canvas); // let mut command_buffer = self.compute_state.compute_commands(compute_frame, command_buffer, &self.canvas);
drop(g); drop(g);
let g = hprof::enter("Push draw commands to command buffer"); let g = hprof::enter("Push draw commands to command buffer");
// Add the draw commands // Add the draw commands
// let mut command_buffer = self.canvas.draw_commands(command_buffer, framebuffers, image_num); // let mut command_buffer = self.canvas.draw_commands(command_buffer, framebuffers, image_num);
drop(g); drop(g);
// And build // And build
let command_buffer = command_buffer.build().unwrap(); let command_buffer = command_buffer.build().unwrap();
// Wait on the previous frame, then execute the command buffer and present the image // Wait on the previous frame, then execute the command buffer and present the image
{
let g = hprof::enter("Mussing with the frame future");
let future = future //frame_future.join(acquire_future) //let future = future //frame_future.join(acquire_future)
.then_execute(self.queue.clone(), command_buffer).unwrap() let future = sync::now(self.device.clone())
.then_swapchain_present(self.queue.clone(), self.swapchain.clone().unwrap().clone(), image_num) .then_execute(self.queue.clone(), command_buffer).unwrap()
.then_signal_fence_and_flush(); .then_swapchain_present(self.queue.clone(), self.swapchain.clone().unwrap().clone(), image_num)
.then_signal_fence_and_flush();
future.unwrap().wait(None).unwrap();
match future { // match future {
Ok(future) => { // Ok(future) => {
(Box::new(future) as Box<_>) // (Box::new(future) as Box<_>)
} // }
Err(FlushError::OutOfDate) => { // Err(FlushError::OutOfDate) => {
self.swapchain_recreate_needed = true; // self.swapchain_recreate_needed = true;
(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);
(Box::new(sync::now(self.device.clone())) as Box<_>) // (Box::new(sync::now(self.device.clone())) as Box<_>)
} // }
// }
} }
} }
} }
@@ -275,4 +292,3 @@ impl<'a> VkProcessor<'a> {