mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Document arithmetic binary operation type rules.
This commit is contained in:
39
src/lib.rs
39
src/lib.rs
@@ -876,6 +876,45 @@ pub enum UnaryOperator {
|
||||
}
|
||||
|
||||
/// Operation that can be applied on two values.
|
||||
///
|
||||
/// ## Arithmetic type rules
|
||||
///
|
||||
/// The arithmetic operations `Add`, `Subtract`, `Multiply`, `Divide`, and
|
||||
/// `Modulo` can all be applied to [`Scalar`] types other than [`Bool`], or
|
||||
/// [`Vector`]s thereof. Both operands must have the same type.
|
||||
///
|
||||
/// `Add` and `Subtract` can also be applied to [`Matrix`] values. Both operands
|
||||
/// must have the same type.
|
||||
///
|
||||
/// `Multiply` supports additional cases:
|
||||
///
|
||||
/// - A [`Matrix`] or [`Vector`] can be multiplied by a scalar [`Float`],
|
||||
/// either on the left or the right.
|
||||
///
|
||||
/// - A [`Matrix`] on the left can be multiplied by a [`Vector`] on the right
|
||||
/// if the matrix has as many columns as the vector has components (`matCxR
|
||||
/// * VecC`).
|
||||
///
|
||||
/// - A [`Vector`] on the left can be multiplied by a [`Matrix`] on the right
|
||||
/// if the matrix has as many rows as the vector has components (`VecR *
|
||||
/// matCxR`).
|
||||
///
|
||||
/// - Two matrices can be multiplied if the left operand has as many columns
|
||||
/// as the right operand has rows (`matNxR * matCxN`).
|
||||
///
|
||||
/// In all the above `Multiply` cases, the byte widths of the underlying scalar
|
||||
/// types of both operands must be the same.
|
||||
///
|
||||
/// Note that `Multiply` supports mixed vector and scalar operations directly,
|
||||
/// whereas the other arithmetic operations require an explicit [`Splat`] for
|
||||
/// mixed-type use.
|
||||
///
|
||||
/// [`Scalar`]: TypeInner::Scalar
|
||||
/// [`Vector`]: TypeInner::Vector
|
||||
/// [`Matrix`]: TypeInner::Matrix
|
||||
/// [`Float`]: ScalarKind::Float
|
||||
/// [`Bool`]: ScalarKind::Bool
|
||||
/// [`Splat`]: Expression::Splat
|
||||
#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||
|
||||
@@ -740,16 +740,18 @@ impl super::Validator {
|
||||
_ => false,
|
||||
},
|
||||
Bo::Multiply => {
|
||||
let kind_match = match left_inner.scalar_kind() {
|
||||
let kind_allowed = match left_inner.scalar_kind() {
|
||||
Some(Sk::Uint | Sk::Sint | Sk::Float) => true,
|
||||
Some(Sk::Bool) | None => false,
|
||||
};
|
||||
let types_match = match (left_inner, right_inner) {
|
||||
// Straight scalar and mixed scalar/vector.
|
||||
(&Ti::Scalar { kind: kind1, .. }, &Ti::Scalar { kind: kind2, .. })
|
||||
| (&Ti::Vector { kind: kind1, .. }, &Ti::Scalar { kind: kind2, .. })
|
||||
| (&Ti::Scalar { kind: kind1, .. }, &Ti::Vector { kind: kind2, .. }) => {
|
||||
kind1 == kind2
|
||||
}
|
||||
// Scalar/matrix.
|
||||
(
|
||||
&Ti::Scalar {
|
||||
kind: Sk::Float, ..
|
||||
@@ -762,6 +764,7 @@ impl super::Validator {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
) => true,
|
||||
// Vector/vector.
|
||||
(
|
||||
&Ti::Vector {
|
||||
kind: kind1,
|
||||
@@ -774,6 +777,7 @@ impl super::Validator {
|
||||
..
|
||||
},
|
||||
) => kind1 == kind2 && size1 == size2,
|
||||
// Matrix * vector.
|
||||
(
|
||||
&Ti::Matrix { columns, .. },
|
||||
&Ti::Vector {
|
||||
@@ -782,6 +786,7 @@ impl super::Validator {
|
||||
..
|
||||
},
|
||||
) => columns == size,
|
||||
// Vector * matrix.
|
||||
(
|
||||
&Ti::Vector {
|
||||
kind: Sk::Float,
|
||||
@@ -807,7 +812,7 @@ impl super::Validator {
|
||||
| Ti::Matrix { width, .. } => width,
|
||||
_ => 0,
|
||||
};
|
||||
kind_match && types_match && left_width == right_width
|
||||
kind_allowed && types_match && left_width == right_width
|
||||
}
|
||||
Bo::Equal | Bo::NotEqual => left_inner.is_sized() && left_inner == right_inner,
|
||||
Bo::Less | Bo::LessEqual | Bo::Greater | Bo::GreaterEqual => {
|
||||
|
||||
Reference in New Issue
Block a user