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