• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The Dawn Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/dawn_node/binding/Converter.h"
16 
17 #include "src/dawn_node/binding/GPUBuffer.h"
18 #include "src/dawn_node/binding/GPUPipelineLayout.h"
19 #include "src/dawn_node/binding/GPUSampler.h"
20 #include "src/dawn_node/binding/GPUShaderModule.h"
21 #include "src/dawn_node/binding/GPUTexture.h"
22 #include "src/dawn_node/binding/GPUTextureView.h"
23 #include "src/dawn_node/utils/Debug.h"
24 
25 namespace wgpu { namespace binding {
26 
~Converter()27     Converter::~Converter() {
28         for (auto& free : free_) {
29             free();
30         }
31     }
32 
Convert(wgpu::Extent3D & out,const interop::GPUExtent3D & in)33     bool Converter::Convert(wgpu::Extent3D& out, const interop::GPUExtent3D& in) {
34         out = {};
35         if (auto* dict = std::get_if<interop::GPUExtent3DDict>(&in)) {
36             out.depthOrArrayLayers = dict->depthOrArrayLayers;
37             out.width = dict->width;
38             out.height = dict->height;
39             return true;
40         }
41         if (auto* vec = std::get_if<std::vector<interop::GPUIntegerCoordinate>>(&in)) {
42             switch (vec->size()) {
43                 default:
44                 case 3:
45                     out.depthOrArrayLayers = (*vec)[2];
46                 case 2:  // fallthrough
47                     out.height = (*vec)[1];
48                 case 1:  // fallthrough
49                     out.width = (*vec)[0];
50                     return true;
51                 case 0:
52                     break;
53             }
54         }
55         Napi::Error::New(env, "invalid value for GPUExtent3D").ThrowAsJavaScriptException();
56         return false;
57     }
58 
Convert(wgpu::Origin3D & out,const interop::GPUOrigin3DDict & in)59     bool Converter::Convert(wgpu::Origin3D& out, const interop::GPUOrigin3DDict& in) {
60         out = {};
61         out.x = in.x;
62         out.y = in.y;
63         out.z = in.z;
64         return true;
65     }
66 
Convert(wgpu::Color & out,const interop::GPUColor & in)67     bool Converter::Convert(wgpu::Color& out, const interop::GPUColor& in) {
68         out = {};
69         if (auto* dict = std::get_if<interop::GPUColorDict>(&in)) {
70             out.r = dict->r;
71             out.g = dict->g;
72             out.b = dict->b;
73             out.a = dict->a;
74             return true;
75         }
76         if (auto* vec = std::get_if<std::vector<double>>(&in)) {
77             switch (vec->size()) {
78                 default:
79                 case 4:
80                     out.a = (*vec)[3];
81                 case 3:  // fallthrough
82                     out.b = (*vec)[2];
83                 case 2:  // fallthrough
84                     out.g = (*vec)[1];
85                 case 1:  // fallthrough
86                     out.r = (*vec)[0];
87                     return true;
88                 case 0:
89                     break;
90             }
91         }
92         Napi::Error::New(env, "invalid value for GPUColor").ThrowAsJavaScriptException();
93         return false;
94     }
95 
Convert(wgpu::Origin3D & out,const std::vector<interop::GPUIntegerCoordinate> & in)96     bool Converter::Convert(wgpu::Origin3D& out,
97                             const std::vector<interop::GPUIntegerCoordinate>& in) {
98         out = {};
99         switch (in.size()) {
100             default:
101             case 3:
102                 out.z = in[2];
103             case 2:  // fallthrough
104                 out.y = in[1];
105             case 1:  // fallthrough
106                 out.x = in[0];
107             case 0:
108                 break;
109         }
110         return true;
111     }
112 
Convert(wgpu::TextureAspect & out,const interop::GPUTextureAspect & in)113     bool Converter::Convert(wgpu::TextureAspect& out, const interop::GPUTextureAspect& in) {
114         out = wgpu::TextureAspect::All;
115         switch (in) {
116             case interop::GPUTextureAspect::kAll:
117                 out = wgpu::TextureAspect::All;
118                 return true;
119             case interop::GPUTextureAspect::kStencilOnly:
120                 out = wgpu::TextureAspect::StencilOnly;
121                 return true;
122             case interop::GPUTextureAspect::kDepthOnly:
123                 out = wgpu::TextureAspect::DepthOnly;
124                 return true;
125         }
126         Napi::Error::New(env, "invalid value for GPUTextureAspect").ThrowAsJavaScriptException();
127         return false;
128     }
129 
Convert(wgpu::ImageCopyTexture & out,const interop::GPUImageCopyTexture & in)130     bool Converter::Convert(wgpu::ImageCopyTexture& out, const interop::GPUImageCopyTexture& in) {
131         out = {};
132         return Convert(out.texture, in.texture) && Convert(out.mipLevel, in.mipLevel) &&
133                Convert(out.origin, in.origin) && Convert(out.aspect, in.aspect);
134     }
135 
Convert(wgpu::ImageCopyBuffer & out,const interop::GPUImageCopyBuffer & in)136     bool Converter::Convert(wgpu::ImageCopyBuffer& out, const interop::GPUImageCopyBuffer& in) {
137         out = {};
138         out.buffer = *in.buffer.As<GPUBuffer>();
139         return Convert(out.layout.offset, in.offset) &&
140                Convert(out.layout.bytesPerRow, in.bytesPerRow) &&
141                Convert(out.layout.rowsPerImage, in.rowsPerImage);
142     }
143 
Convert(BufferSource & out,interop::BufferSource in)144     bool Converter::Convert(BufferSource& out, interop::BufferSource in) {
145         out = {};
146         if (auto* view = std::get_if<interop::ArrayBufferView>(&in)) {
147             std::visit(
148                 [&](auto&& v) {
149                     auto arr = v.ArrayBuffer();
150                     out.data = arr.Data();
151                     out.size = arr.ByteLength();
152                 },
153                 *view);
154             return true;
155         }
156         if (auto* arr = std::get_if<interop::ArrayBuffer>(&in)) {
157             out.data = arr->Data();
158             out.size = arr->ByteLength();
159             return true;
160         }
161         Napi::Error::New(env, "invalid value for BufferSource").ThrowAsJavaScriptException();
162         return false;
163     }
164 
Convert(wgpu::TextureDataLayout & out,const interop::GPUImageDataLayout & in)165     bool Converter::Convert(wgpu::TextureDataLayout& out, const interop::GPUImageDataLayout& in) {
166         out = {};
167         return Convert(out.bytesPerRow, in.bytesPerRow) && Convert(out.offset, in.offset) &&
168                Convert(out.rowsPerImage, in.rowsPerImage);
169     }
170 
Convert(wgpu::TextureFormat & out,const interop::GPUTextureFormat & in)171     bool Converter::Convert(wgpu::TextureFormat& out, const interop::GPUTextureFormat& in) {
172         out = wgpu::TextureFormat::Undefined;
173         switch (in) {
174             case interop::GPUTextureFormat::kR8Unorm:
175                 out = wgpu::TextureFormat::R8Unorm;
176                 return true;
177             case interop::GPUTextureFormat::kR8Snorm:
178                 out = wgpu::TextureFormat::R8Snorm;
179                 return true;
180             case interop::GPUTextureFormat::kR8Uint:
181                 out = wgpu::TextureFormat::R8Uint;
182                 return true;
183             case interop::GPUTextureFormat::kR8Sint:
184                 out = wgpu::TextureFormat::R8Sint;
185                 return true;
186             case interop::GPUTextureFormat::kR16Uint:
187                 out = wgpu::TextureFormat::R16Uint;
188                 return true;
189             case interop::GPUTextureFormat::kR16Sint:
190                 out = wgpu::TextureFormat::R16Sint;
191                 return true;
192             case interop::GPUTextureFormat::kR16Float:
193                 out = wgpu::TextureFormat::R16Float;
194                 return true;
195             case interop::GPUTextureFormat::kRg8Unorm:
196                 out = wgpu::TextureFormat::RG8Unorm;
197                 return true;
198             case interop::GPUTextureFormat::kRg8Snorm:
199                 out = wgpu::TextureFormat::RG8Snorm;
200                 return true;
201             case interop::GPUTextureFormat::kRg8Uint:
202                 out = wgpu::TextureFormat::RG8Uint;
203                 return true;
204             case interop::GPUTextureFormat::kRg8Sint:
205                 out = wgpu::TextureFormat::RG8Sint;
206                 return true;
207             case interop::GPUTextureFormat::kR32Uint:
208                 out = wgpu::TextureFormat::R32Uint;
209                 return true;
210             case interop::GPUTextureFormat::kR32Sint:
211                 out = wgpu::TextureFormat::R32Sint;
212                 return true;
213             case interop::GPUTextureFormat::kR32Float:
214                 out = wgpu::TextureFormat::R32Float;
215                 return true;
216             case interop::GPUTextureFormat::kRg16Uint:
217                 out = wgpu::TextureFormat::RG16Uint;
218                 return true;
219             case interop::GPUTextureFormat::kRg16Sint:
220                 out = wgpu::TextureFormat::RG16Sint;
221                 return true;
222             case interop::GPUTextureFormat::kRg16Float:
223                 out = wgpu::TextureFormat::RG16Float;
224                 return true;
225             case interop::GPUTextureFormat::kRgba8Unorm:
226                 out = wgpu::TextureFormat::RGBA8Unorm;
227                 return true;
228             case interop::GPUTextureFormat::kRgba8UnormSrgb:
229                 out = wgpu::TextureFormat::RGBA8UnormSrgb;
230                 return true;
231             case interop::GPUTextureFormat::kRgba8Snorm:
232                 out = wgpu::TextureFormat::RGBA8Snorm;
233                 return true;
234             case interop::GPUTextureFormat::kRgba8Uint:
235                 out = wgpu::TextureFormat::RGBA8Uint;
236                 return true;
237             case interop::GPUTextureFormat::kRgba8Sint:
238                 out = wgpu::TextureFormat::RGBA8Sint;
239                 return true;
240             case interop::GPUTextureFormat::kBgra8Unorm:
241                 out = wgpu::TextureFormat::BGRA8Unorm;
242                 return true;
243             case interop::GPUTextureFormat::kBgra8UnormSrgb:
244                 out = wgpu::TextureFormat::BGRA8UnormSrgb;
245                 return true;
246             case interop::GPUTextureFormat::kRgb9E5Ufloat:
247                 out = wgpu::TextureFormat::RGB9E5Ufloat;
248                 return true;
249             case interop::GPUTextureFormat::kRgb10A2Unorm:
250                 out = wgpu::TextureFormat::RGB10A2Unorm;
251                 return true;
252             case interop::GPUTextureFormat::kRg11B10Ufloat:
253                 out = wgpu::TextureFormat::RG11B10Ufloat;
254                 return true;
255             case interop::GPUTextureFormat::kRg32Uint:
256                 out = wgpu::TextureFormat::RG32Uint;
257                 return true;
258             case interop::GPUTextureFormat::kRg32Sint:
259                 out = wgpu::TextureFormat::RG32Sint;
260                 return true;
261             case interop::GPUTextureFormat::kRg32Float:
262                 out = wgpu::TextureFormat::RG32Float;
263                 return true;
264             case interop::GPUTextureFormat::kRgba16Uint:
265                 out = wgpu::TextureFormat::RGBA16Uint;
266                 return true;
267             case interop::GPUTextureFormat::kRgba16Sint:
268                 out = wgpu::TextureFormat::RGBA16Sint;
269                 return true;
270             case interop::GPUTextureFormat::kRgba16Float:
271                 out = wgpu::TextureFormat::RGBA16Float;
272                 return true;
273             case interop::GPUTextureFormat::kRgba32Uint:
274                 out = wgpu::TextureFormat::RGBA32Uint;
275                 return true;
276             case interop::GPUTextureFormat::kRgba32Sint:
277                 out = wgpu::TextureFormat::RGBA32Sint;
278                 return true;
279             case interop::GPUTextureFormat::kRgba32Float:
280                 out = wgpu::TextureFormat::RGBA32Float;
281                 return true;
282             case interop::GPUTextureFormat::kStencil8:
283                 out = wgpu::TextureFormat::Stencil8;
284                 return true;
285             case interop::GPUTextureFormat::kDepth16Unorm:
286                 break;  // TODO(crbug.com/dawn/1130): Unsupported.
287             case interop::GPUTextureFormat::kDepth24Plus:
288                 out = wgpu::TextureFormat::Depth24Plus;
289                 return true;
290             case interop::GPUTextureFormat::kDepth24PlusStencil8:
291                 out = wgpu::TextureFormat::Depth24PlusStencil8;
292                 return true;
293             case interop::GPUTextureFormat::kDepth32Float:
294                 out = wgpu::TextureFormat::Depth32Float;
295                 return true;
296             case interop::GPUTextureFormat::kBc1RgbaUnorm:
297                 out = wgpu::TextureFormat::BC1RGBAUnorm;
298                 return true;
299             case interop::GPUTextureFormat::kBc1RgbaUnormSrgb:
300                 out = wgpu::TextureFormat::BC1RGBAUnormSrgb;
301                 return true;
302             case interop::GPUTextureFormat::kBc2RgbaUnorm:
303                 out = wgpu::TextureFormat::BC2RGBAUnorm;
304                 return true;
305             case interop::GPUTextureFormat::kBc2RgbaUnormSrgb:
306                 out = wgpu::TextureFormat::BC2RGBAUnormSrgb;
307                 return true;
308             case interop::GPUTextureFormat::kBc3RgbaUnorm:
309                 out = wgpu::TextureFormat::BC3RGBAUnorm;
310                 return true;
311             case interop::GPUTextureFormat::kBc3RgbaUnormSrgb:
312                 out = wgpu::TextureFormat::BC3RGBAUnormSrgb;
313                 return true;
314             case interop::GPUTextureFormat::kBc4RUnorm:
315                 out = wgpu::TextureFormat::BC4RUnorm;
316                 return true;
317             case interop::GPUTextureFormat::kBc4RSnorm:
318                 out = wgpu::TextureFormat::BC4RSnorm;
319                 return true;
320             case interop::GPUTextureFormat::kBc5RgUnorm:
321                 out = wgpu::TextureFormat::BC5RGUnorm;
322                 return true;
323             case interop::GPUTextureFormat::kBc5RgSnorm:
324                 out = wgpu::TextureFormat::BC5RGSnorm;
325                 return true;
326             case interop::GPUTextureFormat::kBc6HRgbUfloat:
327                 out = wgpu::TextureFormat::BC6HRGBUfloat;
328                 return true;
329             case interop::GPUTextureFormat::kBc6HRgbFloat:
330                 out = wgpu::TextureFormat::BC6HRGBFloat;
331                 return true;
332             case interop::GPUTextureFormat::kBc7RgbaUnorm:
333                 out = wgpu::TextureFormat::BC7RGBAUnorm;
334                 return true;
335             case interop::GPUTextureFormat::kBc7RgbaUnormSrgb:
336                 out = wgpu::TextureFormat::BC7RGBAUnormSrgb;
337                 return true;
338             case interop::GPUTextureFormat::kDepth24UnormStencil8:
339                 break;  // TODO(crbug.com/dawn/1130): Unsupported.
340             case interop::GPUTextureFormat::kDepth32FloatStencil8:
341                 break;  // TODO(crbug.com/dawn/1130): Unsupported.
342         }
343         // TODO(crbug.com/dawn/1130): Add ASTC and ETC formats.
344         Napi::Error::New(env, "invalid value for GPUTextureFormat").ThrowAsJavaScriptException();
345         return false;
346     }
347 
Convert(wgpu::TextureUsage & out,const interop::GPUTextureUsageFlags & in)348     bool Converter::Convert(wgpu::TextureUsage& out, const interop::GPUTextureUsageFlags& in) {
349         out = static_cast<wgpu::TextureUsage>(in);
350         return true;
351     }
352 
Convert(wgpu::ColorWriteMask & out,const interop::GPUColorWriteFlags & in)353     bool Converter::Convert(wgpu::ColorWriteMask& out, const interop::GPUColorWriteFlags& in) {
354         out = static_cast<wgpu::ColorWriteMask>(in);
355         return true;
356     }
357 
Convert(wgpu::BufferUsage & out,const interop::GPUBufferUsageFlags & in)358     bool Converter::Convert(wgpu::BufferUsage& out, const interop::GPUBufferUsageFlags& in) {
359         out = static_cast<wgpu::BufferUsage>(in);
360         return true;
361     }
362 
Convert(wgpu::MapMode & out,const interop::GPUMapModeFlags & in)363     bool Converter::Convert(wgpu::MapMode& out, const interop::GPUMapModeFlags& in) {
364         out = static_cast<wgpu::MapMode>(in);
365         return true;
366     }
367 
Convert(wgpu::ShaderStage & out,const interop::GPUShaderStageFlags & in)368     bool Converter::Convert(wgpu::ShaderStage& out, const interop::GPUShaderStageFlags& in) {
369         out = static_cast<wgpu::ShaderStage>(in);
370         return true;
371     }
372 
Convert(wgpu::TextureDimension & out,const interop::GPUTextureDimension & in)373     bool Converter::Convert(wgpu::TextureDimension& out, const interop::GPUTextureDimension& in) {
374         out = wgpu::TextureDimension::e1D;
375         switch (in) {
376             case interop::GPUTextureDimension::k1D:
377                 out = wgpu::TextureDimension::e1D;
378                 return true;
379             case interop::GPUTextureDimension::k2D:
380                 out = wgpu::TextureDimension::e2D;
381                 return true;
382             case interop::GPUTextureDimension::k3D:
383                 out = wgpu::TextureDimension::e3D;
384                 return true;
385         }
386         Napi::Error::New(env, "invalid value for GPUTextureDimension").ThrowAsJavaScriptException();
387         return false;
388     }
389 
Convert(wgpu::TextureViewDimension & out,const interop::GPUTextureViewDimension & in)390     bool Converter::Convert(wgpu::TextureViewDimension& out,
391                             const interop::GPUTextureViewDimension& in) {
392         out = wgpu::TextureViewDimension::Undefined;
393         switch (in) {
394             case interop::GPUTextureViewDimension::k1D:
395                 out = wgpu::TextureViewDimension::e1D;
396                 return true;
397             case interop::GPUTextureViewDimension::k2D:
398                 out = wgpu::TextureViewDimension::e2D;
399                 return true;
400             case interop::GPUTextureViewDimension::k2DArray:
401                 out = wgpu::TextureViewDimension::e2DArray;
402                 return true;
403             case interop::GPUTextureViewDimension::kCube:
404                 out = wgpu::TextureViewDimension::Cube;
405                 return true;
406             case interop::GPUTextureViewDimension::kCubeArray:
407                 out = wgpu::TextureViewDimension::CubeArray;
408                 return true;
409             case interop::GPUTextureViewDimension::k3D:
410                 out = wgpu::TextureViewDimension::e3D;
411                 return true;
412             default:
413                 break;
414         }
415         Napi::Error::New(env, "invalid value for GPUTextureViewDimension")
416             .ThrowAsJavaScriptException();
417         return false;
418     }
419 
Convert(wgpu::ProgrammableStageDescriptor & out,const interop::GPUProgrammableStage & in)420     bool Converter::Convert(wgpu::ProgrammableStageDescriptor& out,
421                             const interop::GPUProgrammableStage& in) {
422         out = {};
423         out.entryPoint = in.entryPoint.c_str();
424         out.module = *in.module.As<GPUShaderModule>();
425         return Convert(out.constants, out.constantCount, in.constants);
426     }
427 
Convert(wgpu::ConstantEntry & out,const std::string & in_name,wgpu::interop::GPUPipelineConstantValue in_value)428     bool Converter::Convert(wgpu::ConstantEntry& out,
429                             const std::string& in_name,
430                             wgpu::interop::GPUPipelineConstantValue in_value) {
431         out.key = in_name.c_str();
432         out.value = in_value;
433         return true;
434     }
435 
Convert(wgpu::BlendComponent & out,const interop::GPUBlendComponent & in)436     bool Converter::Convert(wgpu::BlendComponent& out, const interop::GPUBlendComponent& in) {
437         out = {};
438         return Convert(out.operation, in.operation) && Convert(out.dstFactor, in.dstFactor) &&
439                Convert(out.srcFactor, in.srcFactor);
440     }
441 
Convert(wgpu::BlendFactor & out,const interop::GPUBlendFactor & in)442     bool Converter::Convert(wgpu::BlendFactor& out, const interop::GPUBlendFactor& in) {
443         out = wgpu::BlendFactor::Zero;
444         switch (in) {
445             case interop::GPUBlendFactor::kZero:
446                 out = wgpu::BlendFactor::Zero;
447                 return true;
448             case interop::GPUBlendFactor::kOne:
449                 out = wgpu::BlendFactor::One;
450                 return true;
451             case interop::GPUBlendFactor::kSrc:
452                 out = wgpu::BlendFactor::Src;
453                 return true;
454             case interop::GPUBlendFactor::kOneMinusSrc:
455                 out = wgpu::BlendFactor::OneMinusSrc;
456                 return true;
457             case interop::GPUBlendFactor::kSrcAlpha:
458                 out = wgpu::BlendFactor::SrcAlpha;
459                 return true;
460             case interop::GPUBlendFactor::kOneMinusSrcAlpha:
461                 out = wgpu::BlendFactor::OneMinusSrcAlpha;
462                 return true;
463             case interop::GPUBlendFactor::kDst:
464                 out = wgpu::BlendFactor::Dst;
465                 return true;
466             case interop::GPUBlendFactor::kOneMinusDst:
467                 out = wgpu::BlendFactor::OneMinusDst;
468                 return true;
469             case interop::GPUBlendFactor::kDstAlpha:
470                 out = wgpu::BlendFactor::DstAlpha;
471                 return true;
472             case interop::GPUBlendFactor::kOneMinusDstAlpha:
473                 out = wgpu::BlendFactor::OneMinusDstAlpha;
474                 return true;
475             case interop::GPUBlendFactor::kSrcAlphaSaturated:
476                 out = wgpu::BlendFactor::SrcAlphaSaturated;
477                 return true;
478             case interop::GPUBlendFactor::kConstant:
479                 out = wgpu::BlendFactor::Constant;
480                 return true;
481             case interop::GPUBlendFactor::kOneMinusConstant:
482                 out = wgpu::BlendFactor::OneMinusConstant;
483                 return true;
484             default:
485                 break;
486         }
487         Napi::Error::New(env, "invalid value for GPUBlendFactor").ThrowAsJavaScriptException();
488         return false;
489     }
490 
Convert(wgpu::BlendOperation & out,const interop::GPUBlendOperation & in)491     bool Converter::Convert(wgpu::BlendOperation& out, const interop::GPUBlendOperation& in) {
492         out = wgpu::BlendOperation::Add;
493         switch (in) {
494             case interop::GPUBlendOperation::kAdd:
495                 out = wgpu::BlendOperation::Add;
496                 return true;
497             case interop::GPUBlendOperation::kSubtract:
498                 out = wgpu::BlendOperation::Subtract;
499                 return true;
500             case interop::GPUBlendOperation::kReverseSubtract:
501                 out = wgpu::BlendOperation::ReverseSubtract;
502                 return true;
503             case interop::GPUBlendOperation::kMin:
504                 out = wgpu::BlendOperation::Min;
505                 return true;
506             case interop::GPUBlendOperation::kMax:
507                 out = wgpu::BlendOperation::Max;
508                 return true;
509             default:
510                 break;
511         }
512         Napi::Error::New(env, "invalid value for GPUBlendOperation").ThrowAsJavaScriptException();
513         return false;
514     }
515 
Convert(wgpu::BlendState & out,const interop::GPUBlendState & in)516     bool Converter::Convert(wgpu::BlendState& out, const interop::GPUBlendState& in) {
517         out = {};
518         return Convert(out.alpha, in.alpha) && Convert(out.color, in.color);
519     }
520 
Convert(wgpu::PrimitiveState & out,const interop::GPUPrimitiveState & in)521     bool Converter::Convert(wgpu::PrimitiveState& out, const interop::GPUPrimitiveState& in) {
522         out = {};
523         return Convert(out.topology, in.topology) &&
524                Convert(out.stripIndexFormat, in.stripIndexFormat) &&
525                Convert(out.frontFace, in.frontFace) && Convert(out.cullMode, in.cullMode);
526     }
527 
Convert(wgpu::ColorTargetState & out,const interop::GPUColorTargetState & in)528     bool Converter::Convert(wgpu::ColorTargetState& out, const interop::GPUColorTargetState& in) {
529         out = {};
530         return Convert(out.format, in.format) && Convert(out.blend, in.blend) &&
531                Convert(out.writeMask, in.writeMask);
532     }
533 
Convert(wgpu::DepthStencilState & out,const interop::GPUDepthStencilState & in)534     bool Converter::Convert(wgpu::DepthStencilState& out, const interop::GPUDepthStencilState& in) {
535         out = {};
536         return Convert(out.format, in.format) &&
537                Convert(out.depthWriteEnabled, in.depthWriteEnabled) &&
538                Convert(out.depthCompare, in.depthCompare) &&
539                Convert(out.stencilFront, in.stencilFront) &&
540                Convert(out.stencilBack, in.stencilBack) &&
541                Convert(out.stencilReadMask, in.stencilReadMask) &&
542                Convert(out.stencilWriteMask, in.stencilWriteMask) &&
543                Convert(out.depthBias, in.depthBias) &&
544                Convert(out.depthBiasSlopeScale, in.depthBiasSlopeScale) &&
545                Convert(out.depthBiasClamp, in.depthBiasClamp);
546     }
547 
Convert(wgpu::MultisampleState & out,const interop::GPUMultisampleState & in)548     bool Converter::Convert(wgpu::MultisampleState& out, const interop::GPUMultisampleState& in) {
549         out = {};
550         return Convert(out.count, in.count) && Convert(out.mask, in.mask) &&
551                Convert(out.alphaToCoverageEnabled, in.alphaToCoverageEnabled);
552     }
553 
Convert(wgpu::FragmentState & out,const interop::GPUFragmentState & in)554     bool Converter::Convert(wgpu::FragmentState& out, const interop::GPUFragmentState& in) {
555         out = {};
556         return Convert(out.targets, out.targetCount, in.targets) &&  //
557                Convert(out.module, in.module) &&                     //
558                Convert(out.entryPoint, in.entryPoint) &&             //
559                Convert(out.constants, out.constantCount, in.constants);
560     }
561 
Convert(wgpu::PrimitiveTopology & out,const interop::GPUPrimitiveTopology & in)562     bool Converter::Convert(wgpu::PrimitiveTopology& out, const interop::GPUPrimitiveTopology& in) {
563         out = wgpu::PrimitiveTopology::LineList;
564         switch (in) {
565             case interop::GPUPrimitiveTopology::kPointList:
566                 out = wgpu::PrimitiveTopology::PointList;
567                 return true;
568             case interop::GPUPrimitiveTopology::kLineList:
569                 out = wgpu::PrimitiveTopology::LineList;
570                 return true;
571             case interop::GPUPrimitiveTopology::kLineStrip:
572                 out = wgpu::PrimitiveTopology::LineStrip;
573                 return true;
574             case interop::GPUPrimitiveTopology::kTriangleList:
575                 out = wgpu::PrimitiveTopology::TriangleList;
576                 return true;
577             case interop::GPUPrimitiveTopology::kTriangleStrip:
578                 out = wgpu::PrimitiveTopology::TriangleStrip;
579                 return true;
580         }
581         Napi::Error::New(env, "invalid value for GPUPrimitiveTopology")
582             .ThrowAsJavaScriptException();
583         return false;
584     }
585 
Convert(wgpu::FrontFace & out,const interop::GPUFrontFace & in)586     bool Converter::Convert(wgpu::FrontFace& out, const interop::GPUFrontFace& in) {
587         out = wgpu::FrontFace::CW;
588         switch (in) {
589             case interop::GPUFrontFace::kCw:
590                 out = wgpu::FrontFace::CW;
591                 return true;
592             case interop::GPUFrontFace::kCcw:
593                 out = wgpu::FrontFace::CCW;
594                 return true;
595         }
596         Napi::Error::New(env, "invalid value for GPUFrontFace").ThrowAsJavaScriptException();
597         return false;
598     }
599 
Convert(wgpu::CullMode & out,const interop::GPUCullMode & in)600     bool Converter::Convert(wgpu::CullMode& out, const interop::GPUCullMode& in) {
601         out = wgpu::CullMode::None;
602         switch (in) {
603             case interop::GPUCullMode::kNone:
604                 out = wgpu::CullMode::None;
605                 return true;
606             case interop::GPUCullMode::kFront:
607                 out = wgpu::CullMode::Front;
608                 return true;
609             case interop::GPUCullMode::kBack:
610                 out = wgpu::CullMode::Back;
611                 return true;
612         }
613         Napi::Error::New(env, "invalid value for GPUCullMode").ThrowAsJavaScriptException();
614         return false;
615     }
616 
Convert(wgpu::CompareFunction & out,const interop::GPUCompareFunction & in)617     bool Converter::Convert(wgpu::CompareFunction& out, const interop::GPUCompareFunction& in) {
618         out = wgpu::CompareFunction::Undefined;
619         switch (in) {
620             case interop::GPUCompareFunction::kNever:
621                 out = wgpu::CompareFunction::Never;
622                 return true;
623             case interop::GPUCompareFunction::kLess:
624                 out = wgpu::CompareFunction::Less;
625                 return true;
626             case interop::GPUCompareFunction::kLessEqual:
627                 out = wgpu::CompareFunction::LessEqual;
628                 return true;
629             case interop::GPUCompareFunction::kGreater:
630                 out = wgpu::CompareFunction::Greater;
631                 return true;
632             case interop::GPUCompareFunction::kGreaterEqual:
633                 out = wgpu::CompareFunction::GreaterEqual;
634                 return true;
635             case interop::GPUCompareFunction::kEqual:
636                 out = wgpu::CompareFunction::Equal;
637                 return true;
638             case interop::GPUCompareFunction::kNotEqual:
639                 out = wgpu::CompareFunction::NotEqual;
640                 return true;
641             case interop::GPUCompareFunction::kAlways:
642                 out = wgpu::CompareFunction::Always;
643                 return true;
644         }
645         Napi::Error::New(env, "invalid value for GPUCompareFunction").ThrowAsJavaScriptException();
646         return false;
647     }
648 
Convert(wgpu::IndexFormat & out,const interop::GPUIndexFormat & in)649     bool Converter::Convert(wgpu::IndexFormat& out, const interop::GPUIndexFormat& in) {
650         out = wgpu::IndexFormat::Undefined;
651         switch (in) {
652             case interop::GPUIndexFormat::kUint16:
653                 out = wgpu::IndexFormat::Uint16;
654                 return true;
655             case interop::GPUIndexFormat::kUint32:
656                 out = wgpu::IndexFormat::Uint32;
657                 return true;
658         }
659         Napi::Error::New(env, "invalid value for GPUIndexFormat").ThrowAsJavaScriptException();
660         return false;
661     }
662 
Convert(wgpu::StencilOperation & out,const interop::GPUStencilOperation & in)663     bool Converter::Convert(wgpu::StencilOperation& out, const interop::GPUStencilOperation& in) {
664         out = wgpu::StencilOperation::Zero;
665         switch (in) {
666             case interop::GPUStencilOperation::kKeep:
667                 out = wgpu::StencilOperation::Keep;
668                 return true;
669             case interop::GPUStencilOperation::kZero:
670                 out = wgpu::StencilOperation::Zero;
671                 return true;
672             case interop::GPUStencilOperation::kReplace:
673                 out = wgpu::StencilOperation::Replace;
674                 return true;
675             case interop::GPUStencilOperation::kInvert:
676                 out = wgpu::StencilOperation::Invert;
677                 return true;
678             case interop::GPUStencilOperation::kIncrementClamp:
679                 out = wgpu::StencilOperation::IncrementClamp;
680                 return true;
681             case interop::GPUStencilOperation::kDecrementClamp:
682                 out = wgpu::StencilOperation::DecrementClamp;
683                 return true;
684             case interop::GPUStencilOperation::kIncrementWrap:
685                 out = wgpu::StencilOperation::IncrementWrap;
686                 return true;
687             case interop::GPUStencilOperation::kDecrementWrap:
688                 out = wgpu::StencilOperation::DecrementWrap;
689                 return true;
690         }
691         Napi::Error::New(env, "invalid value for GPUStencilOperation").ThrowAsJavaScriptException();
692         return false;
693     }
694 
Convert(wgpu::StencilFaceState & out,const interop::GPUStencilFaceState & in)695     bool Converter::Convert(wgpu::StencilFaceState& out, const interop::GPUStencilFaceState& in) {
696         return Convert(out.compare, in.compare) && Convert(out.failOp, in.failOp) &&
697                Convert(out.depthFailOp, in.depthFailOp) && Convert(out.passOp, in.passOp);
698     }
699 
Convert(wgpu::VertexBufferLayout & out,const interop::GPUVertexBufferLayout & in)700     bool Converter::Convert(wgpu::VertexBufferLayout& out,
701                             const interop::GPUVertexBufferLayout& in) {
702         out = {};
703         return Convert(out.attributes, out.attributeCount, in.attributes) &&
704                Convert(out.arrayStride, in.arrayStride) && Convert(out.stepMode, in.stepMode);
705     }
706 
Convert(wgpu::VertexState & out,const interop::GPUVertexState & in)707     bool Converter::Convert(wgpu::VertexState& out, const interop::GPUVertexState& in) {
708         out = {};
709         return Convert(out.module, in.module) &&
710                Convert(out.buffers, out.bufferCount, in.buffers) &&
711                Convert(out.entryPoint, in.entryPoint) &&
712                Convert(out.constants, out.constantCount, in.constants);
713     }
714 
Convert(wgpu::VertexStepMode & out,const interop::GPUVertexStepMode & in)715     bool Converter::Convert(wgpu::VertexStepMode& out, const interop::GPUVertexStepMode& in) {
716         out = wgpu::VertexStepMode::Instance;
717         switch (in) {
718             case interop::GPUVertexStepMode::kInstance:
719                 out = wgpu::VertexStepMode::Instance;
720                 return true;
721             case interop::GPUVertexStepMode::kVertex:
722                 out = wgpu::VertexStepMode::Vertex;
723                 return true;
724             default:
725                 break;
726         }
727         Napi::Error::New(env, "invalid value for GPUVertexStepMode").ThrowAsJavaScriptException();
728         return false;
729     }
730 
Convert(wgpu::VertexAttribute & out,const interop::GPUVertexAttribute & in)731     bool Converter::Convert(wgpu::VertexAttribute& out, const interop::GPUVertexAttribute& in) {
732         return Convert(out.format, in.format) && Convert(out.offset, in.offset) &&
733                Convert(out.shaderLocation, in.shaderLocation);
734     }
735 
Convert(wgpu::VertexFormat & out,const interop::GPUVertexFormat & in)736     bool Converter::Convert(wgpu::VertexFormat& out, const interop::GPUVertexFormat& in) {
737         out = wgpu::VertexFormat::Undefined;
738         switch (in) {
739             case interop::GPUVertexFormat::kUint8X2:
740                 out = wgpu::VertexFormat::Uint8x2;
741                 return true;
742             case interop::GPUVertexFormat::kUint8X4:
743                 out = wgpu::VertexFormat::Uint8x4;
744                 return true;
745             case interop::GPUVertexFormat::kSint8X2:
746                 out = wgpu::VertexFormat::Sint8x2;
747                 return true;
748             case interop::GPUVertexFormat::kSint8X4:
749                 out = wgpu::VertexFormat::Sint8x4;
750                 return true;
751             case interop::GPUVertexFormat::kUnorm8X2:
752                 out = wgpu::VertexFormat::Unorm8x2;
753                 return true;
754             case interop::GPUVertexFormat::kUnorm8X4:
755                 out = wgpu::VertexFormat::Unorm8x4;
756                 return true;
757             case interop::GPUVertexFormat::kSnorm8X2:
758                 out = wgpu::VertexFormat::Snorm8x2;
759                 return true;
760             case interop::GPUVertexFormat::kSnorm8X4:
761                 out = wgpu::VertexFormat::Snorm8x4;
762                 return true;
763             case interop::GPUVertexFormat::kUint16X2:
764                 out = wgpu::VertexFormat::Uint16x2;
765                 return true;
766             case interop::GPUVertexFormat::kUint16X4:
767                 out = wgpu::VertexFormat::Uint16x4;
768                 return true;
769             case interop::GPUVertexFormat::kSint16X2:
770                 out = wgpu::VertexFormat::Sint16x2;
771                 return true;
772             case interop::GPUVertexFormat::kSint16X4:
773                 out = wgpu::VertexFormat::Sint16x4;
774                 return true;
775             case interop::GPUVertexFormat::kUnorm16X2:
776                 out = wgpu::VertexFormat::Unorm16x2;
777                 return true;
778             case interop::GPUVertexFormat::kUnorm16X4:
779                 out = wgpu::VertexFormat::Unorm16x4;
780                 return true;
781             case interop::GPUVertexFormat::kSnorm16X2:
782                 out = wgpu::VertexFormat::Snorm16x2;
783                 return true;
784             case interop::GPUVertexFormat::kSnorm16X4:
785                 out = wgpu::VertexFormat::Snorm16x4;
786                 return true;
787             case interop::GPUVertexFormat::kFloat16X2:
788                 out = wgpu::VertexFormat::Float16x2;
789                 return true;
790             case interop::GPUVertexFormat::kFloat16X4:
791                 out = wgpu::VertexFormat::Float16x4;
792                 return true;
793             case interop::GPUVertexFormat::kFloat32:
794                 out = wgpu::VertexFormat::Float32;
795                 return true;
796             case interop::GPUVertexFormat::kFloat32X2:
797                 out = wgpu::VertexFormat::Float32x2;
798                 return true;
799             case interop::GPUVertexFormat::kFloat32X3:
800                 out = wgpu::VertexFormat::Float32x3;
801                 return true;
802             case interop::GPUVertexFormat::kFloat32X4:
803                 out = wgpu::VertexFormat::Float32x4;
804                 return true;
805             case interop::GPUVertexFormat::kUint32:
806                 out = wgpu::VertexFormat::Uint32;
807                 return true;
808             case interop::GPUVertexFormat::kUint32X2:
809                 out = wgpu::VertexFormat::Uint32x2;
810                 return true;
811             case interop::GPUVertexFormat::kUint32X3:
812                 out = wgpu::VertexFormat::Uint32x3;
813                 return true;
814             case interop::GPUVertexFormat::kUint32X4:
815                 out = wgpu::VertexFormat::Uint32x4;
816                 return true;
817             case interop::GPUVertexFormat::kSint32:
818                 out = wgpu::VertexFormat::Sint32;
819                 return true;
820             case interop::GPUVertexFormat::kSint32X2:
821                 out = wgpu::VertexFormat::Sint32x2;
822                 return true;
823             case interop::GPUVertexFormat::kSint32X3:
824                 out = wgpu::VertexFormat::Sint32x3;
825                 return true;
826             case interop::GPUVertexFormat::kSint32X4:
827                 out = wgpu::VertexFormat::Sint32x4;
828                 return true;
829             default:
830                 break;
831         }
832         Napi::Error::New(env, "invalid value for GPUVertexFormat").ThrowAsJavaScriptException();
833         return false;
834     }
835 
Convert(wgpu::RenderPassColorAttachment & out,const interop::GPURenderPassColorAttachment & in)836     bool Converter::Convert(wgpu::RenderPassColorAttachment& out,
837                             const interop::GPURenderPassColorAttachment& in) {
838         out = {};
839         if (auto* op = std::get_if<interop::GPULoadOp>(&in.loadValue)) {
840             if (!Convert(out.loadOp, *op)) {
841                 return false;
842             }
843         } else if (auto* color = std::get_if<interop::GPUColor>(&in.loadValue)) {
844             out.loadOp = wgpu::LoadOp::Clear;
845             if (!Convert(out.clearColor, *color)) {
846                 return false;
847             }
848         } else {
849             Napi::Error::New(env, "invalid value for GPURenderPassColorAttachment.loadValue")
850                 .ThrowAsJavaScriptException();
851             return false;
852         }
853 
854         return Convert(out.view, in.view) && Convert(out.resolveTarget, in.resolveTarget) &&
855                Convert(out.storeOp, in.storeOp);
856     }
857 
Convert(wgpu::RenderPassDepthStencilAttachment & out,const interop::GPURenderPassDepthStencilAttachment & in)858     bool Converter::Convert(wgpu::RenderPassDepthStencilAttachment& out,
859                             const interop::GPURenderPassDepthStencilAttachment& in) {
860         out = {};
861         if (auto* op = std::get_if<interop::GPULoadOp>(&in.depthLoadValue)) {
862             if (!Convert(out.depthLoadOp, *op)) {
863                 return false;
864             }
865         } else if (auto* value = std::get_if<float>(&in.depthLoadValue)) {
866             out.stencilLoadOp = wgpu::LoadOp::Clear;
867             if (!Convert(out.clearDepth, *value)) {
868                 return false;
869             }
870         } else {
871             Napi::Error::New(env,
872                              "invalid value for GPURenderPassDepthStencilAttachment.depthLoadValue")
873                 .ThrowAsJavaScriptException();
874             return false;
875         }
876 
877         if (auto* op = std::get_if<interop::GPULoadOp>(&in.stencilLoadValue)) {
878             if (!Convert(out.stencilLoadOp, *op)) {
879                 return false;
880             }
881         } else if (auto* value = std::get_if<interop::GPUStencilValue>(&in.stencilLoadValue)) {
882             if (!Convert(out.clearStencil, *value)) {
883                 return false;
884             }
885         } else {
886             Napi::Error::New(env,
887                              "invalid value for "
888                              "GPURenderPassDepthStencilAttachment.stencilLoadValue")
889                 .ThrowAsJavaScriptException();
890             return false;
891         }
892 
893         return Convert(out.view, in.view) && Convert(out.depthStoreOp, in.depthStoreOp) &&
894                Convert(out.depthReadOnly, in.depthReadOnly) &&
895                Convert(out.stencilStoreOp, in.stencilStoreOp) &&
896                Convert(out.stencilReadOnly, in.stencilReadOnly);
897     }
898 
Convert(wgpu::LoadOp & out,const interop::GPULoadOp & in)899     bool Converter::Convert(wgpu::LoadOp& out, const interop::GPULoadOp& in) {
900         out = wgpu::LoadOp::Clear;
901         switch (in) {
902             case interop::GPULoadOp::kLoad:
903                 out = wgpu::LoadOp::Load;
904                 return true;
905         }
906         Napi::Error::New(env, "invalid value for GPULoadOp").ThrowAsJavaScriptException();
907         return false;
908     }
909 
Convert(wgpu::StoreOp & out,const interop::GPUStoreOp & in)910     bool Converter::Convert(wgpu::StoreOp& out, const interop::GPUStoreOp& in) {
911         out = wgpu::StoreOp::Store;
912         switch (in) {
913             case interop::GPUStoreOp::kStore:
914                 out = wgpu::StoreOp::Store;
915                 return true;
916             case interop::GPUStoreOp::kDiscard:
917                 out = wgpu::StoreOp::Discard;
918                 return true;
919         }
920         Napi::Error::New(env, "invalid value for GPUStoreOp").ThrowAsJavaScriptException();
921         return false;
922     }
923 
Convert(wgpu::BindGroupEntry & out,const interop::GPUBindGroupEntry & in)924     bool Converter::Convert(wgpu::BindGroupEntry& out, const interop::GPUBindGroupEntry& in) {
925         out = {};
926         if (!Convert(out.binding, in.binding)) {
927             return false;
928         }
929 
930         if (auto* res = std::get_if<interop::Interface<interop::GPUSampler>>(&in.resource)) {
931             return Convert(out.sampler, *res);
932         }
933         if (auto* res = std::get_if<interop::Interface<interop::GPUTextureView>>(&in.resource)) {
934             return Convert(out.textureView, *res);
935         }
936         if (auto* res = std::get_if<interop::GPUBufferBinding>(&in.resource)) {
937             auto buffer = res->buffer.As<GPUBuffer>();
938             out.size = wgpu::kWholeSize;
939             if (!buffer || !Convert(out.offset, res->offset) || !Convert(out.size, res->size)) {
940                 return false;
941             }
942             out.buffer = *buffer;
943             return true;
944         }
945         if (auto* res =
946                 std::get_if<interop::Interface<interop::GPUExternalTexture>>(&in.resource)) {
947             // TODO(crbug.com/dawn/1129): External textures
948             UNIMPLEMENTED();
949         }
950         Napi::Error::New(env, "invalid value for GPUBindGroupEntry.resource")
951             .ThrowAsJavaScriptException();
952         return false;
953     }
954 
Convert(wgpu::BindGroupLayoutEntry & out,const interop::GPUBindGroupLayoutEntry & in)955     bool Converter::Convert(wgpu::BindGroupLayoutEntry& out,
956                             const interop::GPUBindGroupLayoutEntry& in) {
957         // TODO(crbug.com/dawn/1129): External textures
958         return Convert(out.binding, in.binding) && Convert(out.visibility, in.visibility) &&
959                Convert(out.buffer, in.buffer) && Convert(out.sampler, in.sampler) &&
960                Convert(out.texture, in.texture) && Convert(out.storageTexture, in.storageTexture);
961     }
962 
Convert(wgpu::BufferBindingLayout & out,const interop::GPUBufferBindingLayout & in)963     bool Converter::Convert(wgpu::BufferBindingLayout& out,
964                             const interop::GPUBufferBindingLayout& in) {
965         return Convert(out.type, in.type) && Convert(out.hasDynamicOffset, in.hasDynamicOffset) &&
966                Convert(out.minBindingSize, in.minBindingSize);
967     }
968 
Convert(wgpu::SamplerBindingLayout & out,const interop::GPUSamplerBindingLayout & in)969     bool Converter::Convert(wgpu::SamplerBindingLayout& out,
970                             const interop::GPUSamplerBindingLayout& in) {
971         return Convert(out.type, in.type);
972     }
973 
Convert(wgpu::TextureBindingLayout & out,const interop::GPUTextureBindingLayout & in)974     bool Converter::Convert(wgpu::TextureBindingLayout& out,
975                             const interop::GPUTextureBindingLayout& in) {
976         return Convert(out.sampleType, in.sampleType) &&
977                Convert(out.viewDimension, in.viewDimension) &&
978                Convert(out.multisampled, in.multisampled);
979     }
980 
Convert(wgpu::StorageTextureBindingLayout & out,const interop::GPUStorageTextureBindingLayout & in)981     bool Converter::Convert(wgpu::StorageTextureBindingLayout& out,
982                             const interop::GPUStorageTextureBindingLayout& in) {
983         return Convert(out.access, in.access) && Convert(out.format, in.format) &&
984                Convert(out.viewDimension, in.viewDimension);
985     }
986 
Convert(wgpu::BufferBindingType & out,const interop::GPUBufferBindingType & in)987     bool Converter::Convert(wgpu::BufferBindingType& out, const interop::GPUBufferBindingType& in) {
988         out = wgpu::BufferBindingType::Undefined;
989         switch (in) {
990             case interop::GPUBufferBindingType::kUniform:
991                 out = wgpu::BufferBindingType::Uniform;
992                 return true;
993             case interop::GPUBufferBindingType::kStorage:
994                 out = wgpu::BufferBindingType::Storage;
995                 return true;
996             case interop::GPUBufferBindingType::kReadOnlyStorage:
997                 out = wgpu::BufferBindingType::ReadOnlyStorage;
998                 return true;
999         }
1000         Napi::Error::New(env, "invalid value for GPUBufferBindingType")
1001             .ThrowAsJavaScriptException();
1002         return false;
1003     }
1004 
Convert(wgpu::TextureSampleType & out,const interop::GPUTextureSampleType & in)1005     bool Converter::Convert(wgpu::TextureSampleType& out, const interop::GPUTextureSampleType& in) {
1006         out = wgpu::TextureSampleType::Undefined;
1007         switch (in) {
1008             case interop::GPUTextureSampleType::kFloat:
1009                 out = wgpu::TextureSampleType::Float;
1010                 return true;
1011             case interop::GPUTextureSampleType::kUnfilterableFloat:
1012                 out = wgpu::TextureSampleType::UnfilterableFloat;
1013                 return true;
1014             case interop::GPUTextureSampleType::kDepth:
1015                 out = wgpu::TextureSampleType::Depth;
1016                 return true;
1017             case interop::GPUTextureSampleType::kSint:
1018                 out = wgpu::TextureSampleType::Sint;
1019                 return true;
1020             case interop::GPUTextureSampleType::kUint:
1021                 out = wgpu::TextureSampleType::Uint;
1022                 return true;
1023         }
1024         Napi::Error::New(env, "invalid value for GPUTextureSampleType")
1025             .ThrowAsJavaScriptException();
1026         return false;
1027     }
1028 
Convert(wgpu::SamplerBindingType & out,const interop::GPUSamplerBindingType & in)1029     bool Converter::Convert(wgpu::SamplerBindingType& out,
1030                             const interop::GPUSamplerBindingType& in) {
1031         out = wgpu::SamplerBindingType::Undefined;
1032         switch (in) {
1033             case interop::GPUSamplerBindingType::kFiltering:
1034                 out = wgpu::SamplerBindingType::Filtering;
1035                 return true;
1036             case interop::GPUSamplerBindingType::kNonFiltering:
1037                 out = wgpu::SamplerBindingType::NonFiltering;
1038                 return true;
1039             case interop::GPUSamplerBindingType::kComparison:
1040                 out = wgpu::SamplerBindingType::Comparison;
1041                 return true;
1042         }
1043         Napi::Error::New(env, "invalid value for GPUSamplerBindingType")
1044             .ThrowAsJavaScriptException();
1045         return false;
1046     }
1047 
Convert(wgpu::StorageTextureAccess & out,const interop::GPUStorageTextureAccess & in)1048     bool Converter::Convert(wgpu::StorageTextureAccess& out,
1049                             const interop::GPUStorageTextureAccess& in) {
1050         out = wgpu::StorageTextureAccess::Undefined;
1051         switch (in) {
1052             case interop::GPUStorageTextureAccess::kWriteOnly:
1053                 out = wgpu::StorageTextureAccess::WriteOnly;
1054                 return true;
1055         }
1056         Napi::Error::New(env, "invalid value for GPUStorageTextureAccess")
1057             .ThrowAsJavaScriptException();
1058         return false;
1059     }
1060 
Convert(wgpu::QueryType & out,const interop::GPUQueryType & in)1061     bool Converter::Convert(wgpu::QueryType& out, const interop::GPUQueryType& in) {
1062         out = wgpu::QueryType::Occlusion;
1063         switch (in) {
1064             case interop::GPUQueryType::kOcclusion:
1065                 out = wgpu::QueryType::Occlusion;
1066                 return true;
1067             case interop::GPUQueryType::kPipelineStatistics:
1068                 out = wgpu::QueryType::PipelineStatistics;
1069                 return true;
1070             case interop::GPUQueryType::kTimestamp:
1071                 out = wgpu::QueryType::Timestamp;
1072                 return true;
1073         }
1074         Napi::Error::New(env, "invalid value for GPUQueryType").ThrowAsJavaScriptException();
1075         return false;
1076     }
1077 
Convert(wgpu::PipelineStatisticName & out,const interop::GPUPipelineStatisticName & in)1078     bool Converter::Convert(wgpu::PipelineStatisticName& out,
1079                             const interop::GPUPipelineStatisticName& in) {
1080         out = wgpu::PipelineStatisticName::VertexShaderInvocations;
1081         switch (in) {
1082             case interop::GPUPipelineStatisticName::kVertexShaderInvocations:
1083                 out = wgpu::PipelineStatisticName::VertexShaderInvocations;
1084                 return true;
1085             case interop::GPUPipelineStatisticName::kClipperInvocations:
1086                 out = wgpu::PipelineStatisticName::ClipperInvocations;
1087                 return true;
1088             case interop::GPUPipelineStatisticName::kClipperPrimitivesOut:
1089                 out = wgpu::PipelineStatisticName::ClipperPrimitivesOut;
1090                 return true;
1091             case interop::GPUPipelineStatisticName::kFragmentShaderInvocations:
1092                 out = wgpu::PipelineStatisticName::FragmentShaderInvocations;
1093                 return true;
1094             case interop::GPUPipelineStatisticName::kComputeShaderInvocations:
1095                 out = wgpu::PipelineStatisticName::ComputeShaderInvocations;
1096                 return true;
1097         }
1098         Napi::Error::New(env, "invalid value for GPUPipelineStatisticName")
1099             .ThrowAsJavaScriptException();
1100         return false;
1101     }
1102 
Convert(wgpu::AddressMode & out,const interop::GPUAddressMode & in)1103     bool Converter::Convert(wgpu::AddressMode& out, const interop::GPUAddressMode& in) {
1104         out = wgpu::AddressMode::Repeat;
1105         switch (in) {
1106             case interop::GPUAddressMode::kClampToEdge:
1107                 out = wgpu::AddressMode::ClampToEdge;
1108                 return true;
1109             case interop::GPUAddressMode::kRepeat:
1110                 out = wgpu::AddressMode::Repeat;
1111                 return true;
1112             case interop::GPUAddressMode::kMirrorRepeat:
1113                 out = wgpu::AddressMode::MirrorRepeat;
1114                 return true;
1115         }
1116         Napi::Error::New(env, "invalid value for GPUAddressMode").ThrowAsJavaScriptException();
1117         return false;
1118     }
1119 
Convert(wgpu::FilterMode & out,const interop::GPUFilterMode & in)1120     bool Converter::Convert(wgpu::FilterMode& out, const interop::GPUFilterMode& in) {
1121         out = wgpu::FilterMode::Nearest;
1122         switch (in) {
1123             case interop::GPUFilterMode::kNearest:
1124                 out = wgpu::FilterMode::Nearest;
1125                 return true;
1126             case interop::GPUFilterMode::kLinear:
1127                 out = wgpu::FilterMode::Linear;
1128                 return true;
1129         }
1130         Napi::Error::New(env, "invalid value for GPUFilterMode").ThrowAsJavaScriptException();
1131         return false;
1132     }
1133 
Convert(wgpu::ComputePipelineDescriptor & out,const interop::GPUComputePipelineDescriptor & in)1134     bool Converter::Convert(wgpu::ComputePipelineDescriptor& out,
1135                             const interop::GPUComputePipelineDescriptor& in) {
1136         return Convert(out.label, in.label) &&    //
1137                Convert(out.layout, in.layout) &&  //
1138                Convert(out.compute, in.compute);
1139     }
1140 
Convert(wgpu::RenderPipelineDescriptor & out,const interop::GPURenderPipelineDescriptor & in)1141     bool Converter::Convert(wgpu::RenderPipelineDescriptor& out,
1142                             const interop::GPURenderPipelineDescriptor& in) {
1143         wgpu::RenderPipelineDescriptor desc{};
1144         return Convert(out.label, in.label) &&                //
1145                Convert(out.layout, in.layout) &&              //
1146                Convert(out.vertex, in.vertex) &&              //
1147                Convert(out.primitive, in.primitive) &&        //
1148                Convert(out.depthStencil, in.depthStencil) &&  //
1149                Convert(out.multisample, in.multisample) &&    //
1150                Convert(out.fragment, in.fragment);
1151     }
1152 
1153 }}  // namespace wgpu::binding
1154