[naga] Introduce ScalarKind::AbstractInt and AbstractFloat.

Introduce new variants of `naga::ScalarKind`, `AbstractInt` and
`AbstractFloat`, for representing WGSL abstract types.
This commit is contained in:
Jim Blandy 2023-11-09 09:23:15 -08:00 committed by Teodor Tanasoaia
parent 723b8baf2a
commit 276c978b70
13 changed files with 95 additions and 16 deletions

View File

@ -3555,6 +3555,9 @@ impl<'a, W: Write> Writer<'a, W> {
(Sk::Sint | Sk::Uint | Sk::Float, Sk::Bool, None) => {
write!(self.out, "bool")?
}
(Sk::AbstractInt | Sk::AbstractFloat, _, _)
| (_, Sk::AbstractInt | Sk::AbstractFloat, _) => unreachable!(),
};
write!(self.out, "(")?;
@ -4117,6 +4120,11 @@ impl<'a, W: Write> Writer<'a, W> {
crate::ScalarKind::Uint => write!(self.out, "0u")?,
crate::ScalarKind::Float => write!(self.out, "0.0")?,
crate::ScalarKind::Sint => write!(self.out, "0")?,
crate::ScalarKind::AbstractInt | crate::ScalarKind::AbstractFloat => {
return Err(Error::Custom(
"Abstract types should not appear in IR presented to backends".to_string(),
))
}
}
Ok(())
@ -4345,6 +4353,9 @@ const fn glsl_scalar(scalar: crate::Scalar) -> Result<ScalarString<'static>, Err
prefix: "b",
full: "bool",
},
Sk::AbstractInt | Sk::AbstractFloat => {
return Err(Error::UnsupportedScalar(scalar));
}
})
}

View File

@ -10,7 +10,7 @@ impl crate::ScalarKind {
Self::Float => "asfloat",
Self::Sint => "asint",
Self::Uint => "asuint",
Self::Bool => unreachable!(),
Self::Bool | Self::AbstractInt | Self::AbstractFloat => unreachable!(),
}
}
}
@ -30,6 +30,9 @@ impl crate::Scalar {
_ => Err(Error::UnsupportedScalar(self)),
},
crate::ScalarKind::Bool => Ok("bool"),
crate::ScalarKind::AbstractInt | crate::ScalarKind::AbstractFloat => {
Err(Error::UnsupportedScalar(self))
}
}
}
}

View File

@ -338,6 +338,10 @@ impl crate::Scalar {
kind: Sk::Bool,
width: _,
} => "bool",
Self {
kind: Sk::AbstractInt | Sk::AbstractFloat,
width: _,
} => unreachable!(),
}
}
}

View File

@ -1175,7 +1175,7 @@ impl<'w> BlockContext<'w> {
let op = match src_scalar.kind {
Sk::Sint | Sk::Uint => spirv::Op::INotEqual,
Sk::Float => spirv::Op::FUnordNotEqual,
Sk::Bool => unreachable!(),
Sk::Bool | Sk::AbstractInt | Sk::AbstractFloat => unreachable!(),
};
let zero_scalar_id =
self.writer.get_constant_scalar_with(0, src_scalar)?;

View File

@ -334,6 +334,10 @@ impl<'w> BlockContext<'w> {
(_, crate::ScalarKind::Bool | crate::ScalarKind::Float) => {
unreachable!("we don't allow bool or float for array index")
}
(crate::ScalarKind::AbstractInt | crate::ScalarKind::AbstractFloat, _)
| (_, crate::ScalarKind::AbstractInt | crate::ScalarKind::AbstractFloat) => {
unreachable!("abstract types should never reach backends")
}
};
let reconciled_array_index_id = if let Some(cast) = cast {
let component_ty_id = self.get_type_id(LookupType::Local(LocalType::Value {

View File

@ -824,6 +824,9 @@ impl Writer {
Instruction::type_float(id, bits)
}
Sk::Bool => Instruction::type_bool(id),
Sk::AbstractInt | Sk::AbstractFloat => {
unreachable!("abstract types should never reach the backend");
}
}
}
@ -1591,6 +1594,11 @@ impl Writer {
| crate::TypeInner::Vector { scalar, .. } => match scalar.kind {
Sk::Uint | Sk::Sint | Sk::Bool => true,
Sk::Float => false,
Sk::AbstractInt | Sk::AbstractFloat => {
return Err(Error::Validation(
"Abstract types should not appear in IR presented to backends",
))
}
},
_ => false,
};

View File

@ -205,7 +205,7 @@ pub const fn type_power(scalar: Scalar) -> Option<u32> {
ScalarKind::Uint => 1,
ScalarKind::Float if scalar.width == 4 => 2,
ScalarKind::Float => 3,
ScalarKind::Bool => return None,
ScalarKind::Bool | ScalarKind::AbstractInt | ScalarKind::AbstractFloat => return None,
})
}

View File

@ -140,6 +140,8 @@ impl crate::Scalar {
crate::ScalarKind::Uint => "u",
crate::ScalarKind::Float => "f",
crate::ScalarKind::Bool => return "bool".to_string(),
crate::ScalarKind::AbstractInt => return "{AbstractInt}".to_string(),
crate::ScalarKind::AbstractFloat => return "{AbstractFloat}".to_string(),
};
format!("{}{}", prefix, self.width * 8)
}

View File

@ -470,6 +470,16 @@ pub enum ScalarKind {
Float,
/// Boolean type.
Bool,
/// WGSL abstract integer type.
///
/// These are forbidden by validation, and should never reach backends.
AbstractInt,
/// Abstract floating-point type.
///
/// These are forbidden by validation, and should never reach backends.
AbstractFloat,
}
/// Characteristics of a scalar type.

