1#![no_std]
4
5use naga::valid::Capabilities as Caps;
6use wgpu_types as wgt;
7
8pub fn features_to_naga_capabilities(
10 features: wgt::Features,
11 downlevel: wgt::DownlevelFlags,
12) -> Caps {
13 let mut caps = Caps::empty();
14 caps.set(
15 Caps::IMMEDIATES,
16 features.contains(wgt::Features::IMMEDIATES),
17 );
18 caps.set(Caps::FLOAT64, features.contains(wgt::Features::SHADER_F64));
19 caps.set(
20 Caps::SHADER_FLOAT16,
21 features.contains(wgt::Features::SHADER_F16),
22 );
23 caps.set(
24 Caps::SHADER_FLOAT16_IN_FLOAT32,
25 downlevel.contains(wgt::DownlevelFlags::SHADER_F16_IN_F32),
26 );
27 caps.set(
28 Caps::SHADER_INT16,
29 features.contains(wgt::Features::SHADER_I16),
30 );
31 caps.set(
32 Caps::PRIMITIVE_INDEX,
33 features.contains(wgt::Features::PRIMITIVE_INDEX),
34 );
35 caps.set(
36 Caps::TEXTURE_AND_SAMPLER_BINDING_ARRAY,
37 features.contains(wgt::Features::TEXTURE_BINDING_ARRAY),
38 );
39 caps.set(
40 Caps::BUFFER_BINDING_ARRAY,
41 features.contains(wgt::Features::BUFFER_BINDING_ARRAY),
42 );
43 caps.set(
44 Caps::STORAGE_TEXTURE_BINDING_ARRAY,
45 features.contains(wgt::Features::TEXTURE_BINDING_ARRAY)
46 && features.contains(wgt::Features::STORAGE_RESOURCE_BINDING_ARRAY),
47 );
48 caps.set(
49 Caps::STORAGE_BUFFER_BINDING_ARRAY,
50 features.contains(wgt::Features::BUFFER_BINDING_ARRAY)
51 && features.contains(wgt::Features::STORAGE_RESOURCE_BINDING_ARRAY),
52 );
53 caps.set(
54 Caps::TEXTURE_AND_SAMPLER_BINDING_ARRAY_NON_UNIFORM_INDEXING,
55 features
56 .contains(wgt::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING),
57 );
58 caps.set(
59 Caps::BUFFER_BINDING_ARRAY_NON_UNIFORM_INDEXING,
60 features.contains(wgt::Features::UNIFORM_BUFFER_BINDING_ARRAYS),
61 );
62 caps.set(
63 Caps::STORAGE_TEXTURE_BINDING_ARRAY_NON_UNIFORM_INDEXING,
64 features.contains(wgt::Features::STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING),
65 );
66 caps.set(
67 Caps::STORAGE_BUFFER_BINDING_ARRAY_NON_UNIFORM_INDEXING,
68 features
69 .contains(wgt::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING),
70 );
71 caps.set(
72 Caps::ACCELERATION_STRUCTURE_BINDING_ARRAY,
73 features.contains(wgt::Features::ACCELERATION_STRUCTURE_BINDING_ARRAY),
74 );
75 caps.set(
76 Caps::STORAGE_TEXTURE_16BIT_NORM_FORMATS,
77 features.contains(wgt::Features::TEXTURE_FORMAT_16BIT_NORM),
78 );
79 caps.set(Caps::MULTIVIEW, features.contains(wgt::Features::MULTIVIEW));
80 caps.set(
81 Caps::EARLY_DEPTH_TEST,
82 features.contains(wgt::Features::SHADER_EARLY_DEPTH_TEST),
83 );
84 caps.set(
85 Caps::SHADER_INT64,
86 features.contains(wgt::Features::SHADER_INT64),
87 );
88 caps.set(
89 Caps::SHADER_INT64_ATOMIC_MIN_MAX,
90 features.intersects(
91 wgt::Features::SHADER_INT64_ATOMIC_MIN_MAX | wgt::Features::SHADER_INT64_ATOMIC_ALL_OPS,
92 ),
93 );
94 caps.set(
95 Caps::SHADER_INT64_ATOMIC_ALL_OPS,
96 features.contains(wgt::Features::SHADER_INT64_ATOMIC_ALL_OPS),
97 );
98 caps.set(
99 Caps::TEXTURE_ATOMIC,
100 features.contains(wgt::Features::TEXTURE_ATOMIC),
101 );
102 caps.set(
103 Caps::TEXTURE_INT64_ATOMIC,
104 features.contains(wgt::Features::TEXTURE_INT64_ATOMIC),
105 );
106 caps.set(
107 Caps::SHADER_FLOAT32_ATOMIC,
108 features.contains(wgt::Features::SHADER_FLOAT32_ATOMIC),
109 );
110 caps.set(
111 Caps::MULTISAMPLED_SHADING,
112 downlevel.contains(wgt::DownlevelFlags::MULTISAMPLED_SHADING),
113 );
114 caps.set(
115 Caps::DUAL_SOURCE_BLENDING,
116 features.contains(wgt::Features::DUAL_SOURCE_BLENDING),
117 );
118 caps.set(
119 Caps::CLIP_DISTANCES,
120 features.contains(wgt::Features::CLIP_DISTANCES),
121 );
122 caps.set(
123 Caps::CUBE_ARRAY_TEXTURES,
124 downlevel.contains(wgt::DownlevelFlags::CUBE_ARRAY_TEXTURES),
125 );
126 caps.set(
127 Caps::SUBGROUP,
128 features.intersects(wgt::Features::SUBGROUP | wgt::Features::SUBGROUP_VERTEX),
129 );
130 caps.set(
131 Caps::SUBGROUP_BARRIER,
132 features.intersects(wgt::Features::SUBGROUP_BARRIER),
133 );
134 caps.set(
135 Caps::RAY_QUERY,
136 features.intersects(wgt::Features::EXPERIMENTAL_RAY_QUERY),
137 );
138 caps.set(
139 Caps::SUBGROUP_VERTEX_STAGE,
140 features.contains(wgt::Features::SUBGROUP_VERTEX),
141 );
142 caps.set(
143 Caps::RAY_HIT_VERTEX_POSITION,
144 features.intersects(wgt::Features::EXPERIMENTAL_RAY_HIT_VERTEX_RETURN),
145 );
146 caps.set(
147 Caps::TEXTURE_EXTERNAL,
148 features.intersects(wgt::Features::EXTERNAL_TEXTURE),
149 );
150 caps.set(
151 Caps::SHADER_BARYCENTRICS,
152 features.intersects(wgt::Features::SHADER_BARYCENTRICS),
153 );
154 caps.set(
155 Caps::MESH_SHADER,
156 features.intersects(wgt::Features::EXPERIMENTAL_MESH_SHADER),
157 );
158 caps.set(
159 Caps::MESH_SHADER_POINT_TOPOLOGY,
160 features.intersects(wgt::Features::EXPERIMENTAL_MESH_SHADER_POINTS),
161 );
162 caps.set(
163 Caps::COOPERATIVE_MATRIX,
164 features.intersects(wgt::Features::EXPERIMENTAL_COOPERATIVE_MATRIX),
165 );
166 caps.set(
167 Caps::PER_VERTEX,
168 features.intersects(wgt::Features::SHADER_PER_VERTEX),
169 );
170 caps.set(
171 Caps::DRAW_INDEX,
172 features.intersects(wgt::Features::SHADER_DRAW_INDEX),
173 );
174 caps.set(
175 Caps::MEMORY_DECORATION_COHERENT,
176 features.contains(wgt::Features::MEMORY_DECORATION_COHERENT),
177 );
178 caps.set(
179 Caps::MEMORY_DECORATION_VOLATILE,
180 features.contains(wgt::Features::MEMORY_DECORATION_VOLATILE),
181 );
182 caps.set(
183 Caps::RAY_TRACING_PIPELINE,
184 features.intersects(wgt::Features::EXPERIMENTAL_RAY_TRACING_PIPELINES),
185 );
186 caps.set(
187 Caps::LINEAR_INTERPOLATION,
188 downlevel.contains(wgt::DownlevelFlags::LINEAR_INTERPOLATION),
189 );
190 caps
191}
192
193pub fn create_validator(
195 features: wgt::Features,
196 downlevel: wgt::DownlevelFlags,
197 flags: naga::valid::ValidationFlags,
198) -> naga::valid::Validator {
199 let caps = features_to_naga_capabilities(features, downlevel);
200 naga::valid::Validator::new(flags, caps)
201}
202
203pub fn map_storage_format_to_naga(format: wgt::TextureFormat) -> Option<naga::StorageFormat> {
205 use naga::StorageFormat as Sf;
206 use wgt::TextureFormat as Tf;
207
208 Some(match format {
209 Tf::R8Unorm => Sf::R8Unorm,
210 Tf::R8Snorm => Sf::R8Snorm,
211 Tf::R8Uint => Sf::R8Uint,
212 Tf::R8Sint => Sf::R8Sint,
213
214 Tf::R16Uint => Sf::R16Uint,
215 Tf::R16Sint => Sf::R16Sint,
216 Tf::R16Float => Sf::R16Float,
217 Tf::Rg8Unorm => Sf::Rg8Unorm,
218 Tf::Rg8Snorm => Sf::Rg8Snorm,
219 Tf::Rg8Uint => Sf::Rg8Uint,
220 Tf::Rg8Sint => Sf::Rg8Sint,
221
222 Tf::R32Uint => Sf::R32Uint,
223 Tf::R32Sint => Sf::R32Sint,
224 Tf::R32Float => Sf::R32Float,
225 Tf::Rg16Uint => Sf::Rg16Uint,
226 Tf::Rg16Sint => Sf::Rg16Sint,
227 Tf::Rg16Float => Sf::Rg16Float,
228 Tf::Rgba8Unorm => Sf::Rgba8Unorm,
229 Tf::Rgba8Snorm => Sf::Rgba8Snorm,
230 Tf::Rgba8Uint => Sf::Rgba8Uint,
231 Tf::Rgba8Sint => Sf::Rgba8Sint,
232 Tf::Bgra8Unorm => Sf::Bgra8Unorm,
233
234 Tf::Rgb10a2Uint => Sf::Rgb10a2Uint,
235 Tf::Rgb10a2Unorm => Sf::Rgb10a2Unorm,
236 Tf::Rg11b10Ufloat => Sf::Rg11b10Ufloat,
237
238 Tf::R64Uint => Sf::R64Uint,
239 Tf::Rg32Uint => Sf::Rg32Uint,
240 Tf::Rg32Sint => Sf::Rg32Sint,
241 Tf::Rg32Float => Sf::Rg32Float,
242 Tf::Rgba16Uint => Sf::Rgba16Uint,
243 Tf::Rgba16Sint => Sf::Rgba16Sint,
244 Tf::Rgba16Float => Sf::Rgba16Float,
245
246 Tf::Rgba32Uint => Sf::Rgba32Uint,
247 Tf::Rgba32Sint => Sf::Rgba32Sint,
248 Tf::Rgba32Float => Sf::Rgba32Float,
249
250 Tf::R16Unorm => Sf::R16Unorm,
251 Tf::R16Snorm => Sf::R16Snorm,
252 Tf::Rg16Unorm => Sf::Rg16Unorm,
253 Tf::Rg16Snorm => Sf::Rg16Snorm,
254 Tf::Rgba16Unorm => Sf::Rgba16Unorm,
255 Tf::Rgba16Snorm => Sf::Rgba16Snorm,
256
257 _ => return None,
258 })
259}
260
261pub fn map_storage_format_from_naga(format: naga::StorageFormat) -> wgt::TextureFormat {
263 use naga::StorageFormat as Sf;
264 use wgt::TextureFormat as Tf;
265
266 match format {
267 Sf::R8Unorm => Tf::R8Unorm,
268 Sf::R8Snorm => Tf::R8Snorm,
269 Sf::R8Uint => Tf::R8Uint,
270 Sf::R8Sint => Tf::R8Sint,
271
272 Sf::R16Uint => Tf::R16Uint,
273 Sf::R16Sint => Tf::R16Sint,
274 Sf::R16Float => Tf::R16Float,
275 Sf::Rg8Unorm => Tf::Rg8Unorm,
276 Sf::Rg8Snorm => Tf::Rg8Snorm,
277 Sf::Rg8Uint => Tf::Rg8Uint,
278 Sf::Rg8Sint => Tf::Rg8Sint,
279
280 Sf::R32Uint => Tf::R32Uint,
281 Sf::R32Sint => Tf::R32Sint,
282 Sf::R32Float => Tf::R32Float,
283 Sf::Rg16Uint => Tf::Rg16Uint,
284 Sf::Rg16Sint => Tf::Rg16Sint,
285 Sf::Rg16Float => Tf::Rg16Float,
286 Sf::Rgba8Unorm => Tf::Rgba8Unorm,
287 Sf::Rgba8Snorm => Tf::Rgba8Snorm,
288 Sf::Rgba8Uint => Tf::Rgba8Uint,
289 Sf::Rgba8Sint => Tf::Rgba8Sint,
290 Sf::Bgra8Unorm => Tf::Bgra8Unorm,
291
292 Sf::Rgb10a2Uint => Tf::Rgb10a2Uint,
293 Sf::Rgb10a2Unorm => Tf::Rgb10a2Unorm,
294 Sf::Rg11b10Ufloat => Tf::Rg11b10Ufloat,
295
296 Sf::R64Uint => Tf::R64Uint,
297 Sf::Rg32Uint => Tf::Rg32Uint,
298 Sf::Rg32Sint => Tf::Rg32Sint,
299 Sf::Rg32Float => Tf::Rg32Float,
300 Sf::Rgba16Uint => Tf::Rgba16Uint,
301 Sf::Rgba16Sint => Tf::Rgba16Sint,
302 Sf::Rgba16Float => Tf::Rgba16Float,
303
304 Sf::Rgba32Uint => Tf::Rgba32Uint,
305 Sf::Rgba32Sint => Tf::Rgba32Sint,
306 Sf::Rgba32Float => Tf::Rgba32Float,
307
308 Sf::R16Unorm => Tf::R16Unorm,
309 Sf::R16Snorm => Tf::R16Snorm,
310 Sf::Rg16Unorm => Tf::Rg16Unorm,
311 Sf::Rg16Snorm => Tf::Rg16Snorm,
312 Sf::Rgba16Unorm => Tf::Rgba16Unorm,
313 Sf::Rgba16Snorm => Tf::Rgba16Snorm,
314 }
315}
316
317pub fn map_naga_stage(stage: naga::ShaderStage) -> wgt::ShaderStages {
319 match stage {
320 naga::ShaderStage::Vertex => wgt::ShaderStages::VERTEX,
321 naga::ShaderStage::Fragment => wgt::ShaderStages::FRAGMENT,
322 naga::ShaderStage::Compute => wgt::ShaderStages::COMPUTE,
323 naga::ShaderStage::Task => wgt::ShaderStages::TASK,
324 naga::ShaderStage::Mesh => wgt::ShaderStages::MESH,
325 naga::ShaderStage::RayGeneration => wgt::ShaderStages::RAY_GENERATION,
326 naga::ShaderStage::AnyHit => wgt::ShaderStages::ANY_HIT,
327 naga::ShaderStage::ClosestHit => wgt::ShaderStages::CLOSEST_HIT,
328 naga::ShaderStage::Miss => wgt::ShaderStages::MISS,
329 }
330}