naga/front/wgsl/parse/directive/
enable_extension.rs1use crate::front::wgsl::{Error, Result};
6use crate::Span;
7
8use alloc::boxed::Box;
9
10#[derive(Clone, Copy, Debug, Eq, PartialEq)]
12pub(crate) struct EnableExtensions {
13 wgpu_mesh_shader: bool,
14 wgpu_ray_query: bool,
15 wgpu_ray_query_vertex_return: bool,
16 wgpu_ray_tracing_pipelines: bool,
17 dual_source_blending: bool,
18 f16: bool,
20 wgpu_int16: bool,
22 clip_distances: bool,
23 wgpu_cooperative_matrix: bool,
24 draw_index: bool,
25 primitive_index: bool,
26 per_vertex: bool,
27 wgpu_binding_array: bool,
28}
29
30impl EnableExtensions {
31 pub(crate) const fn empty() -> Self {
32 Self {
33 wgpu_mesh_shader: false,
34 wgpu_ray_query: false,
35 wgpu_ray_query_vertex_return: false,
36 wgpu_ray_tracing_pipelines: false,
37 f16: false,
38 wgpu_int16: false,
39 dual_source_blending: false,
40 clip_distances: false,
41 wgpu_cooperative_matrix: false,
42 draw_index: false,
43 primitive_index: false,
44 per_vertex: false,
45 wgpu_binding_array: false,
46 }
47 }
48
49 pub(crate) const fn add(&mut self, ext: ImplementedEnableExtension) {
51 let field = match ext {
52 ImplementedEnableExtension::WgpuMeshShader => &mut self.wgpu_mesh_shader,
53 ImplementedEnableExtension::WgpuRayQuery => &mut self.wgpu_ray_query,
54 ImplementedEnableExtension::WgpuRayQueryVertexReturn => {
55 &mut self.wgpu_ray_query_vertex_return
56 }
57 ImplementedEnableExtension::WgpuRayTracingPipeline => {
58 &mut self.wgpu_ray_tracing_pipelines
59 }
60 ImplementedEnableExtension::DualSourceBlending => &mut self.dual_source_blending,
61 ImplementedEnableExtension::F16 => &mut self.f16,
62 ImplementedEnableExtension::WgpuInt16 => &mut self.wgpu_int16,
63 ImplementedEnableExtension::ClipDistances => &mut self.clip_distances,
64 ImplementedEnableExtension::WgpuCooperativeMatrix => &mut self.wgpu_cooperative_matrix,
65 ImplementedEnableExtension::DrawIndex => &mut self.draw_index,
66 ImplementedEnableExtension::PrimitiveIndex => &mut self.primitive_index,
67 ImplementedEnableExtension::WgpuPerVertex => &mut self.per_vertex,
68 ImplementedEnableExtension::WgpuBindingArray => &mut self.wgpu_binding_array,
69 };
70 *field = true;
71 }
72
73 pub(crate) const fn contains(&self, ext: ImplementedEnableExtension) -> bool {
75 match ext {
76 ImplementedEnableExtension::WgpuMeshShader => self.wgpu_mesh_shader,
77 ImplementedEnableExtension::WgpuRayQuery => self.wgpu_ray_query,
78 ImplementedEnableExtension::WgpuRayQueryVertexReturn => {
79 self.wgpu_ray_query_vertex_return
80 }
81 ImplementedEnableExtension::WgpuRayTracingPipeline => self.wgpu_ray_tracing_pipelines,
82 ImplementedEnableExtension::DualSourceBlending => self.dual_source_blending,
83 ImplementedEnableExtension::F16 => self.f16,
84 ImplementedEnableExtension::WgpuInt16 => self.wgpu_int16,
85 ImplementedEnableExtension::ClipDistances => self.clip_distances,
86 ImplementedEnableExtension::WgpuCooperativeMatrix => self.wgpu_cooperative_matrix,
87 ImplementedEnableExtension::DrawIndex => self.draw_index,
88 ImplementedEnableExtension::PrimitiveIndex => self.primitive_index,
89 ImplementedEnableExtension::WgpuPerVertex => self.per_vertex,
90 ImplementedEnableExtension::WgpuBindingArray => self.wgpu_binding_array,
91 }
92 }
93
94 pub(crate) fn require(
95 &self,
96 ext: ImplementedEnableExtension,
97 span: Span,
98 ) -> Result<'static, ()> {
99 if !self.contains(ext) {
100 Err(Box::new(Error::EnableExtensionNotEnabled {
101 span,
102 kind: ext.into(),
103 }))
104 } else {
105 Ok(())
106 }
107 }
108}
109
110impl Default for EnableExtensions {
111 fn default() -> Self {
112 Self::empty()
113 }
114}
115
116#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
120pub enum EnableExtension {
121 Implemented(ImplementedEnableExtension),
122 Unimplemented(UnimplementedEnableExtension),
123}
124
125impl From<ImplementedEnableExtension> for EnableExtension {
126 fn from(value: ImplementedEnableExtension) -> Self {
127 Self::Implemented(value)
128 }
129}
130
131impl EnableExtension {
132 const F16: &'static str = "f16";
133 const CLIP_DISTANCES: &'static str = "clip_distances";
134 const DUAL_SOURCE_BLENDING: &'static str = "dual_source_blending";
135 const MESH_SHADER: &'static str = "wgpu_mesh_shader";
136 const RAY_QUERY: &'static str = "wgpu_ray_query";
137 const RAY_QUERY_VERTEX_RETURN: &'static str = "wgpu_ray_query_vertex_return";
138 const RAY_TRACING_PIPELINE: &'static str = "wgpu_ray_tracing_pipeline";
139 const COOPERATIVE_MATRIX: &'static str = "wgpu_cooperative_matrix";
140 const SUBGROUPS: &'static str = "subgroups";
141 const PRIMITIVE_INDEX: &'static str = "primitive_index";
142 const DRAW_INDEX: &'static str = "draw_index";
143 const PER_VERTEX: &'static str = "wgpu_per_vertex";
144 const BINDING_ARRAY: &'static str = "wgpu_binding_array";
145 const INT16: &'static str = "wgpu_int16";
146
147 pub(crate) fn from_ident(word: &str, span: Span) -> Result<'_, Self> {
149 Ok(match word {
150 Self::F16 => Self::Implemented(ImplementedEnableExtension::F16),
151 Self::CLIP_DISTANCES => Self::Implemented(ImplementedEnableExtension::ClipDistances),
152 Self::DUAL_SOURCE_BLENDING => {
153 Self::Implemented(ImplementedEnableExtension::DualSourceBlending)
154 }
155 Self::MESH_SHADER => Self::Implemented(ImplementedEnableExtension::WgpuMeshShader),
156 Self::RAY_QUERY => Self::Implemented(ImplementedEnableExtension::WgpuRayQuery),
157 Self::RAY_QUERY_VERTEX_RETURN => {
158 Self::Implemented(ImplementedEnableExtension::WgpuRayQueryVertexReturn)
159 }
160 Self::RAY_TRACING_PIPELINE => {
161 Self::Implemented(ImplementedEnableExtension::WgpuRayTracingPipeline)
162 }
163 Self::COOPERATIVE_MATRIX => {
164 Self::Implemented(ImplementedEnableExtension::WgpuCooperativeMatrix)
165 }
166 Self::SUBGROUPS => Self::Unimplemented(UnimplementedEnableExtension::Subgroups),
167 Self::DRAW_INDEX => Self::Implemented(ImplementedEnableExtension::DrawIndex),
168 Self::PRIMITIVE_INDEX => Self::Implemented(ImplementedEnableExtension::PrimitiveIndex),
169 Self::PER_VERTEX => Self::Implemented(ImplementedEnableExtension::WgpuPerVertex),
170 Self::BINDING_ARRAY => Self::Implemented(ImplementedEnableExtension::WgpuBindingArray),
171 Self::INT16 => Self::Implemented(ImplementedEnableExtension::WgpuInt16),
172 _ => return Err(Box::new(Error::UnknownEnableExtension(span, word))),
173 })
174 }
175
176 pub const fn to_ident(self) -> &'static str {
178 match self {
179 Self::Implemented(kind) => match kind {
180 ImplementedEnableExtension::WgpuMeshShader => Self::MESH_SHADER,
181 ImplementedEnableExtension::WgpuRayQuery => Self::RAY_QUERY,
182 ImplementedEnableExtension::WgpuRayQueryVertexReturn => {
183 Self::RAY_QUERY_VERTEX_RETURN
184 }
185 ImplementedEnableExtension::WgpuCooperativeMatrix => Self::COOPERATIVE_MATRIX,
186 ImplementedEnableExtension::DualSourceBlending => Self::DUAL_SOURCE_BLENDING,
187 ImplementedEnableExtension::F16 => Self::F16,
188 ImplementedEnableExtension::ClipDistances => Self::CLIP_DISTANCES,
189 ImplementedEnableExtension::DrawIndex => Self::DRAW_INDEX,
190 ImplementedEnableExtension::PrimitiveIndex => Self::PRIMITIVE_INDEX,
191 ImplementedEnableExtension::WgpuRayTracingPipeline => Self::RAY_TRACING_PIPELINE,
192 ImplementedEnableExtension::WgpuPerVertex => Self::PER_VERTEX,
193 ImplementedEnableExtension::WgpuBindingArray => Self::BINDING_ARRAY,
194 ImplementedEnableExtension::WgpuInt16 => Self::INT16,
195 },
196 Self::Unimplemented(kind) => match kind {
197 UnimplementedEnableExtension::Subgroups => Self::SUBGROUPS,
198 },
199 }
200 }
201}
202
203#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
205#[cfg_attr(test, derive(strum::VariantArray))]
206pub enum ImplementedEnableExtension {
207 F16,
213 DualSourceBlending,
219 ClipDistances,
225 WgpuMeshShader,
227 WgpuRayQuery,
229 WgpuRayQueryVertexReturn,
231 WgpuRayTracingPipeline,
233 WgpuCooperativeMatrix,
235 DrawIndex,
237 PrimitiveIndex,
243 WgpuPerVertex,
245 WgpuBindingArray,
247 WgpuInt16,
249}
250
251impl ImplementedEnableExtension {
252 pub const VARIANTS: &'static [Self] = &[
254 Self::F16,
255 Self::DualSourceBlending,
256 Self::ClipDistances,
257 Self::WgpuMeshShader,
258 Self::WgpuRayQuery,
259 Self::WgpuRayQueryVertexReturn,
260 Self::WgpuRayTracingPipeline,
261 Self::WgpuCooperativeMatrix,
262 Self::DrawIndex,
263 Self::PrimitiveIndex,
264 Self::WgpuPerVertex,
265 Self::WgpuBindingArray,
266 Self::WgpuInt16,
267 ];
268
269 pub const fn all() -> &'static [Self] {
271 Self::VARIANTS
272 }
273
274 pub const fn capability(self) -> crate::valid::Capabilities {
276 use crate::valid::Capabilities as C;
277 match self {
278 Self::F16 => C::SHADER_FLOAT16,
279 Self::DualSourceBlending => C::DUAL_SOURCE_BLENDING,
280 Self::ClipDistances => C::CLIP_DISTANCES,
281 Self::WgpuMeshShader => C::MESH_SHADER,
282 Self::WgpuRayQuery => C::RAY_QUERY,
283 Self::WgpuRayQueryVertexReturn => C::RAY_HIT_VERTEX_POSITION,
284 Self::WgpuCooperativeMatrix => C::COOPERATIVE_MATRIX,
285 Self::WgpuRayTracingPipeline => C::RAY_TRACING_PIPELINE,
286 Self::DrawIndex => C::DRAW_INDEX,
287 Self::PrimitiveIndex => C::PRIMITIVE_INDEX,
288 Self::WgpuPerVertex => C::PER_VERTEX,
289 Self::WgpuBindingArray => C::BUFFER_BINDING_ARRAY
290 .union(C::BUFFER_BINDING_ARRAY_NON_UNIFORM_INDEXING)
291 .union(C::STORAGE_BUFFER_BINDING_ARRAY)
292 .union(C::STORAGE_BUFFER_BINDING_ARRAY_NON_UNIFORM_INDEXING)
293 .union(C::STORAGE_TEXTURE_BINDING_ARRAY)
294 .union(C::STORAGE_TEXTURE_BINDING_ARRAY_NON_UNIFORM_INDEXING)
295 .union(C::TEXTURE_AND_SAMPLER_BINDING_ARRAY)
296 .union(C::TEXTURE_AND_SAMPLER_BINDING_ARRAY_NON_UNIFORM_INDEXING)
297 .union(C::ACCELERATION_STRUCTURE_BINDING_ARRAY),
298 Self::WgpuInt16 => C::SHADER_INT16,
299 }
300 }
301}
302
303#[test]
304fn test_manual_variants_array_is_correct() {
307 assert_eq!(
308 <ImplementedEnableExtension as strum::VariantArray>::VARIANTS,
309 ImplementedEnableExtension::VARIANTS
310 );
311}
312
313#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
315pub enum UnimplementedEnableExtension {
316 Subgroups,
322}
323
324impl UnimplementedEnableExtension {
325 pub(crate) const fn tracking_issue_num(self) -> u16 {
326 match self {
327 Self::Subgroups => 5555,
328 }
329 }
330}