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}
25
26impl EnableExtensions {
27 pub(crate) const fn empty() -> Self {
28 Self {
29 wgpu_mesh_shader: false,
30 wgpu_ray_query: false,
31 wgpu_ray_query_vertex_return: false,
32 wgpu_ray_tracing_pipelines: false,
33 f16: false,
34 dual_source_blending: false,
35 clip_distances: false,
36 wgpu_cooperative_matrix: false,
37 draw_index: false,
38 primitive_index: false,
39 }
40 }
41
42 pub(crate) const fn add(&mut self, ext: ImplementedEnableExtension) {
44 let field = match ext {
45 ImplementedEnableExtension::WgpuMeshShader => &mut self.wgpu_mesh_shader,
46 ImplementedEnableExtension::WgpuRayQuery => &mut self.wgpu_ray_query,
47 ImplementedEnableExtension::WgpuRayQueryVertexReturn => {
48 &mut self.wgpu_ray_query_vertex_return
49 }
50 ImplementedEnableExtension::WgpuRayTracingPipeline => {
51 &mut self.wgpu_ray_tracing_pipelines
52 }
53 ImplementedEnableExtension::DualSourceBlending => &mut self.dual_source_blending,
54 ImplementedEnableExtension::F16 => &mut self.f16,
55 ImplementedEnableExtension::ClipDistances => &mut self.clip_distances,
56 ImplementedEnableExtension::WgpuCooperativeMatrix => &mut self.wgpu_cooperative_matrix,
57 ImplementedEnableExtension::DrawIndex => &mut self.draw_index,
58 ImplementedEnableExtension::PrimitiveIndex => &mut self.primitive_index,
59 };
60 *field = true;
61 }
62
63 pub(crate) const fn contains(&self, ext: ImplementedEnableExtension) -> bool {
65 match ext {
66 ImplementedEnableExtension::WgpuMeshShader => self.wgpu_mesh_shader,
67 ImplementedEnableExtension::WgpuRayQuery => self.wgpu_ray_query,
68 ImplementedEnableExtension::WgpuRayQueryVertexReturn => {
69 self.wgpu_ray_query_vertex_return
70 }
71 ImplementedEnableExtension::WgpuRayTracingPipeline => self.wgpu_ray_tracing_pipelines,
72 ImplementedEnableExtension::DualSourceBlending => self.dual_source_blending,
73 ImplementedEnableExtension::F16 => self.f16,
74 ImplementedEnableExtension::ClipDistances => self.clip_distances,
75 ImplementedEnableExtension::WgpuCooperativeMatrix => self.wgpu_cooperative_matrix,
76 ImplementedEnableExtension::DrawIndex => self.draw_index,
77 ImplementedEnableExtension::PrimitiveIndex => self.primitive_index,
78 }
79 }
80
81 pub(crate) fn require(
82 &self,
83 ext: ImplementedEnableExtension,
84 span: Span,
85 ) -> Result<'static, ()> {
86 if !self.contains(ext) {
87 Err(Box::new(Error::EnableExtensionNotEnabled {
88 span,
89 kind: ext.into(),
90 }))
91 } else {
92 Ok(())
93 }
94 }
95}
96
97impl Default for EnableExtensions {
98 fn default() -> Self {
99 Self::empty()
100 }
101}
102
103#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
107pub enum EnableExtension {
108 Implemented(ImplementedEnableExtension),
109 Unimplemented(UnimplementedEnableExtension),
110}
111
112impl From<ImplementedEnableExtension> for EnableExtension {
113 fn from(value: ImplementedEnableExtension) -> Self {
114 Self::Implemented(value)
115 }
116}
117
118impl EnableExtension {
119 const F16: &'static str = "f16";
120 const CLIP_DISTANCES: &'static str = "clip_distances";
121 const DUAL_SOURCE_BLENDING: &'static str = "dual_source_blending";
122 const MESH_SHADER: &'static str = "wgpu_mesh_shader";
123 const RAY_QUERY: &'static str = "wgpu_ray_query";
124 const RAY_QUERY_VERTEX_RETURN: &'static str = "wgpu_ray_query_vertex_return";
125 const RAY_TRACING_PIPELINE: &'static str = "wgpu_ray_tracing_pipeline";
126 const COOPERATIVE_MATRIX: &'static str = "wgpu_cooperative_matrix";
127 const SUBGROUPS: &'static str = "subgroups";
128 const PRIMITIVE_INDEX: &'static str = "primitive_index";
129 const DRAW_INDEX: &'static str = "draw_index";
130
131 pub(crate) fn from_ident(word: &str, span: Span) -> Result<'_, Self> {
133 Ok(match word {
134 Self::F16 => Self::Implemented(ImplementedEnableExtension::F16),
135 Self::CLIP_DISTANCES => Self::Implemented(ImplementedEnableExtension::ClipDistances),
136 Self::DUAL_SOURCE_BLENDING => {
137 Self::Implemented(ImplementedEnableExtension::DualSourceBlending)
138 }
139 Self::MESH_SHADER => Self::Implemented(ImplementedEnableExtension::WgpuMeshShader),
140 Self::RAY_QUERY => Self::Implemented(ImplementedEnableExtension::WgpuRayQuery),
141 Self::RAY_QUERY_VERTEX_RETURN => {
142 Self::Implemented(ImplementedEnableExtension::WgpuRayQueryVertexReturn)
143 }
144 Self::RAY_TRACING_PIPELINE => {
145 Self::Implemented(ImplementedEnableExtension::WgpuRayTracingPipeline)
146 }
147 Self::COOPERATIVE_MATRIX => {
148 Self::Implemented(ImplementedEnableExtension::WgpuCooperativeMatrix)
149 }
150 Self::SUBGROUPS => Self::Unimplemented(UnimplementedEnableExtension::Subgroups),
151 Self::DRAW_INDEX => Self::Implemented(ImplementedEnableExtension::DrawIndex),
152 Self::PRIMITIVE_INDEX => Self::Implemented(ImplementedEnableExtension::PrimitiveIndex),
153 _ => return Err(Box::new(Error::UnknownEnableExtension(span, word))),
154 })
155 }
156
157 pub const fn to_ident(self) -> &'static str {
159 match self {
160 Self::Implemented(kind) => match kind {
161 ImplementedEnableExtension::WgpuMeshShader => Self::MESH_SHADER,
162 ImplementedEnableExtension::WgpuRayQuery => Self::RAY_QUERY,
163 ImplementedEnableExtension::WgpuRayQueryVertexReturn => {
164 Self::RAY_QUERY_VERTEX_RETURN
165 }
166 ImplementedEnableExtension::WgpuCooperativeMatrix => Self::COOPERATIVE_MATRIX,
167 ImplementedEnableExtension::DualSourceBlending => Self::DUAL_SOURCE_BLENDING,
168 ImplementedEnableExtension::F16 => Self::F16,
169 ImplementedEnableExtension::ClipDistances => Self::CLIP_DISTANCES,
170 ImplementedEnableExtension::DrawIndex => Self::DRAW_INDEX,
171 ImplementedEnableExtension::PrimitiveIndex => Self::PRIMITIVE_INDEX,
172 ImplementedEnableExtension::WgpuRayTracingPipeline => Self::RAY_TRACING_PIPELINE,
173 },
174 Self::Unimplemented(kind) => match kind {
175 UnimplementedEnableExtension::Subgroups => Self::SUBGROUPS,
176 },
177 }
178 }
179}
180
181#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
183#[cfg_attr(test, derive(strum::VariantArray))]
184pub enum ImplementedEnableExtension {
185 F16,
191 DualSourceBlending,
197 ClipDistances,
203 WgpuMeshShader,
205 WgpuRayQuery,
207 WgpuRayQueryVertexReturn,
209 WgpuRayTracingPipeline,
211 WgpuCooperativeMatrix,
213 DrawIndex,
215 PrimitiveIndex,
221}
222
223impl ImplementedEnableExtension {
224 pub const VARIANTS: &'static [Self] = &[
226 Self::F16,
227 Self::DualSourceBlending,
228 Self::ClipDistances,
229 Self::WgpuMeshShader,
230 Self::WgpuRayQuery,
231 Self::WgpuRayQueryVertexReturn,
232 Self::WgpuRayTracingPipeline,
233 Self::WgpuCooperativeMatrix,
234 Self::DrawIndex,
235 Self::PrimitiveIndex,
236 ];
237
238 pub const fn all() -> &'static [Self] {
240 Self::VARIANTS
241 }
242
243 pub const fn capability(self) -> crate::valid::Capabilities {
245 use crate::valid::Capabilities as C;
246 match self {
247 Self::F16 => C::SHADER_FLOAT16,
248 Self::DualSourceBlending => C::DUAL_SOURCE_BLENDING,
249 Self::ClipDistances => C::CLIP_DISTANCE,
250 Self::WgpuMeshShader => C::MESH_SHADER,
251 Self::WgpuRayQuery => C::RAY_QUERY,
252 Self::WgpuRayQueryVertexReturn => C::RAY_HIT_VERTEX_POSITION,
253 Self::WgpuCooperativeMatrix => C::COOPERATIVE_MATRIX,
254 Self::WgpuRayTracingPipeline => C::RAY_TRACING_PIPELINE,
255 Self::DrawIndex => C::DRAW_INDEX,
256 Self::PrimitiveIndex => C::PRIMITIVE_INDEX,
257 }
258 }
259}
260
261#[test]
262fn test_manual_variants_array_is_correct() {
265 assert_eq!(
266 <ImplementedEnableExtension as strum::VariantArray>::VARIANTS,
267 ImplementedEnableExtension::VARIANTS
268 );
269}
270
271#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
273pub enum UnimplementedEnableExtension {
274 Subgroups,
280}
281
282impl UnimplementedEnableExtension {
283 pub(crate) const fn tracking_issue_num(self) -> u16 {
284 match self {
285 Self::Subgroups => 5555,
286 }
287 }
288}