Splat expression in the IR

This commit is contained in:
Dzmitry Malyshau
2021-04-14 01:03:25 -04:00
committed by Dzmitry Malyshau
parent 6701e2bf96
commit d3b39d9e58
8 changed files with 64 additions and 0 deletions

View File

@@ -183,6 +183,10 @@ fn write_fun(
(Cow::Owned(format!("AccessIndex[{}]", index)), 1)
}
E::Constant(_) => (Cow::Borrowed("Constant"), 2),
E::Splat { size, value } => {
edges.insert("value", value);
(Cow::Owned(format!("Splat{:?}", size)), 3)
}
E::Compose { ref components, .. } => {
payload = Some(Payload::Arguments(components));
(Cow::Borrowed("Compose"), 3)

View File

@@ -1477,6 +1477,10 @@ impl<'a, W: Write> Writer<'a, W> {
Expression::Constant(constant) => {
self.write_constant(&self.module.constants[constant])?
}
// `Splat` is just writing `value`
Expression::Splat { size: _, value } => {
self.write_expr(value, ctx)?;
}
// `Compose` is pretty simple we just write `type(components)` where `components` is a
// comma separated list of expressions
Expression::Compose { ty, ref components } => {

View File

@@ -608,6 +608,9 @@ impl<W: Write> Writer<W> {
};
write!(self.out, "{}", coco)?;
}
crate::Expression::Splat { size: _, value } => {
self.put_expression(value, context, is_scoped)?;
}
crate::Expression::Compose { ty, ref components } => {
let inner = &context.module.types[ty].inner;
match *inner {

View File

@@ -49,6 +49,8 @@ pub enum ConstantSolvingError {
InvalidUnaryOpArg,
#[error("Cannot apply the binary op to the arguments")]
InvalidBinaryOpArgs,
#[error("Splat type is not registered")]
SplatType,
}
impl<'a> ConstantSolver<'a> {
@@ -64,6 +66,28 @@ impl<'a> ConstantSolver<'a> {
self.access(base, self.constant_index(index)?)
}
Expression::Splat {
size,
value: splat_value,
} => {
let tgt = self.solve(splat_value)?;
let ty = match self.constants[tgt].inner {
ConstantInner::Scalar { ref value, width } => {
let kind = value.scalar_kind();
self.types
.fetch_if(|t| t.inner == crate::TypeInner::Vector { size, kind, width })
}
ConstantInner::Composite { .. } => None,
};
Ok(self.constants.fetch_or_append(Constant {
name: None,
specialization: None,
inner: ConstantInner::Composite {
ty: ty.ok_or(ConstantSolvingError::SplatType)?,
components: vec![tgt; size as usize],
},
}))
}
Expression::Compose { ty, ref components } => {
let components = components
.iter()

View File

@@ -683,6 +683,11 @@ pub enum Expression {
},
/// Constant value.
Constant(Handle<Constant>),
/// Splat scalar into a vector.
Splat {
size: VectorSize,
value: Handle<Expression>,
},
/// Composite expression.
Compose {
ty: Handle<Type>,

View File

@@ -79,6 +79,8 @@ pub enum ResolveError {
ty: Handle<crate::Type>,
indexed: bool,
},
#[error("Invalid scalar {0:?}")]
InvalidScalar(Handle<crate::Expression>),
#[error("Invalid pointer {0:?}")]
InvalidPointer(Handle<crate::Expression>),
#[error("Invalid image {0:?}")]
@@ -265,6 +267,15 @@ impl<'a> ResolveContext<'a> {
}
crate::ConstantInner::Composite { ty, components: _ } => TypeResolution::Handle(ty),
},
crate::Expression::Splat { size, value } => match *past(value).inner_with(types) {
Ti::Scalar { kind, width } => {
TypeResolution::Value(Ti::Vector { size, kind, width })
}
ref other => {
log::error!("Scalar type {:?}", other);
return Err(ResolveError::InvalidScalar(value));
}
},
crate::Expression::Compose { ty, .. } => TypeResolution::Handle(ty),
crate::Expression::FunctionArgument(index) => {
TypeResolution::Handle(self.arguments[index as usize].ty)

View File

@@ -318,6 +318,10 @@ impl FunctionInfo {
},
// always uniform
E::Constant(_) => Uniformity::new(),
E::Splat { size: _, value } => Uniformity {
non_uniform_result: self.add_ref(value),
requirements: UniformityRequirements::empty(),
},
E::Compose { ref components, .. } => {
let non_uniform_result = components
.iter()

View File

@@ -31,6 +31,8 @@ pub enum ExpressionError {
InvalidPointerType(Handle<crate::Expression>),
#[error("Array length of {0:?} can't be done")]
InvalidArrayType(Handle<crate::Expression>),
#[error("Splatting {0:?} can't be done")]
InvalidSplatType(Handle<crate::Expression>),
#[error("Compose type {0:?} doesn't exist")]
ComposeTypeDoesntExist(Handle<crate::Type>),
#[error("Composing of type {0:?} can't be done")]
@@ -197,6 +199,13 @@ impl super::Validator {
.ok_or(ExpressionError::ConstantDoesntExist(handle))?;
ShaderStages::all()
}
E::Splat { size: _, value } => match *resolver.resolve(value)? {
Ti::Scalar { .. } => ShaderStages::all(),
ref other => {
log::error!("Splat scalar type {:?}", other);
return Err(ExpressionError::InvalidSplatType(value));
}
},
E::Compose { ref components, ty } => {
match module
.types