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    const IMMEDIATE_ADDRESS_SPACE: &'static str = "immediate_address_space";
21
22    /// Convert from a sentinel word in WGSL into its associated [`LanguageExtension`], if possible.
23    pub fn from_ident(s: &str) -> Option<Self> {
24        Some(match s {
25            Self::READONLY_AND_READWRITE_STORAGE_TEXTURES => {
26                Self::Implemented(ImplementedLanguageExtension::ReadOnlyAndReadWriteStorageTextures)
27            }
28            Self::PACKED4X8_INTEGER_DOT_PRODUCT => {
29                Self::Implemented(ImplementedLanguageExtension::Packed4x8IntegerDotProduct)
30            }
31            Self::UNRESTRICTED_POINTER_PARAMETERS => {
32                Self::Unimplemented(UnimplementedLanguageExtension::UnrestrictedPointerParameters)
33            }
34            Self::POINTER_COMPOSITE_ACCESS => {
35                Self::Implemented(ImplementedLanguageExtension::PointerCompositeAccess)
36            }
37            Self::IMMEDIATE_ADDRESS_SPACE => {
38                Self::Implemented(ImplementedLanguageExtension::ImmediateAddressSpace)
39            }
40            _ => return None,
41        })
42    }
43
44    /// Maps this [`LanguageExtension`] into the sentinel word associated with it in WGSL.
45    pub const fn to_ident(self) -> &'static str {
46        match self {
47            Self::Implemented(kind) => kind.to_ident(),
48            Self::Unimplemented(kind) => match kind {
49                UnimplementedLanguageExtension::UnrestrictedPointerParameters => {
50                    Self::UNRESTRICTED_POINTER_PARAMETERS
51                }
52            },
53        }
54    }
55}
56
57/// A variant of [`LanguageExtension::Implemented`].
58#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
59#[cfg_attr(test, derive(strum::VariantArray))]
60pub enum ImplementedLanguageExtension {
61    ReadOnlyAndReadWriteStorageTextures,
62    Packed4x8IntegerDotProduct,
63    PointerCompositeAccess,
64    ImmediateAddressSpace,
65}
66
67impl ImplementedLanguageExtension {
68    /// A slice of all variants of [`ImplementedLanguageExtension`].
69    pub const VARIANTS: &'static [Self] = &[
70        Self::ReadOnlyAndReadWriteStorageTextures,
71        Self::Packed4x8IntegerDotProduct,
72        Self::PointerCompositeAccess,
73        Self::ImmediateAddressSpace,
74    ];
75
76    /// Returns slice of all variants of [`ImplementedLanguageExtension`].
77    pub const fn all() -> &'static [Self] {
78        Self::VARIANTS
79    }
80
81    /// Maps this [`ImplementedLanguageExtension`] into the sentinel word associated with it in WGSL.
82    pub const fn to_ident(self) -> &'static str {
83        match self {
84            ImplementedLanguageExtension::ReadOnlyAndReadWriteStorageTextures => {
85                LanguageExtension::READONLY_AND_READWRITE_STORAGE_TEXTURES
86            }
87            ImplementedLanguageExtension::Packed4x8IntegerDotProduct => {
88                LanguageExtension::PACKED4X8_INTEGER_DOT_PRODUCT
89            }
90            ImplementedLanguageExtension::PointerCompositeAccess => {
91                LanguageExtension::POINTER_COMPOSITE_ACCESS
92            }
93            ImplementedLanguageExtension::ImmediateAddressSpace => {
94                LanguageExtension::IMMEDIATE_ADDRESS_SPACE
95            }
96        }
97    }
98}
99
100#[test]
101/// Asserts that the manual implementation of VARIANTS is the same as the derived strum version would be
102/// while still allowing strum to be a dev-only dependency
103fn test_manual_variants_array_is_correct() {
104    assert_eq!(
105        <ImplementedLanguageExtension as strum::VariantArray>::VARIANTS,
106        ImplementedLanguageExtension::VARIANTS
107    );
108}
109
110/// A variant of [`LanguageExtension::Unimplemented`].
111#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
112pub enum UnimplementedLanguageExtension {
113    UnrestrictedPointerParameters,
114}
115
116impl UnimplementedLanguageExtension {
117    pub(crate) const fn tracking_issue_num(self) -> u16 {
118        match self {
119            Self::UnrestrictedPointerParameters => 5158,
120        }
121    }
122}