// Copyright 2019 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "src/dawn/native/Format.h"

#include <bitset>
#include <optional>
#include <utility>

#include "src/dawn/common/MatchVariant.h"
#include "src/dawn/native/Device.h"
#include "src/dawn/native/EnumMaskIterator.h"
#include "src/dawn/native/Features.h"
#include "src/dawn/native/Texture.h"
#include "src/utils/numeric.h"
#include "src/utils/typed_integer.h"

namespace dawn::native {

using Cap = FormatCapability;

// Format

SampleTypeBit SampleTypeToSampleTypeBit(wgpu::TextureSampleType sampleType) {
    switch (sampleType) {
        case wgpu::TextureSampleType::Float:
        case wgpu::TextureSampleType::UnfilterableFloat:
        case wgpu::TextureSampleType::Sint:
        case wgpu::TextureSampleType::Uint:
        case wgpu::TextureSampleType::Depth:
        case wgpu::TextureSampleType::BindingNotUsed:
        case wgpu::TextureSampleType::Undefined:
            // When the compiler complains that you need to add a case statement here, please
            // also add a corresponding static assert below!
            break;
    }

    static_assert(static_cast<uint32_t>(wgpu::TextureSampleType::BindingNotUsed) == 0);
    if (sampleType == wgpu::TextureSampleType::BindingNotUsed) {
        return SampleTypeBit::None;
    }

    static_assert(static_cast<uint32_t>(wgpu::TextureSampleType::Undefined) == 1);
    if (sampleType == wgpu::TextureSampleType::Undefined) {
        DAWN_UNREACHABLE();
        return SampleTypeBit::None;
    }

    // Check that SampleTypeBit bits are in the same position / order as the respective
    // wgpu::TextureSampleType value.
    static_assert(SampleTypeBit::Float ==
                  static_cast<SampleTypeBit>(
                      1 << (static_cast<uint32_t>(wgpu::TextureSampleType::Float) - 2)));
    static_assert(
        SampleTypeBit::UnfilterableFloat ==
        static_cast<SampleTypeBit>(
            1 << (static_cast<uint32_t>(wgpu::TextureSampleType::UnfilterableFloat) - 2)));
    static_assert(SampleTypeBit::Uint ==
                  static_cast<SampleTypeBit>(
                      1 << (static_cast<uint32_t>(wgpu::TextureSampleType::Uint) - 2)));
    static_assert(SampleTypeBit::Sint ==
                  static_cast<SampleTypeBit>(
                      1 << (static_cast<uint32_t>(wgpu::TextureSampleType::Sint) - 2)));
    static_assert(SampleTypeBit::Depth ==
                  static_cast<SampleTypeBit>(
                      1 << (static_cast<uint32_t>(wgpu::TextureSampleType::Depth) - 2)));
    return static_cast<SampleTypeBit>(1 << (static_cast<uint32_t>(sampleType) - 2));
}

const UnsupportedReason Format::supported;

bool Format::IsSupported() const {
    return std::holds_alternative<std::monostate>(unsupportedReason);
}

bool Format::IsColor() const {
    return aspects == Aspect::Color;
}

bool Format::HasDepth() const {
    return aspects & Aspect::Depth;
}

bool Format::HasStencil() const {
    return aspects & Aspect::Stencil;
}

bool Format::HasDepthOrStencil() const {
    return aspects & (Aspect::Depth | Aspect::Stencil);
}

bool Format::HasAlphaChannel() const {
    // This is true for current formats. May need revisit if new formats and extensions are added.
    return componentCount == 4 && IsColor();
}

bool Format::IsSnorm() const {
    return format == wgpu::TextureFormat::RGBA8Snorm || format == wgpu::TextureFormat::RG8Snorm ||
           format == wgpu::TextureFormat::R8Snorm;
}

bool Format::IsMultiPlanar() const {
    return aspects & (Aspect::Plane0 | Aspect::Plane1 | Aspect::Plane2);
}

bool Format::CopyCompatibleWith(const Format& otherFormat) const {
    // TODO(crbug.com/dawn/1332): Add a Format compatibility matrix.
    return baseFormat == otherFormat.baseFormat;
}

bool Format::ViewCompatibleWith(const Format& otherFormat) const {
    // TODO(crbug.com/dawn/1332): Add a Format compatibility matrix.
    return baseFormat == otherFormat.baseFormat;
}

const AspectInfo& Format::GetAspectInfo(wgpu::TextureAspect aspect) const {
    return GetAspectInfo(SelectFormatAspects(*this, aspect));
}

const AspectInfo& Format::GetAspectInfo(Aspect aspect) const {
    DAWN_CHECK(HasOneBit(aspect));
    DAWN_CHECK(aspects & aspect);
    const size_t aspectIndex = GetAspectIndex(aspect);
    DAWN_CHECK(aspectIndex < GetAspectCount(aspects));
    return aspectInfo[aspectIndex];
}

FormatIndex Format::GetIndex() const {
    return ComputeFormatIndex(format);
}

// FormatSet implementation

bool FormatSet::operator[](const Format& format) const {
    return Base::operator[](format.GetIndex());
}

typename std::bitset<kKnownFormatCount>::reference FormatSet::operator[](const Format& format) {
    return Base::operator[](format.GetIndex());
}

// Implementation details of the format table of the DeviceBase

// For the enum for formats are packed but this might change when we have a broader feature
// mechanism for webgpu.h. Formats start at 1 because 0 is the undefined format.
// Dawn internal formats start with a prefix. We strip the prefix and then pack
// them after the last WebGPU format.
FormatIndex ComputeFormatIndex(wgpu::TextureFormat format) {
    uint32_t formatValue = static_cast<uint32_t>(format);
    switch (formatValue & kEnumPrefixMask) {
        case 0: {
            // This takes advantage of overflows to make the index of TextureFormat::Undefined
            // outside of the range of the FormatTable.
            static_assert(static_cast<uint32_t>(wgpu::TextureFormat::Undefined) - 1 >
                          kKnownFormatCount);

            uint32_t index = formatValue - 1;
            if (index < kWebGPUFormatCount) {
                return static_cast<FormatIndex>(index);
            }
            break;
        }
        case kDawnEnumPrefix: {
            uint32_t dawnIndex = formatValue & ~kEnumPrefixMask;
            if (dawnIndex < kDawnFormatCount) {
                return static_cast<FormatIndex>(dawnIndex + kWebGPUFormatCount);
            }
            break;
        }
        default:
            break;
    }
    // Invalid format. Return an index outside the format table.
    return FormatIndex(~0u);
}

// Adds capabilities to color formats.
void ComputeFormatCapabilities(const DeviceBase* device, FormatTable& table) {
    // Track the set of supported formats independently of Format::unsupportedReason because that
    // std::variant does not allow discriminating between "uninitialized" and "supported".
    ityp::bitset<FormatIndex, kKnownFormatCount> formatSupported;

    // Add initial capabilities to formats.
    auto InitialCapsAddedBy = [&](std::optional<Feature> feature,
                                  std::initializer_list<wgpu::TextureFormat> formats, Cap caps) {
        const bool supported = !feature.has_value() || device->HasFeature(*feature);

        for (wgpu::TextureFormat fmt : formats) {
            FormatIndex index = ComputeFormatIndex(fmt);
            DAWN_CHECK(index < table.size());
            Format& format = table[index];

            if (supported) {
                format.caps |= caps;  // set the initial capabilities
                format.unsupportedReason = Format::supported;
                formatSupported[index] = true;
            } else if (!formatSupported[index] &&
                       std::holds_alternative<std::monostate>(format.unsupportedReason)) {
                auto requestedFeature = *feature;
                format.unsupportedReason =
                    requestedFeature == Feature::CoreFeaturesAndLimits
                        ? UnsupportedReason{CompatibilityMode{}}
                        : UnsupportedReason{RequiresFeature{ToCppAPI(requestedFeature)}};
            }
        }
    };

    // Add caps for the supported formats
    auto AddCaps = [&](std::initializer_list<wgpu::TextureFormat> formats, Cap caps) {
        DAWN_CHECK(caps != Cap::None);
        for (wgpu::TextureFormat fmt : formats) {
            FormatIndex index = ComputeFormatIndex(fmt);
            DAWN_CHECK(index < table.size());
            Format& format = table[index];

            if (!format.IsSupported()) {
                continue;
            }
            format.caps |= caps;
        }
    };
    // ---Initial Format capabilities without any feature ---

    // R8Snorm, RG8Snorm, RG11B10Ufloat, and RGB9E5Ufloat are always considered supported
    // even with Cap::None capabilities.
    InitialCapsAddedBy(std::nullopt,
                       {wgpu::TextureFormat::R8Snorm, wgpu::TextureFormat::RG8Snorm,
                        wgpu::TextureFormat::RG11B10Ufloat, wgpu::TextureFormat::RGB9E5Ufloat},
                       Cap::None);

    InitialCapsAddedBy(std::nullopt,
                       {wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::RG8Unorm,
                        wgpu::TextureFormat::RGBA8UnormSrgb, wgpu::TextureFormat::BGRA8Unorm,
                        wgpu::TextureFormat::R16Float, wgpu::TextureFormat::RG16Float,
                        wgpu::TextureFormat::RGB10A2Unorm},
                       Cap::Renderable | Cap::Multisample | Cap::Resolve | Cap::Blendable);

    InitialCapsAddedBy(std::nullopt, {wgpu::TextureFormat::RGBA8Snorm},
                       Cap::StorageROnly | Cap::StorageWOnly);
    InitialCapsAddedBy(std::nullopt, {wgpu::TextureFormat::RGBA8Unorm},
                       Cap::StorageROnly | Cap::StorageWOnly | Cap::Renderable | Cap::Multisample |
                           Cap::Resolve | Cap::Blendable);

    InitialCapsAddedBy(
        std::nullopt,
        {wgpu::TextureFormat::R8Uint, wgpu::TextureFormat::R8Sint, wgpu::TextureFormat::R16Uint,
         wgpu::TextureFormat::R16Sint, wgpu::TextureFormat::RG8Uint, wgpu::TextureFormat::RG8Sint,
         wgpu::TextureFormat::RG16Uint, wgpu::TextureFormat::RG16Sint,
         wgpu::TextureFormat::RGB10A2Uint},
        Cap::Renderable);

    InitialCapsAddedBy(
        std::nullopt,
        {wgpu::TextureFormat::R32Uint, wgpu::TextureFormat::R32Sint, wgpu::TextureFormat::R32Float},
        Cap::Renderable | Cap::StorageROnly | Cap::StorageWOnly | Cap::StorageRW);

    InitialCapsAddedBy(std::nullopt,
                       {wgpu::TextureFormat::RGBA8Uint, wgpu::TextureFormat::RGBA8Sint},
                       Cap::Renderable | Cap::StorageROnly | Cap::StorageWOnly);

    InitialCapsAddedBy(std::nullopt,
                       {wgpu::TextureFormat::RG32Uint, wgpu::TextureFormat::RG32Sint,
                        wgpu::TextureFormat::RG32Float},
                       Cap::Renderable);

    InitialCapsAddedBy(std::nullopt,
                       {wgpu::TextureFormat::RGBA16Uint, wgpu::TextureFormat::RGBA16Sint},
                       Cap::Renderable | Cap::StorageROnly | Cap::StorageWOnly);

    InitialCapsAddedBy(
        std::nullopt, {wgpu::TextureFormat::RGBA16Float},
        Cap::Renderable | Cap::StorageROnly | Cap::StorageWOnly | Cap::Resolve | Cap::Blendable);

    InitialCapsAddedBy(std::nullopt,
                       {wgpu::TextureFormat::RGBA32Uint, wgpu::TextureFormat::RGBA32Sint,
                        wgpu::TextureFormat::RGBA32Float},
                       Cap::Renderable | Cap::StorageROnly | Cap::StorageWOnly);

    // Initialize the format capabilities and add the pre-initialized format capabilities when
    // relevant features are enabled

    // The two YCbCr extensions each add support for OpaqueYCbCrAndroid.
    InitialCapsAddedBy(Feature::YCbCrVulkanSamplers, {wgpu::TextureFormat::OpaqueYCbCrAndroid},
                       Cap::None);
    InitialCapsAddedBy(Feature::OpaqueYCbCrAndroidForExternalTexture,
                       {wgpu::TextureFormat::OpaqueYCbCrAndroid}, Cap::None);

    InitialCapsAddedBy(Feature::CoreFeaturesAndLimits, {wgpu::TextureFormat::BGRA8UnormSrgb},
                       Cap::Renderable | Cap::Multisample | Cap::Resolve | Cap::Blendable);

    if (device->HasFeature(Feature::CoreFeaturesAndLimits)) {
        AddCaps(
            {wgpu::TextureFormat::R8Uint, wgpu::TextureFormat::R8Sint, wgpu::TextureFormat::R16Uint,
             wgpu::TextureFormat::R16Sint, wgpu::TextureFormat::RG8Uint,
             wgpu::TextureFormat::RG8Sint, wgpu::TextureFormat::RG16Uint,
             wgpu::TextureFormat::RG16Sint, wgpu::TextureFormat::RGB10A2Uint,
             wgpu::TextureFormat::R32Float, wgpu::TextureFormat::RGBA8Uint,
             wgpu::TextureFormat::RGBA8Sint, wgpu::TextureFormat::RGBA16Float,
             wgpu::TextureFormat::RGBA16Uint, wgpu::TextureFormat::RGBA16Sint},
            Cap::Multisample);
        AddCaps({wgpu::TextureFormat::RG32Uint, wgpu::TextureFormat::RG32Sint,
                 wgpu::TextureFormat::RG32Float},
                Cap::StorageROnly | Cap::StorageWOnly);
    }

    if (device->HasFeature(Feature::PixelLocalStorageCoherent) ||
        device->HasFeature(Feature::PixelLocalStorageNonCoherent)) {
        AddCaps({wgpu::TextureFormat::R32Uint, wgpu::TextureFormat::R32Sint,
                 wgpu::TextureFormat::R32Float},
                Cap::PLS);
    }

    if (device->HasFeature(Feature::Float32Blendable)) {
        AddCaps({wgpu::TextureFormat::R32Float, wgpu::TextureFormat::RG32Float,
                 wgpu::TextureFormat::RGBA32Float},
                Cap::Blendable);
    }

    InitialCapsAddedBy(Feature::TextureFormatsTier1,
                       {wgpu::TextureFormat::R16Unorm, wgpu::TextureFormat::RG16Unorm,
                        wgpu::TextureFormat::RGBA16Unorm, wgpu::TextureFormat::R16Snorm,
                        wgpu::TextureFormat::RG16Snorm, wgpu::TextureFormat::RGBA16Snorm},
                       Cap::Renderable | Cap::Multisample | Cap::Blendable | Cap::StorageROnly |
                           Cap::StorageWOnly);

    if (device->HasFeature(Feature::TextureFormatsTier1)) {
        AddCaps({wgpu::TextureFormat::R8Snorm, wgpu::TextureFormat::RG8Snorm,
                 wgpu::TextureFormat::RGBA8Snorm},
                Cap::Renderable | Cap::Multisample | Cap::Resolve | Cap::Blendable);

        AddCaps(
            {
                wgpu::TextureFormat::R8Unorm,
                wgpu::TextureFormat::R8Snorm,
                wgpu::TextureFormat::R8Uint,
                wgpu::TextureFormat::R8Sint,
                wgpu::TextureFormat::RG8Unorm,
                wgpu::TextureFormat::RG8Snorm,
                wgpu::TextureFormat::RG8Uint,
                wgpu::TextureFormat::RG8Sint,
                wgpu::TextureFormat::R16Uint,
                wgpu::TextureFormat::R16Sint,
                wgpu::TextureFormat::R16Float,
                wgpu::TextureFormat::RG16Uint,
                wgpu::TextureFormat::RG16Sint,
                wgpu::TextureFormat::RG16Float,
                wgpu::TextureFormat::RGB10A2Uint,
                wgpu::TextureFormat::RGB10A2Unorm,
                wgpu::TextureFormat::RG11B10Ufloat,
            },
            Cap::StorageROnly | Cap::StorageWOnly);
    }

    if (device->HasFeature(Feature::TextureFormatsTier2)) {
        AddCaps(
            {wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Uint, wgpu::TextureFormat::R8Sint,
             wgpu::TextureFormat::R16Uint, wgpu::TextureFormat::R16Sint,
             wgpu::TextureFormat::R16Float, wgpu::TextureFormat::RGBA8Unorm,
             wgpu::TextureFormat::RGBA8Uint, wgpu::TextureFormat::RGBA8Sint,
             wgpu::TextureFormat::RGBA16Uint, wgpu::TextureFormat::RGBA16Sint,
             wgpu::TextureFormat::RGBA16Float, wgpu::TextureFormat::RGBA32Uint,
             wgpu::TextureFormat::RGBA32Sint, wgpu::TextureFormat::RGBA32Float},
            Cap::StorageRW);
    }

    if (device->HasFeature(Feature::BGRA8UnormStorage)) {
        AddCaps({wgpu::TextureFormat::BGRA8Unorm}, Cap::StorageWOnly);
    }

    if (device->HasFeature(Feature::RG11B10UfloatRenderable)) {
        AddCaps({wgpu::TextureFormat::RG11B10Ufloat},
                Cap::Renderable | Cap::Multisample | Cap::Resolve | Cap::Blendable);
    }

    InitialCapsAddedBy(Feature::Unorm16TextureFormats,
                       {wgpu::TextureFormat::R16Unorm, wgpu::TextureFormat::RG16Unorm,
                        wgpu::TextureFormat::RGBA16Unorm},
                       Cap::Renderable | Cap::Multisample | Cap::Resolve);
}

FormatTable BuildFormatTable(const DeviceBase* device) {
    FormatTable table;
    FormatSet formatsSet;

    static constexpr SampleTypeBit kAnyFloat =
        SampleTypeBit::Float | SampleTypeBit::UnfilterableFloat;

    auto AddFormat = [&table, &formatsSet](Format format) {
        FormatIndex index = ComputeFormatIndex(format.format);
        DAWN_CHECK(index < table.size());

        // This checks that each format is set at most once, the first part of checking that all
        // formats are set exactly once.
        DAWN_CHECK(!formatsSet[index]);

        // Vulkan describes bytesPerRow in units of texels. If there's any format for which this
        // DAWN_CHECK isn't true, then additional validation on bytesPerRow must be added.
        const bool hasMultipleAspects = !HasOneBit(format.aspects);
        DAWN_CHECK(hasMultipleAspects ||
                   (kTextureBytesPerRowAlignment % format.aspectInfo[0].block.byteSize) == 0);

        table[index] = format;
        formatsSet.set(index);
    };

    using Width = TypedInteger<struct WidthT, uint32_t>;
    using Height = TypedInteger<struct HeightT, uint32_t>;
    using ByteSize = TypedInteger<struct ByteSizeT, uint32_t>;
    using RenderTargetPixelByteCost = TypedInteger<struct RenderTargetPixelByteCostT, uint32_t>;
    using ComponentCount = TypedInteger<struct ComponentCountT, uint32_t>;
    using RenderTargetComponentAlignment =
        TypedInteger<struct RenderTargetComponentAlignmentT, uint32_t>;

    auto DefineColorFormat =
        [&](wgpu::TextureFormat fmt, ByteSize byteSize, SampleTypeBit sampleTypes,
            ComponentCount componentCount,
            RenderTargetPixelByteCost rtPixelCost = RenderTargetPixelByteCost(0u),
            RenderTargetComponentAlignment rtComponentAlign = RenderTargetComponentAlignment(0u),
            wgpu::TextureFormat baseFormat = wgpu::TextureFormat::Undefined) {
            Format internalFormat;
            internalFormat.format = fmt;
            internalFormat.baseFormat =
                (baseFormat == wgpu::TextureFormat::Undefined) ? fmt : baseFormat;
            internalFormat.isCompressed = false;
            internalFormat.aspects = Aspect::Color;
            internalFormat.componentCount = dchecked_cast<uint8_t>(componentCount);
            internalFormat.unsupportedReason = std::monostate{};
            internalFormat.caps = Cap::None;

            if (rtPixelCost != RenderTargetPixelByteCost(0u)) {
                internalFormat.renderTargetPixelByteCost = dchecked_cast<uint8_t>(rtPixelCost);
                internalFormat.renderTargetComponentAlignment =
                    dchecked_cast<uint8_t>(rtComponentAlign);
            }
            AspectInfo* aspect = internalFormat.aspectInfo.data();
            aspect->block.byteSize = static_cast<uint32_t>(byteSize);
            aspect->block.width = 1;
            aspect->block.height = 1;
            aspect->supportedSampleTypes = sampleTypes;
            aspect->format = fmt;

            if (HasOneBit(sampleTypes)) {
                switch (sampleTypes) {
                    case SampleTypeBit::Float:
                    case SampleTypeBit::UnfilterableFloat:
                        aspect->baseType = TextureComponentType::Float;
                        break;
                    case SampleTypeBit::Sint:
                        aspect->baseType = TextureComponentType::Sint;
                        break;
                    case SampleTypeBit::Uint:
                        aspect->baseType = TextureComponentType::Uint;
                        break;
                    default:
                        DAWN_UNREACHABLE();
                }
            } else {
                aspect->baseType = TextureComponentType::Float;
            }

            AddFormat(internalFormat);
        };

    SampleTypeBit sampleTypeFor32BitFloatFormats = device->HasFeature(Feature::Float32Filterable)
                                                       ? kAnyFloat
                                                       : SampleTypeBit::UnfilterableFloat;
    SampleTypeBit sampleTypeForNorm16Formats =
        (device->HasFeature(Feature::Unorm16TextureFormats) ||
         device->HasFeature(Feature::Unorm16Filterable))
            ? kAnyFloat
            : SampleTypeBit::UnfilterableFloat;

    // 1 byte
    DefineColorFormat(wgpu::TextureFormat::R8Unorm, ByteSize(1u), kAnyFloat, ComponentCount(1u),
                      RenderTargetPixelByteCost(1u), RenderTargetComponentAlignment(1u));
    DefineColorFormat(wgpu::TextureFormat::R8Snorm, ByteSize(1u), kAnyFloat, ComponentCount(1u),
                      RenderTargetPixelByteCost(1u), RenderTargetComponentAlignment(1u));
    DefineColorFormat(wgpu::TextureFormat::R8Uint, ByteSize(1u), SampleTypeBit::Uint,
                      ComponentCount(1u), RenderTargetPixelByteCost(1u),
                      RenderTargetComponentAlignment(1u));
    DefineColorFormat(wgpu::TextureFormat::R8Sint, ByteSize(1u), SampleTypeBit::Sint,
                      ComponentCount(1u), RenderTargetPixelByteCost(1u),
                      RenderTargetComponentAlignment(1u));

    // 2 bytes
    DefineColorFormat(wgpu::TextureFormat::R16Uint, ByteSize(2u), SampleTypeBit::Uint,
                      ComponentCount(1u), RenderTargetPixelByteCost(2u),
                      RenderTargetComponentAlignment(2u));
    DefineColorFormat(wgpu::TextureFormat::R16Sint, ByteSize(2u), SampleTypeBit::Sint,
                      ComponentCount(1u), RenderTargetPixelByteCost(2u),
                      RenderTargetComponentAlignment(2u));
    DefineColorFormat(wgpu::TextureFormat::R16Float, ByteSize(2u), kAnyFloat, ComponentCount(1u),
                      RenderTargetPixelByteCost(2u), RenderTargetComponentAlignment(2u));
    DefineColorFormat(wgpu::TextureFormat::RG8Unorm, ByteSize(2u), kAnyFloat, ComponentCount(2u),
                      RenderTargetPixelByteCost(2u), RenderTargetComponentAlignment(1u));
    DefineColorFormat(wgpu::TextureFormat::RG8Snorm, ByteSize(2u), kAnyFloat, ComponentCount(2u),
                      RenderTargetPixelByteCost(2u), RenderTargetComponentAlignment(2u));
    DefineColorFormat(wgpu::TextureFormat::RG8Uint, ByteSize(2u), SampleTypeBit::Uint,
                      ComponentCount(2u), RenderTargetPixelByteCost(2u),
                      RenderTargetComponentAlignment(1u));
    DefineColorFormat(wgpu::TextureFormat::RG8Sint, ByteSize(2u), SampleTypeBit::Sint,
                      ComponentCount(2u), RenderTargetPixelByteCost(2u),
                      RenderTargetComponentAlignment(1u));

    // 4 bytes
    DefineColorFormat(wgpu::TextureFormat::R32Uint, ByteSize(4u), SampleTypeBit::Uint,
                      ComponentCount(1u), RenderTargetPixelByteCost(4u),
                      RenderTargetComponentAlignment(4u));
    DefineColorFormat(wgpu::TextureFormat::R32Sint, ByteSize(4u), SampleTypeBit::Sint,
                      ComponentCount(1u), RenderTargetPixelByteCost(4u),
                      RenderTargetComponentAlignment(4u));
    DefineColorFormat(wgpu::TextureFormat::R32Float, ByteSize(4u), sampleTypeFor32BitFloatFormats,
                      ComponentCount(1u), RenderTargetPixelByteCost(4u),
                      RenderTargetComponentAlignment(4u));
    DefineColorFormat(wgpu::TextureFormat::RG16Uint, ByteSize(4u), SampleTypeBit::Uint,
                      ComponentCount(2u), RenderTargetPixelByteCost(4u),
                      RenderTargetComponentAlignment(2u));
    DefineColorFormat(wgpu::TextureFormat::RG16Sint, ByteSize(4u), SampleTypeBit::Sint,
                      ComponentCount(2u), RenderTargetPixelByteCost(4u),
                      RenderTargetComponentAlignment(2u));
    DefineColorFormat(wgpu::TextureFormat::RG16Float, ByteSize(4u), kAnyFloat, ComponentCount(2u),
                      RenderTargetPixelByteCost(4u), RenderTargetComponentAlignment(2u));
    DefineColorFormat(wgpu::TextureFormat::RGBA8Unorm, ByteSize(4u), kAnyFloat, ComponentCount(4u),
                      RenderTargetPixelByteCost(8u), RenderTargetComponentAlignment(1u));
    DefineColorFormat(wgpu::TextureFormat::RGBA8UnormSrgb, ByteSize(4u), kAnyFloat,
                      ComponentCount(4u), RenderTargetPixelByteCost(8u),
                      RenderTargetComponentAlignment(1u), wgpu::TextureFormat::RGBA8Unorm);
    DefineColorFormat(wgpu::TextureFormat::RGBA8Snorm, ByteSize(4u), kAnyFloat, ComponentCount(4u),
                      RenderTargetPixelByteCost(4u), RenderTargetComponentAlignment(4u));
    DefineColorFormat(wgpu::TextureFormat::RGBA8Uint, ByteSize(4u), SampleTypeBit::Uint,
                      ComponentCount(4u), RenderTargetPixelByteCost(4u),
                      RenderTargetComponentAlignment(1u));
    DefineColorFormat(wgpu::TextureFormat::RGBA8Sint, ByteSize(4u), SampleTypeBit::Sint,
                      ComponentCount(4u), RenderTargetPixelByteCost(4u),
                      RenderTargetComponentAlignment(1u));
    DefineColorFormat(wgpu::TextureFormat::BGRA8Unorm, ByteSize(4u), kAnyFloat, ComponentCount(4u),
                      RenderTargetPixelByteCost(8u), RenderTargetComponentAlignment(1u));
    DefineColorFormat(wgpu::TextureFormat::BGRA8UnormSrgb, ByteSize(4u), kAnyFloat,
                      ComponentCount(4u), RenderTargetPixelByteCost(8u),
                      RenderTargetComponentAlignment(1u), wgpu::TextureFormat::BGRA8Unorm);
    DefineColorFormat(wgpu::TextureFormat::RGB10A2Uint, ByteSize(4u), SampleTypeBit::Uint,
                      ComponentCount(4u), RenderTargetPixelByteCost(8u),
                      RenderTargetComponentAlignment(4u));
    DefineColorFormat(wgpu::TextureFormat::RGB10A2Unorm, ByteSize(4u), kAnyFloat,
                      ComponentCount(4u), RenderTargetPixelByteCost(8u),
                      RenderTargetComponentAlignment(4u));
    DefineColorFormat(wgpu::TextureFormat::RG11B10Ufloat, ByteSize(4u), kAnyFloat,
                      ComponentCount(3u), RenderTargetPixelByteCost(8u),
                      RenderTargetComponentAlignment(4u));
    DefineColorFormat(wgpu::TextureFormat::RGB9E5Ufloat, ByteSize(4u), kAnyFloat,
                      ComponentCount(3u));

    // The OpaqueYCbCrAndroid format acts as if it is a float format, but we later validate when it
    // is used with a static sampler that the sampler's filteringness matches what the YCbCr info
    // allows.
    DefineColorFormat(wgpu::TextureFormat::OpaqueYCbCrAndroid, ByteSize(1u), kAnyFloat,
                      ComponentCount(0u));

    // 8 bytes
    DefineColorFormat(wgpu::TextureFormat::RG32Uint, ByteSize(8u), SampleTypeBit::Uint,
                      ComponentCount(2u), RenderTargetPixelByteCost(8u),
                      RenderTargetComponentAlignment(4u));
    DefineColorFormat(wgpu::TextureFormat::RG32Sint, ByteSize(8u), SampleTypeBit::Sint,
                      ComponentCount(2u), RenderTargetPixelByteCost(8u),
                      RenderTargetComponentAlignment(4u));
    DefineColorFormat(wgpu::TextureFormat::RG32Float, ByteSize(8u), sampleTypeFor32BitFloatFormats,
                      ComponentCount(2u), RenderTargetPixelByteCost(8u),
                      RenderTargetComponentAlignment(4u));
    DefineColorFormat(wgpu::TextureFormat::RGBA16Uint, ByteSize(8u), SampleTypeBit::Uint,
                      ComponentCount(4u), RenderTargetPixelByteCost(8u),
                      RenderTargetComponentAlignment(2u));
    DefineColorFormat(wgpu::TextureFormat::RGBA16Sint, ByteSize(8u), SampleTypeBit::Sint,
                      ComponentCount(4u), RenderTargetPixelByteCost(8u),
                      RenderTargetComponentAlignment(2u));
    DefineColorFormat(wgpu::TextureFormat::RGBA16Float, ByteSize(8u), kAnyFloat, ComponentCount(4u),
                      RenderTargetPixelByteCost(8u), RenderTargetComponentAlignment(2u));

    // 16 bytes
    DefineColorFormat(wgpu::TextureFormat::RGBA32Uint, ByteSize(16u), SampleTypeBit::Uint,
                      ComponentCount(4u), RenderTargetPixelByteCost(16u),
                      RenderTargetComponentAlignment(4u));
    DefineColorFormat(wgpu::TextureFormat::RGBA32Sint, ByteSize(16u), SampleTypeBit::Sint,
                      ComponentCount(4u), RenderTargetPixelByteCost(16u),
                      RenderTargetComponentAlignment(4u));
    DefineColorFormat(wgpu::TextureFormat::RGBA32Float, ByteSize(16u),
                      sampleTypeFor32BitFloatFormats, ComponentCount(4u),
                      RenderTargetPixelByteCost(16u), RenderTargetComponentAlignment(4u));

    // Norm16
    DefineColorFormat(wgpu::TextureFormat::R16Unorm, ByteSize(2u), sampleTypeForNorm16Formats,
                      ComponentCount(1u), RenderTargetPixelByteCost(2u),
                      RenderTargetComponentAlignment(2u));
    DefineColorFormat(wgpu::TextureFormat::RG16Unorm, ByteSize(4u), sampleTypeForNorm16Formats,
                      ComponentCount(2u), RenderTargetPixelByteCost(4u),
                      RenderTargetComponentAlignment(2u));
    DefineColorFormat(wgpu::TextureFormat::RGBA16Unorm, ByteSize(8u), sampleTypeForNorm16Formats,
                      ComponentCount(4u), RenderTargetPixelByteCost(8u),
                      RenderTargetComponentAlignment(2u));
    DefineColorFormat(wgpu::TextureFormat::R16Snorm, ByteSize(2u), sampleTypeForNorm16Formats,
                      ComponentCount(1u), RenderTargetPixelByteCost(2u),
                      RenderTargetComponentAlignment(2u));
    DefineColorFormat(wgpu::TextureFormat::RG16Snorm, ByteSize(4u), sampleTypeForNorm16Formats,
                      ComponentCount(2u), RenderTargetPixelByteCost(4u),
                      RenderTargetComponentAlignment(2u));
    DefineColorFormat(wgpu::TextureFormat::RGBA16Snorm, ByteSize(8u), sampleTypeForNorm16Formats,
                      ComponentCount(4u), RenderTargetPixelByteCost(8u),
                      RenderTargetComponentAlignment(2u));

    ComputeFormatCapabilities(device, table);

    auto AddDepthFormat = [&AddFormat](wgpu::TextureFormat format, uint32_t byteSize,
                                       UnsupportedReason unsupportedReason) {
        Format internalFormat;
        internalFormat.format = format;
        internalFormat.baseFormat = format;
        internalFormat.isCompressed = false;
        internalFormat.unsupportedReason = unsupportedReason;
        internalFormat.aspects = Aspect::Depth;
        internalFormat.componentCount = 1;
        internalFormat.caps = Cap::Renderable | Cap::Multisample;
        AspectInfo* firstAspect = internalFormat.aspectInfo.data();
        firstAspect->block.byteSize = byteSize;
        firstAspect->block.width = 1;
        firstAspect->block.height = 1;
        firstAspect->baseType = TextureComponentType::Float;
        firstAspect->supportedSampleTypes = SampleTypeBit::Depth | SampleTypeBit::UnfilterableFloat;
        firstAspect->format = format;
        AddFormat(internalFormat);
    };

    auto AddStencilFormat = [&AddFormat](wgpu::TextureFormat format,
                                         UnsupportedReason unsupportedReason) {
        Format internalFormat;
        internalFormat.format = format;
        internalFormat.baseFormat = format;
        internalFormat.isCompressed = false;
        internalFormat.unsupportedReason = unsupportedReason;
        internalFormat.caps = Cap::Renderable | Cap::Multisample;
        internalFormat.aspects = Aspect::Stencil;
        internalFormat.componentCount = 1;

        // Duplicate the data for the stencil aspect in both the first and second aspect info.
        //  - aspectInfo[0] is used by AddMultiAspectFormat to copy the info for the whole
        //    stencil8 aspect of depth-stencil8 formats.
        //  - aspectInfo[1] is the actual info used in the rest of Dawn since
        //    GetAspectIndex(Aspect::Stencil) is 1.
        DAWN_CHECK(GetAspectIndex(Aspect::Stencil) == 1);

        internalFormat.aspectInfo[0].block.byteSize = 1;
        internalFormat.aspectInfo[0].block.width = 1;
        internalFormat.aspectInfo[0].block.height = 1;
        internalFormat.aspectInfo[0].baseType = TextureComponentType::Uint;
        internalFormat.aspectInfo[0].supportedSampleTypes = SampleTypeBit::Uint;
        internalFormat.aspectInfo[0].format = format;

        internalFormat.aspectInfo[1] = internalFormat.aspectInfo[0];

        AddFormat(internalFormat);
    };

    auto BaseCompressedFormat = [](wgpu::TextureFormat format, ByteSize byteSize, Width width,
                                   Height height, UnsupportedReason unsupportedReason,
                                   ComponentCount componentCount, wgpu::TextureFormat baseFormat) {
        Format internalFormat;
        internalFormat.format = format;
        internalFormat.isCompressed = true;
        internalFormat.unsupportedReason = unsupportedReason;
        internalFormat.aspects = Aspect::Color;
        internalFormat.componentCount = dchecked_cast<uint8_t>(componentCount);

        // Default baseFormat of each compressed formats should be themselves.
        if (baseFormat == wgpu::TextureFormat::Undefined) {
            internalFormat.baseFormat = format;
        } else {
            internalFormat.baseFormat = baseFormat;
        }

        AspectInfo* firstAspect = internalFormat.aspectInfo.data();
        firstAspect->block.byteSize = static_cast<uint32_t>(byteSize);
        firstAspect->block.width = static_cast<uint32_t>(width);
        firstAspect->block.height = static_cast<uint32_t>(height);
        firstAspect->baseType = TextureComponentType::Float;
        firstAspect->supportedSampleTypes = kAnyFloat;
        firstAspect->format = format;
        return internalFormat;
    };

    auto AddETCCompressedFormat =
        [&BaseCompressedFormat, &AddFormat](
            wgpu::TextureFormat format, ByteSize byteSize, Width width, Height height,
            UnsupportedReason unsupportedReason, ComponentCount componentCount,
            wgpu::TextureFormat baseFormat = wgpu::TextureFormat::Undefined) {
            Format internalFormat = BaseCompressedFormat(
                format, byteSize, width, height, unsupportedReason, componentCount, baseFormat);
            AddFormat(internalFormat);
        };

    auto AddBCCompressedFormat =
        [&BaseCompressedFormat, &AddFormat](
            wgpu::TextureFormat format, ByteSize byteSize, Width width, Height height,
            UnsupportedReason unsupportedReason, ComponentCount componentCount,
            wgpu::TextureFormat baseFormat = wgpu::TextureFormat::Undefined) {
            Format internalFormat = BaseCompressedFormat(
                format, byteSize, width, height, unsupportedReason, componentCount, baseFormat);
            internalFormat.isBC = true;
            AddFormat(internalFormat);
        };

    auto AddASTCCompressedFormat =
        [&BaseCompressedFormat, &AddFormat](
            wgpu::TextureFormat format, ByteSize byteSize, Width width, Height height,
            UnsupportedReason unsupportedReason, ComponentCount componentCount,
            wgpu::TextureFormat baseFormat = wgpu::TextureFormat::Undefined) {
            Format internalFormat = BaseCompressedFormat(
                format, byteSize, width, height, unsupportedReason, componentCount, baseFormat);
            internalFormat.isASTC = true;
            AddFormat(internalFormat);
        };

    auto AddMultiAspectFormat =
        [&AddFormat, &table](wgpu::TextureFormat format, TextureSubsampling subSampling,
                             Aspect aspects, Cap capabilites, UnsupportedReason unsupportedReason,
                             ComponentCount componentCount, wgpu::TextureFormat firstFormat,
                             wgpu::TextureFormat secondFormat,
                             wgpu::TextureFormat thirdFormat = wgpu::TextureFormat::Undefined) {
            Format internalFormat;
            internalFormat.format = format;
            internalFormat.baseFormat = format;
            internalFormat.subSampling = subSampling;
            internalFormat.isCompressed = false;
            internalFormat.unsupportedReason = unsupportedReason;
            internalFormat.caps = capabilites;
            internalFormat.aspects = aspects;
            internalFormat.componentCount = dchecked_cast<uint8_t>(componentCount);

            // Multi aspect formats just copy information about single-aspect formats. This
            // means that the single-plane formats must have been added before multi-aspect
            // ones. (it is ASSERTed below).
            const FormatIndex firstFormatIndex = ComputeFormatIndex(firstFormat);
            const FormatIndex secondFormatIndex = ComputeFormatIndex(secondFormat);

            DAWN_CHECK(table[firstFormatIndex].aspectInfo[0].format !=
                       wgpu::TextureFormat::Undefined);
            DAWN_CHECK(table[secondFormatIndex].aspectInfo[0].format !=
                       wgpu::TextureFormat::Undefined);

            internalFormat.aspectInfo[0] = table[firstFormatIndex].aspectInfo[0];
            internalFormat.aspectInfo[1] = table[secondFormatIndex].aspectInfo[0];
            if (thirdFormat != wgpu::TextureFormat::Undefined) {
                const FormatIndex thirdFormatIndex = ComputeFormatIndex(thirdFormat);
                internalFormat.aspectInfo[2] = table[thirdFormatIndex].aspectInfo[0];
            }

            AddFormat(internalFormat);
        };

    // clang-format off

    // Depth-stencil formats
    AddStencilFormat(wgpu::TextureFormat::Stencil8, Format::supported);
    AddDepthFormat(wgpu::TextureFormat::Depth16Unorm, 2, Format::supported);
    // TODO(crbug.com/dawn/843): This is 4 because we read this to perform zero initialization,
    // and textures are always use depth32float. We should improve this to be more robust. Perhaps,
    // using 0 here to mean "unsized" and adding a backend-specific query for the block size.
    AddDepthFormat(wgpu::TextureFormat::Depth24Plus, 4, Format::supported);
    AddMultiAspectFormat(wgpu::TextureFormat::Depth24PlusStencil8, TextureSubsampling::Undefined,
                          Aspect::Depth | Aspect::Stencil, Cap::Renderable | Cap::Multisample, Format::supported, ComponentCount(2u), wgpu::TextureFormat::Depth24Plus, wgpu::TextureFormat::Stencil8);
    AddDepthFormat(wgpu::TextureFormat::Depth32Float, 4, Format::supported);
    UnsupportedReason d32s8UnsupportedReason = device->HasFeature(Feature::Depth32FloatStencil8) ? Format::supported : RequiresFeature{wgpu::FeatureName::Depth32FloatStencil8};
    AddMultiAspectFormat(wgpu::TextureFormat::Depth32FloatStencil8, TextureSubsampling::Undefined,
                          Aspect::Depth | Aspect::Stencil, Cap::Renderable | Cap::Multisample, d32s8UnsupportedReason, ComponentCount(2u), wgpu::TextureFormat::Depth32Float, wgpu::TextureFormat::Stencil8);

    // BC compressed formats
    UnsupportedReason bcFormatUnsupportedReason = device->HasFeature(Feature::TextureCompressionBC) ? Format::supported : RequiresFeature{wgpu::FeatureName::TextureCompressionBC};
    AddBCCompressedFormat(wgpu::TextureFormat::BC1RGBAUnorm, ByteSize(8u), Width(4u), Height(4u), bcFormatUnsupportedReason, ComponentCount(4u));
    AddBCCompressedFormat(wgpu::TextureFormat::BC1RGBAUnormSrgb, ByteSize(8u), Width(4u), Height(4u), bcFormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::BC1RGBAUnorm);
    AddBCCompressedFormat(wgpu::TextureFormat::BC4RSnorm, ByteSize(8u), Width(4u), Height(4u), bcFormatUnsupportedReason, ComponentCount(1u));
    AddBCCompressedFormat(wgpu::TextureFormat::BC4RUnorm, ByteSize(8u), Width(4u), Height(4u), bcFormatUnsupportedReason, ComponentCount(1u));
    AddBCCompressedFormat(wgpu::TextureFormat::BC2RGBAUnorm, ByteSize(16u), Width(4u), Height(4u), bcFormatUnsupportedReason, ComponentCount(4u));
    AddBCCompressedFormat(wgpu::TextureFormat::BC2RGBAUnormSrgb, ByteSize(16u), Width(4u), Height(4u), bcFormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::BC2RGBAUnorm);
    AddBCCompressedFormat(wgpu::TextureFormat::BC3RGBAUnorm, ByteSize(16u), Width(4u), Height(4u), bcFormatUnsupportedReason, ComponentCount(4u));
    AddBCCompressedFormat(wgpu::TextureFormat::BC3RGBAUnormSrgb, ByteSize(16u), Width(4u), Height(4u), bcFormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::BC3RGBAUnorm);
    AddBCCompressedFormat(wgpu::TextureFormat::BC5RGSnorm, ByteSize(16u), Width(4u), Height(4u), bcFormatUnsupportedReason, ComponentCount(2u));
    AddBCCompressedFormat(wgpu::TextureFormat::BC5RGUnorm, ByteSize(16u), Width(4u), Height(4u), bcFormatUnsupportedReason, ComponentCount(2u));
    AddBCCompressedFormat(wgpu::TextureFormat::BC6HRGBFloat, ByteSize(16u), Width(4u), Height(4u), bcFormatUnsupportedReason, ComponentCount(3u));
    AddBCCompressedFormat(wgpu::TextureFormat::BC6HRGBUfloat, ByteSize(16u), Width(4u), Height(4u), bcFormatUnsupportedReason, ComponentCount(3u));
    AddBCCompressedFormat(wgpu::TextureFormat::BC7RGBAUnorm, ByteSize(16u), Width(4u), Height(4u), bcFormatUnsupportedReason, ComponentCount(4u));
    AddBCCompressedFormat(wgpu::TextureFormat::BC7RGBAUnormSrgb, ByteSize(16u), Width(4u), Height(4u), bcFormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::BC7RGBAUnorm);

    // ETC2/EAC compressed formats
    UnsupportedReason etc2FormatUnsupportedReason = device->HasFeature(Feature::TextureCompressionETC2) ?  Format::supported : RequiresFeature{wgpu::FeatureName::TextureCompressionETC2};
    AddETCCompressedFormat(wgpu::TextureFormat::ETC2RGB8Unorm, ByteSize(8u), Width(4u), Height(4u), etc2FormatUnsupportedReason, ComponentCount(3u));
    AddETCCompressedFormat(wgpu::TextureFormat::ETC2RGB8UnormSrgb, ByteSize(8u), Width(4u), Height(4u), etc2FormatUnsupportedReason, ComponentCount(3u), wgpu::TextureFormat::ETC2RGB8Unorm);
    AddETCCompressedFormat(wgpu::TextureFormat::ETC2RGB8A1Unorm, ByteSize(8u), Width(4u), Height(4u), etc2FormatUnsupportedReason, ComponentCount(4u));
    AddETCCompressedFormat(wgpu::TextureFormat::ETC2RGB8A1UnormSrgb, ByteSize(8u), Width(4u), Height(4u), etc2FormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::ETC2RGB8A1Unorm);
    AddETCCompressedFormat(wgpu::TextureFormat::ETC2RGBA8Unorm, ByteSize(16u), Width(4u), Height(4u), etc2FormatUnsupportedReason, ComponentCount(4u));
    AddETCCompressedFormat(wgpu::TextureFormat::ETC2RGBA8UnormSrgb, ByteSize(16u), Width(4u), Height(4u), etc2FormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::ETC2RGBA8Unorm);
    AddETCCompressedFormat(wgpu::TextureFormat::EACR11Unorm, ByteSize(8u), Width(4u), Height(4u), etc2FormatUnsupportedReason, ComponentCount(1u));
    AddETCCompressedFormat(wgpu::TextureFormat::EACR11Snorm, ByteSize(8u), Width(4u), Height(4u), etc2FormatUnsupportedReason, ComponentCount(1u));
    AddETCCompressedFormat(wgpu::TextureFormat::EACRG11Unorm, ByteSize(16u), Width(4u), Height(4u), etc2FormatUnsupportedReason, ComponentCount(2u));
    AddETCCompressedFormat(wgpu::TextureFormat::EACRG11Snorm, ByteSize(16u), Width(4u), Height(4u), etc2FormatUnsupportedReason, ComponentCount(2u));

    // ASTC compressed formats
    UnsupportedReason astcFormatUnsupportedReason = device->HasFeature(Feature::TextureCompressionASTC) ?  Format::supported : RequiresFeature{wgpu::FeatureName::TextureCompressionASTC};
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC4x4Unorm, ByteSize(16u), Width(4u), Height(4u), astcFormatUnsupportedReason, ComponentCount(4u));
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC4x4UnormSrgb, ByteSize(16u), Width(4u), Height(4u), astcFormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::ASTC4x4Unorm);
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC5x4Unorm, ByteSize(16u), Width(5u), Height(4u), astcFormatUnsupportedReason, ComponentCount(4u));
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC5x4UnormSrgb, ByteSize(16u), Width(5u), Height(4u), astcFormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::ASTC5x4Unorm);
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC5x5Unorm, ByteSize(16u), Width(5u), Height(5u), astcFormatUnsupportedReason, ComponentCount(4u));
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC5x5UnormSrgb, ByteSize(16u), Width(5u), Height(5u), astcFormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::ASTC5x5Unorm);
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC6x5Unorm, ByteSize(16u), Width(6u), Height(5u), astcFormatUnsupportedReason, ComponentCount(4u));
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC6x5UnormSrgb, ByteSize(16u), Width(6u), Height(5u), astcFormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::ASTC6x5Unorm);
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC6x6Unorm, ByteSize(16u), Width(6u), Height(6u), astcFormatUnsupportedReason, ComponentCount(4u));
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC6x6UnormSrgb, ByteSize(16u), Width(6u), Height(6u), astcFormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::ASTC6x6Unorm);
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC8x5Unorm, ByteSize(16u), Width(8u), Height(5u), astcFormatUnsupportedReason, ComponentCount(4u));
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC8x5UnormSrgb, ByteSize(16u), Width(8u), Height(5u), astcFormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::ASTC8x5Unorm);
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC8x6Unorm, ByteSize(16u), Width(8u), Height(6u), astcFormatUnsupportedReason, ComponentCount(4u));
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC8x6UnormSrgb, ByteSize(16u), Width(8u), Height(6u), astcFormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::ASTC8x6Unorm);
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC8x8Unorm, ByteSize(16u), Width(8u), Height(8u), astcFormatUnsupportedReason, ComponentCount(4u));
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC8x8UnormSrgb, ByteSize(16u), Width(8u), Height(8u), astcFormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::ASTC8x8Unorm);
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC10x5Unorm, ByteSize(16u), Width(10u), Height(5u), astcFormatUnsupportedReason, ComponentCount(4u));
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC10x5UnormSrgb, ByteSize(16u), Width(10u), Height(5u), astcFormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::ASTC10x5Unorm);
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC10x6Unorm, ByteSize(16u), Width(10u), Height(6u), astcFormatUnsupportedReason, ComponentCount(4u));
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC10x6UnormSrgb, ByteSize(16u), Width(10u), Height(6u), astcFormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::ASTC10x6Unorm);
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC10x8Unorm, ByteSize(16u), Width(10u), Height(8u), astcFormatUnsupportedReason, ComponentCount(4u));
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC10x8UnormSrgb, ByteSize(16u), Width(10u), Height(8u), astcFormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::ASTC10x8Unorm);
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC10x10Unorm, ByteSize(16u), Width(10u), Height(10u), astcFormatUnsupportedReason, ComponentCount(4u));
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC10x10UnormSrgb, ByteSize(16u), Width(10u), Height(10u), astcFormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::ASTC10x10Unorm);
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC12x10Unorm, ByteSize(16u), Width(12u), Height(10u), astcFormatUnsupportedReason, ComponentCount(4u));
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC12x10UnormSrgb, ByteSize(16u), Width(12u), Height(10u), astcFormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::ASTC12x10Unorm);
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC12x12Unorm, ByteSize(16u), Width(12u), Height(12u), astcFormatUnsupportedReason, ComponentCount(4u));
    AddASTCCompressedFormat(wgpu::TextureFormat::ASTC12x12UnormSrgb, ByteSize(16u), Width(12u), Height(12u), astcFormatUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::ASTC12x12Unorm);

    // multi-planar formats
    auto multiPlanarCapabilities = device->HasFeature(Feature::MultiPlanarRenderTargets) ? Cap::Renderable : Cap::None;
    const UnsupportedReason multiPlanarFormatNv12UnsupportedReason = device->HasFeature(Feature::DawnMultiPlanarFormats) ?  Format::supported : RequiresFeature{wgpu::FeatureName::DawnMultiPlanarFormats};
    AddMultiAspectFormat(wgpu::TextureFormat::R8BG8Biplanar420Unorm, TextureSubsampling::e420, Aspect::Plane0 | Aspect::Plane1,
        multiPlanarCapabilities, multiPlanarFormatNv12UnsupportedReason, ComponentCount(3u), wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::RG8Unorm);
    const UnsupportedReason multiPlanarFormatNv16UnsupportedReason = device->HasFeature(Feature::MultiPlanarFormatNv16) ?  Format::supported : RequiresFeature{wgpu::FeatureName::MultiPlanarFormatNv16};
    AddMultiAspectFormat(wgpu::TextureFormat::R8BG8Biplanar422Unorm, TextureSubsampling::e422, Aspect::Plane0 | Aspect::Plane1,
        multiPlanarCapabilities, multiPlanarFormatNv16UnsupportedReason, ComponentCount(3u), wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::RG8Unorm);
    const UnsupportedReason multiPlanarFormatNv24UnsupportedReason = device->HasFeature(Feature::MultiPlanarFormatNv24) ?  Format::supported : RequiresFeature{wgpu::FeatureName::MultiPlanarFormatNv24};
    AddMultiAspectFormat(wgpu::TextureFormat::R8BG8Biplanar444Unorm, TextureSubsampling::e444, Aspect::Plane0 | Aspect::Plane1,
        multiPlanarCapabilities, multiPlanarFormatNv24UnsupportedReason, ComponentCount(3u), wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::RG8Unorm);
    const UnsupportedReason multiPlanarFormatP010UnsupportedReason = device->HasFeature(Feature::MultiPlanarFormatP010) ?  Format::supported : RequiresFeature{wgpu::FeatureName::MultiPlanarFormatP010};
    AddMultiAspectFormat(wgpu::TextureFormat::R10X6BG10X6Biplanar420Unorm, TextureSubsampling::e420, Aspect::Plane0 | Aspect::Plane1,
        multiPlanarCapabilities, multiPlanarFormatP010UnsupportedReason, ComponentCount(3u), wgpu::TextureFormat::R16Unorm, wgpu::TextureFormat::RG16Unorm);
    const UnsupportedReason multiPlanarFormatP210UnsupportedReason = device->HasFeature(Feature::MultiPlanarFormatP210) ?  Format::supported : RequiresFeature{wgpu::FeatureName::MultiPlanarFormatP210};
    AddMultiAspectFormat(wgpu::TextureFormat::R10X6BG10X6Biplanar422Unorm, TextureSubsampling::e422, Aspect::Plane0 | Aspect::Plane1,
        multiPlanarCapabilities, multiPlanarFormatP210UnsupportedReason, ComponentCount(3u), wgpu::TextureFormat::R16Unorm, wgpu::TextureFormat::RG16Unorm);
    const UnsupportedReason multiPlanarFormatP410UnsupportedReason = device->HasFeature(Feature::MultiPlanarFormatP410) ?  Format::supported : RequiresFeature{wgpu::FeatureName::MultiPlanarFormatP410};
    AddMultiAspectFormat(wgpu::TextureFormat::R10X6BG10X6Biplanar444Unorm, TextureSubsampling::e444, Aspect::Plane0 | Aspect::Plane1,
        multiPlanarCapabilities, multiPlanarFormatP410UnsupportedReason, ComponentCount(3u), wgpu::TextureFormat::R16Unorm, wgpu::TextureFormat::RG16Unorm);
    const UnsupportedReason multiPlanarFormatNv12aUnsupportedReason = device->HasFeature(Feature::MultiPlanarFormatNv12a) ?  Format::supported : RequiresFeature{wgpu::FeatureName::MultiPlanarFormatNv12a};
    AddMultiAspectFormat(wgpu::TextureFormat::R8BG8A8Triplanar420Unorm, TextureSubsampling::e420, Aspect::Plane0 | Aspect::Plane1 | Aspect::Plane2,
        multiPlanarCapabilities, multiPlanarFormatNv12aUnsupportedReason, ComponentCount(4u), wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::RG8Unorm, wgpu::TextureFormat::R8Unorm);

    // clang-format on

    // This checks that each format is set at least once, the second part of checking that all
    // formats are checked exactly once. If this assertion is failing and texture formats have
    // been added or removed recently, check that kKnownFormatCount has been updated.
    DAWN_CHECK(formatsSet.all());

    for (const Format& f : table) {
        if (f.format != f.baseFormat) {
            auto& baseViewFormat = table[ComputeFormatIndex(f.baseFormat)].baseViewFormat;
            // Currently, Dawn only supports sRGB reinterpretation, so there should only be one
            // view format.
            DAWN_CHECK(baseViewFormat == wgpu::TextureFormat::Undefined);
            baseViewFormat = f.format;
        }
    }
    return table;
}

absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
    const UnsupportedReason& value,
    const absl::FormatConversionSpec& spec,
    absl::FormatSink* s) {
    MatchVariant(
        value, [](const std::monostate&) { DAWN_UNREACHABLE(); },
        [s](const RequiresFeature& requiresFeature) {
            s->Append(absl::StrFormat("requires feature %s", requiresFeature.feature));
        },
        [s](const CompatibilityMode&) { s->Append("not supported in compatibility mode"); });
    return {true};
}

}  // namespace dawn::native
