mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-22 14:55:05 +00:00
[wgpu-core] when mapping buffers for reading, mark buffers as initialized only when they have MAP_WRITE
usage (#6178)
This commit is contained in:
parent
ee35b0e586
commit
4e78829d82
@ -336,6 +336,23 @@ fn map_buffer(
|
|||||||
|
|
||||||
let mapped = unsafe { std::slice::from_raw_parts_mut(mapping.ptr.as_ptr(), size as usize) };
|
let mapped = unsafe { std::slice::from_raw_parts_mut(mapping.ptr.as_ptr(), size as usize) };
|
||||||
|
|
||||||
|
// We can't call flush_mapped_ranges in this case, so we can't drain the uninitialized ranges either
|
||||||
|
if !mapping.is_coherent
|
||||||
|
&& kind == HostMap::Read
|
||||||
|
&& !buffer.usage.contains(wgt::BufferUsages::MAP_WRITE)
|
||||||
|
{
|
||||||
|
for uninitialized in buffer
|
||||||
|
.initialization_status
|
||||||
|
.write()
|
||||||
|
.uninitialized(offset..(size + offset))
|
||||||
|
{
|
||||||
|
// The mapping's pointer is already offset, however we track the
|
||||||
|
// uninitialized range relative to the buffer's start.
|
||||||
|
let fill_range =
|
||||||
|
(uninitialized.start - offset) as usize..(uninitialized.end - offset) as usize;
|
||||||
|
mapped[fill_range].fill(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
for uninitialized in buffer
|
for uninitialized in buffer
|
||||||
.initialization_status
|
.initialization_status
|
||||||
.write()
|
.write()
|
||||||
@ -347,10 +364,15 @@ fn map_buffer(
|
|||||||
(uninitialized.start - offset) as usize..(uninitialized.end - offset) as usize;
|
(uninitialized.start - offset) as usize..(uninitialized.end - offset) as usize;
|
||||||
mapped[fill_range].fill(0);
|
mapped[fill_range].fill(0);
|
||||||
|
|
||||||
if !mapping.is_coherent && kind == HostMap::Read {
|
// NOTE: This is only possible when MAPPABLE_PRIMARY_BUFFERS is enabled.
|
||||||
|
if !mapping.is_coherent
|
||||||
|
&& kind == HostMap::Read
|
||||||
|
&& buffer.usage.contains(wgt::BufferUsages::MAP_WRITE)
|
||||||
|
{
|
||||||
unsafe { raw.flush_mapped_ranges(raw_buffer, &[uninitialized]) };
|
unsafe { raw.flush_mapped_ranges(raw_buffer, &[uninitialized]) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(mapping)
|
Ok(mapping)
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,35 @@ pub(crate) struct InitTracker<Idx: Ord + Copy + Default> {
|
|||||||
uninitialized_ranges: UninitializedRangeVec<Idx>,
|
uninitialized_ranges: UninitializedRangeVec<Idx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) struct UninitializedIter<'a, Idx: fmt::Debug + Ord + Copy> {
|
||||||
|
uninitialized_ranges: &'a UninitializedRangeVec<Idx>,
|
||||||
|
drain_range: Range<Idx>,
|
||||||
|
next_index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Idx> Iterator for UninitializedIter<'a, Idx>
|
||||||
|
where
|
||||||
|
Idx: fmt::Debug + Ord + Copy,
|
||||||
|
{
|
||||||
|
type Item = Range<Idx>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.uninitialized_ranges
|
||||||
|
.get(self.next_index)
|
||||||
|
.and_then(|range| {
|
||||||
|
if range.start < self.drain_range.end {
|
||||||
|
self.next_index += 1;
|
||||||
|
Some(
|
||||||
|
range.start.max(self.drain_range.start)
|
||||||
|
..range.end.min(self.drain_range.end),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) struct InitTrackerDrain<'a, Idx: fmt::Debug + Ord + Copy> {
|
pub(crate) struct InitTrackerDrain<'a, Idx: fmt::Debug + Ord + Copy> {
|
||||||
uninitialized_ranges: &'a mut UninitializedRangeVec<Idx>,
|
uninitialized_ranges: &'a mut UninitializedRangeVec<Idx>,
|
||||||
drain_range: Range<Idx>,
|
drain_range: Range<Idx>,
|
||||||
@ -190,6 +219,18 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns an iterator over the uninitialized ranges in a query range.
|
||||||
|
pub(crate) fn uninitialized(&mut self, drain_range: Range<Idx>) -> UninitializedIter<Idx> {
|
||||||
|
let index = self
|
||||||
|
.uninitialized_ranges
|
||||||
|
.partition_point(|r| r.end <= drain_range.start);
|
||||||
|
UninitializedIter {
|
||||||
|
drain_range,
|
||||||
|
uninitialized_ranges: &self.uninitialized_ranges,
|
||||||
|
next_index: index,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Drains uninitialized ranges in a query range.
|
// Drains uninitialized ranges in a query range.
|
||||||
pub(crate) fn drain(&mut self, drain_range: Range<Idx>) -> InitTrackerDrain<Idx> {
|
pub(crate) fn drain(&mut self, drain_range: Range<Idx>) -> InitTrackerDrain<Idx> {
|
||||||
let index = self
|
let index = self
|
||||||
|
Loading…
Reference in New Issue
Block a user