mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-21 22:34:43 +00:00
Improve DeviceLayout
convenience (#2599)
This commit is contained in:
parent
4f87b525e7
commit
a52e327184
@ -30,7 +30,6 @@
|
|||||||
use glam::f32::Mat4;
|
use glam::f32::Mat4;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use std::{
|
use std::{
|
||||||
alloc::Layout,
|
|
||||||
error::Error,
|
error::Error,
|
||||||
slice,
|
slice,
|
||||||
sync::{
|
sync::{
|
||||||
@ -293,7 +292,7 @@ impl App {
|
|||||||
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
DeviceLayout::from_layout(Layout::for_value(&vertices)).unwrap(),
|
DeviceLayout::for_value(vertices.as_slice()).unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -311,7 +310,7 @@ impl App {
|
|||||||
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
DeviceLayout::from_layout(Layout::new::<vs::Data>()).unwrap(),
|
DeviceLayout::new_sized::<vs::Data>(),
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{App, RenderContext};
|
use crate::{App, RenderContext};
|
||||||
use std::{alloc::Layout, slice, sync::Arc};
|
use std::{slice, sync::Arc};
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
buffer::{Buffer, BufferContents, BufferCreateInfo, BufferUsage},
|
buffer::{Buffer, BufferContents, BufferCreateInfo, BufferUsage},
|
||||||
command_buffer::RenderPassBeginInfo,
|
command_buffer::RenderPassBeginInfo,
|
||||||
@ -122,7 +122,7 @@ impl SceneTask {
|
|||||||
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
DeviceLayout::from_layout(Layout::for_value(&vertices)).unwrap(),
|
DeviceLayout::for_value(vertices.as_slice()).unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
DeviceAlignment,
|
DeviceAlignment,
|
||||||
},
|
},
|
||||||
DeviceSize, NonZeroDeviceSize, Validated,
|
DeviceSize, Validated,
|
||||||
};
|
};
|
||||||
use crossbeam_queue::ArrayQueue;
|
use crossbeam_queue::ArrayQueue;
|
||||||
use std::{
|
use std::{
|
||||||
@ -241,7 +241,6 @@ where
|
|||||||
where
|
where
|
||||||
T: BufferContents + ?Sized,
|
T: BufferContents + ?Sized,
|
||||||
{
|
{
|
||||||
let len = NonZeroDeviceSize::new(len).expect("empty slices are not valid buffer contents");
|
|
||||||
let layout = T::LAYOUT.layout_for_len(len).unwrap();
|
let layout = T::LAYOUT.layout_for_len(len).unwrap();
|
||||||
|
|
||||||
unsafe { &mut *self.state.get() }
|
unsafe { &mut *self.state.get() }
|
||||||
|
@ -83,8 +83,8 @@ use crate::{
|
|||||||
},
|
},
|
||||||
range_map::RangeMap,
|
range_map::RangeMap,
|
||||||
sync::{future::AccessError, AccessConflict, CurrentAccess, Sharing},
|
sync::{future::AccessError, AccessConflict, CurrentAccess, Sharing},
|
||||||
DeviceSize, NonNullDeviceAddress, NonZeroDeviceSize, Requires, RequiresAllOf, RequiresOneOf,
|
DeviceSize, NonNullDeviceAddress, Requires, RequiresAllOf, RequiresOneOf, Validated,
|
||||||
Validated, ValidationError, Version, VulkanError, VulkanObject,
|
ValidationError, Version, VulkanError, VulkanObject,
|
||||||
};
|
};
|
||||||
use parking_lot::{Mutex, MutexGuard};
|
use parking_lot::{Mutex, MutexGuard};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
@ -352,7 +352,6 @@ impl Buffer {
|
|||||||
where
|
where
|
||||||
T: BufferContents + ?Sized,
|
T: BufferContents + ?Sized,
|
||||||
{
|
{
|
||||||
let len = NonZeroDeviceSize::new(len).expect("empty slices are not valid buffer contents");
|
|
||||||
let layout = T::LAYOUT.layout_for_len(len).unwrap();
|
let layout = T::LAYOUT.layout_for_len(len).unwrap();
|
||||||
let buffer = Subbuffer::new(Buffer::new(
|
let buffer = Subbuffer::new(Buffer::new(
|
||||||
allocator,
|
allocator,
|
||||||
|
@ -944,10 +944,10 @@ impl BufferContentsLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the [`DeviceLayout`] for the data for the given `len`, or returns [`None`] on
|
/// Returns the [`DeviceLayout`] for the data for the given `len`, or returns [`None`] if `len`
|
||||||
/// arithmetic overflow or if the total size would exceed [`DeviceLayout::MAX_SIZE`].
|
/// is zero or if the total size would exceed [`DeviceLayout::MAX_SIZE`].
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn layout_for_len(&self, len: NonZeroDeviceSize) -> Option<DeviceLayout> {
|
pub const fn layout_for_len(&self, len: DeviceSize) -> Option<DeviceLayout> {
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
BufferContentsLayoutInner::Sized(sized) => Some(*sized),
|
BufferContentsLayoutInner::Sized(sized) => Some(*sized),
|
||||||
BufferContentsLayoutInner::Unsized {
|
BufferContentsLayoutInner::Unsized {
|
||||||
@ -977,7 +977,7 @@ impl BufferContentsLayout {
|
|||||||
"types with alignments above 64 are not valid buffer contents",
|
"types with alignments above 64 are not valid buffer contents",
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Ok(sized) = DeviceLayout::from_layout(sized) {
|
if let Some(sized) = DeviceLayout::from_layout(sized) {
|
||||||
Self(BufferContentsLayoutInner::Sized(sized))
|
Self(BufferContentsLayoutInner::Sized(sized))
|
||||||
} else {
|
} else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@ -994,7 +994,7 @@ impl BufferContentsLayout {
|
|||||||
"types with alignments above 64 are not valid buffer contents",
|
"types with alignments above 64 are not valid buffer contents",
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Ok(element_layout) = DeviceLayout::from_layout(element_layout) {
|
if let Some(element_layout) = DeviceLayout::from_layout(element_layout) {
|
||||||
Self(BufferContentsLayoutInner::Unsized {
|
Self(BufferContentsLayoutInner::Unsized {
|
||||||
head_layout: None,
|
head_layout: None,
|
||||||
element_layout,
|
element_layout,
|
||||||
@ -1021,11 +1021,11 @@ impl BufferContentsLayout {
|
|||||||
|
|
||||||
while i < field_layouts.len() {
|
while i < field_layouts.len() {
|
||||||
head_layout = match DeviceLayout::from_layout(field_layouts[i]) {
|
head_layout = match DeviceLayout::from_layout(field_layouts[i]) {
|
||||||
Ok(field_layout) => Some(match head_layout {
|
Some(field_layout) => Some(match head_layout {
|
||||||
Some(layout) => extend(layout, field_layout),
|
Some(layout) => extend(layout, field_layout),
|
||||||
None => field_layout,
|
None => field_layout,
|
||||||
}),
|
}),
|
||||||
Err(_) => unreachable!(),
|
None => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
i += 1;
|
i += 1;
|
||||||
@ -1133,7 +1133,7 @@ impl BufferContentsLayout {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) const fn unwrap_sized(self) -> DeviceLayout {
|
pub(crate) const fn unwrap_sized(self) -> DeviceLayout {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
BufferContentsLayoutInner::Sized(sized) => sized,
|
BufferContentsLayoutInner::Sized(sized) => sized,
|
||||||
BufferContentsLayoutInner::Unsized { .. } => {
|
BufferContentsLayoutInner::Unsized { .. } => {
|
||||||
|
@ -4,7 +4,7 @@ use std::{
|
|||||||
error::Error,
|
error::Error,
|
||||||
fmt::{Debug, Display, Formatter, Result as FmtResult},
|
fmt::{Debug, Display, Formatter, Result as FmtResult},
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
mem::{self, align_of, size_of},
|
mem,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Vulkan analog of std's [`Alignment`], stored as a [`DeviceSize`] that is guaranteed to be a
|
/// Vulkan analog of std's [`Alignment`], stored as a [`DeviceSize`] that is guaranteed to be a
|
||||||
@ -15,8 +15,10 @@ use std::{
|
|||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct DeviceAlignment(AlignmentEnum);
|
pub struct DeviceAlignment(AlignmentEnum);
|
||||||
|
|
||||||
const _: () = assert!(size_of::<DeviceAlignment>() == size_of::<DeviceSize>());
|
const _: () = assert!(mem::size_of::<DeviceAlignment>() == mem::size_of::<DeviceSize>());
|
||||||
const _: () = assert!(align_of::<DeviceAlignment>() == align_of::<DeviceSize>());
|
const _: () = assert!(mem::align_of::<DeviceAlignment>() == mem::align_of::<DeviceSize>());
|
||||||
|
|
||||||
|
const _: () = assert!(mem::size_of::<DeviceSize>() >= mem::size_of::<usize>());
|
||||||
|
|
||||||
impl DeviceAlignment {
|
impl DeviceAlignment {
|
||||||
/// The smallest possible alignment, 1.
|
/// The smallest possible alignment, 1.
|
||||||
@ -28,17 +30,15 @@ impl DeviceAlignment {
|
|||||||
/// Returns the alignment for a type.
|
/// Returns the alignment for a type.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn of<T>() -> Self {
|
pub const fn of<T>() -> Self {
|
||||||
#[cfg(any(
|
|
||||||
target_pointer_width = "64",
|
|
||||||
target_pointer_width = "32",
|
|
||||||
target_pointer_width = "16",
|
|
||||||
))]
|
|
||||||
{
|
|
||||||
const _: () = assert!(size_of::<DeviceSize>() >= size_of::<usize>());
|
|
||||||
|
|
||||||
// SAFETY: rustc guarantees that the alignment of types is a power of two.
|
// SAFETY: rustc guarantees that the alignment of types is a power of two.
|
||||||
unsafe { DeviceAlignment::new_unchecked(align_of::<T>() as DeviceSize) }
|
unsafe { DeviceAlignment::new_unchecked(mem::align_of::<T>() as DeviceSize) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the alignment for a value.
|
||||||
|
#[inline]
|
||||||
|
pub fn of_val<T: ?Sized>(value: &T) -> Self {
|
||||||
|
// SAFETY: rustc guarantees that the alignment of types is a power of two.
|
||||||
|
unsafe { DeviceAlignment::new_unchecked(mem::align_of_val(value) as DeviceSize) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tries to create a `DeviceAlignment` from a [`DeviceSize`], returning [`None`] if it's not a
|
/// Tries to create a `DeviceAlignment` from a [`DeviceSize`], returning [`None`] if it's not a
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
use super::align_up;
|
use super::align_up;
|
||||||
use crate::{macros::try_opt, memory::DeviceAlignment, DeviceSize, NonZeroDeviceSize};
|
use crate::{
|
||||||
|
buffer::BufferContents, macros::try_opt, memory::DeviceAlignment, DeviceSize, NonZeroDeviceSize,
|
||||||
|
};
|
||||||
use std::{
|
use std::{
|
||||||
alloc::Layout,
|
alloc::Layout,
|
||||||
error::Error,
|
error::Error,
|
||||||
fmt::{Debug, Display, Formatter, Result as FmtResult},
|
fmt::{Debug, Display, Formatter, Result as FmtResult},
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
mem::size_of,
|
mem,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Vulkan analog of std's [`Layout`], represented using [`DeviceSize`]s.
|
/// Vulkan analog of std's [`Layout`], represented using [`DeviceSize`]s.
|
||||||
@ -17,6 +19,9 @@ pub struct DeviceLayout {
|
|||||||
alignment: DeviceAlignment,
|
alignment: DeviceAlignment,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const _: () = assert!(mem::size_of::<DeviceSize>() >= mem::size_of::<usize>());
|
||||||
|
const _: () = assert!(DeviceLayout::MAX_SIZE >= isize::MAX as DeviceSize);
|
||||||
|
|
||||||
impl DeviceLayout {
|
impl DeviceLayout {
|
||||||
/// The maximum size of a memory block after its layout's size has been rounded up to the
|
/// The maximum size of a memory block after its layout's size has been rounded up to the
|
||||||
/// nearest multiple of its layout's alignment.
|
/// nearest multiple of its layout's alignment.
|
||||||
@ -26,59 +31,43 @@ impl DeviceLayout {
|
|||||||
/// undefined behavior*.
|
/// undefined behavior*.
|
||||||
pub const MAX_SIZE: DeviceSize = DeviceAlignment::MAX.as_devicesize() - 1;
|
pub const MAX_SIZE: DeviceSize = DeviceAlignment::MAX.as_devicesize() - 1;
|
||||||
|
|
||||||
/// Creates a new `DeviceLayout` from a [`Layout`], or returns an error if the `Layout` has
|
/// Creates a new `DeviceLayout` from a [`Layout`], or returns [`None`] if the `Layout` has
|
||||||
/// zero size.
|
/// zero size.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn from_layout(layout: Layout) -> Result<Self, TryFromLayoutError> {
|
pub const fn from_layout(layout: Layout) -> Option<DeviceLayout> {
|
||||||
let (size, alignment) = Self::size_alignment_from_layout(&layout);
|
let (size, alignment) = Self::size_alignment_from_layout(&layout);
|
||||||
|
|
||||||
#[cfg(any(
|
|
||||||
target_pointer_width = "64",
|
|
||||||
target_pointer_width = "32",
|
|
||||||
target_pointer_width = "16",
|
|
||||||
))]
|
|
||||||
{
|
|
||||||
const _: () = assert!(size_of::<DeviceSize>() >= size_of::<usize>());
|
|
||||||
const _: () = assert!(DeviceLayout::MAX_SIZE >= isize::MAX as DeviceSize);
|
|
||||||
|
|
||||||
if let Some(size) = NonZeroDeviceSize::new(size) {
|
if let Some(size) = NonZeroDeviceSize::new(size) {
|
||||||
// SAFETY: Under the precondition that `usize` can't overflow `DeviceSize`, which
|
// SAFETY: Under the precondition that `usize` can't overflow `DeviceSize`, which we
|
||||||
// we checked above, `Layout`'s overflow-invariant is the same if not stricter than
|
// checked above, `Layout`'s overflow-invariant is the same if not stricter than that
|
||||||
// that of `DeviceLayout`.
|
// of `DeviceLayout`.
|
||||||
Ok(unsafe { DeviceLayout::new_unchecked(size, alignment) })
|
Some(unsafe { DeviceLayout::new_unchecked(size, alignment) })
|
||||||
} else {
|
} else {
|
||||||
Err(TryFromLayoutError)
|
None
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts the `DeviceLayout` into a [`Layout`], or returns an error if the `DeviceLayout`
|
/// Converts the `DeviceLayout` into a [`Layout`], or returns [`None`] if the `DeviceLayout`
|
||||||
/// doesn't meet the invariants of `Layout`.
|
/// doesn't meet the invariants of `Layout`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn into_layout(self) -> Result<Layout, TryFromDeviceLayoutError> {
|
pub const fn into_layout(self) -> Option<Layout> {
|
||||||
let (size, alignment) = (self.size(), self.alignment().as_devicesize());
|
let (size, alignment) = (self.size(), self.alignment().as_devicesize());
|
||||||
|
|
||||||
#[cfg(target_pointer_width = "64")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
{
|
{
|
||||||
const _: () = assert!(size_of::<DeviceSize>() <= size_of::<usize>());
|
|
||||||
const _: () = assert!(DeviceLayout::MAX_SIZE as usize <= isize::MAX as usize);
|
|
||||||
|
|
||||||
// SAFETY: Under the precondition that `DeviceSize` can't overflow `usize`, which we
|
// SAFETY: Under the precondition that `DeviceSize` can't overflow `usize`, which we
|
||||||
// checked above, `DeviceLayout`'s overflow-invariant is the same if not stricter that
|
// checked above, `DeviceLayout`'s overflow-invariant is the same if not stricter that
|
||||||
// of `Layout`.
|
// of `Layout`.
|
||||||
Ok(unsafe { Layout::from_size_align_unchecked(size as usize, alignment as usize) })
|
Some(unsafe { Layout::from_size_align_unchecked(size as usize, alignment as usize) })
|
||||||
}
|
}
|
||||||
#[cfg(any(target_pointer_width = "32", target_pointer_width = "16"))]
|
#[cfg(any(target_pointer_width = "32", target_pointer_width = "16"))]
|
||||||
{
|
{
|
||||||
const _: () = assert!(size_of::<DeviceSize>() > size_of::<usize>());
|
|
||||||
const _: () = assert!(DeviceLayout::MAX_SIZE > isize::MAX as DeviceSize);
|
|
||||||
|
|
||||||
if size > usize::MAX as DeviceSize || alignment > usize::MAX as DeviceSize {
|
if size > usize::MAX as DeviceSize || alignment > usize::MAX as DeviceSize {
|
||||||
Err(TryFromDeviceLayoutError)
|
None
|
||||||
} else if let Ok(layout) = Layout::from_size_align(size as usize, alignment as usize) {
|
} else if let Ok(layout) = Layout::from_size_align(size as usize, alignment as usize) {
|
||||||
Ok(layout)
|
Some(layout)
|
||||||
} else {
|
} else {
|
||||||
Err(TryFromDeviceLayoutError)
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,6 +105,24 @@ impl DeviceLayout {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new `DeviceLayout` for a sized `T`.
|
||||||
|
#[inline]
|
||||||
|
pub const fn new_sized<T: BufferContents>() -> DeviceLayout {
|
||||||
|
T::LAYOUT.unwrap_sized()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new `DeviceLayout` for an unsized `T` with an unsized tail of `len` elements.
|
||||||
|
///
|
||||||
|
/// Returns [`None`] if `len` is zero or if the total size would exceed
|
||||||
|
/// [`DeviceLayout::MAX_SIZE`], unless the `T` is actually sized, in which case this behaves
|
||||||
|
/// identically to [`new_sized`] and `len` is ignored.
|
||||||
|
///
|
||||||
|
/// [`new_sized`]: Self::new_sized
|
||||||
|
#[inline]
|
||||||
|
pub const fn new_unsized<T: BufferContents + ?Sized>(len: DeviceSize) -> Option<DeviceLayout> {
|
||||||
|
T::LAYOUT.layout_for_len(len)
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new `DeviceLayout` from the given `size` and `alignment`.
|
/// Creates a new `DeviceLayout` from the given `size` and `alignment`.
|
||||||
///
|
///
|
||||||
/// Returns [`None`] if `size` would exceed [`DeviceLayout::MAX_SIZE`] when rounded up to the
|
/// Returns [`None`] if `size` would exceed [`DeviceLayout::MAX_SIZE`] when rounded up to the
|
||||||
@ -151,6 +158,14 @@ impl DeviceLayout {
|
|||||||
DeviceLayout { size, alignment }
|
DeviceLayout { size, alignment }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new `DeviceLayout` for the given `value`.
|
||||||
|
///
|
||||||
|
/// Returns [`None`] if the value is zero-sized.
|
||||||
|
#[inline]
|
||||||
|
pub fn for_value<T: BufferContents + ?Sized>(value: &T) -> Option<DeviceLayout> {
|
||||||
|
DeviceLayout::from_layout(Layout::for_value(value))
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the minimum size in bytes for a memory block of this layout.
|
/// Returns the minimum size in bytes for a memory block of this layout.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn size(&self) -> DeviceSize {
|
pub const fn size(&self) -> DeviceSize {
|
||||||
@ -202,10 +217,11 @@ impl DeviceLayout {
|
|||||||
/// with padding at the end of each to ensure correct alignment of all instances.
|
/// with padding at the end of each to ensure correct alignment of all instances.
|
||||||
///
|
///
|
||||||
/// Returns a tuple consisting of the new layout and the stride, in bytes, of `self`, or
|
/// Returns a tuple consisting of the new layout and the stride, in bytes, of `self`, or
|
||||||
/// returns [`None`] on arithmetic overflow or when the total size would exceed
|
/// returns [`None`] if `n` is zero or when the total size would exceed
|
||||||
/// [`DeviceLayout::MAX_SIZE`].
|
/// [`DeviceLayout::MAX_SIZE`].
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn repeat(&self, n: NonZeroDeviceSize) -> Option<(Self, DeviceSize)> {
|
pub const fn repeat(&self, n: DeviceSize) -> Option<(Self, DeviceSize)> {
|
||||||
|
let n = try_opt!(NonZeroDeviceSize::new(n));
|
||||||
let stride = self.padded_size();
|
let stride = self.padded_size();
|
||||||
let size = try_opt!(stride.checked_mul(n));
|
let size = try_opt!(stride.checked_mul(n));
|
||||||
let layout = try_opt!(DeviceLayout::new(size, self.alignment));
|
let layout = try_opt!(DeviceLayout::new(size, self.alignment));
|
||||||
@ -275,16 +291,7 @@ impl DeviceLayout {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
const fn size_alignment_from_layout(layout: &Layout) -> (DeviceSize, DeviceAlignment) {
|
const fn size_alignment_from_layout(layout: &Layout) -> (DeviceSize, DeviceAlignment) {
|
||||||
#[cfg(any(
|
// We checked that `usize` can't overflow `DeviceSize` above, so this can't truncate.
|
||||||
target_pointer_width = "64",
|
|
||||||
target_pointer_width = "32",
|
|
||||||
target_pointer_width = "16",
|
|
||||||
))]
|
|
||||||
{
|
|
||||||
const _: () = assert!(size_of::<DeviceSize>() >= size_of::<usize>());
|
|
||||||
const _: () = assert!(DeviceLayout::MAX_SIZE >= isize::MAX as DeviceSize);
|
|
||||||
|
|
||||||
// We checked that `usize` can't overflow `DeviceSize`, so this can't truncate.
|
|
||||||
let (size, alignment) = (layout.size() as DeviceSize, layout.align() as DeviceSize);
|
let (size, alignment) = (layout.size() as DeviceSize, layout.align() as DeviceSize);
|
||||||
|
|
||||||
// SAFETY: `Layout`'s alignment-invariant guarantees that it is a power of two.
|
// SAFETY: `Layout`'s alignment-invariant guarantees that it is a power of two.
|
||||||
@ -292,7 +299,6 @@ impl DeviceLayout {
|
|||||||
|
|
||||||
(size, alignment)
|
(size, alignment)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<Layout> for DeviceLayout {
|
impl TryFrom<Layout> for DeviceLayout {
|
||||||
@ -300,7 +306,7 @@ impl TryFrom<Layout> for DeviceLayout {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn try_from(layout: Layout) -> Result<Self, Self::Error> {
|
fn try_from(layout: Layout) -> Result<Self, Self::Error> {
|
||||||
DeviceLayout::from_layout(layout)
|
DeviceLayout::from_layout(layout).ok_or(TryFromLayoutError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,7 +315,7 @@ impl TryFrom<DeviceLayout> for Layout {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn try_from(device_layout: DeviceLayout) -> Result<Self, Self::Error> {
|
fn try_from(device_layout: DeviceLayout) -> Result<Self, Self::Error> {
|
||||||
DeviceLayout::into_layout(device_layout)
|
DeviceLayout::into_layout(device_layout).ok_or(TryFromDeviceLayoutError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user