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