Skip to content

Commit

Permalink
Remove uses of Option::unwrap_unchecked as a safety precaution (vul…
Browse files Browse the repository at this point in the history
  • Loading branch information
marc0246 authored and hakolao committed Feb 20, 2024
1 parent 0455dd5 commit d2bdeec
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 5 deletions.
8 changes: 3 additions & 5 deletions vulkano/src/buffer/subbuffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,9 @@ impl<T: ?Sized> Subbuffer<T> {
/// [`MappingState::slice`]: crate::memory::MappingState::slice
pub fn mapped_slice(&self) -> Result<NonNull<[u8]>, HostAccessError> {
match self.buffer().memory() {
BufferMemory::Normal(a) => {
let opt = a.mapped_slice(self.range());

BufferMemory::Normal(allocation) => {
// SAFETY: `self.range()` is in bounds of the allocation.
unsafe { opt.unwrap_unchecked() }
unsafe { allocation.mapped_slice_unchecked(self.range()) }
}
BufferMemory::Sparse => unreachable!(),
}
Expand Down Expand Up @@ -510,7 +508,7 @@ impl<T> Subbuffer<[T]> {

#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn slice_unchecked(mut self, range: impl RangeBounds<DeviceSize>) -> Subbuffer<[T]> {
let Range { start, end } = memory::range(range, ..self.len()).unwrap_unchecked();
let Range { start, end } = memory::range_unchecked(range, ..self.len());

self.offset += start * size_of::<T>() as DeviceSize;
self.size = (end - start) * size_of::<T>() as DeviceSize;
Expand Down
17 changes: 17 additions & 0 deletions vulkano/src/memory/allocator/suballocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,23 @@ impl MemoryAlloc {
Some(res)
}

#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
#[inline]
pub unsafe fn mapped_slice_unchecked(
&self,
range: impl RangeBounds<DeviceSize>,
) -> Result<NonNull<[u8]>, HostAccessError> {
let mut range = memory::range_unchecked(range, ..self.size());
range.start += self.offset();
range.end += self.offset();

if let Some(state) = self.device_memory().mapping_state() {
state.slice(range).ok_or(HostAccessError::OutOfMappedRange)
} else {
Err(HostAccessError::NotHostMapped)
}
}

pub(crate) fn atom_size(&self) -> Option<DeviceAlignment> {
self.atom_size
}
Expand Down
24 changes: 24 additions & 0 deletions vulkano/src/memory/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,3 +590,27 @@ pub(crate) fn range(

(start <= end && end <= len).then_some(Range { start, end })
}

/// Converts a `RangeBounds` into a `Range` without doing any bounds checking.
pub(crate) fn range_unchecked(
range: impl RangeBounds<DeviceSize>,
bounds: RangeTo<DeviceSize>,
) -> Range<DeviceSize> {
let len = bounds.end;

let start = match range.start_bound() {
Bound::Included(&start) => start,
Bound::Excluded(start) => start + 1,
Bound::Unbounded => 0,
};

let end = match range.end_bound() {
Bound::Included(end) => end + 1,
Bound::Excluded(&end) => end,
Bound::Unbounded => len,
};

debug_assert!(start <= end && end <= len);

Range { start, end }
}

0 comments on commit d2bdeec

Please # to comment.