1use std::borrow::Cow;
6use std::num::NonZeroU64;
7
8use js::context::JSContext;
9use script_bindings::codegen::GenericBindings::WebGPUBinding::GPUQueryType;
10use webgpu_traits::WebGPUTextureView;
11use wgpu_core::binding_model::{BindGroupEntry, BindingResource, BufferBinding};
12use wgpu_core::command::{self as wgpu_com, ComputePassDescriptor, PassTimestampWrites};
13use wgpu_core::pipeline::ProgrammableStageDescriptor;
14use wgpu_core::resource::{QuerySetDescriptor, TextureDescriptor};
15use wgpu_types::{self, AstcBlock, AstcChannel};
16
17use crate::conversions::{Convert, TryConvert};
18use crate::dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::PredefinedColorSpace;
19use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
20 GPUAddressMode, GPUBindGroupEntry, GPUBindGroupLayoutEntry, GPUBindingResource,
21 GPUBlendComponent, GPUBlendFactor, GPUBlendOperation, GPUBufferBindingType, GPUColor,
22 GPUCompareFunction, GPUComputePassDescriptor, GPUComputePassTimestampWrites, GPUCullMode,
23 GPUExtent3D, GPUFilterMode, GPUFrontFace, GPUIndexFormat, GPULoadOp, GPUMipmapFilterMode,
24 GPUObjectDescriptorBase, GPUOrigin2D, GPUOrigin3D, GPUPrimitiveState, GPUPrimitiveTopology,
25 GPUProgrammableStage, GPUQuerySetDescriptor, GPURenderPassTimestampWrites,
26 GPUSamplerBindingType, GPUStencilOperation, GPUStorageTextureAccess, GPUStoreOp,
27 GPUTexelCopyBufferInfo, GPUTexelCopyBufferLayout, GPUTexelCopyTextureInfo, GPUTextureAspect,
28 GPUTextureDescriptor, GPUTextureDimension, GPUTextureFormat, GPUTextureSampleType,
29 GPUTextureViewDimension, GPUVertexFormat,
30};
31use crate::dom::bindings::codegen::UnionTypes::GPUTextureOrGPUTextureView;
32use crate::dom::bindings::error::{Error, Fallible};
33use crate::dom::types::GPUDevice;
34
35impl Convert<wgpu_types::TextureFormat> for GPUTextureFormat {
36 fn convert(self) -> wgpu_types::TextureFormat {
37 match self {
38 GPUTextureFormat::R8unorm => wgpu_types::TextureFormat::R8Unorm,
40 GPUTextureFormat::R8snorm => wgpu_types::TextureFormat::R8Snorm,
41 GPUTextureFormat::R8uint => wgpu_types::TextureFormat::R8Uint,
42 GPUTextureFormat::R8sint => wgpu_types::TextureFormat::R8Sint,
43 GPUTextureFormat::R16unorm => wgpu_types::TextureFormat::R16Unorm,
45 GPUTextureFormat::R16snorm => wgpu_types::TextureFormat::R16Snorm,
46 GPUTextureFormat::R16uint => wgpu_types::TextureFormat::R16Uint,
47 GPUTextureFormat::R16sint => wgpu_types::TextureFormat::R16Sint,
48 GPUTextureFormat::R16float => wgpu_types::TextureFormat::R16Float,
49 GPUTextureFormat::Rg8unorm => wgpu_types::TextureFormat::Rg8Unorm,
50 GPUTextureFormat::Rg8snorm => wgpu_types::TextureFormat::Rg8Snorm,
51 GPUTextureFormat::Rg8uint => wgpu_types::TextureFormat::Rg8Uint,
52 GPUTextureFormat::Rg8sint => wgpu_types::TextureFormat::Rg8Sint,
53 GPUTextureFormat::R32uint => wgpu_types::TextureFormat::R32Uint,
55 GPUTextureFormat::R32sint => wgpu_types::TextureFormat::R32Sint,
56 GPUTextureFormat::R32float => wgpu_types::TextureFormat::R32Float,
57 GPUTextureFormat::Rg16unorm => wgpu_types::TextureFormat::Rg16Unorm,
58 GPUTextureFormat::Rg16snorm => wgpu_types::TextureFormat::Rg16Snorm,
59 GPUTextureFormat::Rg16uint => wgpu_types::TextureFormat::Rg16Uint,
60 GPUTextureFormat::Rg16sint => wgpu_types::TextureFormat::Rg16Sint,
61 GPUTextureFormat::Rg16float => wgpu_types::TextureFormat::Rg16Float,
62 GPUTextureFormat::Rgba8unorm => wgpu_types::TextureFormat::Rgba8Unorm,
63 GPUTextureFormat::Rgba8unorm_srgb => wgpu_types::TextureFormat::Rgba8UnormSrgb,
64 GPUTextureFormat::Rgba8snorm => wgpu_types::TextureFormat::Rgba8Snorm,
65 GPUTextureFormat::Rgba8uint => wgpu_types::TextureFormat::Rgba8Uint,
66 GPUTextureFormat::Rgba8sint => wgpu_types::TextureFormat::Rgba8Sint,
67 GPUTextureFormat::Bgra8unorm => wgpu_types::TextureFormat::Bgra8Unorm,
68 GPUTextureFormat::Bgra8unorm_srgb => wgpu_types::TextureFormat::Bgra8UnormSrgb,
69 GPUTextureFormat::Rgb9e5ufloat => wgpu_types::TextureFormat::Rgb9e5Ufloat,
71 GPUTextureFormat::Rgb10a2uint => wgpu_types::TextureFormat::Rgb10a2Uint,
72 GPUTextureFormat::Rgb10a2unorm => wgpu_types::TextureFormat::Rgb10a2Unorm,
73 GPUTextureFormat::Rg11b10ufloat => wgpu_types::TextureFormat::Rg11b10Ufloat,
74 GPUTextureFormat::Rg32uint => wgpu_types::TextureFormat::Rg32Uint,
76 GPUTextureFormat::Rg32sint => wgpu_types::TextureFormat::Rg32Sint,
77 GPUTextureFormat::Rg32float => wgpu_types::TextureFormat::Rg32Float,
78 GPUTextureFormat::Rgba16unorm => wgpu_types::TextureFormat::Rgba16Unorm,
79 GPUTextureFormat::Rgba16snorm => wgpu_types::TextureFormat::Rgba16Snorm,
80 GPUTextureFormat::Rgba16uint => wgpu_types::TextureFormat::Rgba16Uint,
81 GPUTextureFormat::Rgba16sint => wgpu_types::TextureFormat::Rgba16Sint,
82 GPUTextureFormat::Rgba16float => wgpu_types::TextureFormat::Rgba16Float,
83 GPUTextureFormat::Rgba32uint => wgpu_types::TextureFormat::Rgba32Uint,
85 GPUTextureFormat::Rgba32sint => wgpu_types::TextureFormat::Rgba32Sint,
86 GPUTextureFormat::Rgba32float => wgpu_types::TextureFormat::Rgba32Float,
87 GPUTextureFormat::Stencil8 => wgpu_types::TextureFormat::Stencil8,
89 GPUTextureFormat::Depth16unorm => wgpu_types::TextureFormat::Depth16Unorm,
90 GPUTextureFormat::Depth24plus => wgpu_types::TextureFormat::Depth24Plus,
91 GPUTextureFormat::Depth24plus_stencil8 => {
92 wgpu_types::TextureFormat::Depth24PlusStencil8
93 },
94 GPUTextureFormat::Depth32float => wgpu_types::TextureFormat::Depth32Float,
95 GPUTextureFormat::Depth32float_stencil8 => {
97 wgpu_types::TextureFormat::Depth32FloatStencil8
98 },
99 GPUTextureFormat::Bc1_rgba_unorm => wgpu_types::TextureFormat::Bc1RgbaUnorm,
102 GPUTextureFormat::Bc1_rgba_unorm_srgb => wgpu_types::TextureFormat::Bc1RgbaUnormSrgb,
103 GPUTextureFormat::Bc2_rgba_unorm => wgpu_types::TextureFormat::Bc2RgbaUnorm,
104 GPUTextureFormat::Bc2_rgba_unorm_srgb => wgpu_types::TextureFormat::Bc2RgbaUnormSrgb,
105 GPUTextureFormat::Bc3_rgba_unorm => wgpu_types::TextureFormat::Bc3RgbaUnorm,
106 GPUTextureFormat::Bc3_rgba_unorm_srgb => wgpu_types::TextureFormat::Bc3RgbaUnormSrgb,
107 GPUTextureFormat::Bc4_r_unorm => wgpu_types::TextureFormat::Bc4RUnorm,
108 GPUTextureFormat::Bc4_r_snorm => wgpu_types::TextureFormat::Bc4RSnorm,
109 GPUTextureFormat::Bc5_rg_unorm => wgpu_types::TextureFormat::Bc5RgUnorm,
110 GPUTextureFormat::Bc5_rg_snorm => wgpu_types::TextureFormat::Bc5RgSnorm,
111 GPUTextureFormat::Bc6h_rgb_ufloat => wgpu_types::TextureFormat::Bc6hRgbUfloat,
112 GPUTextureFormat::Bc6h_rgb_float => wgpu_types::TextureFormat::Bc6hRgbFloat,
113 GPUTextureFormat::Bc7_rgba_unorm => wgpu_types::TextureFormat::Bc7RgbaUnorm,
114 GPUTextureFormat::Bc7_rgba_unorm_srgb => wgpu_types::TextureFormat::Bc7RgbaUnormSrgb,
115 GPUTextureFormat::Etc2_rgb8unorm => wgpu_types::TextureFormat::Etc2Rgb8Unorm,
118 GPUTextureFormat::Etc2_rgb8unorm_srgb => wgpu_types::TextureFormat::Etc2Rgb8UnormSrgb,
119 GPUTextureFormat::Etc2_rgb8a1unorm => wgpu_types::TextureFormat::Etc2Rgb8A1Unorm,
120 GPUTextureFormat::Etc2_rgb8a1unorm_srgb => {
121 wgpu_types::TextureFormat::Etc2Rgb8A1UnormSrgb
122 },
123 GPUTextureFormat::Etc2_rgba8unorm => wgpu_types::TextureFormat::Etc2Rgba8Unorm,
124 GPUTextureFormat::Etc2_rgba8unorm_srgb => wgpu_types::TextureFormat::Etc2Rgba8UnormSrgb,
125 GPUTextureFormat::Eac_r11unorm => wgpu_types::TextureFormat::EacR11Unorm,
126 GPUTextureFormat::Eac_r11snorm => wgpu_types::TextureFormat::EacR11Snorm,
127 GPUTextureFormat::Eac_rg11unorm => wgpu_types::TextureFormat::EacRg11Unorm,
128 GPUTextureFormat::Eac_rg11snorm => wgpu_types::TextureFormat::EacRg11Snorm,
129 GPUTextureFormat::Astc_4x4_unorm => wgpu_types::TextureFormat::Astc {
132 block: AstcBlock::B4x4,
133 channel: AstcChannel::Unorm,
134 },
135 GPUTextureFormat::Astc_4x4_unorm_srgb => wgpu_types::TextureFormat::Astc {
136 block: AstcBlock::B4x4,
137 channel: AstcChannel::UnormSrgb,
138 },
139 GPUTextureFormat::Astc_5x4_unorm => wgpu_types::TextureFormat::Astc {
140 block: AstcBlock::B5x4,
141 channel: AstcChannel::Unorm,
142 },
143 GPUTextureFormat::Astc_5x4_unorm_srgb => wgpu_types::TextureFormat::Astc {
144 block: AstcBlock::B5x4,
145 channel: AstcChannel::UnormSrgb,
146 },
147 GPUTextureFormat::Astc_5x5_unorm => wgpu_types::TextureFormat::Astc {
148 block: AstcBlock::B5x5,
149 channel: AstcChannel::Unorm,
150 },
151 GPUTextureFormat::Astc_5x5_unorm_srgb => wgpu_types::TextureFormat::Astc {
152 block: AstcBlock::B5x5,
153 channel: AstcChannel::UnormSrgb,
154 },
155 GPUTextureFormat::Astc_6x5_unorm => wgpu_types::TextureFormat::Astc {
156 block: AstcBlock::B6x5,
157 channel: AstcChannel::Unorm,
158 },
159 GPUTextureFormat::Astc_6x5_unorm_srgb => wgpu_types::TextureFormat::Astc {
160 block: AstcBlock::B6x5,
161 channel: AstcChannel::UnormSrgb,
162 },
163 GPUTextureFormat::Astc_6x6_unorm => wgpu_types::TextureFormat::Astc {
164 block: AstcBlock::B6x6,
165 channel: AstcChannel::Unorm,
166 },
167 GPUTextureFormat::Astc_6x6_unorm_srgb => wgpu_types::TextureFormat::Astc {
168 block: AstcBlock::B6x6,
169 channel: AstcChannel::UnormSrgb,
170 },
171 GPUTextureFormat::Astc_8x5_unorm => wgpu_types::TextureFormat::Astc {
172 block: AstcBlock::B8x5,
173 channel: AstcChannel::Unorm,
174 },
175 GPUTextureFormat::Astc_8x5_unorm_srgb => wgpu_types::TextureFormat::Astc {
176 block: AstcBlock::B8x5,
177 channel: AstcChannel::UnormSrgb,
178 },
179 GPUTextureFormat::Astc_8x6_unorm => wgpu_types::TextureFormat::Astc {
180 block: AstcBlock::B8x6,
181 channel: AstcChannel::Unorm,
182 },
183 GPUTextureFormat::Astc_8x6_unorm_srgb => wgpu_types::TextureFormat::Astc {
184 block: AstcBlock::B8x6,
185 channel: AstcChannel::UnormSrgb,
186 },
187 GPUTextureFormat::Astc_8x8_unorm => wgpu_types::TextureFormat::Astc {
188 block: AstcBlock::B8x8,
189 channel: AstcChannel::Unorm,
190 },
191 GPUTextureFormat::Astc_8x8_unorm_srgb => wgpu_types::TextureFormat::Astc {
192 block: AstcBlock::B8x8,
193 channel: AstcChannel::UnormSrgb,
194 },
195 GPUTextureFormat::Astc_10x5_unorm => wgpu_types::TextureFormat::Astc {
196 block: AstcBlock::B10x5,
197 channel: AstcChannel::Unorm,
198 },
199 GPUTextureFormat::Astc_10x5_unorm_srgb => wgpu_types::TextureFormat::Astc {
200 block: AstcBlock::B10x5,
201 channel: AstcChannel::UnormSrgb,
202 },
203 GPUTextureFormat::Astc_10x6_unorm => wgpu_types::TextureFormat::Astc {
204 block: AstcBlock::B10x6,
205 channel: AstcChannel::Unorm,
206 },
207 GPUTextureFormat::Astc_10x6_unorm_srgb => wgpu_types::TextureFormat::Astc {
208 block: AstcBlock::B10x6,
209 channel: AstcChannel::UnormSrgb,
210 },
211 GPUTextureFormat::Astc_10x8_unorm => wgpu_types::TextureFormat::Astc {
212 block: AstcBlock::B10x8,
213 channel: AstcChannel::Unorm,
214 },
215 GPUTextureFormat::Astc_10x8_unorm_srgb => wgpu_types::TextureFormat::Astc {
216 block: AstcBlock::B10x8,
217 channel: AstcChannel::UnormSrgb,
218 },
219 GPUTextureFormat::Astc_10x10_unorm => wgpu_types::TextureFormat::Astc {
220 block: AstcBlock::B10x10,
221 channel: AstcChannel::Unorm,
222 },
223 GPUTextureFormat::Astc_10x10_unorm_srgb => wgpu_types::TextureFormat::Astc {
224 block: AstcBlock::B10x10,
225 channel: AstcChannel::UnormSrgb,
226 },
227 GPUTextureFormat::Astc_12x10_unorm => wgpu_types::TextureFormat::Astc {
228 block: AstcBlock::B12x10,
229 channel: AstcChannel::Unorm,
230 },
231 GPUTextureFormat::Astc_12x10_unorm_srgb => wgpu_types::TextureFormat::Astc {
232 block: AstcBlock::B12x10,
233 channel: AstcChannel::UnormSrgb,
234 },
235 GPUTextureFormat::Astc_12x12_unorm => wgpu_types::TextureFormat::Astc {
236 block: AstcBlock::B12x12,
237 channel: AstcChannel::Unorm,
238 },
239 GPUTextureFormat::Astc_12x12_unorm_srgb => wgpu_types::TextureFormat::Astc {
240 block: AstcBlock::B12x12,
241 channel: AstcChannel::UnormSrgb,
242 },
243 }
244 }
245}
246
247impl TryConvert<wgpu_types::Extent3d> for &GPUExtent3D {
248 type Error = Error;
249
250 fn try_convert(self) -> Result<wgpu_types::Extent3d, Self::Error> {
251 match *self {
252 GPUExtent3D::GPUExtent3DDict(ref dict) => Ok(wgpu_types::Extent3d {
253 width: dict.width,
254 height: dict.height,
255 depth_or_array_layers: dict.depthOrArrayLayers,
256 }),
257 GPUExtent3D::RangeEnforcedUnsignedLongSequence(ref v) => {
258 if v.is_empty() || v.len() > 3 {
260 Err(Error::Type(
261 c"GPUExtent3D size must be between 1 and 3 (inclusive)".to_owned(),
262 ))
263 } else {
264 Ok(wgpu_types::Extent3d {
265 width: v[0],
266 height: v.get(1).copied().unwrap_or(1),
267 depth_or_array_layers: v.get(2).copied().unwrap_or(1),
268 })
269 }
270 },
271 }
272 }
273}
274
275impl Convert<wgpu_types::TexelCopyBufferLayout> for &GPUTexelCopyBufferLayout {
276 fn convert(self) -> wgpu_types::TexelCopyBufferLayout {
277 wgpu_types::TexelCopyBufferLayout {
278 offset: self.offset as wgpu_types::BufferAddress,
279 bytes_per_row: self.bytesPerRow,
280 rows_per_image: self.rowsPerImage,
281 }
282 }
283}
284
285impl Convert<wgpu_types::VertexFormat> for GPUVertexFormat {
286 fn convert(self) -> wgpu_types::VertexFormat {
287 match self {
288 GPUVertexFormat::Uint8 => wgpu_types::VertexFormat::Uint8,
289 GPUVertexFormat::Uint8x2 => wgpu_types::VertexFormat::Uint8x2,
290 GPUVertexFormat::Uint8x4 => wgpu_types::VertexFormat::Uint8x4,
291 GPUVertexFormat::Sint8 => wgpu_types::VertexFormat::Sint8,
292 GPUVertexFormat::Sint8x2 => wgpu_types::VertexFormat::Sint8x2,
293 GPUVertexFormat::Sint8x4 => wgpu_types::VertexFormat::Sint8x4,
294 GPUVertexFormat::Unorm8 => wgpu_types::VertexFormat::Unorm8,
295 GPUVertexFormat::Unorm8x2 => wgpu_types::VertexFormat::Unorm8x2,
296 GPUVertexFormat::Unorm8x4 => wgpu_types::VertexFormat::Unorm8x4,
297 GPUVertexFormat::Snorm8 => wgpu_types::VertexFormat::Snorm8,
298 GPUVertexFormat::Snorm8x2 => wgpu_types::VertexFormat::Snorm8x2,
299 GPUVertexFormat::Snorm8x4 => wgpu_types::VertexFormat::Snorm8x4,
300 GPUVertexFormat::Uint16 => wgpu_types::VertexFormat::Uint16,
301 GPUVertexFormat::Uint16x2 => wgpu_types::VertexFormat::Uint16x2,
302 GPUVertexFormat::Uint16x4 => wgpu_types::VertexFormat::Uint16x4,
303 GPUVertexFormat::Sint16 => wgpu_types::VertexFormat::Sint16,
304 GPUVertexFormat::Sint16x2 => wgpu_types::VertexFormat::Sint16x2,
305 GPUVertexFormat::Sint16x4 => wgpu_types::VertexFormat::Sint16x4,
306 GPUVertexFormat::Unorm16 => wgpu_types::VertexFormat::Unorm16,
307 GPUVertexFormat::Unorm16x2 => wgpu_types::VertexFormat::Unorm16x2,
308 GPUVertexFormat::Unorm16x4 => wgpu_types::VertexFormat::Unorm16x4,
309 GPUVertexFormat::Snorm16 => wgpu_types::VertexFormat::Snorm16,
310 GPUVertexFormat::Snorm16x2 => wgpu_types::VertexFormat::Snorm16x2,
311 GPUVertexFormat::Snorm16x4 => wgpu_types::VertexFormat::Snorm16x4,
312 GPUVertexFormat::Float16 => wgpu_types::VertexFormat::Float16,
313 GPUVertexFormat::Float16x2 => wgpu_types::VertexFormat::Float16x2,
314 GPUVertexFormat::Float16x4 => wgpu_types::VertexFormat::Float16x4,
315 GPUVertexFormat::Float32 => wgpu_types::VertexFormat::Float32,
316 GPUVertexFormat::Float32x2 => wgpu_types::VertexFormat::Float32x2,
317 GPUVertexFormat::Float32x3 => wgpu_types::VertexFormat::Float32x3,
318 GPUVertexFormat::Float32x4 => wgpu_types::VertexFormat::Float32x4,
319 GPUVertexFormat::Uint32 => wgpu_types::VertexFormat::Uint32,
320 GPUVertexFormat::Uint32x2 => wgpu_types::VertexFormat::Uint32x2,
321 GPUVertexFormat::Uint32x3 => wgpu_types::VertexFormat::Uint32x3,
322 GPUVertexFormat::Uint32x4 => wgpu_types::VertexFormat::Uint32x4,
323 GPUVertexFormat::Sint32 => wgpu_types::VertexFormat::Sint32,
324 GPUVertexFormat::Sint32x2 => wgpu_types::VertexFormat::Sint32x2,
325 GPUVertexFormat::Sint32x3 => wgpu_types::VertexFormat::Sint32x3,
326 GPUVertexFormat::Sint32x4 => wgpu_types::VertexFormat::Sint32x4,
327 GPUVertexFormat::Unorm10_10_10_2 => wgpu_types::VertexFormat::Unorm10_10_10_2,
328 GPUVertexFormat::Unorm8x4_bgra => wgpu_types::VertexFormat::Unorm8x4Bgra,
329 }
330 }
331}
332
333impl Convert<wgpu_types::PrimitiveState> for &GPUPrimitiveState {
334 fn convert(self) -> wgpu_types::PrimitiveState {
335 wgpu_types::PrimitiveState {
336 topology: self.topology.convert(),
337 strip_index_format: self
338 .stripIndexFormat
339 .map(|index_format| match index_format {
340 GPUIndexFormat::Uint16 => wgpu_types::IndexFormat::Uint16,
341 GPUIndexFormat::Uint32 => wgpu_types::IndexFormat::Uint32,
342 }),
343 front_face: match self.frontFace {
344 GPUFrontFace::Ccw => wgpu_types::FrontFace::Ccw,
345 GPUFrontFace::Cw => wgpu_types::FrontFace::Cw,
346 },
347 cull_mode: match self.cullMode {
348 GPUCullMode::None => None,
349 GPUCullMode::Front => Some(wgpu_types::Face::Front),
350 GPUCullMode::Back => Some(wgpu_types::Face::Back),
351 },
352 unclipped_depth: self.clampDepth,
353 ..Default::default()
354 }
355 }
356}
357
358impl Convert<wgpu_types::PrimitiveTopology> for &GPUPrimitiveTopology {
359 fn convert(self) -> wgpu_types::PrimitiveTopology {
360 match self {
361 GPUPrimitiveTopology::Point_list => wgpu_types::PrimitiveTopology::PointList,
362 GPUPrimitiveTopology::Line_list => wgpu_types::PrimitiveTopology::LineList,
363 GPUPrimitiveTopology::Line_strip => wgpu_types::PrimitiveTopology::LineStrip,
364 GPUPrimitiveTopology::Triangle_list => wgpu_types::PrimitiveTopology::TriangleList,
365 GPUPrimitiveTopology::Triangle_strip => wgpu_types::PrimitiveTopology::TriangleStrip,
366 }
367 }
368}
369
370impl Convert<wgpu_types::AddressMode> for GPUAddressMode {
371 fn convert(self) -> wgpu_types::AddressMode {
372 match self {
373 GPUAddressMode::Clamp_to_edge => wgpu_types::AddressMode::ClampToEdge,
374 GPUAddressMode::Repeat => wgpu_types::AddressMode::Repeat,
375 GPUAddressMode::Mirror_repeat => wgpu_types::AddressMode::MirrorRepeat,
376 }
377 }
378}
379
380impl Convert<wgpu_types::FilterMode> for GPUFilterMode {
381 fn convert(self) -> wgpu_types::FilterMode {
382 match self {
383 GPUFilterMode::Nearest => wgpu_types::FilterMode::Nearest,
384 GPUFilterMode::Linear => wgpu_types::FilterMode::Linear,
385 }
386 }
387}
388
389impl Convert<wgpu_types::MipmapFilterMode> for GPUMipmapFilterMode {
390 fn convert(self) -> wgpu_types::MipmapFilterMode {
391 match self {
392 GPUMipmapFilterMode::Nearest => wgpu_types::MipmapFilterMode::Nearest,
393 GPUMipmapFilterMode::Linear => wgpu_types::MipmapFilterMode::Linear,
394 }
395 }
396}
397
398impl Convert<wgpu_types::TextureViewDimension> for GPUTextureViewDimension {
399 fn convert(self) -> wgpu_types::TextureViewDimension {
400 match self {
401 GPUTextureViewDimension::_1d => wgpu_types::TextureViewDimension::D1,
402 GPUTextureViewDimension::_2d => wgpu_types::TextureViewDimension::D2,
403 GPUTextureViewDimension::_2d_array => wgpu_types::TextureViewDimension::D2Array,
404 GPUTextureViewDimension::Cube => wgpu_types::TextureViewDimension::Cube,
405 GPUTextureViewDimension::Cube_array => wgpu_types::TextureViewDimension::CubeArray,
406 GPUTextureViewDimension::_3d => wgpu_types::TextureViewDimension::D3,
407 }
408 }
409}
410
411impl Convert<wgpu_types::CompareFunction> for GPUCompareFunction {
412 fn convert(self) -> wgpu_types::CompareFunction {
413 match self {
414 GPUCompareFunction::Never => wgpu_types::CompareFunction::Never,
415 GPUCompareFunction::Less => wgpu_types::CompareFunction::Less,
416 GPUCompareFunction::Equal => wgpu_types::CompareFunction::Equal,
417 GPUCompareFunction::Less_equal => wgpu_types::CompareFunction::LessEqual,
418 GPUCompareFunction::Greater => wgpu_types::CompareFunction::Greater,
419 GPUCompareFunction::Not_equal => wgpu_types::CompareFunction::NotEqual,
420 GPUCompareFunction::Greater_equal => wgpu_types::CompareFunction::GreaterEqual,
421 GPUCompareFunction::Always => wgpu_types::CompareFunction::Always,
422 }
423 }
424}
425
426impl Convert<wgpu_types::BlendFactor> for &GPUBlendFactor {
427 fn convert(self) -> wgpu_types::BlendFactor {
428 match self {
429 GPUBlendFactor::Zero => wgpu_types::BlendFactor::Zero,
430 GPUBlendFactor::One => wgpu_types::BlendFactor::One,
431 GPUBlendFactor::Src => wgpu_types::BlendFactor::Src,
432 GPUBlendFactor::One_minus_src => wgpu_types::BlendFactor::OneMinusSrc,
433 GPUBlendFactor::Src_alpha => wgpu_types::BlendFactor::SrcAlpha,
434 GPUBlendFactor::One_minus_src_alpha => wgpu_types::BlendFactor::OneMinusSrcAlpha,
435 GPUBlendFactor::Dst => wgpu_types::BlendFactor::Dst,
436 GPUBlendFactor::One_minus_dst => wgpu_types::BlendFactor::OneMinusDst,
437 GPUBlendFactor::Dst_alpha => wgpu_types::BlendFactor::DstAlpha,
438 GPUBlendFactor::One_minus_dst_alpha => wgpu_types::BlendFactor::OneMinusDstAlpha,
439 GPUBlendFactor::Src_alpha_saturated => wgpu_types::BlendFactor::SrcAlphaSaturated,
440 GPUBlendFactor::Constant => wgpu_types::BlendFactor::Constant,
441 GPUBlendFactor::One_minus_constant => wgpu_types::BlendFactor::OneMinusConstant,
442 GPUBlendFactor::Src1 => wgpu_types::BlendFactor::Src1,
443 GPUBlendFactor::One_minus_src1 => wgpu_types::BlendFactor::OneMinusSrc1,
444 GPUBlendFactor::Src1_alpha => wgpu_types::BlendFactor::Src1Alpha,
445 GPUBlendFactor::One_minus_src1_alpha => wgpu_types::BlendFactor::OneMinusSrc1Alpha,
446 }
447 }
448}
449
450impl Convert<wgpu_types::BlendComponent> for &GPUBlendComponent {
451 fn convert(self) -> wgpu_types::BlendComponent {
452 wgpu_types::BlendComponent {
453 src_factor: self.srcFactor.convert(),
454 dst_factor: self.dstFactor.convert(),
455 operation: match self.operation {
456 GPUBlendOperation::Add => wgpu_types::BlendOperation::Add,
457 GPUBlendOperation::Subtract => wgpu_types::BlendOperation::Subtract,
458 GPUBlendOperation::Reverse_subtract => wgpu_types::BlendOperation::ReverseSubtract,
459 GPUBlendOperation::Min => wgpu_types::BlendOperation::Min,
460 GPUBlendOperation::Max => wgpu_types::BlendOperation::Max,
461 },
462 }
463 }
464}
465
466pub(crate) fn convert_load_op<T>(load: &GPULoadOp, clear: T) -> wgpu_com::LoadOp<T> {
467 match load {
468 GPULoadOp::Load => wgpu_com::LoadOp::Load,
469 GPULoadOp::Clear => wgpu_com::LoadOp::Clear(clear),
470 }
471}
472
473impl Convert<wgpu_com::StoreOp> for &GPUStoreOp {
474 fn convert(self) -> wgpu_com::StoreOp {
475 match self {
476 GPUStoreOp::Store => wgpu_com::StoreOp::Store,
477 GPUStoreOp::Discard => wgpu_com::StoreOp::Discard,
478 }
479 }
480}
481
482impl Convert<wgpu_types::StencilOperation> for GPUStencilOperation {
483 fn convert(self) -> wgpu_types::StencilOperation {
484 match self {
485 GPUStencilOperation::Keep => wgpu_types::StencilOperation::Keep,
486 GPUStencilOperation::Zero => wgpu_types::StencilOperation::Zero,
487 GPUStencilOperation::Replace => wgpu_types::StencilOperation::Replace,
488 GPUStencilOperation::Invert => wgpu_types::StencilOperation::Invert,
489 GPUStencilOperation::Increment_clamp => wgpu_types::StencilOperation::IncrementClamp,
490 GPUStencilOperation::Decrement_clamp => wgpu_types::StencilOperation::DecrementClamp,
491 GPUStencilOperation::Increment_wrap => wgpu_types::StencilOperation::IncrementWrap,
492 GPUStencilOperation::Decrement_wrap => wgpu_types::StencilOperation::DecrementWrap,
493 }
494 }
495}
496
497impl Convert<wgpu_com::TexelCopyBufferInfo> for &GPUTexelCopyBufferInfo {
498 fn convert(self) -> wgpu_com::TexelCopyBufferInfo {
499 wgpu_com::TexelCopyBufferInfo {
500 buffer: self.buffer.id().0,
501 layout: self.parent.convert(),
502 }
503 }
504}
505
506impl TryConvert<wgpu_types::Origin3d> for &GPUOrigin3D {
507 type Error = Error;
508
509 fn try_convert(self) -> Result<wgpu_types::Origin3d, Self::Error> {
510 match self {
511 GPUOrigin3D::RangeEnforcedUnsignedLongSequence(v) => {
512 if v.len() > 3 {
514 Err(Error::Type(
515 c"sequence is too long for GPUOrigin3D".to_owned(),
516 ))
517 } else {
518 Ok(wgpu_types::Origin3d {
519 x: v.first().copied().unwrap_or(0),
520 y: v.get(1).copied().unwrap_or(0),
521 z: v.get(2).copied().unwrap_or(0),
522 })
523 }
524 },
525 GPUOrigin3D::GPUOrigin3DDict(d) => Ok(wgpu_types::Origin3d {
526 x: d.x,
527 y: d.y,
528 z: d.z,
529 }),
530 }
531 }
532}
533
534impl TryConvert<wgpu_types::Origin2d> for &GPUOrigin2D {
535 type Error = Error;
536
537 fn try_convert(self) -> Result<wgpu_types::Origin2d, Self::Error> {
539 match self {
540 GPUOrigin2D::RangeEnforcedUnsignedLongSequence(v) => {
541 if v.len() > 2 {
542 Err(Error::Type(
543 c"sequence is too long for GPUOrigin2D".to_owned(),
544 ))
545 } else {
546 Ok(wgpu_types::Origin2d {
547 x: v.first().copied().unwrap_or(0),
548 y: v.get(1).copied().unwrap_or(0),
549 })
550 }
551 },
552 GPUOrigin2D::GPUOrigin2DDict(d) => Ok(wgpu_types::Origin2d { x: d.x, y: d.y }),
553 }
554 }
555}
556
557impl TryConvert<wgpu_com::TexelCopyTextureInfo> for &GPUTexelCopyTextureInfo {
558 type Error = Error;
559
560 fn try_convert(self) -> Result<wgpu_com::TexelCopyTextureInfo, Self::Error> {
561 Ok(wgpu_com::TexelCopyTextureInfo {
562 texture: self.texture.id().0,
563 mip_level: self.mipLevel,
564 origin: self
565 .origin
566 .as_ref()
567 .map(TryConvert::<wgpu_types::Origin3d>::try_convert)
568 .transpose()?
569 .unwrap_or_default(),
570 aspect: match self.aspect {
571 GPUTextureAspect::All => wgpu_types::TextureAspect::All,
572 GPUTextureAspect::Stencil_only => wgpu_types::TextureAspect::StencilOnly,
573 GPUTextureAspect::Depth_only => wgpu_types::TextureAspect::DepthOnly,
574 },
575 })
576 }
577}
578
579impl<'a> Convert<Option<Cow<'a, str>>> for &GPUObjectDescriptorBase {
580 fn convert(self) -> Option<Cow<'a, str>> {
581 if self.label.is_empty() {
582 None
583 } else {
584 Some(Cow::Owned(self.label.to_string()))
585 }
586 }
587}
588
589pub(crate) fn convert_bind_group_layout_entry(
590 bgle: &GPUBindGroupLayoutEntry,
591 device: &GPUDevice,
592) -> Fallible<Result<wgpu_types::BindGroupLayoutEntry, webgpu_traits::Error>> {
593 let number_of_provided_bindings = bgle.buffer.is_some() as u8 +
594 bgle.sampler.is_some() as u8 +
595 bgle.storageTexture.is_some() as u8 +
596 bgle.texture.is_some() as u8;
597 let ty = if let Some(buffer) = &bgle.buffer {
598 Some(wgpu_types::BindingType::Buffer {
599 ty: match buffer.type_ {
600 GPUBufferBindingType::Uniform => wgpu_types::BufferBindingType::Uniform,
601 GPUBufferBindingType::Storage => {
602 wgpu_types::BufferBindingType::Storage { read_only: false }
603 },
604 GPUBufferBindingType::Read_only_storage => {
605 wgpu_types::BufferBindingType::Storage { read_only: true }
606 },
607 },
608 has_dynamic_offset: buffer.hasDynamicOffset,
609 min_binding_size: NonZeroU64::new(buffer.minBindingSize),
610 })
611 } else if let Some(sampler) = &bgle.sampler {
612 Some(wgpu_types::BindingType::Sampler(match sampler.type_ {
613 GPUSamplerBindingType::Filtering => wgpu_types::SamplerBindingType::Filtering,
614 GPUSamplerBindingType::Non_filtering => wgpu_types::SamplerBindingType::NonFiltering,
615 GPUSamplerBindingType::Comparison => wgpu_types::SamplerBindingType::Comparison,
616 }))
617 } else if let Some(storage) = &bgle.storageTexture {
618 Some(wgpu_types::BindingType::StorageTexture {
619 access: match storage.access {
620 GPUStorageTextureAccess::Write_only => wgpu_types::StorageTextureAccess::WriteOnly,
621 GPUStorageTextureAccess::Read_only => wgpu_types::StorageTextureAccess::ReadOnly,
622 GPUStorageTextureAccess::Read_write => wgpu_types::StorageTextureAccess::ReadWrite,
623 },
624 format: device.validate_texture_format_required_features(&storage.format)?,
625 view_dimension: storage.viewDimension.convert(),
626 })
627 } else if let Some(texture) = &bgle.texture {
628 Some(wgpu_types::BindingType::Texture {
629 sample_type: match texture.sampleType {
630 GPUTextureSampleType::Float => {
631 wgpu_types::TextureSampleType::Float { filterable: true }
632 },
633 GPUTextureSampleType::Unfilterable_float => {
634 wgpu_types::TextureSampleType::Float { filterable: false }
635 },
636 GPUTextureSampleType::Depth => wgpu_types::TextureSampleType::Depth,
637 GPUTextureSampleType::Sint => wgpu_types::TextureSampleType::Sint,
638 GPUTextureSampleType::Uint => wgpu_types::TextureSampleType::Uint,
639 },
640 view_dimension: texture.viewDimension.convert(),
641 multisampled: texture.multisampled,
642 })
643 } else {
644 assert_eq!(number_of_provided_bindings, 0);
645 None
646 };
647 let ty = if number_of_provided_bindings != 1 {
650 None
651 } else {
652 ty
653 }
654 .ok_or(webgpu_traits::Error::Validation(
655 "Exactly on entry type must be provided".to_string(),
656 ));
657
658 Ok(ty.map(|ty| wgpu_types::BindGroupLayoutEntry {
659 binding: bgle.binding,
660 visibility: wgpu_types::ShaderStages::from_bits_retain(bgle.visibility),
661 ty,
662 count: None,
663 }))
664}
665
666pub(crate) fn convert_texture_descriptor(
667 descriptor: &GPUTextureDescriptor,
668 device: &GPUDevice,
669) -> Fallible<(TextureDescriptor<'static>, wgpu_types::Extent3d)> {
670 let size = (&descriptor.size).try_convert()?;
671 let desc = TextureDescriptor {
672 label: (&descriptor.parent).convert(),
673 size,
674 mip_level_count: descriptor.mipLevelCount,
675 sample_count: descriptor.sampleCount,
676 dimension: descriptor.dimension.convert(),
677 format: device.validate_texture_format_required_features(&descriptor.format)?,
678 usage: wgpu_types::TextureUsages::from_bits_retain(descriptor.usage),
679 view_formats: descriptor
680 .viewFormats
681 .iter()
682 .map(|tf| device.validate_texture_format_required_features(tf))
683 .collect::<Fallible<_>>()?,
684 };
685 Ok((desc, size))
686}
687
688impl TryConvert<wgpu_types::Color> for &GPUColor {
689 type Error = Error;
690
691 fn try_convert(self) -> Result<wgpu_types::Color, Self::Error> {
692 match self {
693 GPUColor::DoubleSequence(s) => {
694 if s.len() != 4 {
696 Err(Error::Type(c"GPUColor sequence must be len 4".to_owned()))
697 } else {
698 Ok(wgpu_types::Color {
699 r: *s[0],
700 g: *s[1],
701 b: *s[2],
702 a: *s[3],
703 })
704 }
705 },
706 GPUColor::GPUColorDict(d) => Ok(wgpu_types::Color {
707 r: *d.r,
708 g: *d.g,
709 b: *d.b,
710 a: *d.a,
711 }),
712 }
713 }
714}
715
716impl<'a> Convert<ProgrammableStageDescriptor<'a>> for &GPUProgrammableStage {
717 fn convert(self) -> ProgrammableStageDescriptor<'a> {
718 ProgrammableStageDescriptor {
719 module: self.module.id().0,
720 entry_point: self
721 .entryPoint
722 .as_ref()
723 .map(|ep| Cow::Owned(ep.to_string())),
724 constants: self
725 .constants
726 .as_ref()
727 .map(|records| records.iter().map(|(k, v)| (k.0.clone(), **v)).collect())
728 .unwrap_or_default(),
729 zero_initialize_workgroup_memory: true,
730 }
731 }
732}
733
734pub(crate) fn convert_texture_for_wgpu_with_cx(
735 cx: &mut JSContext,
736 texture_view: &GPUTextureOrGPUTextureView,
737) -> WebGPUTextureView {
738 match texture_view {
739 GPUTextureOrGPUTextureView::GPUTextureView(view) => view.id(),
740 GPUTextureOrGPUTextureView::GPUTexture(texture) => texture.get_default_view(cx),
741 }
742}
743
744pub(crate) fn convert_bind_group_entry<'a>(
745 cx: &mut JSContext,
746 bind_group: &GPUBindGroupEntry,
747) -> BindGroupEntry<'a> {
748 BindGroupEntry {
749 binding: bind_group.binding,
750 resource: match bind_group.resource {
751 GPUBindingResource::GPUSampler(ref s) => BindingResource::Sampler(s.id().0),
752 GPUBindingResource::GPUTextureView(ref t) => BindingResource::TextureView(t.id().0),
753 GPUBindingResource::GPUTexture(ref t) => {
754 BindingResource::TextureView(t.get_default_view(cx).0)
755 },
756 GPUBindingResource::GPUBufferBinding(ref b) => BindingResource::Buffer(BufferBinding {
757 buffer: b.buffer.id().0,
758 offset: b.offset,
759 size: b.size,
760 }),
761 GPUBindingResource::GPUBuffer(ref b) => BindingResource::Buffer(BufferBinding {
762 buffer: b.id().0,
763 offset: 0,
764 size: None,
765 }),
766 GPUBindingResource::GPUExternalTexture(ref t) => {
767 BindingResource::ExternalTexture(t.id().0)
768 },
769 },
770 }
771}
772
773impl Convert<wgpu_types::TextureDimension> for GPUTextureDimension {
774 fn convert(self) -> wgpu_types::TextureDimension {
775 match self {
776 GPUTextureDimension::_1d => wgpu_types::TextureDimension::D1,
777 GPUTextureDimension::_2d => wgpu_types::TextureDimension::D2,
778 GPUTextureDimension::_3d => wgpu_types::TextureDimension::D3,
779 }
780 }
781}
782
783impl Convert<wgpu_types::PredefinedColorSpace> for PredefinedColorSpace {
784 fn convert(self) -> wgpu_types::PredefinedColorSpace {
785 match self {
786 PredefinedColorSpace::Srgb => wgpu_types::PredefinedColorSpace::Srgb,
787 }
788 }
789}
790
791impl Convert<QuerySetDescriptor<'static>> for &GPUQuerySetDescriptor {
792 fn convert(self) -> QuerySetDescriptor<'static> {
793 QuerySetDescriptor {
794 label: (&self.parent).convert(),
795 count: self.count,
796 ty: match self.type_ {
797 GPUQueryType::Occlusion => wgpu_types::QueryType::Occlusion,
798 GPUQueryType::Timestamp => wgpu_types::QueryType::Timestamp,
799 },
800 }
801 }
802}
803
804impl Convert<PassTimestampWrites> for &GPUComputePassTimestampWrites {
805 fn convert(self) -> PassTimestampWrites {
806 PassTimestampWrites {
807 query_set: self.querySet.id().0,
808 beginning_of_pass_write_index: self.beginningOfPassWriteIndex,
809 end_of_pass_write_index: self.endOfPassWriteIndex,
810 }
811 }
812}
813
814impl Convert<PassTimestampWrites> for &GPURenderPassTimestampWrites {
815 fn convert(self) -> PassTimestampWrites {
816 PassTimestampWrites {
817 query_set: self.querySet.id().0,
818 beginning_of_pass_write_index: self.beginningOfPassWriteIndex,
819 end_of_pass_write_index: self.endOfPassWriteIndex,
820 }
821 }
822}
823
824impl Convert<ComputePassDescriptor<'static>> for &GPUComputePassDescriptor {
825 fn convert(self) -> ComputePassDescriptor<'static> {
826 ComputePassDescriptor {
827 label: (&self.parent).convert(),
828 timestamp_writes: self.timestampWrites.as_ref().map(Convert::convert),
829 }
830 }
831}