pubconstfn new(n: u32) -> Option<Self> { if n.is_power_of_two() { // SAFETY: value can't be 0 since we just checked if it's a power of 2
Some(Self(unsafe { NonZeroU32::new_unchecked(n) }))
} else {
None
}
}
/// # Panics /// If `width` is not a power of 2 pubfn from_width(width: u8) -> Self { Self::new(width as u32).unwrap()
}
/// Returns whether or not `n` is a multiple of this alignment. pubconstfn is_aligned(&self, n: u32) -> bool { // equivalent to: `n % self.0.get() == 0` but much faster
n & (self.0.get() - 1) == 0
}
/// Round `n` up to the nearest alignment boundary. pubconstfn round_up(&self, n: u32) -> u32 { // equivalent to: // match n % self.0.get() { // 0 => n, // rem => n + (self.0.get() - rem), // } let mask = self.0.get() - 1;
(n + mask) & !mask
}
}
impl ops::Mul for Alignment { type Output = Alignment;
fn mul(self, rhs: Alignment) -> Self::Output { // SAFETY: both lhs and rhs are powers of 2, the result will be a power of 2 Self(unsafe { NonZeroU32::new_unchecked(self.0.get() * rhs.0.get()) })
}
}
/// Size and alignment information for a type. #[derive(Clone, Copy, Debug, Hash, PartialEq)] #[cfg_attr(feature = "serialize", derive(serde::Serialize))] #[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] pubstruct TypeLayout { pub size: u32, pub alignment: Alignment,
}
impl TypeLayout { /// Produce the stride as if this type is a base of an array. pubconstfn to_stride(&self) -> u32 { self.alignment.round_up(self.size)
}
}
/// Helper processor that derives the sizes of all types. /// /// `Layouter` uses the default layout algorithm/table, described in /// [WGSL §4.3.7, "Memory Layout"] /// /// A `Layouter` may be indexed by `Handle<Type>` values: `layouter[handle]` is the /// layout of the type whose handle is `handle`. /// /// [WGSL §4.3.7, "Memory Layout"](https://gpuweb.github.io/gpuweb/wgsl/#memory-layouts) #[derive(Debug, Default)] pubstruct Layouter { /// Layouts for types in an arena.
layouts: HandleVec<crate::Type, TypeLayout>,
}
impl ops::Index<Handle<crate::Type>> for Layouter { type Output = TypeLayout; fn index(&self, handle: Handle<crate::Type>) -> &TypeLayout {
&self.layouts[handle]
}
}
#[derive(Clone, Copy, Debug, PartialEq, thiserror::Error)] pubenum LayoutErrorInner { #[error("Array element type {0:?} doesn't exist")]
InvalidArrayElementType(Handle<crate::Type>), #[error("Struct member[{0}] type {1:?} doesn't exist")]
InvalidStructMemberType(u32, Handle<crate::Type>), #[error("Type width must be a power of two")]
NonPowerOfTwoWidth,
}
impl Layouter { /// Remove all entries from this `Layouter`, retaining storage. pubfn clear(&mutself) { self.layouts.clear();
}
/// Extend this `Layouter` with layouts for any new entries in `gctx.types`. /// /// Ensure that every type in `gctx.types` has a corresponding [TypeLayout] /// in [`self.layouts`]. /// /// Some front ends need to be able to compute layouts for existing types /// while module construction is still in progress and new types are still /// being added. This function assumes that the `TypeLayout` values already /// present in `self.layouts` cover their corresponding entries in `types`, /// and extends `self.layouts` as needed to cover the rest. Thus, a front /// end can call this function at any time, passing its current type and /// constant arenas, and then assume that layouts are available for all /// types. #[allow(clippy::or_fun_call)] pubfn update(&mutself, gctx: super::GlobalCtx) -> Result<(), LayoutError> { usecrate::TypeInner as Ti;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.