Utility.cpp (25517B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #include "Utility.h" 7 8 #include "mozilla/dom/TypedArray.h" 9 #include "mozilla/dom/WebGPUBinding.h" 10 #include "mozilla/webgpu/WebGPUTypes.h" 11 #include "mozilla/webgpu/ffi/wgpu.h" 12 13 namespace mozilla::webgpu { 14 15 template <typename E> 16 void ConvertToExtent3D(const E& aExtent, ffi::WGPUExtent3d* aExtentFFI) { 17 *aExtentFFI = {}; 18 if (aExtent.IsRangeEnforcedUnsignedLongSequence()) { 19 const auto& seq = aExtent.GetAsRangeEnforcedUnsignedLongSequence(); 20 aExtentFFI->width = seq.Length() > 0 ? seq[0] : 0; 21 aExtentFFI->height = seq.Length() > 1 ? seq[1] : 1; 22 aExtentFFI->depth_or_array_layers = seq.Length() > 2 ? seq[2] : 1; 23 } else if (aExtent.IsGPUExtent3DDict()) { 24 const auto& dict = aExtent.GetAsGPUExtent3DDict(); 25 aExtentFFI->width = dict.mWidth; 26 aExtentFFI->height = dict.mHeight; 27 aExtentFFI->depth_or_array_layers = dict.mDepthOrArrayLayers; 28 } else { 29 MOZ_CRASH("Unexpected extent type"); 30 } 31 } 32 33 void ConvertExtent3DToFFI(const dom::GPUExtent3D& aExtent, 34 ffi::WGPUExtent3d* aExtentFFI) { 35 ConvertToExtent3D(aExtent, aExtentFFI); 36 } 37 38 void ConvertExtent3DToFFI(const dom::OwningGPUExtent3D& aExtent, 39 ffi::WGPUExtent3d* aExtentFFI) { 40 ConvertToExtent3D(aExtent, aExtentFFI); 41 } 42 43 ffi::WGPUExtent3d ConvertExtent(const dom::GPUExtent3D& aExtent) { 44 ffi::WGPUExtent3d extent = {}; 45 ConvertToExtent3D(aExtent, &extent); 46 return extent; 47 } 48 49 ffi::WGPUExtent3d ConvertExtent(const dom::OwningGPUExtent3D& aExtent) { 50 ffi::WGPUExtent3d extent = {}; 51 ConvertToExtent3D(aExtent, &extent); 52 return extent; 53 } 54 55 ffi::WGPUCompareFunction ConvertCompareFunction( 56 const dom::GPUCompareFunction& aCompare) { 57 // Value of 0 = Undefined is reserved on the C side for "null" semantics. 58 return ffi::WGPUCompareFunction(UnderlyingValue(aCompare) + 1); 59 } 60 61 ffi::WGPUTextureFormat ConvertTextureFormat( 62 const dom::GPUTextureFormat& aFormat) { 63 ffi::WGPUTextureFormat result = {ffi::WGPUTextureFormat_Sentinel}; 64 switch (aFormat) { 65 case dom::GPUTextureFormat::R8unorm: 66 result.tag = ffi::WGPUTextureFormat_R8Unorm; 67 break; 68 case dom::GPUTextureFormat::R8snorm: 69 result.tag = ffi::WGPUTextureFormat_R8Snorm; 70 break; 71 case dom::GPUTextureFormat::R8uint: 72 result.tag = ffi::WGPUTextureFormat_R8Uint; 73 break; 74 case dom::GPUTextureFormat::R8sint: 75 result.tag = ffi::WGPUTextureFormat_R8Sint; 76 break; 77 case dom::GPUTextureFormat::R16uint: 78 result.tag = ffi::WGPUTextureFormat_R16Uint; 79 break; 80 case dom::GPUTextureFormat::R16sint: 81 result.tag = ffi::WGPUTextureFormat_R16Sint; 82 break; 83 case dom::GPUTextureFormat::R16float: 84 result.tag = ffi::WGPUTextureFormat_R16Float; 85 break; 86 case dom::GPUTextureFormat::Rg8unorm: 87 result.tag = ffi::WGPUTextureFormat_Rg8Unorm; 88 break; 89 case dom::GPUTextureFormat::Rg8snorm: 90 result.tag = ffi::WGPUTextureFormat_Rg8Snorm; 91 break; 92 case dom::GPUTextureFormat::Rg8uint: 93 result.tag = ffi::WGPUTextureFormat_Rg8Uint; 94 break; 95 case dom::GPUTextureFormat::Rg8sint: 96 result.tag = ffi::WGPUTextureFormat_Rg8Sint; 97 break; 98 case dom::GPUTextureFormat::R32uint: 99 result.tag = ffi::WGPUTextureFormat_R32Uint; 100 break; 101 case dom::GPUTextureFormat::R32sint: 102 result.tag = ffi::WGPUTextureFormat_R32Sint; 103 break; 104 case dom::GPUTextureFormat::R32float: 105 result.tag = ffi::WGPUTextureFormat_R32Float; 106 break; 107 case dom::GPUTextureFormat::Rg16uint: 108 result.tag = ffi::WGPUTextureFormat_Rg16Uint; 109 break; 110 case dom::GPUTextureFormat::Rg16sint: 111 result.tag = ffi::WGPUTextureFormat_Rg16Sint; 112 break; 113 case dom::GPUTextureFormat::Rg16float: 114 result.tag = ffi::WGPUTextureFormat_Rg16Float; 115 break; 116 case dom::GPUTextureFormat::Rgba8unorm: 117 result.tag = ffi::WGPUTextureFormat_Rgba8Unorm; 118 break; 119 case dom::GPUTextureFormat::Rgba8unorm_srgb: 120 result.tag = ffi::WGPUTextureFormat_Rgba8UnormSrgb; 121 break; 122 case dom::GPUTextureFormat::Rgba8snorm: 123 result.tag = ffi::WGPUTextureFormat_Rgba8Snorm; 124 break; 125 case dom::GPUTextureFormat::Rgba8uint: 126 result.tag = ffi::WGPUTextureFormat_Rgba8Uint; 127 break; 128 case dom::GPUTextureFormat::Rgba8sint: 129 result.tag = ffi::WGPUTextureFormat_Rgba8Sint; 130 break; 131 case dom::GPUTextureFormat::Bgra8unorm: 132 result.tag = ffi::WGPUTextureFormat_Bgra8Unorm; 133 break; 134 case dom::GPUTextureFormat::Bgra8unorm_srgb: 135 result.tag = ffi::WGPUTextureFormat_Bgra8UnormSrgb; 136 break; 137 case dom::GPUTextureFormat::Rgb9e5ufloat: 138 result.tag = ffi::WGPUTextureFormat_Rgb9e5Ufloat; 139 break; 140 case dom::GPUTextureFormat::Rgb10a2unorm: 141 result.tag = ffi::WGPUTextureFormat_Rgb10a2Unorm; 142 break; 143 case dom::GPUTextureFormat::Rg11b10ufloat: 144 result.tag = ffi::WGPUTextureFormat_Rg11b10Ufloat; 145 break; 146 case dom::GPUTextureFormat::Rg32uint: 147 result.tag = ffi::WGPUTextureFormat_Rg32Uint; 148 break; 149 case dom::GPUTextureFormat::Rg32sint: 150 result.tag = ffi::WGPUTextureFormat_Rg32Sint; 151 break; 152 case dom::GPUTextureFormat::Rg32float: 153 result.tag = ffi::WGPUTextureFormat_Rg32Float; 154 break; 155 case dom::GPUTextureFormat::Rgba16uint: 156 result.tag = ffi::WGPUTextureFormat_Rgba16Uint; 157 break; 158 case dom::GPUTextureFormat::Rgba16sint: 159 result.tag = ffi::WGPUTextureFormat_Rgba16Sint; 160 break; 161 case dom::GPUTextureFormat::Rgba16float: 162 result.tag = ffi::WGPUTextureFormat_Rgba16Float; 163 break; 164 case dom::GPUTextureFormat::Rgba32uint: 165 result.tag = ffi::WGPUTextureFormat_Rgba32Uint; 166 break; 167 case dom::GPUTextureFormat::Rgba32sint: 168 result.tag = ffi::WGPUTextureFormat_Rgba32Sint; 169 break; 170 case dom::GPUTextureFormat::Rgba32float: 171 result.tag = ffi::WGPUTextureFormat_Rgba32Float; 172 break; 173 case dom::GPUTextureFormat::Depth32float: 174 result.tag = ffi::WGPUTextureFormat_Depth32Float; 175 break; 176 case dom::GPUTextureFormat::Bc1_rgba_unorm: 177 result.tag = ffi::WGPUTextureFormat_Bc1RgbaUnorm; 178 break; 179 case dom::GPUTextureFormat::Bc1_rgba_unorm_srgb: 180 result.tag = ffi::WGPUTextureFormat_Bc1RgbaUnormSrgb; 181 break; 182 case dom::GPUTextureFormat::Bc4_r_unorm: 183 result.tag = ffi::WGPUTextureFormat_Bc4RUnorm; 184 break; 185 case dom::GPUTextureFormat::Bc4_r_snorm: 186 result.tag = ffi::WGPUTextureFormat_Bc4RSnorm; 187 break; 188 case dom::GPUTextureFormat::Bc2_rgba_unorm: 189 result.tag = ffi::WGPUTextureFormat_Bc2RgbaUnorm; 190 break; 191 case dom::GPUTextureFormat::Bc2_rgba_unorm_srgb: 192 result.tag = ffi::WGPUTextureFormat_Bc2RgbaUnormSrgb; 193 break; 194 case dom::GPUTextureFormat::Bc3_rgba_unorm: 195 result.tag = ffi::WGPUTextureFormat_Bc3RgbaUnorm; 196 break; 197 case dom::GPUTextureFormat::Bc3_rgba_unorm_srgb: 198 result.tag = ffi::WGPUTextureFormat_Bc3RgbaUnormSrgb; 199 break; 200 case dom::GPUTextureFormat::Bc5_rg_unorm: 201 result.tag = ffi::WGPUTextureFormat_Bc5RgUnorm; 202 break; 203 case dom::GPUTextureFormat::Bc5_rg_snorm: 204 result.tag = ffi::WGPUTextureFormat_Bc5RgSnorm; 205 break; 206 case dom::GPUTextureFormat::Bc6h_rgb_ufloat: 207 result.tag = ffi::WGPUTextureFormat_Bc6hRgbUfloat; 208 break; 209 case dom::GPUTextureFormat::Bc6h_rgb_float: 210 result.tag = ffi::WGPUTextureFormat_Bc6hRgbFloat; 211 break; 212 case dom::GPUTextureFormat::Bc7_rgba_unorm: 213 result.tag = ffi::WGPUTextureFormat_Bc7RgbaUnorm; 214 break; 215 case dom::GPUTextureFormat::Bc7_rgba_unorm_srgb: 216 result.tag = ffi::WGPUTextureFormat_Bc7RgbaUnormSrgb; 217 break; 218 case dom::GPUTextureFormat::Stencil8: 219 result.tag = ffi::WGPUTextureFormat_Stencil8; 220 break; 221 case dom::GPUTextureFormat::Depth16unorm: 222 result.tag = ffi::WGPUTextureFormat_Depth16Unorm; 223 break; 224 case dom::GPUTextureFormat::Depth24plus: 225 result.tag = ffi::WGPUTextureFormat_Depth24Plus; 226 break; 227 case dom::GPUTextureFormat::Depth24plus_stencil8: 228 result.tag = ffi::WGPUTextureFormat_Depth24PlusStencil8; 229 break; 230 case dom::GPUTextureFormat::Depth32float_stencil8: 231 result.tag = ffi::WGPUTextureFormat_Depth32FloatStencil8; 232 break; 233 case dom::GPUTextureFormat::Astc_4x4_unorm: 234 result.tag = ffi::WGPUTextureFormat_Astc; 235 result.astc.block = ffi::WGPUAstcBlock_B4x4; 236 result.astc.channel = ffi::WGPUAstcChannel_Unorm; 237 break; 238 case dom::GPUTextureFormat::Astc_4x4_unorm_srgb: 239 result.tag = ffi::WGPUTextureFormat_Astc; 240 result.astc.block = ffi::WGPUAstcBlock_B4x4; 241 result.astc.channel = ffi::WGPUAstcChannel_UnormSrgb; 242 break; 243 case dom::GPUTextureFormat::Astc_5x4_unorm: 244 result.tag = ffi::WGPUTextureFormat_Astc; 245 result.astc.block = ffi::WGPUAstcBlock_B5x4; 246 result.astc.channel = ffi::WGPUAstcChannel_Unorm; 247 break; 248 case dom::GPUTextureFormat::Astc_5x4_unorm_srgb: 249 result.tag = ffi::WGPUTextureFormat_Astc; 250 result.astc.block = ffi::WGPUAstcBlock_B5x4; 251 result.astc.channel = ffi::WGPUAstcChannel_UnormSrgb; 252 break; 253 case dom::GPUTextureFormat::Astc_5x5_unorm: 254 result.tag = ffi::WGPUTextureFormat_Astc; 255 result.astc.block = ffi::WGPUAstcBlock_B5x5; 256 result.astc.channel = ffi::WGPUAstcChannel_Unorm; 257 break; 258 case dom::GPUTextureFormat::Astc_5x5_unorm_srgb: 259 result.tag = ffi::WGPUTextureFormat_Astc; 260 result.astc.block = ffi::WGPUAstcBlock_B5x5; 261 result.astc.channel = ffi::WGPUAstcChannel_UnormSrgb; 262 break; 263 case dom::GPUTextureFormat::Astc_6x5_unorm: 264 result.tag = ffi::WGPUTextureFormat_Astc; 265 result.astc.block = ffi::WGPUAstcBlock_B6x5; 266 result.astc.channel = ffi::WGPUAstcChannel_Unorm; 267 break; 268 case dom::GPUTextureFormat::Astc_6x5_unorm_srgb: 269 result.tag = ffi::WGPUTextureFormat_Astc; 270 result.astc.block = ffi::WGPUAstcBlock_B6x5; 271 result.astc.channel = ffi::WGPUAstcChannel_UnormSrgb; 272 break; 273 case dom::GPUTextureFormat::Astc_6x6_unorm: 274 result.tag = ffi::WGPUTextureFormat_Astc; 275 result.astc.block = ffi::WGPUAstcBlock_B6x6; 276 result.astc.channel = ffi::WGPUAstcChannel_Unorm; 277 break; 278 case dom::GPUTextureFormat::Astc_6x6_unorm_srgb: 279 result.tag = ffi::WGPUTextureFormat_Astc; 280 result.astc.block = ffi::WGPUAstcBlock_B6x6; 281 result.astc.channel = ffi::WGPUAstcChannel_UnormSrgb; 282 break; 283 case dom::GPUTextureFormat::Astc_8x5_unorm: 284 result.tag = ffi::WGPUTextureFormat_Astc; 285 result.astc.block = ffi::WGPUAstcBlock_B8x5; 286 result.astc.channel = ffi::WGPUAstcChannel_Unorm; 287 break; 288 case dom::GPUTextureFormat::Astc_8x5_unorm_srgb: 289 result.tag = ffi::WGPUTextureFormat_Astc; 290 result.astc.block = ffi::WGPUAstcBlock_B8x5; 291 result.astc.channel = ffi::WGPUAstcChannel_UnormSrgb; 292 break; 293 case dom::GPUTextureFormat::Astc_8x6_unorm: 294 result.tag = ffi::WGPUTextureFormat_Astc; 295 result.astc.block = ffi::WGPUAstcBlock_B8x6; 296 result.astc.channel = ffi::WGPUAstcChannel_Unorm; 297 break; 298 case dom::GPUTextureFormat::Astc_8x6_unorm_srgb: 299 result.tag = ffi::WGPUTextureFormat_Astc; 300 result.astc.block = ffi::WGPUAstcBlock_B8x6; 301 result.astc.channel = ffi::WGPUAstcChannel_UnormSrgb; 302 break; 303 case dom::GPUTextureFormat::Astc_8x8_unorm: 304 result.tag = ffi::WGPUTextureFormat_Astc; 305 result.astc.block = ffi::WGPUAstcBlock_B8x8; 306 result.astc.channel = ffi::WGPUAstcChannel_Unorm; 307 break; 308 case dom::GPUTextureFormat::Astc_8x8_unorm_srgb: 309 result.tag = ffi::WGPUTextureFormat_Astc; 310 result.astc.block = ffi::WGPUAstcBlock_B8x8; 311 result.astc.channel = ffi::WGPUAstcChannel_UnormSrgb; 312 break; 313 case dom::GPUTextureFormat::Astc_10x5_unorm: 314 result.tag = ffi::WGPUTextureFormat_Astc; 315 result.astc.block = ffi::WGPUAstcBlock_B10x5; 316 result.astc.channel = ffi::WGPUAstcChannel_Unorm; 317 break; 318 case dom::GPUTextureFormat::Astc_10x5_unorm_srgb: 319 result.tag = ffi::WGPUTextureFormat_Astc; 320 result.astc.block = ffi::WGPUAstcBlock_B10x5; 321 result.astc.channel = ffi::WGPUAstcChannel_UnormSrgb; 322 break; 323 case dom::GPUTextureFormat::Astc_10x6_unorm: 324 result.tag = ffi::WGPUTextureFormat_Astc; 325 result.astc.block = ffi::WGPUAstcBlock_B10x6; 326 result.astc.channel = ffi::WGPUAstcChannel_Unorm; 327 break; 328 case dom::GPUTextureFormat::Astc_10x6_unorm_srgb: 329 result.tag = ffi::WGPUTextureFormat_Astc; 330 result.astc.block = ffi::WGPUAstcBlock_B10x6; 331 result.astc.channel = ffi::WGPUAstcChannel_UnormSrgb; 332 break; 333 case dom::GPUTextureFormat::Astc_10x8_unorm: 334 result.tag = ffi::WGPUTextureFormat_Astc; 335 result.astc.block = ffi::WGPUAstcBlock_B10x8; 336 result.astc.channel = ffi::WGPUAstcChannel_Unorm; 337 break; 338 case dom::GPUTextureFormat::Astc_10x8_unorm_srgb: 339 result.tag = ffi::WGPUTextureFormat_Astc; 340 result.astc.block = ffi::WGPUAstcBlock_B10x8; 341 result.astc.channel = ffi::WGPUAstcChannel_UnormSrgb; 342 break; 343 case dom::GPUTextureFormat::Astc_10x10_unorm: 344 result.tag = ffi::WGPUTextureFormat_Astc; 345 result.astc.block = ffi::WGPUAstcBlock_B10x10; 346 result.astc.channel = ffi::WGPUAstcChannel_Unorm; 347 break; 348 case dom::GPUTextureFormat::Astc_10x10_unorm_srgb: 349 result.tag = ffi::WGPUTextureFormat_Astc; 350 result.astc.block = ffi::WGPUAstcBlock_B10x10; 351 result.astc.channel = ffi::WGPUAstcChannel_UnormSrgb; 352 break; 353 case dom::GPUTextureFormat::Astc_12x10_unorm: 354 result.tag = ffi::WGPUTextureFormat_Astc; 355 result.astc.block = ffi::WGPUAstcBlock_B12x10; 356 result.astc.channel = ffi::WGPUAstcChannel_Unorm; 357 break; 358 case dom::GPUTextureFormat::Astc_12x10_unorm_srgb: 359 result.tag = ffi::WGPUTextureFormat_Astc; 360 result.astc.block = ffi::WGPUAstcBlock_B12x10; 361 result.astc.channel = ffi::WGPUAstcChannel_UnormSrgb; 362 break; 363 case dom::GPUTextureFormat::Astc_12x12_unorm: 364 result.tag = ffi::WGPUTextureFormat_Astc; 365 result.astc.block = ffi::WGPUAstcBlock_B12x12; 366 result.astc.channel = ffi::WGPUAstcChannel_Unorm; 367 break; 368 case dom::GPUTextureFormat::Astc_12x12_unorm_srgb: 369 result.tag = ffi::WGPUTextureFormat_Astc; 370 result.astc.block = ffi::WGPUAstcBlock_B12x12; 371 result.astc.channel = ffi::WGPUAstcChannel_UnormSrgb; 372 break; 373 case dom::GPUTextureFormat::Etc2_rgb8unorm: 374 result.tag = ffi::WGPUTextureFormat_Etc2Rgb8Unorm; 375 break; 376 case dom::GPUTextureFormat::Etc2_rgb8unorm_srgb: 377 result.tag = ffi::WGPUTextureFormat_Etc2Rgb8UnormSrgb; 378 break; 379 case dom::GPUTextureFormat::Etc2_rgb8a1unorm: 380 result.tag = ffi::WGPUTextureFormat_Etc2Rgb8A1Unorm; 381 break; 382 case dom::GPUTextureFormat::Etc2_rgb8a1unorm_srgb: 383 result.tag = ffi::WGPUTextureFormat_Etc2Rgb8A1UnormSrgb; 384 break; 385 case dom::GPUTextureFormat::Etc2_rgba8unorm: 386 result.tag = ffi::WGPUTextureFormat_Etc2Rgba8Unorm; 387 break; 388 case dom::GPUTextureFormat::Etc2_rgba8unorm_srgb: 389 result.tag = ffi::WGPUTextureFormat_Etc2Rgba8UnormSrgb; 390 break; 391 case dom::GPUTextureFormat::Eac_r11unorm: 392 result.tag = ffi::WGPUTextureFormat_EacR11Unorm; 393 break; 394 case dom::GPUTextureFormat::Eac_r11snorm: 395 result.tag = ffi::WGPUTextureFormat_EacR11Snorm; 396 break; 397 case dom::GPUTextureFormat::Eac_rg11unorm: 398 result.tag = ffi::WGPUTextureFormat_EacRg11Unorm; 399 break; 400 case dom::GPUTextureFormat::Eac_rg11snorm: 401 result.tag = ffi::WGPUTextureFormat_EacRg11Snorm; 402 break; 403 case dom::GPUTextureFormat::Rgb10a2uint: 404 result.tag = ffi::WGPUTextureFormat_Rgb10a2Uint; 405 break; 406 } 407 408 // Clang will check for us that the switch above is exhaustive, 409 // but not if we add a 'default' case. So, check this here. 410 MOZ_RELEASE_ASSERT(result.tag != ffi::WGPUTextureFormat_Sentinel, 411 "unexpected texture format enum"); 412 413 return result; 414 } 415 416 ffi::WGPUTextureAspect ConvertTextureAspect( 417 const dom::GPUTextureAspect& aAspect) { 418 ffi::WGPUTextureAspect result = ffi::WGPUTextureAspect_Sentinel; 419 switch (aAspect) { 420 case dom::GPUTextureAspect::All: 421 result = ffi::WGPUTextureAspect_All; 422 break; 423 case dom::GPUTextureAspect::Depth_only: 424 result = ffi::WGPUTextureAspect_DepthOnly; 425 break; 426 case dom::GPUTextureAspect::Stencil_only: 427 result = ffi::WGPUTextureAspect_StencilOnly; 428 break; 429 } 430 431 // Clang will check for us that the switch above is exhaustive, 432 // but not if we add a 'default' case. So, check this here. 433 MOZ_RELEASE_ASSERT(result != ffi::WGPUTextureAspect_Sentinel, 434 "unexpected texture aspect enum"); 435 436 return result; 437 } 438 439 ffi::WGPUVertexFormat ConvertVertexFormat(const dom::GPUVertexFormat& aFormat) { 440 ffi::WGPUVertexFormat result = ffi::WGPUVertexFormat_Sentinel; 441 switch (aFormat) { 442 case dom::GPUVertexFormat::Uint8: 443 result = ffi::WGPUVertexFormat_Uint8; 444 break; 445 case dom::GPUVertexFormat::Uint8x2: 446 result = ffi::WGPUVertexFormat_Uint8x2; 447 break; 448 case dom::GPUVertexFormat::Uint8x4: 449 result = ffi::WGPUVertexFormat_Uint8x4; 450 break; 451 case dom::GPUVertexFormat::Sint8: 452 result = ffi::WGPUVertexFormat_Sint8; 453 break; 454 case dom::GPUVertexFormat::Sint8x2: 455 result = ffi::WGPUVertexFormat_Sint8x2; 456 break; 457 case dom::GPUVertexFormat::Sint8x4: 458 result = ffi::WGPUVertexFormat_Sint8x4; 459 break; 460 case dom::GPUVertexFormat::Unorm8: 461 result = ffi::WGPUVertexFormat_Unorm8; 462 break; 463 case dom::GPUVertexFormat::Unorm8x2: 464 result = ffi::WGPUVertexFormat_Unorm8x2; 465 break; 466 case dom::GPUVertexFormat::Unorm8x4: 467 result = ffi::WGPUVertexFormat_Unorm8x4; 468 break; 469 case dom::GPUVertexFormat::Snorm8: 470 result = ffi::WGPUVertexFormat_Snorm8; 471 break; 472 case dom::GPUVertexFormat::Snorm8x2: 473 result = ffi::WGPUVertexFormat_Snorm8x2; 474 break; 475 case dom::GPUVertexFormat::Snorm8x4: 476 result = ffi::WGPUVertexFormat_Snorm8x4; 477 break; 478 case dom::GPUVertexFormat::Uint16: 479 result = ffi::WGPUVertexFormat_Uint16; 480 break; 481 case dom::GPUVertexFormat::Uint16x2: 482 result = ffi::WGPUVertexFormat_Uint16x2; 483 break; 484 case dom::GPUVertexFormat::Uint16x4: 485 result = ffi::WGPUVertexFormat_Uint16x4; 486 break; 487 case dom::GPUVertexFormat::Sint16: 488 result = ffi::WGPUVertexFormat_Sint16; 489 break; 490 case dom::GPUVertexFormat::Sint16x2: 491 result = ffi::WGPUVertexFormat_Sint16x2; 492 break; 493 case dom::GPUVertexFormat::Sint16x4: 494 result = ffi::WGPUVertexFormat_Sint16x4; 495 break; 496 case dom::GPUVertexFormat::Unorm16: 497 result = ffi::WGPUVertexFormat_Unorm16; 498 break; 499 case dom::GPUVertexFormat::Unorm16x2: 500 result = ffi::WGPUVertexFormat_Unorm16x2; 501 break; 502 case dom::GPUVertexFormat::Unorm16x4: 503 result = ffi::WGPUVertexFormat_Unorm16x4; 504 break; 505 case dom::GPUVertexFormat::Snorm16: 506 result = ffi::WGPUVertexFormat_Snorm16; 507 break; 508 case dom::GPUVertexFormat::Snorm16x2: 509 result = ffi::WGPUVertexFormat_Snorm16x2; 510 break; 511 case dom::GPUVertexFormat::Snorm16x4: 512 result = ffi::WGPUVertexFormat_Snorm16x4; 513 break; 514 case dom::GPUVertexFormat::Float16: 515 result = ffi::WGPUVertexFormat_Float16; 516 break; 517 case dom::GPUVertexFormat::Float16x2: 518 result = ffi::WGPUVertexFormat_Float16x2; 519 break; 520 case dom::GPUVertexFormat::Float16x4: 521 result = ffi::WGPUVertexFormat_Float16x4; 522 break; 523 case dom::GPUVertexFormat::Float32: 524 result = ffi::WGPUVertexFormat_Float32; 525 break; 526 case dom::GPUVertexFormat::Float32x2: 527 result = ffi::WGPUVertexFormat_Float32x2; 528 break; 529 case dom::GPUVertexFormat::Float32x3: 530 result = ffi::WGPUVertexFormat_Float32x3; 531 break; 532 case dom::GPUVertexFormat::Float32x4: 533 result = ffi::WGPUVertexFormat_Float32x4; 534 break; 535 case dom::GPUVertexFormat::Uint32: 536 result = ffi::WGPUVertexFormat_Uint32; 537 break; 538 case dom::GPUVertexFormat::Uint32x2: 539 result = ffi::WGPUVertexFormat_Uint32x2; 540 break; 541 case dom::GPUVertexFormat::Uint32x3: 542 result = ffi::WGPUVertexFormat_Uint32x3; 543 break; 544 case dom::GPUVertexFormat::Uint32x4: 545 result = ffi::WGPUVertexFormat_Uint32x4; 546 break; 547 case dom::GPUVertexFormat::Sint32: 548 result = ffi::WGPUVertexFormat_Sint32; 549 break; 550 case dom::GPUVertexFormat::Sint32x2: 551 result = ffi::WGPUVertexFormat_Sint32x2; 552 break; 553 case dom::GPUVertexFormat::Sint32x3: 554 result = ffi::WGPUVertexFormat_Sint32x3; 555 break; 556 case dom::GPUVertexFormat::Sint32x4: 557 result = ffi::WGPUVertexFormat_Sint32x4; 558 break; 559 case dom::GPUVertexFormat::Unorm10_10_10_2: 560 result = ffi::WGPUVertexFormat_Unorm10_10_10_2; 561 break; 562 case dom::GPUVertexFormat::Unorm8x4_bgra: 563 result = ffi::WGPUVertexFormat_Unorm8x4Bgra; 564 break; 565 } 566 567 // Clang will check for us that the switch above is exhaustive, 568 // but not if we add a 'default' case. So, check this here. 569 MOZ_RELEASE_ASSERT(result != ffi::WGPUVertexFormat_Sentinel, 570 "unexpected texture format enum"); 571 572 return result; 573 } 574 575 ffi::WGPUMultisampleState ConvertMultisampleState( 576 const dom::GPUMultisampleState& aDesc) { 577 ffi::WGPUMultisampleState desc = {}; 578 desc.count = aDesc.mCount; 579 desc.mask = aDesc.mMask; 580 desc.alpha_to_coverage_enabled = aDesc.mAlphaToCoverageEnabled; 581 return desc; 582 } 583 584 ffi::WGPUBlendComponent ConvertBlendComponent( 585 const dom::GPUBlendComponent& aDesc) { 586 ffi::WGPUBlendComponent desc = {}; 587 desc.src_factor = ffi::WGPUBlendFactor(aDesc.mSrcFactor); 588 desc.dst_factor = ffi::WGPUBlendFactor(aDesc.mDstFactor); 589 desc.operation = ffi::WGPUBlendOperation(aDesc.mOperation); 590 return desc; 591 } 592 593 ffi::WGPUStencilFaceState ConvertStencilFaceState( 594 const dom::GPUStencilFaceState& aDesc) { 595 ffi::WGPUStencilFaceState desc = {}; 596 desc.compare = ConvertCompareFunction(aDesc.mCompare); 597 desc.fail_op = ffi::WGPUStencilOperation(aDesc.mFailOp); 598 desc.depth_fail_op = ffi::WGPUStencilOperation(aDesc.mDepthFailOp); 599 desc.pass_op = ffi::WGPUStencilOperation(aDesc.mPassOp); 600 return desc; 601 } 602 603 ffi::WGPUDepthStencilState ConvertDepthStencilState( 604 const dom::GPUDepthStencilState& aDesc) { 605 ffi::WGPUDepthStencilState desc = {}; 606 desc.format = ConvertTextureFormat(aDesc.mFormat); 607 desc.depth_write_enabled = aDesc.mDepthWriteEnabled; 608 desc.depth_compare = ConvertCompareFunction(aDesc.mDepthCompare); 609 desc.stencil.front = ConvertStencilFaceState(aDesc.mStencilFront); 610 desc.stencil.back = ConvertStencilFaceState(aDesc.mStencilBack); 611 desc.stencil.read_mask = aDesc.mStencilReadMask; 612 desc.stencil.write_mask = aDesc.mStencilWriteMask; 613 desc.bias.constant = aDesc.mDepthBias; 614 desc.bias.slope_scale = aDesc.mDepthBiasSlopeScale; 615 desc.bias.clamp = aDesc.mDepthBiasClamp; 616 return desc; 617 } 618 619 ffi::WGPUPredefinedColorSpace ConvertPredefinedColorSpace( 620 const dom::PredefinedColorSpace& aColorSpace) { 621 ffi::WGPUPredefinedColorSpace result = ffi::WGPUPredefinedColorSpace_Sentinel; 622 switch (aColorSpace) { 623 case dom::PredefinedColorSpace::Srgb: 624 result = ffi::WGPUPredefinedColorSpace_Srgb; 625 break; 626 case dom::PredefinedColorSpace::Display_p3: 627 result = ffi::WGPUPredefinedColorSpace_DisplayP3; 628 break; 629 } 630 631 // Clang will check for us that the switch above is exhaustive, 632 // but not if we add a 'default' case. So, check this here. 633 MOZ_RELEASE_ASSERT(result != ffi::WGPUPredefinedColorSpace_Sentinel, 634 "unexpected predefined color space enum"); 635 636 return result; 637 } 638 639 // Extract a list of dynamic offsets from a larger JS-supplied buffer. 640 // Used by implementions of the `setBindGroup` method of the spec's 641 // `GPUBindingCommandsMixin`. 642 // 643 // If the given start/length are out of bounds, sets a 644 // `RangeError` in `aRv` and returns `Nothing`. 645 mozilla::Maybe<mozilla::Buffer<uint32_t>> GetDynamicOffsetsFromArray( 646 const dom::Uint32Array& aDynamicOffsetsData, 647 uint64_t aDynamicOffsetsDataStart, uint64_t aDynamicOffsetsDataLength, 648 ErrorResult& aRv) { 649 auto dynamicOffsets = 650 aDynamicOffsetsData.CreateFromData<mozilla::Buffer<uint32_t>>( 651 [&](const size_t& aLength) 652 -> mozilla::Maybe<std::pair<uint64_t, uint64_t>> { 653 auto checkedLength = 654 CheckedInt<uint64_t>(aDynamicOffsetsDataStart) + 655 aDynamicOffsetsDataLength; 656 if (!checkedLength.isValid() || checkedLength.value() > aLength) { 657 return mozilla::Nothing(); 658 } else { 659 return mozilla::Some(std::make_pair(aDynamicOffsetsDataStart, 660 aDynamicOffsetsDataLength)); 661 } 662 }); 663 664 if (dynamicOffsets.isNothing()) { 665 aRv.ThrowRangeError<dom::MSG_VALUE_OUT_OF_RANGE>( 666 "dynamicOffsetsDataStart/Length"); 667 } 668 669 return dynamicOffsets; 670 } 671 672 } // namespace mozilla::webgpu