mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Assert on swapchain output usage before presenting
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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<B: hal::Backend> {
|
||||
pub fence: B::Fence,
|
||||
pub sem_available: B::Semaphore,
|
||||
pub sem_present: B::Semaphore,
|
||||
pub wait_for_epoch: Mutex<Option<SwapImageEpoch>>,
|
||||
pub acquired_epoch: Option<SwapImageEpoch>,
|
||||
pub need_waiting: AtomicBool,
|
||||
pub comb: hal::command::CommandBuffer<B, hal::General, hal::command::MultiShot>,
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
Reference in New Issue
Block a user