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