mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
As expressions
This commit is contained in:
committed by
Dzmitry Malyshau
parent
35e14378b3
commit
462c82fb71
@@ -1041,6 +1041,24 @@ fn write_expression<'a, 'b>(
|
||||
left_ty,
|
||||
)
|
||||
}
|
||||
Expression::As(value, kind) => {
|
||||
let (value_expr, value_ty) =
|
||||
write_expression(&builder.expressions[value], module, builder)?;
|
||||
let (width, out_ty) = match *value_ty.as_ref() {
|
||||
TypeInner::Scalar { width, kind: _ } => {
|
||||
(width, Cow::Owned(TypeInner::Scalar { kind, width }))
|
||||
}
|
||||
TypeInner::Vector {
|
||||
width,
|
||||
kind: _,
|
||||
size,
|
||||
} => (width, Cow::Owned(TypeInner::Vector { kind, width, size })),
|
||||
_ => return Err(Error::Custom(format!("Cannot cast {}", value_expr))),
|
||||
};
|
||||
let ty_expr = map_scalar(kind, width, builder.features)?;
|
||||
|
||||
(Cow::Owned(format!("{}({})", ty_expr, value_expr)), out_ty)
|
||||
}
|
||||
Expression::Derivative { axis, expr } => {
|
||||
let (expr, ty) = write_expression(&builder.expressions[expr], module, builder)?;
|
||||
|
||||
@@ -1138,6 +1156,28 @@ fn write_constant(
|
||||
})
|
||||
}
|
||||
|
||||
fn map_scalar(
|
||||
kind: ScalarKind,
|
||||
width: crate::Bytes,
|
||||
features: SupportedFeatures,
|
||||
) -> Result<&'static str, Error> {
|
||||
Ok(match kind {
|
||||
ScalarKind::Sint => "int",
|
||||
ScalarKind::Uint => "uint",
|
||||
ScalarKind::Float => match width {
|
||||
4 => "float",
|
||||
8 if features.contains(SupportedFeatures::DOUBLE_TYPE) => "double",
|
||||
_ => {
|
||||
return Err(Error::Custom(format!(
|
||||
"Cannot build float of width {}",
|
||||
width
|
||||
)))
|
||||
}
|
||||
},
|
||||
ScalarKind::Bool => "bool",
|
||||
})
|
||||
}
|
||||
|
||||
fn write_type<'a>(
|
||||
ty: Handle<Type>,
|
||||
types: &Arena<Type>,
|
||||
@@ -1146,21 +1186,7 @@ fn write_type<'a>(
|
||||
features: SupportedFeatures,
|
||||
) -> Result<Cow<'a, str>, Error> {
|
||||
Ok(match types[ty].inner {
|
||||
TypeInner::Scalar { kind, width } => match kind {
|
||||
ScalarKind::Sint => Cow::Borrowed("int"),
|
||||
ScalarKind::Uint => Cow::Borrowed("uint"),
|
||||
ScalarKind::Float => match width {
|
||||
4 => Cow::Borrowed("float"),
|
||||
8 if features.contains(SupportedFeatures::DOUBLE_TYPE) => Cow::Borrowed("double"),
|
||||
_ => {
|
||||
return Err(Error::Custom(format!(
|
||||
"Cannot build float of width {}",
|
||||
width
|
||||
)))
|
||||
}
|
||||
},
|
||||
ScalarKind::Bool => Cow::Borrowed("bool"),
|
||||
},
|
||||
TypeInner::Scalar { kind, width } => Cow::Borrowed(map_scalar(kind, width, features)?),
|
||||
TypeInner::Vector { size, kind, width } => Cow::Owned(format!(
|
||||
"{}vec{}",
|
||||
match kind {
|
||||
|
||||
@@ -44,6 +44,7 @@ pub enum Error {
|
||||
InvalidSampleSampler(Handle<crate::Type>),
|
||||
InvalidSampleCoordinates(Handle<crate::Type>),
|
||||
InvalidDepthReference(Handle<crate::Type>),
|
||||
InvalidAsType(Handle<crate::Type>),
|
||||
InconsistentComparisonSampling(Handle<crate::Type>),
|
||||
WrongFunctionResultType(spirv::Word),
|
||||
WrongFunctionParameterType(spirv::Word),
|
||||
|
||||
@@ -1009,6 +1009,29 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
},
|
||||
);
|
||||
}
|
||||
Op::ConvertSToF | Op::ConvertUToF | Op::ConvertFToU | Op::ConvertFToS => {
|
||||
inst.expect_at_least(4)?;
|
||||
let result_type_id = self.next()?;
|
||||
let result_id = self.next()?;
|
||||
let value_id = self.next()?;
|
||||
|
||||
let value_expr = self.lookup_expression.lookup(value_id)?;
|
||||
let ty_lookup = self.lookup_type.lookup(result_type_id)?;
|
||||
let kind = match type_arena[ty_lookup.handle].inner {
|
||||
crate::TypeInner::Scalar { kind, .. }
|
||||
| crate::TypeInner::Vector { kind, .. } => kind,
|
||||
_ => return Err(Error::InvalidAsType(ty_lookup.handle)),
|
||||
};
|
||||
|
||||
let expr = crate::Expression::As(value_expr.handle, kind);
|
||||
self.lookup_expression.insert(
|
||||
result_id,
|
||||
LookupExpression {
|
||||
handle: expressions.append(expr),
|
||||
type_id: result_type_id,
|
||||
},
|
||||
);
|
||||
}
|
||||
Op::FunctionCall => {
|
||||
inst.expect_at_least(4)?;
|
||||
let result_type_id = self.next()?;
|
||||
|
||||
@@ -526,6 +526,8 @@ pub enum Expression {
|
||||
DotProduct(Handle<Expression>, Handle<Expression>),
|
||||
/// Cross product between two vectors.
|
||||
CrossProduct(Handle<Expression>, Handle<Expression>),
|
||||
/// Cast a scalar or a vector to another kind.
|
||||
As(Handle<Expression>, ScalarKind),
|
||||
/// Compute the derivative on an axis.
|
||||
Derivative {
|
||||
axis: DerivativeAxis,
|
||||
|
||||
@@ -80,6 +80,9 @@ impl<'a> Interface<'a> {
|
||||
self.add_inputs(left);
|
||||
self.add_inputs(right);
|
||||
}
|
||||
E::As(expr, _) => {
|
||||
self.add_inputs(expr);
|
||||
}
|
||||
E::Derivative { expr, .. } => {
|
||||
self.add_inputs(expr);
|
||||
}
|
||||
|
||||
@@ -182,8 +182,34 @@ impl Typifier {
|
||||
};
|
||||
types.fetch_or_append(Type { name: None, inner })
|
||||
}
|
||||
crate::Expression::DotProduct(_, _) => unimplemented!(),
|
||||
crate::Expression::DotProduct(left_expr, _) => {
|
||||
let left_ty = self.types[left_expr.index()];
|
||||
let inner = match types[left_ty].inner {
|
||||
crate::TypeInner::Vector {
|
||||
kind,
|
||||
size: _,
|
||||
width,
|
||||
} => crate::TypeInner::Scalar { kind, width },
|
||||
ref other => panic!("incompatible dot of {:?}", other),
|
||||
};
|
||||
types.fetch_or_append(Type { name: None, inner })
|
||||
}
|
||||
crate::Expression::CrossProduct(_, _) => unimplemented!(),
|
||||
crate::Expression::As(expr, kind) => {
|
||||
let ty_handle = self.types[expr.index()];
|
||||
let inner = match types[ty_handle].inner {
|
||||
crate::TypeInner::Scalar { kind: _, width } => {
|
||||
crate::TypeInner::Scalar { kind, width }
|
||||
}
|
||||
crate::TypeInner::Vector {
|
||||
kind: _,
|
||||
size,
|
||||
width,
|
||||
} => crate::TypeInner::Vector { kind, size, width },
|
||||
ref other => panic!("incompatible as of {:?}", other),
|
||||
};
|
||||
types.fetch_or_append(Type { name: None, inner })
|
||||
}
|
||||
crate::Expression::Derivative { .. } => unimplemented!(),
|
||||
crate::Expression::Call {
|
||||
origin: crate::FunctionOrigin::External(ref name),
|
||||
|
||||
Reference in New Issue
Block a user