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