Align buffer usage end to 4

This commit is contained in:
Dzmitry Malyshau
2021-09-20 14:56:37 -04:00
committed by Dzmitry Malyshau
parent be6898f166
commit 08ff76f150
3 changed files with 29 additions and 10 deletions

View File

@@ -90,7 +90,17 @@ impl<A: hal::Api> BakedCommands<A> {
.get_mut(buffer_use.id)
.map_err(|_| DestroyedBufferError(buffer_use.id))?;
let uninitialized_ranges = buffer.initialization_status.drain(buffer_use.range.clone());
// align the end to 4
let end_remainder = buffer_use.range.end % wgt::COPY_BUFFER_ALIGNMENT;
let end = if end_remainder == 0 {
buffer_use.range.end
} else {
buffer_use.range.end + wgt::COPY_BUFFER_ALIGNMENT - end_remainder
};
let uninitialized_ranges = buffer
.initialization_status
.drain(buffer_use.range.start..end);
match buffer_use.kind {
MemoryInitKind::ImplicitlyInitialized => {
uninitialized_ranges.for_each(drop);
@@ -140,8 +150,8 @@ impl<A: hal::Api> BakedCommands<A> {
}
for range in ranges.iter() {
assert!(range.start % 4 == 0, "Buffer {:?} has an uninitialized range with a start not aligned to 4 (start was {})", raw_buf, range.start);
assert!(range.end % 4 == 0, "Buffer {:?} has an uninitialized range with an end not aligned to 4 (end was {})", raw_buf, range.end);
assert!(range.start % wgt::COPY_BUFFER_ALIGNMENT == 0, "Buffer {:?} has an uninitialized range with a start not aligned to 4 (start was {})", raw_buf, range.start);
assert!(range.end % wgt::COPY_BUFFER_ALIGNMENT == 0, "Buffer {:?} has an uninitialized range with an end not aligned to 4 (end was {})", raw_buf, range.end);
unsafe {
self.encoder.clear_buffer(raw_buf, range.clone());

View File

@@ -160,6 +160,8 @@ fn map_buffer<A: hal::Api>(
_ => None,
};
assert_eq!(offset % wgt::COPY_BUFFER_ALIGNMENT, 0);
assert_eq!(size % wgt::COPY_BUFFER_ALIGNMENT, 0);
// Zero out uninitialized parts of the mapping. (Spec dictates all resources behave as if they were initialized with zero)
//
// If this is a read mapping, ideally we would use a `clear_buffer` command before reading the data from GPU (i.e. `invalidate_range`).
@@ -510,13 +512,19 @@ impl<A: HalApi> Device<A> {
} else {
desc.size
};
let clear_remainder = actual_size % wgt::COPY_BUFFER_ALIGNMENT;
let aligned_size = if clear_remainder != 0 {
actual_size + wgt::COPY_BUFFER_ALIGNMENT - clear_remainder
} else {
actual_size
};
let mut memory_flags = hal::MemoryFlags::empty();
memory_flags.set(hal::MemoryFlags::TRANSIENT, transient);
let hal_desc = hal::BufferDescriptor {
label: desc.label.borrow_option(),
size: actual_size,
size: aligned_size,
usage,
memory_flags,
};
@@ -1323,9 +1331,10 @@ impl<A: HalApi> Device<A> {
return Err(Error::BindingZeroSize(bb.buffer_id));
}
assert_eq!(bb.offset % wgt::COPY_BUFFER_ALIGNMENT, 0);
used_buffer_ranges.extend(buffer.initialization_status.create_action(
bb.buffer_id,
bb.offset..(bb.offset + bind_size),
bb.offset..bb.offset + bind_size,
MemoryInitKind::NeedsInitializedMemory,
));
@@ -2771,6 +2780,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
}
};
assert_eq!(buffer.size % wgt::COPY_BUFFER_ALIGNMENT, 0);
// Zero initialize memory and then mark both staging and buffer as initialized
// (it's guaranteed that this is the case by the time the buffer is usable)
unsafe { ptr::write_bytes(mapping.ptr.as_ptr(), 0, buffer.size as usize) };

View File

@@ -14,7 +14,7 @@
// therefore this leads to a `MemoryInitKind.ImplicitlyInitialized` action, exactly like a read would.
use smallvec::SmallVec;
use std::{iter, ops::Range};
use std::{fmt, iter, ops::Range};
mod buffer;
//mod texture;
@@ -46,7 +46,7 @@ pub(crate) struct InitTracker<Idx: Ord + Copy + Default> {
uninitialized_ranges: UninitializedRangeVec<Idx>,
}
pub(crate) struct InitTrackerDrain<'a, Idx: Ord + Copy> {
pub(crate) struct InitTrackerDrain<'a, Idx: fmt::Debug + Ord + Copy> {
uninitialized_ranges: &'a mut UninitializedRangeVec<Idx>,
drain_range: Range<Idx>,
first_index: usize,
@@ -55,7 +55,7 @@ pub(crate) struct InitTrackerDrain<'a, Idx: Ord + Copy> {
impl<'a, Idx> Iterator for InitTrackerDrain<'a, Idx>
where
Idx: Ord + Copy,
Idx: fmt::Debug + Ord + Copy,
{
type Item = Range<Idx>;
@@ -78,7 +78,6 @@ where
if num_affected == 0 {
return None;
}
let first_range = &mut self.uninitialized_ranges[self.first_index];
// Split one "big" uninitialized range?
@@ -118,7 +117,7 @@ where
impl<Idx> InitTracker<Idx>
where
Idx: Ord + Copy + Default,
Idx: fmt::Debug + Ord + Copy + Default,
{
pub(crate) fn new(size: Idx) -> Self {
Self {