View File

@ -71,7 +71,11 @@ impl From<super::StorageFormat> for super::ScalarKind {
impl super::ScalarKind {
pub const fn is_numeric(self) -> bool {
match self {
crate::ScalarKind::Sint | crate::ScalarKind::Uint | crate::ScalarKind::Float => true,
crate::ScalarKind::Sint
| crate::ScalarKind::Uint
| crate::ScalarKind::Float
| crate::ScalarKind::AbstractInt
| crate::ScalarKind::AbstractFloat => true,
crate::ScalarKind::Bool => false,
}
}

View File

@ -670,7 +670,11 @@ impl super::Validator {
let good = match op {
Bo::Add | Bo::Subtract => match *left_inner {
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => match scalar.kind {
Sk::Uint | Sk::Sint | Sk::Float => left_inner == right_inner,
Sk::Uint
| Sk::Sint
| Sk::Float
| Sk::AbstractInt
| Sk::AbstractFloat => left_inner == right_inner,
Sk::Bool => false,
},
Ti::Matrix { .. } => left_inner == right_inner,
@ -678,14 +682,24 @@ impl super::Validator {
},
Bo::Divide | Bo::Modulo => match *left_inner {
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => match scalar.kind {
Sk::Uint | Sk::Sint | Sk::Float => left_inner == right_inner,
Sk::Uint
| Sk::Sint
| Sk::Float
| Sk::AbstractInt
| Sk::AbstractFloat => left_inner == right_inner,
Sk::Bool => false,
},
_ => false,
},
Bo::Multiply => {
let kind_allowed = match left_inner.scalar_kind() {
Some(Sk::Uint | Sk::Sint | Sk::Float) => true,
Some(
Sk::Uint
| Sk::Sint
| Sk::Float
| Sk::AbstractInt
| Sk::AbstractFloat,
) => true,
Some(Sk::Bool) | None => false,
};
let types_match = match (left_inner, right_inner) {
@ -762,7 +776,11 @@ impl super::Validator {
Bo::Less | Bo::LessEqual | Bo::Greater | Bo::GreaterEqual => {
match *left_inner {
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => match scalar.kind {
Sk::Uint | Sk::Sint | Sk::Float => left_inner == right_inner,
Sk::Uint
| Sk::Sint
| Sk::Float
| Sk::AbstractInt
| Sk::AbstractFloat => left_inner == right_inner,
Sk::Bool => false,
},
ref other => {
@ -784,8 +802,10 @@ impl super::Validator {
},
Bo::And | Bo::InclusiveOr => match *left_inner {
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => match scalar.kind {
Sk::Bool | Sk::Sint | Sk::Uint => left_inner == right_inner,
Sk::Float => false,
Sk::Bool | Sk::Sint | Sk::Uint | Sk::AbstractInt => {
left_inner == right_inner
}
Sk::Float | Sk::AbstractFloat => false,
},
ref other => {
log::error!("Op {:?} left type {:?}", op, other);
@ -794,8 +814,8 @@ impl super::Validator {
},
Bo::ExclusiveOr => match *left_inner {
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => match scalar.kind {
Sk::Sint | Sk::Uint => left_inner == right_inner,
Sk::Bool | Sk::Float => false,
Sk::Sint | Sk::Uint | Sk::AbstractInt => left_inner == right_inner,
Sk::Bool | Sk::Float | Sk::AbstractFloat => false,
},
ref other => {
log::error!("Op {:?} left type {:?}", op, other);
@ -823,8 +843,10 @@ impl super::Validator {
}
};
match base_scalar.kind {
Sk::Sint | Sk::Uint => base_size.is_ok() && base_size == shift_size,
Sk::Float | Sk::Bool => false,
Sk::Sint | Sk::Uint | Sk::AbstractInt => {
base_size.is_ok() && base_size == shift_size
}
Sk::Float | Sk::AbstractFloat | Sk::Bool => false,
}
}
};

View File

@ -143,6 +143,9 @@ pub enum WidthError {
#[error("64-bit integers are not yet supported")]
Unsupported64Bit,
#[error("Abstract types may only appear in constant expressions")]
Abstract,
}
// Only makes sense if `flags.contains(HOST_SHAREABLE)`
@ -248,6 +251,9 @@ impl super::Validator {
}
scalar.width == 4
}
crate::ScalarKind::AbstractInt | crate::ScalarKind::AbstractFloat => {
return Err(WidthError::Abstract);
}
};
if good {
Ok(())
@ -325,7 +331,10 @@ impl super::Validator {
}
Ti::Atomic(crate::Scalar { kind, width }) => {
let good = match kind {
crate::ScalarKind::Bool | crate::ScalarKind::Float => false,
crate::ScalarKind::Bool
| crate::ScalarKind::Float
| crate::ScalarKind::AbstractInt
| crate::ScalarKind::AbstractFloat => false,
crate::ScalarKind::Sint | crate::ScalarKind::Uint => width == 4,
};
if !good {

View File

@ -560,7 +560,9 @@ impl Resource {
}
naga::ScalarKind::Sint => wgt::TextureSampleType::Sint,
naga::ScalarKind::Uint => wgt::TextureSampleType::Uint,
naga::ScalarKind::Bool => unreachable!(),
naga::ScalarKind::AbstractInt
| naga::ScalarKind::AbstractFloat
| naga::ScalarKind::Bool => unreachable!(),
},
view_dimension,
multisampled: multi,