mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
MemoryInitTracker drain is now O(N)
This commit is contained in:
parent
018ad05f56
commit
a8460b438c
@ -25,6 +25,7 @@ pub(crate) struct MemoryInitTracker {
|
||||
pub(crate) struct MemoryInitTrackerDrain<'a> {
|
||||
uninitialized_ranges: &'a mut Vec<Range<wgt::BufferAddress>>,
|
||||
drain_range: Range<wgt::BufferAddress>,
|
||||
first_index: usize,
|
||||
next_index: usize,
|
||||
}
|
||||
|
||||
@ -32,44 +33,58 @@ impl<'a> Iterator for MemoryInitTrackerDrain<'a> {
|
||||
type Item = Range<wgt::BufferAddress>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let uninitialized_range = match self.uninitialized_ranges.get_mut(self.next_index) {
|
||||
Some(range) => range,
|
||||
None => return None,
|
||||
};
|
||||
if uninitialized_range.start >= self.drain_range.end {
|
||||
// No more cuts possible (we're going left to right!)
|
||||
None
|
||||
} else if uninitialized_range.end > self.drain_range.end {
|
||||
// cut-out / split
|
||||
if uninitialized_range.start < self.drain_range.start {
|
||||
let old_start = uninitialized_range.start;
|
||||
uninitialized_range.start = self.drain_range.end;
|
||||
self.uninitialized_ranges
|
||||
.insert(self.next_index, old_start..self.drain_range.start);
|
||||
self.next_index = std::usize::MAX;
|
||||
Some(self.drain_range.clone())
|
||||
}
|
||||
// right cut
|
||||
else {
|
||||
let result = uninitialized_range.start..self.drain_range.end;
|
||||
self.next_index = std::usize::MAX;
|
||||
uninitialized_range.start = self.drain_range.end;
|
||||
Some(result)
|
||||
}
|
||||
if let Some(r) = self
|
||||
.uninitialized_ranges
|
||||
.get(self.next_index)
|
||||
.and_then(|range| {
|
||||
if range.start < self.drain_range.end {
|
||||
Some(range.clone())
|
||||
} else {
|
||||
// left cut
|
||||
if uninitialized_range.start < self.drain_range.start {
|
||||
let result = self.drain_range.start..uninitialized_range.end;
|
||||
uninitialized_range.end = self.drain_range.start;
|
||||
self.next_index = self.next_index + 1;
|
||||
Some(result)
|
||||
None
|
||||
}
|
||||
// fully contained.
|
||||
})
|
||||
{
|
||||
self.next_index += 1;
|
||||
Some(r.start.max(self.drain_range.start)..r.end.min(self.drain_range.end))
|
||||
} else {
|
||||
let num_affected = self.next_index - self.first_index;
|
||||
if num_affected == 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let first_range = &mut self.uninitialized_ranges[self.first_index];
|
||||
|
||||
// Split one "big" uninitialized range?
|
||||
if num_affected == 1
|
||||
&& first_range.start < self.drain_range.start
|
||||
&& first_range.end > self.drain_range.end
|
||||
{
|
||||
let old_start = first_range.start;
|
||||
first_range.start = self.drain_range.end;
|
||||
self.uninitialized_ranges
|
||||
.insert(self.first_index, old_start..self.drain_range.start);
|
||||
}
|
||||
// Adjust border ranges and delete everything in-between.
|
||||
else {
|
||||
let result = uninitialized_range.clone();
|
||||
self.uninitialized_ranges.remove(self.next_index);
|
||||
Some(result)
|
||||
let remove_start = if first_range.start >= self.drain_range.start {
|
||||
self.first_index
|
||||
} else {
|
||||
first_range.end = self.drain_range.start;
|
||||
self.first_index + 1
|
||||
};
|
||||
|
||||
let last_range = &mut self.uninitialized_ranges[self.next_index - 1];
|
||||
let remove_end = if last_range.end <= self.drain_range.end {
|
||||
self.next_index
|
||||
} else {
|
||||
last_range.start = self.drain_range.end;
|
||||
self.next_index - 1
|
||||
};
|
||||
|
||||
self.uninitialized_ranges.drain(remove_start..remove_end);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -142,10 +157,12 @@ impl MemoryInitTracker {
|
||||
&'a mut self,
|
||||
drain_range: Range<wgt::BufferAddress>,
|
||||
) -> MemoryInitTrackerDrain<'a> {
|
||||
let index = self.lower_bound(drain_range.start);
|
||||
MemoryInitTrackerDrain {
|
||||
next_index: self.lower_bound(drain_range.start),
|
||||
drain_range,
|
||||
uninitialized_ranges: &mut self.uninitialized_ranges,
|
||||
first_index: index,
|
||||
next_index: index,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user