mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Splat expression in the IR
This commit is contained in:
committed by
Dzmitry Malyshau
parent
6701e2bf96
commit
d3b39d9e58
@@ -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)
|
||||
|
||||
@@ -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 } => {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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>,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user