1190: Fix crash on zero init of buffer with no more ref count r=kvark a=Wumpf

**Description**
Previously, if a buffer would no longer have any reference, the zero init step crashed when trying to unwrap its ref_count.

**Testing**
Tested successfully on 54a0f4ff13 where this problem would pop up

Co-authored-by: Andreas Reich <r_andreas2@web.de>
This commit is contained in:
bors[bot] 2021-02-06 22:15:44 +00:00 committed by GitHub
commit dc18ac72e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 3 deletions

View File

@ -559,9 +559,15 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}
}
let (buffer, transition) = trackers
.buffers
.use_replace(&*buffer_guard, buffer_id, (), BufferUse::COPY_DST)
// Don't do use_replace since the buffer may already no longer have a ref_count.
// However, we *know* that it is currently in use, so the tracker must already know about it.
let transition = trackers.buffers.change_replace_tracked(
id::Valid(buffer_id),
(),
BufferUse::COPY_DST,
);
let buffer = buffer_guard
.get(buffer_id)
.map_err(|_| QueueSubmitError::DestroyedBuffer(buffer_id))?;
let &(ref buffer_raw, _) = buffer
.raw

View File

@ -315,6 +315,18 @@ impl<S: ResourceState> ResourceTracker<S> {
}
}
fn get<'a>(
self_backend: wgt::Backend,
map: &'a mut FastHashMap<Index, Resource<S>>,
id: Valid<S::Id>,
) -> &'a mut Resource<S> {
let (index, epoch, backend) = id.0.unzip();
debug_assert_eq!(self_backend, backend);
let e = map.get_mut(&index).unwrap();
assert_eq!(e.epoch, epoch);
e
}
/// Extend the usage of a specified resource.
///
/// Returns conflicting transition as an error.
@ -345,6 +357,21 @@ impl<S: ResourceState> ResourceTracker<S> {
self.temp.drain(..)
}
/// Replace the usage of a specified already tracked resource.
/// (panics if the resource is not yet tracked)
pub(crate) fn change_replace_tracked(
&mut self,
id: Valid<S::Id>,
selector: S::Selector,
usage: S::Usage,
) -> Drain<PendingTransition<S>> {
let res = Self::get(self.backend, &mut self.map, id);
res.state
.change(id, selector, usage, Some(&mut self.temp))
.ok();
self.temp.drain(..)
}
/// Turn the tracking from the "expand" mode into the "replace" one,
/// installing the selected usage as the "first".
/// This is a special operation only used by the render pass attachments.