diff --git a/wgpu-native/src/command/mod.rs b/wgpu-native/src/command/mod.rs index cb24c8feb0..167ef3aabe 100644 --- a/wgpu-native/src/command/mod.rs +++ b/wgpu-native/src/command/mod.rs @@ -155,6 +155,7 @@ pub struct CommandEncoderDescriptor { pub extern "C" fn wgpu_command_encoder_finish( command_encoder_id: CommandEncoderId, ) -> CommandBufferId { + //TODO: actually close the last recorded command buffer HUB.command_buffers.write()[command_encoder_id].is_recording = false; //TODO: check for the old value command_encoder_id } diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index c0529365b7..0a70d0b6ff 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -51,7 +51,17 @@ use log::{info, trace}; //use rendy_memory::{allocator, Config, Heaps}; use parking_lot::Mutex; -use std::{collections::hash_map::Entry, ffi, iter, ptr, slice, sync::atomic::Ordering}; +use std::{ + collections::hash_map::Entry, + ffi, + iter, + ptr, + slice, + sync::atomic::Ordering, +}; +#[cfg(feature = "local")] +use std::sync::atomic::AtomicBool; + pub const MAX_COLOR_TARGETS: usize = 4; @@ -1271,17 +1281,17 @@ pub extern "C" fn wgpu_queue_submit( let wait_semaphores = swap_chain_links.into_iter().flat_map(|link| { let swap_chain = surface_guard[link.swap_chain_id].swap_chain.as_ref()?; let frame = &swap_chain.frames[link.image_index as usize]; - let mut wait_for_epoch = frame.wait_for_epoch.lock(); - let current_epoch = *wait_for_epoch.as_ref()?; - if link.epoch < current_epoch { - None - } else { - debug_assert_eq!(link.epoch, current_epoch); - *wait_for_epoch = None; + if frame.need_waiting.swap(false, Ordering::Relaxed) { + assert_eq!(frame.acquired_epoch, Some(link.epoch), + "{}. Image index {} with epoch {} != current epoch {:?}", + "Attempting to rendering to a swapchain output that has already been presented", + link.image_index, link.epoch, frame.acquired_epoch); Some(( &frame.sem_available, hal::pso::PipelineStage::COLOR_ATTACHMENT_OUTPUT, )) + } else { + None } }); @@ -1798,7 +1808,8 @@ pub fn swap_chain_populate_textures( fence: device.raw.create_fence(true).unwrap(), sem_available: device.raw.create_semaphore().unwrap(), sem_present: device.raw.create_semaphore().unwrap(), - wait_for_epoch: Mutex::new(None), + acquired_epoch: None, + need_waiting: AtomicBool::new(false), comb: swap_chain.command_pool.acquire_command_buffer(), }); } diff --git a/wgpu-native/src/swap_chain.rs b/wgpu-native/src/swap_chain.rs index e97e1ff806..d419379e3b 100644 --- a/wgpu-native/src/swap_chain.rs +++ b/wgpu-native/src/swap_chain.rs @@ -16,7 +16,9 @@ use hal::{self, Device as _, Swapchain as _}; use log::{trace, warn}; use parking_lot::Mutex; -use std::{iter, mem}; +use std::{ + iter, mem, sync::atomic::{AtomicBool, Ordering}, +}; pub type SwapImageEpoch = u16; @@ -54,7 +56,8 @@ pub(crate) struct Frame { pub fence: B::Fence, pub sem_available: B::Semaphore, pub sem_present: B::Semaphore, - pub wait_for_epoch: Mutex>, + pub acquired_epoch: Option, + pub need_waiting: AtomicBool, pub comb: hal::command::CommandBuffer, } @@ -153,13 +156,15 @@ pub extern "C" fn wgpu_swap_chain_get_next_texture(swap_chain_id: SwapChainId) - device.raw.wait_for_fence(&frame.fence, !0).unwrap(); } mem::swap(&mut frame.sem_available, &mut swap_chain.sem_available); + frame.need_waiting.store(true, Ordering::Release); let frame_epoch = HUB.textures.read()[frame.texture_id.value] .placement .as_swap_chain() .bump_epoch(); - *frame.wait_for_epoch.lock() = Some(frame_epoch); + assert_eq!(frame.acquired_epoch, None, "Last swapchain output hasn't been presented"); + frame.acquired_epoch =Some(frame_epoch); SwapChainOutput { texture_id: frame.texture_id.value, @@ -174,6 +179,10 @@ pub extern "C" fn wgpu_swap_chain_present(swap_chain_id: SwapChainId) { let image_index = swap_chain.acquired.remove(0); let frame = &mut swap_chain.frames[image_index as usize]; + let epoch = frame.acquired_epoch.take(); + assert!(epoch.is_some(), "Presented frame (image {}) was not acquired", image_index); + assert!(!frame.need_waiting.load(Ordering::Acquire), + "No rendering work has been submitted for the presented frame (image {})", image_index); let mut device_guard = HUB.devices.write(); let device = &mut device_guard[swap_chain.device_id.value];