1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h"
6 
7 #include <dawn/webgpu.h>
8 
9 #include "third_party/blink/renderer/bindings/modules/v8/double_sequence_or_gpu_color_dict.h"
10 #include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_enforce_range_sequence_or_gpu_extent_3d_dict.h"
11 #include "third_party/blink/renderer/bindings/modules/v8/unsigned_long_enforce_range_sequence_or_gpu_origin_3d_dict.h"
12 #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_programmable_stage_descriptor.h"
13 #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_copy_view.h"
14 #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_texture_data_layout.h"
15 #include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
16 #include "third_party/blink/renderer/modules/webgpu/gpu_shader_module.h"
17 #include "third_party/blink/renderer/modules/webgpu/gpu_texture.h"
18 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
19 
20 namespace blink {
21 
22 template <>
AsDawnEnum(const WTF::String & webgpu_enum)23 WGPUBindingType AsDawnEnum<WGPUBindingType>(const WTF::String& webgpu_enum) {
24   if (webgpu_enum == "uniform-buffer") {
25     return WGPUBindingType_UniformBuffer;
26   }
27   if (webgpu_enum == "storage-buffer") {
28     return WGPUBindingType_StorageBuffer;
29   }
30   if (webgpu_enum == "readonly-storage-buffer") {
31     return WGPUBindingType_ReadonlyStorageBuffer;
32   }
33   if (webgpu_enum == "sampler") {
34     return WGPUBindingType_Sampler;
35   }
36   if (webgpu_enum == "comparison-sampler") {
37     return WGPUBindingType_ComparisonSampler;
38   }
39   if (webgpu_enum == "sampled-texture") {
40     return WGPUBindingType_SampledTexture;
41   }
42   if (webgpu_enum == "multisampled-texture") {
43     return WGPUBindingType_MultisampledTexture;
44   }
45   if (webgpu_enum == "readonly-storage-texture") {
46     return WGPUBindingType_ReadonlyStorageTexture;
47   }
48   if (webgpu_enum == "writeonly-storage-texture") {
49     return WGPUBindingType_WriteonlyStorageTexture;
50   }
51   NOTREACHED();
52   return WGPUBindingType_Force32;
53 }
54 
55 template <>
AsDawnEnum(const WTF::String & webgpu_enum)56 WGPUTextureComponentType AsDawnEnum<WGPUTextureComponentType>(
57     const WTF::String& webgpu_enum) {
58   if (webgpu_enum == "float") {
59     return WGPUTextureComponentType_Float;
60   }
61   if (webgpu_enum == "uint") {
62     return WGPUTextureComponentType_Uint;
63   }
64   if (webgpu_enum == "sint") {
65     return WGPUTextureComponentType_Sint;
66   }
67   if (webgpu_enum == "depth-comparison") {
68     return WGPUTextureComponentType_DepthComparison;
69   }
70   NOTREACHED();
71   return WGPUTextureComponentType_Force32;
72 }
73 
74 template <>
AsDawnEnum(const WTF::String & webgpu_enum)75 WGPUCompareFunction AsDawnEnum<WGPUCompareFunction>(
76     const WTF::String& webgpu_enum) {
77   if (webgpu_enum == "never") {
78     return WGPUCompareFunction_Never;
79   }
80   if (webgpu_enum == "less") {
81     return WGPUCompareFunction_Less;
82   }
83   if (webgpu_enum == "equal") {
84     return WGPUCompareFunction_Equal;
85   }
86   if (webgpu_enum == "less-equal") {
87     return WGPUCompareFunction_LessEqual;
88   }
89   if (webgpu_enum == "greater") {
90     return WGPUCompareFunction_Greater;
91   }
92   if (webgpu_enum == "not-equal") {
93     return WGPUCompareFunction_NotEqual;
94   }
95   if (webgpu_enum == "greater-equal") {
96     return WGPUCompareFunction_GreaterEqual;
97   }
98   if (webgpu_enum == "always") {
99     return WGPUCompareFunction_Always;
100   }
101   NOTREACHED();
102   return WGPUCompareFunction_Force32;
103 }
104 
105 template <>
AsDawnEnum(const WTF::String & webgpu_enum)106 WGPUQueryType AsDawnEnum<WGPUQueryType>(const WTF::String& webgpu_enum) {
107   if (webgpu_enum == "occlusion") {
108     return WGPUQueryType_Occlusion;
109   }
110   if (webgpu_enum == "pipeline-statistics") {
111     return WGPUQueryType_PipelineStatistics;
112   }
113   if (webgpu_enum == "timestamp") {
114     return WGPUQueryType_Timestamp;
115   }
116   NOTREACHED();
117   return WGPUQueryType_Force32;
118 }
119 
120 template <>
AsDawnEnum(const WTF::String & webgpu_enum)121 WGPUPipelineStatisticName AsDawnEnum<WGPUPipelineStatisticName>(
122     const WTF::String& webgpu_enum) {
123   if (webgpu_enum == "vertex-shader-invocations") {
124     return WGPUPipelineStatisticName_VertexShaderInvocations;
125   }
126   if (webgpu_enum == "clipper-invocations") {
127     return WGPUPipelineStatisticName_ClipperInvocations;
128   }
129   if (webgpu_enum == "clipper-primitives-out") {
130     return WGPUPipelineStatisticName_ClipperPrimitivesOut;
131   }
132   if (webgpu_enum == "fragment-shader-invocations") {
133     return WGPUPipelineStatisticName_FragmentShaderInvocations;
134   }
135   if (webgpu_enum == "compute-shader-invocations") {
136     return WGPUPipelineStatisticName_ComputeShaderInvocations;
137   }
138   NOTREACHED();
139   return WGPUPipelineStatisticName_Force32;
140 }
141 
142 template <>
AsDawnEnum(const WTF::String & webgpu_enum)143 WGPUTextureFormat AsDawnEnum<WGPUTextureFormat>(
144     const WTF::String& webgpu_enum) {
145   if (webgpu_enum.IsNull()) {
146     return WGPUTextureFormat_Undefined;
147   }
148 
149   // Normal 8 bit formats
150   if (webgpu_enum == "r8unorm") {
151     return WGPUTextureFormat_R8Unorm;
152   }
153   if (webgpu_enum == "r8snorm") {
154     return WGPUTextureFormat_R8Snorm;
155   }
156   if (webgpu_enum == "r8uint") {
157     return WGPUTextureFormat_R8Uint;
158   }
159   if (webgpu_enum == "r8sint") {
160     return WGPUTextureFormat_R8Sint;
161   }
162 
163   // Normal 16 bit formats
164   if (webgpu_enum == "r16uint") {
165     return WGPUTextureFormat_R16Uint;
166   }
167   if (webgpu_enum == "r16sint") {
168     return WGPUTextureFormat_R16Sint;
169   }
170   if (webgpu_enum == "r16float") {
171     return WGPUTextureFormat_R16Float;
172   }
173   if (webgpu_enum == "rg8unorm") {
174     return WGPUTextureFormat_RG8Unorm;
175   }
176   if (webgpu_enum == "rg8snorm") {
177     return WGPUTextureFormat_RG8Snorm;
178   }
179   if (webgpu_enum == "rg8uint") {
180     return WGPUTextureFormat_RG8Uint;
181   }
182   if (webgpu_enum == "rg8sint") {
183     return WGPUTextureFormat_RG8Sint;
184   }
185 
186   // Normal 32 bit formats
187   if (webgpu_enum == "r32uint") {
188     return WGPUTextureFormat_R32Uint;
189   }
190   if (webgpu_enum == "r32sint") {
191     return WGPUTextureFormat_R32Sint;
192   }
193   if (webgpu_enum == "r32float") {
194     return WGPUTextureFormat_R32Float;
195   }
196   if (webgpu_enum == "rg16uint") {
197     return WGPUTextureFormat_RG16Uint;
198   }
199   if (webgpu_enum == "rg16sint") {
200     return WGPUTextureFormat_RG16Sint;
201   }
202   if (webgpu_enum == "rg16float") {
203     return WGPUTextureFormat_RG16Float;
204   }
205   if (webgpu_enum == "rgba8unorm") {
206     return WGPUTextureFormat_RGBA8Unorm;
207   }
208   if (webgpu_enum == "rgba8unorm-srgb") {
209     return WGPUTextureFormat_RGBA8UnormSrgb;
210   }
211   if (webgpu_enum == "rgba8snorm") {
212     return WGPUTextureFormat_RGBA8Snorm;
213   }
214   if (webgpu_enum == "rgba8uint") {
215     return WGPUTextureFormat_RGBA8Uint;
216   }
217   if (webgpu_enum == "rgba8sint") {
218     return WGPUTextureFormat_RGBA8Sint;
219   }
220   if (webgpu_enum == "bgra8unorm") {
221     return WGPUTextureFormat_BGRA8Unorm;
222   }
223   if (webgpu_enum == "bgra8unorm-srgb") {
224     return WGPUTextureFormat_BGRA8UnormSrgb;
225   }
226 
227   // Packed 32 bit formats
228   if (webgpu_enum == "rgb9e5ufloat") {
229     return WGPUTextureFormat_RGB9E5Ufloat;
230   }
231   if (webgpu_enum == "rgb10a2unorm") {
232     return WGPUTextureFormat_RGB10A2Unorm;
233   }
234   if (webgpu_enum == "rg11b10float") {
235     // Deprecated.
236     return WGPUTextureFormat_RG11B10Ufloat;
237   }
238   if (webgpu_enum == "rg11b10ufloat") {
239     return WGPUTextureFormat_RG11B10Ufloat;
240   }
241 
242   // Normal 64 bit formats
243   if (webgpu_enum == "rg32uint") {
244     return WGPUTextureFormat_RG32Uint;
245   }
246   if (webgpu_enum == "rg32sint") {
247     return WGPUTextureFormat_RG32Sint;
248   }
249   if (webgpu_enum == "rg32float") {
250     return WGPUTextureFormat_RG32Float;
251   }
252   if (webgpu_enum == "rgba16uint") {
253     return WGPUTextureFormat_RGBA16Uint;
254   }
255   if (webgpu_enum == "rgba16sint") {
256     return WGPUTextureFormat_RGBA16Sint;
257   }
258   if (webgpu_enum == "rgba16float") {
259     return WGPUTextureFormat_RGBA16Float;
260   }
261 
262   // Normal 128 bit formats
263   if (webgpu_enum == "rgba32uint") {
264     return WGPUTextureFormat_RGBA32Uint;
265   }
266   if (webgpu_enum == "rgba32sint") {
267     return WGPUTextureFormat_RGBA32Sint;
268   }
269   if (webgpu_enum == "rgba32float") {
270     return WGPUTextureFormat_RGBA32Float;
271   }
272 
273   // Depth / Stencil formats
274   if (webgpu_enum == "depth32float") {
275     return WGPUTextureFormat_Depth32Float;
276   }
277   if (webgpu_enum == "depth24plus") {
278     return WGPUTextureFormat_Depth24Plus;
279   }
280   if (webgpu_enum == "depth24plus-stencil8") {
281     return WGPUTextureFormat_Depth24PlusStencil8;
282   }
283 
284   // Block Compression (BC) formats
285   if (webgpu_enum == "bc1-rgba-unorm") {
286     return WGPUTextureFormat_BC1RGBAUnorm;
287   }
288   if (webgpu_enum == "bc1-rgba-unorm-srgb") {
289     return WGPUTextureFormat_BC1RGBAUnormSrgb;
290   }
291   if (webgpu_enum == "bc2-rgba-unorm") {
292     return WGPUTextureFormat_BC2RGBAUnorm;
293   }
294   if (webgpu_enum == "bc2-rgba-unorm-srgb") {
295     return WGPUTextureFormat_BC2RGBAUnormSrgb;
296   }
297   if (webgpu_enum == "bc3-rgba-unorm") {
298     return WGPUTextureFormat_BC3RGBAUnorm;
299   }
300   if (webgpu_enum == "bc3-rgba-unorm-srgb") {
301     return WGPUTextureFormat_BC3RGBAUnormSrgb;
302   }
303   if (webgpu_enum == "bc4-r-unorm") {
304     return WGPUTextureFormat_BC4RUnorm;
305   }
306   if (webgpu_enum == "bc4-r-snorm") {
307     return WGPUTextureFormat_BC4RSnorm;
308   }
309   if (webgpu_enum == "bc5-rg-unorm") {
310     return WGPUTextureFormat_BC5RGUnorm;
311   }
312   if (webgpu_enum == "bc5-rg-snorm") {
313     return WGPUTextureFormat_BC5RGSnorm;
314   }
315   if (webgpu_enum == "bc6h-rgb-ufloat") {
316     return WGPUTextureFormat_BC6HRGBUfloat;
317   }
318   if (webgpu_enum == "bc6h-rgb-float") {
319     return WGPUTextureFormat_BC6HRGBFloat;
320   }
321   if (webgpu_enum == "bc6h-rgb-sfloat") {
322     // Deprecated.
323     return WGPUTextureFormat_BC6HRGBFloat;
324   }
325   if (webgpu_enum == "bc7-rgba-unorm") {
326     return WGPUTextureFormat_BC7RGBAUnorm;
327   }
328   if (webgpu_enum == "bc7-rgba-unorm-srgb") {
329     return WGPUTextureFormat_BC7RGBAUnormSrgb;
330   }
331 
332   return WGPUTextureFormat_Force32;
333 }
334 
335 template <>
AsDawnEnum(const WTF::String & webgpu_enum)336 WGPUTextureDimension AsDawnEnum<WGPUTextureDimension>(
337     const WTF::String& webgpu_enum) {
338   if (webgpu_enum == "1d") {
339     return WGPUTextureDimension_1D;
340   }
341   if (webgpu_enum == "2d") {
342     return WGPUTextureDimension_2D;
343   }
344   if (webgpu_enum == "3d") {
345     return WGPUTextureDimension_3D;
346   }
347   NOTREACHED();
348   return WGPUTextureDimension_Force32;
349 }
350 
351 template <>
AsDawnEnum(const WTF::String & webgpu_enum)352 WGPUTextureViewDimension AsDawnEnum<WGPUTextureViewDimension>(
353     const WTF::String& webgpu_enum) {
354   if (webgpu_enum.IsNull()) {
355     return WGPUTextureViewDimension_Undefined;
356   }
357   if (webgpu_enum == "1d") {
358     return WGPUTextureViewDimension_1D;
359   }
360   if (webgpu_enum == "2d") {
361     return WGPUTextureViewDimension_2D;
362   }
363   if (webgpu_enum == "2d-array") {
364     return WGPUTextureViewDimension_2DArray;
365   }
366   if (webgpu_enum == "cube") {
367     return WGPUTextureViewDimension_Cube;
368   }
369   if (webgpu_enum == "cube-array") {
370     return WGPUTextureViewDimension_CubeArray;
371   }
372   if (webgpu_enum == "3d") {
373     return WGPUTextureViewDimension_3D;
374   }
375   NOTREACHED();
376   return WGPUTextureViewDimension_Force32;
377 }
378 
379 template <>
AsDawnEnum(const WTF::String & webgpu_enum)380 WGPUStencilOperation AsDawnEnum<WGPUStencilOperation>(
381     const WTF::String& webgpu_enum) {
382   if (webgpu_enum == "keep") {
383     return WGPUStencilOperation_Keep;
384   }
385   if (webgpu_enum == "zero") {
386     return WGPUStencilOperation_Zero;
387   }
388   if (webgpu_enum == "replace") {
389     return WGPUStencilOperation_Replace;
390   }
391   if (webgpu_enum == "invert") {
392     return WGPUStencilOperation_Invert;
393   }
394   if (webgpu_enum == "increment-clamp") {
395     return WGPUStencilOperation_IncrementClamp;
396   }
397   if (webgpu_enum == "decrement-clamp") {
398     return WGPUStencilOperation_DecrementClamp;
399   }
400   if (webgpu_enum == "increment-wrap") {
401     return WGPUStencilOperation_IncrementWrap;
402   }
403   if (webgpu_enum == "decrement-wrap") {
404     return WGPUStencilOperation_DecrementWrap;
405   }
406   NOTREACHED();
407   return WGPUStencilOperation_Force32;
408 }
409 
410 template <>
AsDawnEnum(const WTF::String & webgpu_enum)411 WGPUStoreOp AsDawnEnum<WGPUStoreOp>(const WTF::String& webgpu_enum) {
412   if (webgpu_enum == "store") {
413     return WGPUStoreOp_Store;
414   }
415   if (webgpu_enum == "clear") {
416     return WGPUStoreOp_Clear;
417   }
418   NOTREACHED();
419   return WGPUStoreOp_Force32;
420 }
421 
422 template <>
AsDawnEnum(const WTF::String & webgpu_enum)423 WGPULoadOp AsDawnEnum<WGPULoadOp>(const WTF::String& webgpu_enum) {
424   if (webgpu_enum == "load") {
425     return WGPULoadOp_Load;
426   }
427   NOTREACHED();
428   return WGPULoadOp_Force32;
429 }
430 
431 template <>
AsDawnEnum(const WTF::String & webgpu_enum)432 WGPUIndexFormat AsDawnEnum<WGPUIndexFormat>(const WTF::String& webgpu_enum) {
433   if (webgpu_enum.IsNull()) {
434     return WGPUIndexFormat_Undefined;
435   }
436   if (webgpu_enum == "uint16") {
437     return WGPUIndexFormat_Uint16;
438   }
439   if (webgpu_enum == "uint32") {
440     return WGPUIndexFormat_Uint32;
441   }
442   NOTREACHED();
443   return WGPUIndexFormat_Force32;
444 }
445 
446 template <>
AsDawnEnum(const WTF::String & webgpu_enum)447 WGPUPrimitiveTopology AsDawnEnum<WGPUPrimitiveTopology>(
448     const WTF::String& webgpu_enum) {
449   if (webgpu_enum == "point-list") {
450     return WGPUPrimitiveTopology_PointList;
451   }
452   if (webgpu_enum == "line-list") {
453     return WGPUPrimitiveTopology_LineList;
454   }
455   if (webgpu_enum == "line-strip") {
456     return WGPUPrimitiveTopology_LineStrip;
457   }
458   if (webgpu_enum == "triangle-list") {
459     return WGPUPrimitiveTopology_TriangleList;
460   }
461   if (webgpu_enum == "triangle-strip") {
462     return WGPUPrimitiveTopology_TriangleStrip;
463   }
464   NOTREACHED();
465   return WGPUPrimitiveTopology_Force32;
466 }
467 
468 template <>
AsDawnEnum(const WTF::String & webgpu_enum)469 WGPUBlendFactor AsDawnEnum<WGPUBlendFactor>(const WTF::String& webgpu_enum) {
470   if (webgpu_enum == "zero") {
471     return WGPUBlendFactor_Zero;
472   }
473   if (webgpu_enum == "one") {
474     return WGPUBlendFactor_One;
475   }
476   if (webgpu_enum == "src-color") {
477     return WGPUBlendFactor_SrcColor;
478   }
479   if (webgpu_enum == "one-minus-src-color") {
480     return WGPUBlendFactor_OneMinusSrcColor;
481   }
482   if (webgpu_enum == "src-alpha") {
483     return WGPUBlendFactor_SrcAlpha;
484   }
485   if (webgpu_enum == "one-minus-src-alpha") {
486     return WGPUBlendFactor_OneMinusSrcAlpha;
487   }
488   if (webgpu_enum == "dst-color") {
489     return WGPUBlendFactor_DstColor;
490   }
491   if (webgpu_enum == "one-minus-dst-color") {
492     return WGPUBlendFactor_OneMinusDstColor;
493   }
494   if (webgpu_enum == "dst-alpha") {
495     return WGPUBlendFactor_DstAlpha;
496   }
497   if (webgpu_enum == "one-minus-dst-alpha") {
498     return WGPUBlendFactor_OneMinusDstAlpha;
499   }
500   if (webgpu_enum == "src-alpha-saturated") {
501     return WGPUBlendFactor_SrcAlphaSaturated;
502   }
503   if (webgpu_enum == "blend-color") {
504     return WGPUBlendFactor_BlendColor;
505   }
506   if (webgpu_enum == "one-minus-blend-color") {
507     return WGPUBlendFactor_OneMinusBlendColor;
508   }
509   NOTREACHED();
510   return WGPUBlendFactor_Force32;
511 }
512 
513 template <>
AsDawnEnum(const WTF::String & webgpu_enum)514 WGPUBlendOperation AsDawnEnum<WGPUBlendOperation>(
515     const WTF::String& webgpu_enum) {
516   if (webgpu_enum == "add") {
517     return WGPUBlendOperation_Add;
518   }
519   if (webgpu_enum == "subtract") {
520     return WGPUBlendOperation_Subtract;
521   }
522   if (webgpu_enum == "reverse-subtract") {
523     return WGPUBlendOperation_ReverseSubtract;
524   }
525   if (webgpu_enum == "min") {
526     return WGPUBlendOperation_Min;
527   }
528   if (webgpu_enum == "max") {
529     return WGPUBlendOperation_Max;
530   }
531   NOTREACHED();
532   return WGPUBlendOperation_Force32;
533 }
534 
535 template <>
AsDawnEnum(const WTF::String & webgpu_enum)536 WGPUInputStepMode AsDawnEnum<WGPUInputStepMode>(
537     const WTF::String& webgpu_enum) {
538   if (webgpu_enum == "vertex") {
539     return WGPUInputStepMode_Vertex;
540   }
541   if (webgpu_enum == "instance") {
542     return WGPUInputStepMode_Instance;
543   }
544   NOTREACHED();
545   return WGPUInputStepMode_Force32;
546 }
547 
548 template <>
AsDawnEnum(const WTF::String & webgpu_enum)549 WGPUVertexFormat AsDawnEnum<WGPUVertexFormat>(const WTF::String& webgpu_enum) {
550   if (webgpu_enum == "uchar2") {
551     return WGPUVertexFormat_UChar2;
552   }
553   if (webgpu_enum == "uchar4") {
554     return WGPUVertexFormat_UChar4;
555   }
556   if (webgpu_enum == "char2") {
557     return WGPUVertexFormat_Char2;
558   }
559   if (webgpu_enum == "char4") {
560     return WGPUVertexFormat_Char4;
561   }
562   if (webgpu_enum == "uchar2norm") {
563     return WGPUVertexFormat_UChar2Norm;
564   }
565   if (webgpu_enum == "uchar4norm") {
566     return WGPUVertexFormat_UChar4Norm;
567   }
568   if (webgpu_enum == "char2norm") {
569     return WGPUVertexFormat_Char2Norm;
570   }
571   if (webgpu_enum == "char4norm") {
572     return WGPUVertexFormat_Char4Norm;
573   }
574   if (webgpu_enum == "ushort2") {
575     return WGPUVertexFormat_UShort2;
576   }
577   if (webgpu_enum == "ushort4") {
578     return WGPUVertexFormat_UShort4;
579   }
580   if (webgpu_enum == "short2") {
581     return WGPUVertexFormat_Short2;
582   }
583   if (webgpu_enum == "short4") {
584     return WGPUVertexFormat_Short4;
585   }
586   if (webgpu_enum == "ushort2norm") {
587     return WGPUVertexFormat_UShort2Norm;
588   }
589   if (webgpu_enum == "ushort4norm") {
590     return WGPUVertexFormat_UShort4Norm;
591   }
592   if (webgpu_enum == "short2norm") {
593     return WGPUVertexFormat_Short2Norm;
594   }
595   if (webgpu_enum == "short4norm") {
596     return WGPUVertexFormat_Short4Norm;
597   }
598   if (webgpu_enum == "half2") {
599     return WGPUVertexFormat_Half2;
600   }
601   if (webgpu_enum == "half4") {
602     return WGPUVertexFormat_Half4;
603   }
604   if (webgpu_enum == "float") {
605     return WGPUVertexFormat_Float;
606   }
607   if (webgpu_enum == "float2") {
608     return WGPUVertexFormat_Float2;
609   }
610   if (webgpu_enum == "float3") {
611     return WGPUVertexFormat_Float3;
612   }
613   if (webgpu_enum == "float4") {
614     return WGPUVertexFormat_Float4;
615   }
616   if (webgpu_enum == "uint") {
617     return WGPUVertexFormat_UInt;
618   }
619   if (webgpu_enum == "uint2") {
620     return WGPUVertexFormat_UInt2;
621   }
622   if (webgpu_enum == "uint3") {
623     return WGPUVertexFormat_UInt3;
624   }
625   if (webgpu_enum == "uint4") {
626     return WGPUVertexFormat_UInt4;
627   }
628   if (webgpu_enum == "int") {
629     return WGPUVertexFormat_Int;
630   }
631   if (webgpu_enum == "int2") {
632     return WGPUVertexFormat_Int2;
633   }
634   if (webgpu_enum == "int3") {
635     return WGPUVertexFormat_Int3;
636   }
637   if (webgpu_enum == "int4") {
638     return WGPUVertexFormat_Int4;
639   }
640   NOTREACHED();
641   return WGPUVertexFormat_Force32;
642 }
643 
644 template <>
AsDawnEnum(const WTF::String & webgpu_enum)645 WGPUAddressMode AsDawnEnum<WGPUAddressMode>(const WTF::String& webgpu_enum) {
646   if (webgpu_enum == "clamp-to-edge") {
647     return WGPUAddressMode_ClampToEdge;
648   }
649   if (webgpu_enum == "repeat") {
650     return WGPUAddressMode_Repeat;
651   }
652   if (webgpu_enum == "mirror-repeat") {
653     return WGPUAddressMode_MirrorRepeat;
654   }
655   NOTREACHED();
656   return WGPUAddressMode_Force32;
657 }
658 
659 template <>
AsDawnEnum(const WTF::String & webgpu_enum)660 WGPUFilterMode AsDawnEnum<WGPUFilterMode>(const WTF::String& webgpu_enum) {
661   if (webgpu_enum == "nearest") {
662     return WGPUFilterMode_Nearest;
663   }
664   if (webgpu_enum == "linear") {
665     return WGPUFilterMode_Linear;
666   }
667   NOTREACHED();
668   return WGPUFilterMode_Force32;
669 }
670 
671 template <>
AsDawnEnum(const WTF::String & webgpu_enum)672 WGPUCullMode AsDawnEnum<WGPUCullMode>(const WTF::String& webgpu_enum) {
673   if (webgpu_enum == "none") {
674     return WGPUCullMode_None;
675   }
676   if (webgpu_enum == "front") {
677     return WGPUCullMode_Front;
678   }
679   if (webgpu_enum == "back") {
680     return WGPUCullMode_Back;
681   }
682   NOTREACHED();
683   return WGPUCullMode_Force32;
684 }
685 
686 template <>
AsDawnEnum(const WTF::String & webgpu_enum)687 WGPUFrontFace AsDawnEnum<WGPUFrontFace>(const WTF::String& webgpu_enum) {
688   if (webgpu_enum == "ccw") {
689     return WGPUFrontFace_CCW;
690   }
691   if (webgpu_enum == "cw") {
692     return WGPUFrontFace_CW;
693   }
694   NOTREACHED();
695   return WGPUFrontFace_Force32;
696 }
697 
698 template <>
AsDawnEnum(const WTF::String & webgpu_enum)699 WGPUTextureAspect AsDawnEnum<WGPUTextureAspect>(
700     const WTF::String& webgpu_enum) {
701   if (webgpu_enum == "all") {
702     return WGPUTextureAspect_All;
703   }
704   if (webgpu_enum == "stencil-only") {
705     return WGPUTextureAspect_StencilOnly;
706   }
707   if (webgpu_enum == "depth-only") {
708     return WGPUTextureAspect_DepthOnly;
709   }
710   NOTREACHED();
711   return WGPUTextureAspect_Force32;
712 }
713 
714 template <>
AsDawnEnum(const WTF::String & webgpu_enum)715 WGPUErrorFilter AsDawnEnum<WGPUErrorFilter>(const WTF::String& webgpu_enum) {
716   if (webgpu_enum == "none") {
717     return WGPUErrorFilter_None;
718   }
719   if (webgpu_enum == "out-of-memory") {
720     return WGPUErrorFilter_OutOfMemory;
721   }
722   if (webgpu_enum == "validation") {
723     return WGPUErrorFilter_Validation;
724   }
725   NOTREACHED();
726   return WGPUErrorFilter_Force32;
727 }
728 
AsDawnColor(const Vector<double> & webgpu_color)729 WGPUColor AsDawnColor(const Vector<double>& webgpu_color) {
730   DCHECK_EQ(webgpu_color.size(), 4UL);
731 
732   WGPUColor dawn_color = {};
733   dawn_color.r = webgpu_color[0];
734   dawn_color.g = webgpu_color[1];
735   dawn_color.b = webgpu_color[2];
736   dawn_color.a = webgpu_color[3];
737 
738   return dawn_color;
739 }
740 
AsDawnType(const GPUColorDict * webgpu_color)741 WGPUColor AsDawnType(const GPUColorDict* webgpu_color) {
742   DCHECK(webgpu_color);
743 
744   WGPUColor dawn_color = {};
745   dawn_color.r = webgpu_color->r();
746   dawn_color.g = webgpu_color->g();
747   dawn_color.b = webgpu_color->b();
748   dawn_color.a = webgpu_color->a();
749 
750   return dawn_color;
751 }
752 
AsDawnType(const DoubleSequenceOrGPUColorDict * webgpu_color)753 WGPUColor AsDawnType(const DoubleSequenceOrGPUColorDict* webgpu_color) {
754   DCHECK(webgpu_color);
755 
756   if (webgpu_color->IsDoubleSequence()) {
757     return AsDawnColor(webgpu_color->GetAsDoubleSequence());
758   } else if (webgpu_color->IsGPUColorDict()) {
759     return AsDawnType(webgpu_color->GetAsGPUColorDict());
760   }
761   NOTREACHED();
762   WGPUColor dawn_color = {};
763   return dawn_color;
764 }
765 
AsDawnType(const UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict * webgpu_extent)766 WGPUExtent3D AsDawnType(
767     const UnsignedLongEnforceRangeSequenceOrGPUExtent3DDict* webgpu_extent) {
768   DCHECK(webgpu_extent);
769 
770   WGPUExtent3D dawn_extent = {1, 1, 1};
771 
772   if (webgpu_extent->IsUnsignedLongEnforceRangeSequence()) {
773     const Vector<uint32_t>& webgpu_extent_sequence =
774         webgpu_extent->GetAsUnsignedLongEnforceRangeSequence();
775 
776     // The WebGPU spec states that if the sequence isn't big enough then the
777     // default values of 1 are used (which are set above).
778     switch (webgpu_extent_sequence.size()) {
779       default:
780         dawn_extent.depth = webgpu_extent_sequence[2];
781         FALLTHROUGH;
782       case 2:
783         dawn_extent.height = webgpu_extent_sequence[1];
784         FALLTHROUGH;
785       case 1:
786         dawn_extent.width = webgpu_extent_sequence[0];
787         FALLTHROUGH;
788       case 0:
789         break;
790     }
791 
792   } else if (webgpu_extent->IsGPUExtent3DDict()) {
793     const GPUExtent3DDict* webgpu_extent_3d_dict =
794         webgpu_extent->GetAsGPUExtent3DDict();
795     dawn_extent.width = webgpu_extent_3d_dict->width();
796     dawn_extent.height = webgpu_extent_3d_dict->height();
797     dawn_extent.depth = webgpu_extent_3d_dict->depth();
798 
799   } else {
800     NOTREACHED();
801   }
802 
803   return dawn_extent;
804 }
805 
AsDawnType(const UnsignedLongEnforceRangeSequenceOrGPUOrigin3DDict * webgpu_origin)806 WGPUOrigin3D AsDawnType(
807     const UnsignedLongEnforceRangeSequenceOrGPUOrigin3DDict* webgpu_origin) {
808   DCHECK(webgpu_origin);
809 
810   WGPUOrigin3D dawn_origin = {0, 0, 0};
811 
812   if (webgpu_origin->IsUnsignedLongEnforceRangeSequence()) {
813     const Vector<uint32_t>& webgpu_origin_sequence =
814         webgpu_origin->GetAsUnsignedLongEnforceRangeSequence();
815 
816     // The WebGPU spec states that if the sequence isn't big enough then the
817     // default values of 0 are used (which are set above).
818     switch (webgpu_origin_sequence.size()) {
819       default:
820         dawn_origin.z = webgpu_origin_sequence[2];
821         FALLTHROUGH;
822       case 2:
823         dawn_origin.y = webgpu_origin_sequence[1];
824         FALLTHROUGH;
825       case 1:
826         dawn_origin.x = webgpu_origin_sequence[0];
827         FALLTHROUGH;
828       case 0:
829         break;
830     }
831 
832   } else if (webgpu_origin->IsGPUOrigin3DDict()) {
833     const GPUOrigin3DDict* webgpu_origin_3d_dict =
834         webgpu_origin->GetAsGPUOrigin3DDict();
835     dawn_origin.x = webgpu_origin_3d_dict->x();
836     dawn_origin.y = webgpu_origin_3d_dict->y();
837     dawn_origin.z = webgpu_origin_3d_dict->z();
838 
839   } else {
840     NOTREACHED();
841   }
842 
843   return dawn_origin;
844 }
845 
AsDawnType(const GPUTextureCopyView * webgpu_view,GPUDevice * device)846 WGPUTextureCopyView AsDawnType(const GPUTextureCopyView* webgpu_view,
847                                GPUDevice* device) {
848   DCHECK(webgpu_view);
849   DCHECK(webgpu_view->texture());
850 
851   WGPUTextureCopyView dawn_view = {};
852   dawn_view.texture = webgpu_view->texture()->GetHandle();
853   dawn_view.mipLevel = webgpu_view->mipLevel();
854   dawn_view.origin = AsDawnType(&webgpu_view->origin());
855   dawn_view.aspect = AsDawnEnum<WGPUTextureAspect>(webgpu_view->aspect());
856 
857   return dawn_view;
858 }
859 
860 // Dawn represents `undefined` as the special uint32_t value
861 // WGPU_STRIDE_UNDEFINED (0xFFFF'FFFF). Blink must make sure that an actual
862 // value of 0xFFFF'FFFF coming in from JS is not treated as
863 // WGPU_STRIDE_UNDEFINED, so it injects an error in that case.
ValidateTextureDataLayout(const GPUTextureDataLayout * webgpu_layout,WGPUTextureDataLayout * dawn_layout)864 const char* ValidateTextureDataLayout(const GPUTextureDataLayout* webgpu_layout,
865                                       WGPUTextureDataLayout* dawn_layout) {
866   DCHECK(webgpu_layout);
867 
868   uint32_t bytesPerRow = 0;
869   if (webgpu_layout->hasBytesPerRow()) {
870     bytesPerRow = webgpu_layout->bytesPerRow();
871     if (bytesPerRow == WGPU_STRIDE_UNDEFINED) {
872       return "bytesPerRow must be a multiple of 256";
873     }
874   } else {
875     bytesPerRow = WGPU_STRIDE_UNDEFINED;
876   }
877 
878   uint32_t rowsPerImage = 0;
879   if (webgpu_layout->hasRowsPerImage()) {
880     rowsPerImage = webgpu_layout->rowsPerImage();
881     if (rowsPerImage == WGPU_STRIDE_UNDEFINED) {
882       return "rowsPerImage is too large";
883     }
884   } else {
885     rowsPerImage = WGPU_STRIDE_UNDEFINED;
886   }
887 
888   *dawn_layout = {};
889   dawn_layout->offset = webgpu_layout->offset();
890   dawn_layout->bytesPerRow = bytesPerRow;
891   dawn_layout->rowsPerImage = rowsPerImage;
892 
893   return nullptr;
894 }
895 
AsDawnType(const GPUProgrammableStageDescriptor * webgpu_stage)896 OwnedProgrammableStageDescriptor AsDawnType(
897     const GPUProgrammableStageDescriptor* webgpu_stage) {
898   DCHECK(webgpu_stage);
899 
900   std::string entry_point = webgpu_stage->entryPoint().Ascii();
901   // length() is in bytes (not utf-8 characters or something), so this is ok.
902   size_t byte_size = entry_point.length() + 1;
903 
904   std::unique_ptr<char[]> entry_point_keepalive =
905       std::make_unique<char[]>(byte_size);
906   char* entry_point_ptr = entry_point_keepalive.get();
907   memcpy(entry_point_ptr, entry_point.c_str(), byte_size);
908 
909   WGPUProgrammableStageDescriptor dawn_stage = {};
910   dawn_stage.module = webgpu_stage->module()->GetHandle();
911   dawn_stage.entryPoint = entry_point_ptr;
912 
913   return std::make_tuple(dawn_stage, std::move(entry_point_keepalive));
914 }
915 
916 }  // namespace blink
917