220: Support more than one frame in flight r=kvark a=kvark

Fixes #219 
![portability-dota2](https://user-images.githubusercontent.com/107301/92435144-9d3e6f80-f16f-11ea-91d3-8bffbb36dc44.jpg)


Co-authored-by: Dzmitry Malyshau <kvarkus@gmail.com>
This commit is contained in:
bors[bot] 2020-09-08 05:07:43 +00:00 committed by GitHub
commit a81b5a4f21
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 440 additions and 438 deletions

820
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -4378,9 +4378,9 @@ pub unsafe extern "C" fn gfxCreateSwapchainKHR(
let swapchain = Swapchain {
gpu,
surface: info.surface,
count: info.minImageCount as u8,
count: info.minImageCount,
current_index: 0,
active: None,
active: Vec::new(),
lazy_framebuffers: Mutex::new(Vec::with_capacity(1)),
};
*pSwapchain = Handle::new(swapchain);
@ -4419,7 +4419,7 @@ pub unsafe extern "C" fn gfxGetSwapchainImagesKHR(
debug_assert!(!pSwapchainImageCount.is_null());
let swapchain_image_count = &mut *pSwapchainImageCount;
let available_images = swapchain.count as u32;
let available_images = swapchain.count;
if pSwapchainImages.is_null() {
// If NULL the number of presentable images is returned.
@ -4427,7 +4427,7 @@ pub unsafe extern "C" fn gfxGetSwapchainImagesKHR(
} else {
*swapchain_image_count = available_images.min(*swapchain_image_count);
for frame in 0..*swapchain_image_count as u8 {
for frame in 0..*swapchain_image_count {
*pSwapchainImages.offset(frame as isize) =
Handle::new(Image::SwapchainFrame { swapchain, frame });
}
@ -4663,17 +4663,12 @@ pub unsafe extern "C" fn gfxAcquireNextImageKHR(
sem.is_fake = true;
}
if let Some(_old_frame) = swapchain.active.take() {
warn!(
"Swapchain frame {} was not presented!",
swapchain.current_index
);
}
match swapchain.surface.acquire_image(timeout) {
Ok((frame, suboptimal)) => {
swapchain.current_index = (swapchain.current_index + 1) % swapchain.count;
swapchain.active = Some(frame);
*pImageIndex = swapchain.current_index as u32;
let index = (swapchain.current_index + 1) % swapchain.count;
swapchain.active.push((index, frame));
*pImageIndex = index;
swapchain.current_index = index;
match suboptimal {
Some(_) => VkResult::VK_SUBOPTIMAL_KHR,
None => VkResult::VK_SUCCESS,
@ -4704,16 +4699,17 @@ pub unsafe extern "C" fn gfxQueuePresentKHR(
);
}
for (swapchain, index) in swapchain_slice.iter().zip(index_slice) {
for (swapchain, &index) in swapchain_slice.iter().zip(index_slice) {
let sc = swapchain.as_mut().unwrap();
let frame = sc.active.take().expect("Frame was not acquired properly!");
if sc.current_index == *index as u8 {
let sem = wait_semaphores.first().map(|s| &s.raw);
if let Err(_) = queue.present(&mut *sc.surface, frame, sem) {
return VkResult::VK_ERROR_SURFACE_LOST_KHR;
}
} else {
warn!("Swapchain frame {} is stale, can't be presented.", *index);
let active_pos = sc
.active
.iter()
.position(|&(frame, _)| frame == index)
.expect("Frame was not acquired properly!");
let frame = sc.active.swap_remove(active_pos).1;
let sem = wait_semaphores.first().map(|s| &s.raw);
if let Err(_) = queue.present(&mut *sc.surface, frame, sem) {
return VkResult::VK_ERROR_SURFACE_LOST_KHR;
}
for framebuffer in sc.lazy_framebuffers.lock().drain(..) {
sc.gpu.device.destroy_framebuffer(framebuffer)

View file

@ -117,7 +117,7 @@ pub enum Image<B: hal::Backend> {
},
SwapchainFrame {
swapchain: VkSwapchainKHR,
frame: u8,
frame: hal::window::SwapImageIndex,
},
}
@ -137,7 +137,7 @@ pub enum ImageView {
Native(<B as hal::Backend>::ImageView),
SwapchainFrame {
swapchain: VkSwapchainKHR,
frame: u8,
frame: hal::window::SwapImageIndex,
},
}
@ -194,11 +194,12 @@ impl Framebuffer {
frame,
} => {
use std::borrow::Borrow;
debug_assert_eq!(frame, swapchain.current_index);
swapchain
.active
.as_ref()
.iter()
.find(|&&(index, _)| index == frame)
.expect("Swapchain frame isn't acquired")
.1
.borrow()
}
});
@ -246,9 +247,12 @@ pub type VkSwapchainKHR = Handle<Swapchain<B>>;
pub struct Swapchain<B: hal::Backend> {
gpu: VkDevice,
surface: VkSurfaceKHR,
count: u8,
current_index: u8,
active: Option<<B::Surface as hal::window::PresentationSurface<B>>::SwapchainImage>,
count: hal::window::SwapImageIndex,
current_index: hal::window::SwapImageIndex,
active: Vec<(
hal::window::SwapImageIndex,
<B::Surface as hal::window::PresentationSurface<B>>::SwapchainImage,
)>,
lazy_framebuffers: parking_lot::Mutex<Vec<<B as hal::Backend>::Framebuffer>>,
}