naga/front/interpolator.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
/*!
Interpolation defaults.
*/
impl crate::Binding {
/// Apply the usual default interpolation for `ty` to `binding`.
///
/// This function is a utility front ends may use to satisfy the Naga IR's
/// requirement, meant to ensure that input languages' policies have been
/// applied appropriately, that all I/O `Binding`s from the vertex shader to the
/// fragment shader must have non-`None` `interpolation` values.
///
/// All the shader languages Naga supports have similar rules:
/// perspective-correct, center-sampled interpolation is the default for any
/// binding that can vary, and everything else either defaults to flat, or
/// requires an explicit flat qualifier/attribute/what-have-you.
///
/// If `binding` is not a [`Location`] binding, or if its [`interpolation`] is
/// already set, then make no changes. Otherwise, set `binding`'s interpolation
/// and sampling to reasonable defaults depending on `ty`, the type of the value
/// being interpolated:
///
/// - If `ty` is a floating-point scalar, vector, or matrix type, then
/// default to [`Perspective`] interpolation and [`Center`] sampling.
///
/// - If `ty` is an integral scalar or vector, then default to [`Flat`]
/// interpolation, which has no associated sampling.
///
/// - For any other types, make no change. Such types are not permitted as
/// user-defined IO values, and will probably be flagged by the verifier
///
/// When structs appear in input or output types, each member ought to have its
/// own [`Binding`], so structs are simply covered by the third case.
///
/// [`Binding`]: crate::Binding
/// [`Location`]: crate::Binding::Location
/// [`interpolation`]: crate::Binding::Location::interpolation
/// [`Perspective`]: crate::Interpolation::Perspective
/// [`Flat`]: crate::Interpolation::Flat
/// [`Center`]: crate::Sampling::Center
pub fn apply_default_interpolation(&mut self, ty: &crate::TypeInner) {
if let crate::Binding::Location {
location: _,
interpolation: ref mut interpolation @ None,
ref mut sampling,
second_blend_source: _,
} = *self
{
match ty.scalar_kind() {
Some(crate::ScalarKind::Float) => {
*interpolation = Some(crate::Interpolation::Perspective);
*sampling = Some(crate::Sampling::Center);
}
Some(crate::ScalarKind::Sint | crate::ScalarKind::Uint) => {
*interpolation = Some(crate::Interpolation::Flat);
*sampling = None;
}
Some(_) | None => {}
}
}
}
}