naga/front/wgsl/parse/directive/
language_extension.rs

1//! `requires …;` extensions in WGSL.
2//!
3//! The focal point of this module is the [`LanguageExtension`] API.
4
5/// A language extension recognized by Naga, but not guaranteed to be present in all environments.
6///
7/// WGSL spec.: <https://www.w3.org/TR/WGSL/#language-extensions-sec>
8#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
9pub enum LanguageExtension {
10    Implemented(ImplementedLanguageExtension),
11    Unimplemented(UnimplementedLanguageExtension),
12}
13
14impl LanguageExtension {
15    const READONLY_AND_READWRITE_STORAGE_TEXTURES: &'static str =
16        "readonly_and_readwrite_storage_textures";
17    const PACKED4X8_INTEGER_DOT_PRODUCT: &'static str = "packed_4x8_integer_dot_product";
18    const UNRESTRICTED_POINTER_PARAMETERS: &'static str = "unrestricted_pointer_parameters";
19    const POINTER_COMPOSITE_ACCESS: &'static str = "pointer_composite_access";
20
21    /// Convert from a sentinel word in WGSL into its associated [`LanguageExtension`], if possible.
22    pub fn from_ident(s: &str) -> Option<Self> {
23        Some(match s {
24            Self::READONLY_AND_READWRITE_STORAGE_TEXTURES => {
25                Self::Implemented(ImplementedLanguageExtension::ReadOnlyAndReadWriteStorageTextures)
26            }
27            Self::PACKED4X8_INTEGER_DOT_PRODUCT => {
28                Self::Implemented(ImplementedLanguageExtension::Packed4x8IntegerDotProduct)
29            }
30            Self::UNRESTRICTED_POINTER_PARAMETERS => {
31                Self::Unimplemented(UnimplementedLanguageExtension::UnrestrictedPointerParameters)
32            }
33            Self::POINTER_COMPOSITE_ACCESS => {
34                Self::Implemented(ImplementedLanguageExtension::PointerCompositeAccess)
35            }
36            _ => return None,
37        })
38    }
39
40    /// Maps this [`LanguageExtension`] into the sentinel word associated with it in WGSL.
41    pub const fn to_ident(self) -> &'static str {
42        match self {
43            Self::Implemented(kind) => kind.to_ident(),
44            Self::Unimplemented(kind) => match kind {
45                UnimplementedLanguageExtension::UnrestrictedPointerParameters => {
46                    Self::UNRESTRICTED_POINTER_PARAMETERS
47                }
48            },
49        }
50    }
51}
52
53/// A variant of [`LanguageExtension::Implemented`].
54#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
55#[cfg_attr(test, derive(strum::VariantArray))]
56pub enum ImplementedLanguageExtension {
57    ReadOnlyAndReadWriteStorageTextures,
58    Packed4x8IntegerDotProduct,
59    PointerCompositeAccess,
60}
61
62impl ImplementedLanguageExtension {
63    /// A slice of all variants of [`ImplementedLanguageExtension`].
64    pub const VARIANTS: &'static [Self] = &[
65        Self::ReadOnlyAndReadWriteStorageTextures,
66        Self::Packed4x8IntegerDotProduct,
67        Self::PointerCompositeAccess,
68    ];
69
70    /// Returns slice of all variants of [`ImplementedLanguageExtension`].
71    pub const fn all() -> &'static [Self] {
72        Self::VARIANTS
73    }
74
75    /// Maps this [`ImplementedLanguageExtension`] into the sentinel word associated with it in WGSL.
76    pub const fn to_ident(self) -> &'static str {
77        match self {
78            ImplementedLanguageExtension::ReadOnlyAndReadWriteStorageTextures => {
79                LanguageExtension::READONLY_AND_READWRITE_STORAGE_TEXTURES
80            }
81            ImplementedLanguageExtension::Packed4x8IntegerDotProduct => {
82                LanguageExtension::PACKED4X8_INTEGER_DOT_PRODUCT
83            }
84            ImplementedLanguageExtension::PointerCompositeAccess => {
85                LanguageExtension::POINTER_COMPOSITE_ACCESS
86            }
87        }
88    }
89}
90
91#[test]
92/// Asserts that the manual implementation of VARIANTS is the same as the derived strum version would be
93/// while still allowing strum to be a dev-only dependency
94fn test_manual_variants_array_is_correct() {
95    assert_eq!(
96        <ImplementedLanguageExtension as strum::VariantArray>::VARIANTS,
97        ImplementedLanguageExtension::VARIANTS
98    );
99}
100
101/// A variant of [`LanguageExtension::Unimplemented`].
102#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
103pub enum UnimplementedLanguageExtension {
104    UnrestrictedPointerParameters,
105}
106
107impl UnimplementedLanguageExtension {
108    pub(crate) const fn tracking_issue_num(self) -> u16 {
109        match self {
110            Self::UnrestrictedPointerParameters => 5158,
111        }
112    }
113}