tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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