Skip to main content

script_webgpu/
gpuconvert.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use 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
40/// A version of the `Into<T>` trait from the standard library that can be used
41/// to convert between two types that are not defined in the script crate.
42/// This is intended to be used on dict/enum types generated from WebIDL once
43/// those types are moved out of the script crate.
44/// Only for WebGPU.
45pub trait WebGPUConvert<T> {
46    fn convert(self) -> T;
47}
48
49/// A version of the `TryInto<T>` trait from the standard library that can be used
50/// to convert between two types that are not defined in the script crate.
51/// This is intended to be used on dict/enum types generated from WebIDL once
52/// those types are moved out of the script crate.
53/// Only for WebGPU.
54pub 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            // 8-bit formats
64            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            // 16-bit formats
69            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            // 32-bit formats
79            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            // Packed 32-bit formats
95            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            // 64-bit formats
100            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            // 96-bit formats
109            GPUTextureFormat::Rgba32uint => wgpu_types::TextureFormat::Rgba32Uint,
110            GPUTextureFormat::Rgba32sint => wgpu_types::TextureFormat::Rgba32Sint,
111            GPUTextureFormat::Rgba32float => wgpu_types::TextureFormat::Rgba32Float,
112            // Depth/stencil formats
113            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            // "depth32float-stencil8" feature
121            GPUTextureFormat::Depth32float_stencil8 => {
122                wgpu_types::TextureFormat::Depth32FloatStencil8
123            },
124            // BC compressed formats usable if "texture-compression-bc" is both
125            // supported by the device/user agent and enabled in requestDevice.
126            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            // ETC2 compressed formats usable if "texture-compression-etc2" is both
141            // supported by the device/user agent and enabled in requestDevice.
142            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            // ASTC compressed formats usable if "texture-compression-astc" is both
155            // supported by the device/user agent and enabled in requestDevice.
156            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                // https://gpuweb.github.io/gpuweb/#abstract-opdef-validate-gpuextent3d-shape
284                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                // https://gpuweb.github.io/gpuweb/#abstract-opdef-validate-gpuorigin3d-shape
544                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    /// <https://gpuweb.github.io/gpuweb/#abstract-opdef-validate-gpuorigin2d-shape>
569    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    // Check for number of bindings should actually be done in device-timeline,
687    // but we do it last on content-timeline to have some visible effect
688    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                // https://gpuweb.github.io/gpuweb/#abstract-opdef-validate-gpucolor-shape
738                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}