Skip to main content

naga_types/
wgsl.rs

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