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