// 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/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{ToAPI(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 = static_cast<uint32_t>(componentCount);
            internalFormat.unsupportedReason = std::monostate{};
            internalFormat.caps = Cap::None;

            if (rtPixelCost != RenderTargetPixelByteCost(0u)) {
                internalFormat.renderTargetPixelByteCost = static_cast<uint32_t>(rtPixelCost);
                internalFormat.renderTargetComponentAlignment =
                    static_cast<uint32_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 = static_cast<uint32_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 = static_cast<uint32_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
