spirv-webgpu-transform 0.1.7

Transform SPIRV to be webgpu friendly
Documentation
use super::*;

// Q: Hey what happens when you stack corrections?
// A: I don't want to think about it... I will start thinking after a refactor...

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u16)]
pub enum CorrectionType {
    /// A combined image sampler has been split, a new `sampler` object should be inserted.
    SplitCombined,
    /// A mixed depth texture / sampler has been duplicated, insert the same object again with a `Regular` bind type.
    SplitDrefRegular,
    /// A mixed depth texture / sampler has been duplicated, insert the same object again with a
    /// `Comparison` bind type.
    SplitDrefComparison,
    /// A storage cube texture has been converted into a storage texture 2D array, change the dimension.
    ConvertStorageCube,
    /// A binding array has been split into new variables. Insert the same resource again.
    /// For an `N` sized array, expect `N-1` entries.
    SplitBindingArray,
}

#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct CorrectionBinding {
    /// In order, what additional bindings have been appended to this one.
    pub corrections: Vec<CorrectionType>,
}

#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct CorrectionSet {
    pub bindings: HashMap<u32, CorrectionBinding>,
}

#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum ImmediatesSetMode {
    /// Place the immediates binding at certain set.
    #[default]
    Absolute,
    /// Place the immediates binding at the max set or up to a certain set.
    /// This causes immediates to always mix with existing sets which may have negative performance
    /// implications.
    ///
    /// TODO(davnotdev): Sounds like a great idea but what about mirroring?
    /// What I mean is that this will cause you issues if you have a vertex shader and fragment
    /// shader with different max uniform sets.
    MaxUpTo,
    /// Place the immediates binding in the set after the max set or up to a certain set.
    /// Unlike [`ImmediatesSetMode::MaxUpTo`], this attempts to give immediates their own set if
    /// possible.
    ///
    /// TODO(davnotdev): Sounds like a great idea but what about mirroring?
    /// What I mean is that this will cause you issues if you have a vertex shader and fragment
    /// shader with different max uniform sets.
    MaxPlusOneUpTo,
}

#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum ImmediatesBindingMode {
    /// Always place the immediates binding one binding after the max binding of the set.
    /// TODO(davnotdev): Once again, sounds like a great idea but what about mirroring?
    /// If you have a fragment and vertex shader with hidden bindings, you will run into issues
    #[default]
    Last,
    /// Place the immediates binding in a fixed binding index.
    Absolute,
}

/// Lookup a set and a binding for a list of [`CorrectionType`].
/// In order, insert a new variable for each, see [`CorrectionType`] for what type of object should
/// be inserted for each variant.
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct CorrectionMap {
    pub sets: Option<HashMap<u32, CorrectionSet>>,
    /// Represents both an input/output where the immediate uniforms should/is written to.
    /// Control the set immediates should be written to by setting before patching.
    /// If this is [`None`], this becomes the max set plus one.
    pub immediates_set: Option<u32>,
    /// Works as an input setting controlling the behaviour of `immediates_set`.
    /// This is valuable when dealing with WebGPU's `maxBindGroup` especially if your sets
    /// previously followed the maximum.
    pub immediates_set_mode: Option<ImmediatesSetMode>,
    /// Represents both an input/output representing which binding the immediate uniform is written
    /// to.
    /// If [`ImmediatesBindingMode`] is [`ImmediatesBindingMode::Absolute`], set the index of the
    /// immediates buffer binding.
    pub immediates_binding: Option<u32>,
    /// Works as an input setting, controlling how the immediate uniform's binding index should be determined
    /// within the bind group set.
    pub immediates_binding_mode: Option<ImmediatesBindingMode>,
}