naga/front/wgsl/parse/directive/enable_extension.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 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
//! `enable …;` extensions in WGSL.
//!
//! The focal point of this module is the [`EnableExtension`] API.
use crate::front::wgsl::{Error, Result};
use crate::Span;
use alloc::boxed::Box;
/// Tracks the status of every enable-extension known to Naga.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct EnableExtensions {
dual_source_blending: bool,
/// Whether `enable f16;` was written earlier in the shader module.
f16: bool,
}
impl EnableExtensions {
pub(crate) const fn empty() -> Self {
Self {
f16: false,
dual_source_blending: false,
}
}
/// Add an enable-extension to the set requested by a module.
pub(crate) fn add(&mut self, ext: ImplementedEnableExtension) {
let field = match ext {
ImplementedEnableExtension::DualSourceBlending => &mut self.dual_source_blending,
ImplementedEnableExtension::F16 => &mut self.f16,
};
*field = true;
}
/// Query whether an enable-extension tracked here has been requested.
pub(crate) const fn contains(&self, ext: ImplementedEnableExtension) -> bool {
match ext {
ImplementedEnableExtension::DualSourceBlending => self.dual_source_blending,
ImplementedEnableExtension::F16 => self.f16,
}
}
}
impl Default for EnableExtensions {
fn default() -> Self {
Self::empty()
}
}
/// An enable-extension not guaranteed to be present in all environments.
///
/// WGSL spec.: <https://www.w3.org/TR/WGSL/#enable-extensions-sec>
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
pub enum EnableExtension {
Implemented(ImplementedEnableExtension),
Unimplemented(UnimplementedEnableExtension),
}
impl From<ImplementedEnableExtension> for EnableExtension {
fn from(value: ImplementedEnableExtension) -> Self {
Self::Implemented(value)
}
}
impl EnableExtension {
const F16: &'static str = "f16";
const CLIP_DISTANCES: &'static str = "clip_distances";
const DUAL_SOURCE_BLENDING: &'static str = "dual_source_blending";
/// Convert from a sentinel word in WGSL into its associated [`EnableExtension`], if possible.
pub(crate) fn from_ident(word: &str, span: Span) -> Result<Self> {
Ok(match word {
Self::F16 => Self::Implemented(ImplementedEnableExtension::F16),
Self::CLIP_DISTANCES => {
Self::Unimplemented(UnimplementedEnableExtension::ClipDistances)
}
Self::DUAL_SOURCE_BLENDING => {
Self::Implemented(ImplementedEnableExtension::DualSourceBlending)
}
_ => return Err(Box::new(Error::UnknownEnableExtension(span, word))),
})
}
/// Maps this [`EnableExtension`] into the sentinel word associated with it in WGSL.
pub const fn to_ident(self) -> &'static str {
match self {
Self::Implemented(kind) => match kind {
ImplementedEnableExtension::DualSourceBlending => Self::DUAL_SOURCE_BLENDING,
ImplementedEnableExtension::F16 => Self::F16,
},
Self::Unimplemented(kind) => match kind {
UnimplementedEnableExtension::ClipDistances => Self::CLIP_DISTANCES,
},
}
}
}
/// A variant of [`EnableExtension::Implemented`].
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
pub enum ImplementedEnableExtension {
/// Enables the `blend_src` attribute in WGSL.
///
/// In the WGSL standard, this corresponds to [`enable dual_source_blending;`].
///
/// [`enable dual_source_blending;`]: https://www.w3.org/TR/WGSL/#extension-dual_source_blending
DualSourceBlending,
/// Enables `f16`/`half` primitive support in all shader languages.
///
/// In the WGSL standard, this corresponds to [`enable f16;`].
///
/// [`enable f16;`]: https://www.w3.org/TR/WGSL/#extension-f16
F16,
}
/// A variant of [`EnableExtension::Unimplemented`].
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
pub enum UnimplementedEnableExtension {
/// Enables the `clip_distances` variable in WGSL.
///
/// In the WGSL standard, this corresponds to [`enable clip_distances;`].
///
/// [`enable clip_distances;`]: https://www.w3.org/TR/WGSL/#extension-clip_distances
ClipDistances,
}
impl UnimplementedEnableExtension {
pub(crate) const fn tracking_issue_num(self) -> u16 {
match self {
Self::ClipDistances => 6236,
}
}
}