|
2 | 2 | //! |
3 | 3 | //! See also <https://www.w3.org/TR/WGSL/#directives>. |
4 | 4 |
|
| 5 | +use alloc::boxed::Box; |
| 6 | + |
| 7 | +/// A parsed sentinel word indicating the type of directive to be parsed next. |
| 8 | +#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] |
| 9 | +#[cfg_attr(test, derive(strum::EnumIter))] |
| 10 | +pub(crate) enum DirectiveKind { |
| 11 | + /// A [`crate::diagnostic_filter`]. |
| 12 | + Diagnostic, |
| 13 | + /// An [`enable_extension`]. |
| 14 | + Enable, |
| 15 | + /// A [`language_extension`]. |
| 16 | + Requires, |
| 17 | +} |
| 18 | + |
| 19 | +impl DirectiveKind { |
| 20 | + const DIAGNOSTIC: &'static str = "diagnostic"; |
| 21 | + const ENABLE: &'static str = "enable"; |
| 22 | + const REQUIRES: &'static str = "requires"; |
| 23 | + |
| 24 | + /// Convert from a sentinel word in WGSL into its associated [`DirectiveKind`], if possible. |
| 25 | + pub fn from_ident(s: &str) -> Option<Self> { |
| 26 | + Some(match s { |
| 27 | + Self::DIAGNOSTIC => Self::Diagnostic, |
| 28 | + Self::ENABLE => Self::Enable, |
| 29 | + Self::REQUIRES => Self::Requires, |
| 30 | + _ => return None, |
| 31 | + }) |
| 32 | + } |
| 33 | +} |
| 34 | + |
| 35 | +impl crate::diagnostic_filter::Severity { |
| 36 | + #[cfg(feature = "wgsl-in")] |
| 37 | + pub(crate) fn report_wgsl_parse_diag<'a>( |
| 38 | + self, |
| 39 | + err: Box<crate::front::wgsl::error::Error<'a>>, |
| 40 | + source: &str, |
| 41 | + ) -> crate::front::wgsl::Result<'a, ()> { |
| 42 | + self.report_diag(err, |e, level| { |
| 43 | + let e = e.as_parse_error(source); |
| 44 | + log::log!(level, "{}", e.emit_to_string(source)); |
| 45 | + }) |
| 46 | + } |
| 47 | +} |
| 48 | + |
5 | 49 | /// Define a bitflags type representing a set of extensions, with their source names. |
6 | 50 | /// |
7 | 51 | /// This is used to define bitflags types for language and enable |
@@ -58,47 +102,117 @@ macro_rules! define_extensions { |
58 | 102 | pub mod enable_extension; |
59 | 103 | pub(crate) mod language_extension; |
60 | 104 |
|
61 | | -use alloc::boxed::Box; |
| 105 | +define_extensions! { |
| 106 | + /// All enable extensions known to Naga. |
| 107 | + /// |
| 108 | + /// This includes extensions that Naga does not implement; the [`IMPLEMENTED`] |
| 109 | + /// associated constant indicates which ones we do support. |
| 110 | + /// |
| 111 | + /// [`IMPLEMENTED`]: EnableExtensions::IMPLEMENTED |
| 112 | + #[derive(Default)] |
| 113 | + pub struct EnableExtensions: u32 { |
| 114 | + /// Enables `f16`/`half` primitive support in all shader languages. |
| 115 | + /// |
| 116 | + /// In the WGSL standard, this corresponds to [`enable f16;`]. |
| 117 | + /// |
| 118 | + /// [`enable f16;`]: https://www.w3.org/TR/WGSL/#extension-f16 |
| 119 | + const F16, "f16" = 0x1; |
62 | 120 |
|
63 | | -/// A parsed sentinel word indicating the type of directive to be parsed next. |
64 | | -#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)] |
65 | | -#[cfg_attr(test, derive(strum::EnumIter))] |
66 | | -pub(crate) enum DirectiveKind { |
67 | | - /// A [`crate::diagnostic_filter`]. |
68 | | - Diagnostic, |
69 | | - /// An [`enable_extension`]. |
70 | | - Enable, |
71 | | - /// A [`language_extension`]. |
72 | | - Requires, |
| 121 | + /// Enables the `clip_distances` variable in WGSL. |
| 122 | + /// |
| 123 | + /// In the WGSL standard, this corresponds to [`enable clip_distances;`]. |
| 124 | + /// |
| 125 | + /// [`enable clip_distances;`]: https://www.w3.org/TR/WGSL/#extension-clip_distances |
| 126 | + const CLIP_DISTANCES, "clip_distances" = 0x2; |
| 127 | + |
| 128 | + /// Enables the `blend_src` attribute in WGSL. |
| 129 | + /// |
| 130 | + /// In the WGSL standard, this corresponds to [`enable dual_source_blending;`]. |
| 131 | + /// |
| 132 | + /// [`enable dual_source_blending;`]: https://www.w3.org/TR/WGSL/#extension-dual_source_blending |
| 133 | + const DUAL_SOURCE_BLENDING, "dual_source_blending" = 0x4; |
| 134 | + |
| 135 | + /// Enables subgroup built-ins in all languages. |
| 136 | + /// |
| 137 | + /// In the WGSL standard, this corresponds to [`enable subgroups;`]. |
| 138 | + /// |
| 139 | + /// [`enable subgroups;`]: https://www.w3.org/TR/WGSL/#extension-subgroups |
| 140 | + const SUBGROUPS, "subgroups" = 0x8; |
| 141 | + |
| 142 | + /// Enables the `@builtin(primitive_index)` attribute in WGSL. |
| 143 | + /// |
| 144 | + /// In the WGSL standard, this corresponds to [`enable primitive-index;`]. |
| 145 | + /// |
| 146 | + /// [`enable primitive-index;`]: https://www.w3.org/TR/WGSL/#extension-primitive_index |
| 147 | + const PRIMITIVE_INDEX, "primitive_index" = 0x10; |
| 148 | + |
| 149 | + // wgpu extensions |
| 150 | + |
| 151 | + /// Enables the `wgpu_mesh_shader` extension, native only |
| 152 | + const WGPU_MESH_SHADER, "wgpu_mesh_shader" = 0x100; |
| 153 | + |
| 154 | + /// Enables the `wgpu_ray_query` extension, native only. |
| 155 | + const WGPU_RAY_QUERY, "wgpu_ray_query" = 0x200; |
| 156 | + |
| 157 | + /// Enables the `wgpu_ray_query_vertex_return` extension, native only. |
| 158 | + const WGPU_RAY_QUERY_VERTEX_RETURN, "wgpu_ray_query_vertex_return" = 0x400; |
| 159 | + } |
73 | 160 | } |
74 | 161 |
|
75 | | -impl DirectiveKind { |
76 | | - const DIAGNOSTIC: &'static str = "diagnostic"; |
77 | | - const ENABLE: &'static str = "enable"; |
78 | | - const REQUIRES: &'static str = "requires"; |
| 162 | +impl EnableExtensions { |
| 163 | + pub const IMPLEMENTED: Self = |
| 164 | + Self::empty() |
| 165 | + .union(Self::WGPU_MESH_SHADER) |
| 166 | + .union(Self::WGPU_RAY_QUERY) |
| 167 | + .union(Self::WGPU_RAY_QUERY_VERTEX_RETURN) |
| 168 | + .union(Self::DUAL_SOURCE_BLENDING) |
| 169 | + .union(Self::F16) |
| 170 | + .union(Self::CLIP_DISTANCES); |
79 | 171 |
|
80 | | - /// Convert from a sentinel word in WGSL into its associated [`DirectiveKind`], if possible. |
81 | | - pub fn from_ident(s: &str) -> Option<Self> { |
82 | | - Some(match s { |
83 | | - Self::DIAGNOSTIC => Self::Diagnostic, |
84 | | - Self::ENABLE => Self::Enable, |
85 | | - Self::REQUIRES => Self::Requires, |
86 | | - _ => return None, |
87 | | - }) |
| 172 | + pub const UNIMPLEMENTED: Self = Self::IMPLEMENTED.complement(); |
| 173 | + |
| 174 | + pub fn tracking_issue_num(self) -> Option<u16> { |
| 175 | + match self { |
| 176 | + Self::SUBGROUPS => Some(5555), |
| 177 | + Self::PRIMITIVE_INDEX => Some(8236), |
| 178 | + other => { |
| 179 | + assert!(Self::IMPLEMENTED.contains(other)); |
| 180 | + None |
| 181 | + } |
| 182 | + } |
88 | 183 | } |
89 | 184 | } |
90 | 185 |
|
91 | | -impl crate::diagnostic_filter::Severity { |
92 | | - #[cfg(feature = "wgsl-in")] |
93 | | - pub(crate) fn report_wgsl_parse_diag<'a>( |
94 | | - self, |
95 | | - err: Box<crate::front::wgsl::error::Error<'a>>, |
96 | | - source: &str, |
97 | | - ) -> crate::front::wgsl::Result<'a, ()> { |
98 | | - self.report_diag(err, |e, level| { |
99 | | - let e = e.as_parse_error(source); |
100 | | - log::log!(level, "{}", e.emit_to_string(source)); |
101 | | - }) |
| 186 | +define_extensions! { |
| 187 | + /// A language extension recognized by Naga, but not guaranteed to be present in all environments. |
| 188 | + /// |
| 189 | + /// WGSL spec.: <https://www.w3.org/TR/WGSL/#language-extensions-sec> |
| 190 | + #[derive(Default)] |
| 191 | + pub struct LanguageExtensions: u32 { |
| 192 | + const READONLY_AND_READWRITE_STORAGE_TEXTURES, "readonly_and_readwrite_storage_textures" = 0x1; |
| 193 | + const PACKED4X8_INTEGER_DOT_PRODUCT, "packed_4x8_integer_dot_product" = 0x2; |
| 194 | + const UNRESTRICTED_POINTER_PARAMETERS, "unrestricted_pointer_parameters" = 0x4; |
| 195 | + const POINTER_COMPOSITE_ACCESS, "pointer_composite_access" = 0x8; |
| 196 | + } |
| 197 | +} |
| 198 | + |
| 199 | +impl LanguageExtensions { |
| 200 | + pub const IMPLEMENTED: Self = |
| 201 | + Self::empty() |
| 202 | + .union(Self::READONLY_AND_READWRITE_STORAGE_TEXTURES) |
| 203 | + .union(Self::PACKED4X8_INTEGER_DOT_PRODUCT) |
| 204 | + .union(Self::POINTER_COMPOSITE_ACCESS); |
| 205 | + |
| 206 | + pub const UNIMPLEMENTED: Self = Self::IMPLEMENTED.complement(); |
| 207 | + |
| 208 | + pub(crate) const fn tracking_issue_num(self) -> Option<u16> { |
| 209 | + match self { |
| 210 | + Self::UNRESTRICTED_POINTER_PARAMETERS => Some(5158), |
| 211 | + other => { |
| 212 | + assert!(Self::IMPLEMENTED.contains(other)); |
| 213 | + None |
| 214 | + } |
| 215 | + } |
102 | 216 | } |
103 | 217 | } |
104 | 218 |
|
|
0 commit comments