mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-02-12 06:52:38 +00:00
Merge #838
838: wait for buffer to be done in the player r=cwfitzgerald a=kvark **Connections** Fixes our code enough to replay #834 without issues. Doesn't help to solve the original problem though. **Description** There are two things in here: 1. don't deduplicate the BGLs if we are not generating new IDs at this layer. This helps Servo/Gecko/player. cc @kunalmohan 2. have an option in `buffer_destroy` to *actually* kill it, at the cost of blocking on GPU sometimes. This is required for the player, since the very next command may try to reuse the ID. **Testing** Tested on the trace in #834 Co-authored-by: Dzmitry Malyshau <kvarkus@gmail.com>
This commit is contained in:
commit
6182495102
@ -147,6 +147,7 @@ impl GlobalPlay for wgc::hub::Global<IdentityPassThroughFactory> {
|
||||
comb_manager: &mut wgc::hub::IdentityManager,
|
||||
) {
|
||||
use wgc::device::trace::Action as A;
|
||||
log::info!("action {:?}", action);
|
||||
match action {
|
||||
A::Init { .. } => panic!("Unexpected Action::Init: has to be the first action only"),
|
||||
A::CreateSwapChain { .. } | A::PresentSwapChain(_) => {
|
||||
@ -159,7 +160,7 @@ impl GlobalPlay for wgc::hub::Global<IdentityPassThroughFactory> {
|
||||
.unwrap();
|
||||
}
|
||||
A::DestroyBuffer(id) => {
|
||||
self.buffer_destroy::<B>(id);
|
||||
self.buffer_destroy::<B>(id, true);
|
||||
}
|
||||
A::CreateTexture(id, desc) => {
|
||||
let label = Label::new(&desc.label);
|
||||
|
@ -593,6 +593,17 @@ impl<B: GfxBackend> Device<B> {
|
||||
|
||||
unsafe { self.raw.create_render_pass(all, iter::once(subpass), &[]) }
|
||||
}
|
||||
|
||||
fn wait_for_submit(&self, submission_index: SubmissionIndex, token: &mut Token<Self>) -> Result<(), WaitIdleError> {
|
||||
if self.last_completed_submission_index() <= submission_index {
|
||||
log::info!("Waiting for submission {:?}", submission_index);
|
||||
self.lock_life(token)
|
||||
.triage_submissions(&self.raw, true)
|
||||
.map(|_| ())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: hal::Backend> Device<B> {
|
||||
@ -773,19 +784,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
.load(Ordering::Acquire)
|
||||
};
|
||||
|
||||
let device = &device_guard[device_id];
|
||||
if device.last_completed_submission_index() <= last_submission {
|
||||
log::info!(
|
||||
"Waiting for submission {:?} before accessing buffer {:?}",
|
||||
last_submission,
|
||||
buffer_id
|
||||
);
|
||||
device
|
||||
.lock_life(&mut token)
|
||||
.triage_submissions(&device.raw, true)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
device_guard[device_id]
|
||||
.wait_for_submit(last_submission, &mut token)
|
||||
}
|
||||
|
||||
pub fn device_set_buffer_sub_data<B: GfxBackend>(
|
||||
@ -879,28 +879,46 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn buffer_destroy<B: GfxBackend>(&self, buffer_id: id::BufferId) {
|
||||
pub fn buffer_destroy<B: GfxBackend>(&self, buffer_id: id::BufferId, now: bool) {
|
||||
span!(_guard, INFO, "Buffer::drop");
|
||||
|
||||
let hub = B::hub(self);
|
||||
let mut token = Token::root();
|
||||
|
||||
log::info!("Buffer {:?} is dropped", buffer_id);
|
||||
let (ref_count, device_id) = {
|
||||
let (ref_count, last_submit_index, device_id) = {
|
||||
let (mut buffer_guard, _) = hub.buffers.write(&mut token);
|
||||
let buffer = &mut buffer_guard[buffer_id];
|
||||
let ref_count = buffer.life_guard.ref_count.take().unwrap();
|
||||
(ref_count, buffer.device_id.value)
|
||||
let last_submit_index = buffer
|
||||
.life_guard
|
||||
.submission_index
|
||||
.load(Ordering::Acquire);
|
||||
(ref_count, last_submit_index, buffer.device_id.value)
|
||||
};
|
||||
|
||||
let (device_guard, mut token) = hub.devices.read(&mut token);
|
||||
device_guard[device_id]
|
||||
.lock_life(&mut token)
|
||||
.future_suspected_buffers
|
||||
.push(Stored {
|
||||
value: buffer_id,
|
||||
ref_count,
|
||||
});
|
||||
let device = &device_guard[device_id];
|
||||
if now {
|
||||
drop(ref_count);
|
||||
device
|
||||
.lock_life(&mut token)
|
||||
.suspected_resources
|
||||
.buffers
|
||||
.push(buffer_id);
|
||||
match device.wait_for_submit(last_submit_index, &mut token) {
|
||||
Ok(()) => (),
|
||||
Err(e) => log::error!("Failed to wait for buffer {:?}: {:?}", buffer_id, e),
|
||||
}
|
||||
} else {
|
||||
device
|
||||
.lock_life(&mut token)
|
||||
.future_suspected_buffers
|
||||
.push(Stored {
|
||||
value: buffer_id,
|
||||
ref_count,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn device_create_texture<B: GfxBackend>(
|
||||
@ -1215,8 +1233,9 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let device = &device_guard[device_id];
|
||||
|
||||
// If there is an equivalent BGL, just bump the refcount and return it.
|
||||
// Warning: this isn't valid logic when `id_in` is provided.
|
||||
{
|
||||
// This is only applicable for identity filters that are generating new IDs,
|
||||
// so their inputs are `PhantomData` of size 0.
|
||||
if mem::size_of::<Input<G, id::BindGroupLayoutId>>() == 0 {
|
||||
let (bgl_guard, _) = hub.bind_group_layouts.read(&mut token);
|
||||
let bind_group_layout_id = bgl_guard
|
||||
.iter(device_id.backend())
|
||||
|
Loading…
Reference in New Issue
Block a user