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