// Copyright 2019 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dawn/native/Format.h"

#include "dawn/native/Device.h"
#include "dawn/native/EnumMaskIterator.h"
#include "dawn/native/Features.h"
#include "dawn/native/Texture.h"

#include <bitset>

namespace dawn::native {

    // Format

    // TODO(dawn:527): Remove when unused.
    SampleTypeBit ToSampleTypeBit(wgpu::TextureComponentType type) {
        switch (type) {
            case wgpu::TextureComponentType::Float:
                return SampleTypeBit::Float;
            case wgpu::TextureComponentType::Sint:
                return SampleTypeBit::Sint;
            case wgpu::TextureComponentType::Uint:
                return SampleTypeBit::Uint;
            case wgpu::TextureComponentType::DepthComparison:
                return SampleTypeBit::Depth;
        }
        UNREACHABLE();
    }

    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::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::Undefined) == 0);
        if (sampleType == wgpu::TextureSampleType::Undefined) {
            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) - 1)));
        static_assert(
            SampleTypeBit::UnfilterableFloat ==
            static_cast<SampleTypeBit>(
                1 << (static_cast<uint32_t>(wgpu::TextureSampleType::UnfilterableFloat) - 1)));
        static_assert(SampleTypeBit::Uint ==
                      static_cast<SampleTypeBit>(
                          1 << (static_cast<uint32_t>(wgpu::TextureSampleType::Uint) - 1)));
        static_assert(SampleTypeBit::Sint ==
                      static_cast<SampleTypeBit>(
                          1 << (static_cast<uint32_t>(wgpu::TextureSampleType::Sint) - 1)));
        static_assert(SampleTypeBit::Depth ==
                      static_cast<SampleTypeBit>(
                          1 << (static_cast<uint32_t>(wgpu::TextureSampleType::Depth) - 1)));
        return static_cast<SampleTypeBit>(1 << (static_cast<uint32_t>(sampleType) - 1));
    }

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

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

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

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

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

    bool Format::CopyCompatibleWith(const Format& format) const {
        return baseFormat == format.baseFormat;
    }

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

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

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

    // 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.
    size_t ComputeFormatIndex(wgpu::TextureFormat format) {
        // 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);
        return static_cast<size_t>(static_cast<uint32_t>(format) - 1);
    }

    FormatTable BuildFormatTable(const DeviceBase* device) {
        FormatTable table;
        std::bitset<kKnownFormatCount> formatsSet;

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

        auto AddFormat = [&table, &formatsSet](Format format) {
            size_t index = ComputeFormatIndex(format.format);
            ASSERT(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.
            ASSERT(!formatsSet[index]);

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

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

        auto AddColorFormat =
            [&AddFormat](wgpu::TextureFormat format, bool renderable, bool supportsStorageUsage,
                         bool supportsMultisample, bool supportsResolveTarget, uint32_t byteSize,
                         SampleTypeBit sampleTypes, uint8_t componentCount,
                         wgpu::TextureFormat baseFormat = wgpu::TextureFormat::Undefined) {
                Format internalFormat;
                internalFormat.format = format;
                internalFormat.isRenderable = renderable;
                internalFormat.isCompressed = false;
                internalFormat.isSupported = true;
                internalFormat.supportsStorageUsage = supportsStorageUsage;

                if (supportsMultisample) {
                    ASSERT(renderable);
                }
                internalFormat.supportsMultisample = supportsMultisample;
                internalFormat.supportsResolveTarget = supportsResolveTarget;
                internalFormat.aspects = Aspect::Color;
                internalFormat.componentCount = componentCount;

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

                AspectInfo* firstAspect = internalFormat.aspectInfo.data();
                firstAspect->block.byteSize = byteSize;
                firstAspect->block.width = 1;
                firstAspect->block.height = 1;
                if (HasOneBit(sampleTypes)) {
                    switch (sampleTypes) {
                        case SampleTypeBit::Float:
                        case SampleTypeBit::UnfilterableFloat:
                            firstAspect->baseType = wgpu::TextureComponentType::Float;
                            break;
                        case SampleTypeBit::Sint:
                            firstAspect->baseType = wgpu::TextureComponentType::Sint;
                            break;
                        case SampleTypeBit::Uint:
                            firstAspect->baseType = wgpu::TextureComponentType::Uint;
                            break;
                        default:
                            UNREACHABLE();
                    }
                } else {
                    ASSERT((sampleTypes & SampleTypeBit::Float) != 0);
                    firstAspect->baseType = wgpu::TextureComponentType::Float;
                }
                firstAspect->supportedSampleTypes = sampleTypes;
                firstAspect->format = format;
                AddFormat(internalFormat);
            };

        auto AddDepthFormat = [&AddFormat](
                                  wgpu::TextureFormat format, uint32_t byteSize, bool isSupported,
                                  wgpu::TextureFormat baseFormat = wgpu::TextureFormat::Undefined) {
            Format internalFormat;
            internalFormat.format = format;
            internalFormat.isRenderable = true;
            internalFormat.isCompressed = false;
            internalFormat.isSupported = isSupported;
            internalFormat.supportsStorageUsage = false;
            internalFormat.supportsMultisample = true;
            internalFormat.supportsResolveTarget = false;
            internalFormat.aspects = Aspect::Depth;
            internalFormat.componentCount = 1;

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

            AspectInfo* firstAspect = internalFormat.aspectInfo.data();
            firstAspect->block.byteSize = byteSize;
            firstAspect->block.width = 1;
            firstAspect->block.height = 1;
            firstAspect->baseType = wgpu::TextureComponentType::Float;
            firstAspect->supportedSampleTypes = SampleTypeBit::Depth;
            firstAspect->format = format;
            AddFormat(internalFormat);
        };

        auto AddStencilFormat = [&AddFormat](wgpu::TextureFormat format, bool isSupported,
                                             wgpu::TextureFormat baseFormat =
                                                 wgpu::TextureFormat::Undefined) {
            Format internalFormat;
            internalFormat.format = format;
            internalFormat.isRenderable = true;
            internalFormat.isCompressed = false;
            internalFormat.isSupported = isSupported;
            internalFormat.supportsStorageUsage = false;
            internalFormat.supportsMultisample = true;
            internalFormat.supportsResolveTarget = false;
            internalFormat.aspects = Aspect::Stencil;
            internalFormat.componentCount = 1;
            internalFormat.baseFormat = baseFormat;

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

            AspectInfo* firstAspect = internalFormat.aspectInfo.data();
            firstAspect->block.byteSize = 1;
            firstAspect->block.width = 1;
            firstAspect->block.height = 1;
            firstAspect->baseType = wgpu::TextureComponentType::Uint;
            firstAspect->supportedSampleTypes = SampleTypeBit::Uint;
            firstAspect->format = format;
            AddFormat(internalFormat);
        };

        auto AddCompressedFormat =
            [&AddFormat](wgpu::TextureFormat format, uint32_t byteSize, uint32_t width,
                         uint32_t height, bool isSupported, uint8_t componentCount,
                         wgpu::TextureFormat baseFormat = wgpu::TextureFormat::Undefined) {
                Format internalFormat;
                internalFormat.format = format;
                internalFormat.isRenderable = false;
                internalFormat.isCompressed = true;
                internalFormat.isSupported = isSupported;
                internalFormat.supportsStorageUsage = false;
                internalFormat.supportsMultisample = false;
                internalFormat.supportsResolveTarget = false;
                internalFormat.aspects = Aspect::Color;
                internalFormat.componentCount = 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 = byteSize;
                firstAspect->block.width = width;
                firstAspect->block.height = height;
                firstAspect->baseType = wgpu::TextureComponentType::Float;
                firstAspect->supportedSampleTypes = kAnyFloat;
                firstAspect->format = format;
                AddFormat(internalFormat);
            };

        auto AddMultiAspectFormat =
            [&AddFormat, &table](wgpu::TextureFormat format, Aspect aspects,
                                 wgpu::TextureFormat firstFormat, wgpu::TextureFormat secondFormat,
                                 bool isRenderable, bool isSupported, bool supportsMultisample,
                                 uint8_t componentCount,
                                 wgpu::TextureFormat baseFormat = wgpu::TextureFormat::Undefined) {
                Format internalFormat;
                internalFormat.format = format;
                internalFormat.isRenderable = isRenderable;
                internalFormat.isCompressed = false;
                internalFormat.isSupported = isSupported;
                internalFormat.supportsStorageUsage = false;
                internalFormat.supportsMultisample = supportsMultisample;
                internalFormat.supportsResolveTarget = false;
                internalFormat.aspects = aspects;
                internalFormat.componentCount = componentCount;

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

                const size_t firstFormatIndex = ComputeFormatIndex(firstFormat);
                const size_t secondFormatIndex = ComputeFormatIndex(secondFormat);

                internalFormat.aspectInfo[0] = table[firstFormatIndex].aspectInfo[0];
                internalFormat.aspectInfo[1] = table[secondFormatIndex].aspectInfo[0];

                AddFormat(internalFormat);
            };

        // clang-format off
        // 1 byte color formats
        AddColorFormat(wgpu::TextureFormat::R8Unorm, true, false, true, true, 1, kAnyFloat, 1);
        AddColorFormat(wgpu::TextureFormat::R8Snorm, false, false, false, false, 1, kAnyFloat, 1);
        AddColorFormat(wgpu::TextureFormat::R8Uint, true, false, true, false, 1, SampleTypeBit::Uint, 1);
        AddColorFormat(wgpu::TextureFormat::R8Sint, true, false, true, false, 1, SampleTypeBit::Sint, 1);

        // 2 bytes color formats
        AddColorFormat(wgpu::TextureFormat::R16Uint, true, false, true, false, 2, SampleTypeBit::Uint, 1);
        AddColorFormat(wgpu::TextureFormat::R16Sint, true, false, true, false, 2, SampleTypeBit::Sint, 1);
        AddColorFormat(wgpu::TextureFormat::R16Float, true, false, true, true, 2, kAnyFloat, 1);
        AddColorFormat(wgpu::TextureFormat::RG8Unorm, true, false, true, true, 2, kAnyFloat, 2);
        AddColorFormat(wgpu::TextureFormat::RG8Snorm, false, false, false, false, 2, kAnyFloat, 2);
        AddColorFormat(wgpu::TextureFormat::RG8Uint, true, false, true, false, 2, SampleTypeBit::Uint, 2);
        AddColorFormat(wgpu::TextureFormat::RG8Sint, true, false, true, false, 2, SampleTypeBit::Sint, 2);

        // 4 bytes color formats
        AddColorFormat(wgpu::TextureFormat::R32Uint, true, true, false, false, 4, SampleTypeBit::Uint, 1);
        AddColorFormat(wgpu::TextureFormat::R32Sint, true, true, false, false, 4, SampleTypeBit::Sint, 1);
        AddColorFormat(wgpu::TextureFormat::R32Float, true, true, true, false, 4, SampleTypeBit::UnfilterableFloat, 1);
        AddColorFormat(wgpu::TextureFormat::RG16Uint, true, false, true, false, 4, SampleTypeBit::Uint, 2);
        AddColorFormat(wgpu::TextureFormat::RG16Sint, true, false, true, false, 4, SampleTypeBit::Sint, 2);
        AddColorFormat(wgpu::TextureFormat::RG16Float, true, false, true, true, 4, kAnyFloat, 2);
        AddColorFormat(wgpu::TextureFormat::RGBA8Unorm, true, true, true, true, 4, kAnyFloat, 4);
        AddColorFormat(wgpu::TextureFormat::RGBA8UnormSrgb, true, false, true, true, 4, kAnyFloat, 4, wgpu::TextureFormat::RGBA8Unorm);
        AddColorFormat(wgpu::TextureFormat::RGBA8Snorm, false, true, false, false, 4, kAnyFloat, 4);
        AddColorFormat(wgpu::TextureFormat::RGBA8Uint, true, true, true, false, 4, SampleTypeBit::Uint, 4);
        AddColorFormat(wgpu::TextureFormat::RGBA8Sint, true, true, true, false, 4, SampleTypeBit::Sint, 4);
        AddColorFormat(wgpu::TextureFormat::BGRA8Unorm, true, false, true, true, 4, kAnyFloat, 4);
        AddColorFormat(wgpu::TextureFormat::BGRA8UnormSrgb, true, false, true, true, 4, kAnyFloat, 4, wgpu::TextureFormat::BGRA8Unorm);
        AddColorFormat(wgpu::TextureFormat::RGB10A2Unorm, true, false, true, true, 4, kAnyFloat, 4);

        AddColorFormat(wgpu::TextureFormat::RG11B10Ufloat, false, false, false, false, 4, kAnyFloat, 3);
        AddColorFormat(wgpu::TextureFormat::RGB9E5Ufloat, false, false, false, false, 4, kAnyFloat, 3);

        // 8 bytes color formats
        AddColorFormat(wgpu::TextureFormat::RG32Uint, true, true, false, false, 8, SampleTypeBit::Uint, 2);
        AddColorFormat(wgpu::TextureFormat::RG32Sint, true, true, false, false, 8, SampleTypeBit::Sint, 2);
        AddColorFormat(wgpu::TextureFormat::RG32Float, true, true, false, false, 8, SampleTypeBit::UnfilterableFloat, 2);
        AddColorFormat(wgpu::TextureFormat::RGBA16Uint, true, true, true, false, 8, SampleTypeBit::Uint, 4);
        AddColorFormat(wgpu::TextureFormat::RGBA16Sint, true, true, true, false, 8, SampleTypeBit::Sint, 4);
        AddColorFormat(wgpu::TextureFormat::RGBA16Float, true, true, true, true, 8, kAnyFloat, 4);

        // 16 bytes color formats
        AddColorFormat(wgpu::TextureFormat::RGBA32Uint, true, true, false, false, 16, SampleTypeBit::Uint, 4);
        AddColorFormat(wgpu::TextureFormat::RGBA32Sint, true, true, false, false, 16, SampleTypeBit::Sint, 4);
        AddColorFormat(wgpu::TextureFormat::RGBA32Float, true, true, false, false, 16, SampleTypeBit::UnfilterableFloat, 4);

        // Depth-stencil formats
        // TODO(dawn:666): Implement the stencil8 format
        AddStencilFormat(wgpu::TextureFormat::Stencil8, false);
        AddDepthFormat(wgpu::TextureFormat::Depth16Unorm, 2, true);
        // 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, true);
        AddMultiAspectFormat(wgpu::TextureFormat::Depth24PlusStencil8,
                              Aspect::Depth | Aspect::Stencil, wgpu::TextureFormat::Depth24Plus, wgpu::TextureFormat::Stencil8, true, true, true, 2);
        bool isD24S8Supported = device->IsFeatureEnabled(Feature::Depth24UnormStencil8);
        AddMultiAspectFormat(wgpu::TextureFormat::Depth24UnormStencil8,
                              Aspect::Depth | Aspect::Stencil, wgpu::TextureFormat::Depth24Plus, wgpu::TextureFormat::Stencil8, true, isD24S8Supported, true, 2);
        AddDepthFormat(wgpu::TextureFormat::Depth32Float, 4, true);
        bool isD32S8Supported = device->IsFeatureEnabled(Feature::Depth32FloatStencil8);
        AddMultiAspectFormat(wgpu::TextureFormat::Depth32FloatStencil8,
                              Aspect::Depth | Aspect::Stencil, wgpu::TextureFormat::Depth32Float, wgpu::TextureFormat::Stencil8, true, isD32S8Supported, true, 2);

        // BC compressed formats
        bool isBCFormatSupported = device->IsFeatureEnabled(Feature::TextureCompressionBC);
        AddCompressedFormat(wgpu::TextureFormat::BC1RGBAUnorm, 8, 4, 4, isBCFormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::BC1RGBAUnormSrgb, 8, 4, 4, isBCFormatSupported, 4, wgpu::TextureFormat::BC1RGBAUnorm);
        AddCompressedFormat(wgpu::TextureFormat::BC4RSnorm, 8, 4, 4, isBCFormatSupported, 1);
        AddCompressedFormat(wgpu::TextureFormat::BC4RUnorm, 8, 4, 4, isBCFormatSupported, 1);
        AddCompressedFormat(wgpu::TextureFormat::BC2RGBAUnorm, 16, 4, 4, isBCFormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::BC2RGBAUnormSrgb, 16, 4, 4, isBCFormatSupported, 4, wgpu::TextureFormat::BC2RGBAUnorm);
        AddCompressedFormat(wgpu::TextureFormat::BC3RGBAUnorm, 16, 4, 4, isBCFormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::BC3RGBAUnormSrgb, 16, 4, 4, isBCFormatSupported, 4, wgpu::TextureFormat::BC3RGBAUnorm);
        AddCompressedFormat(wgpu::TextureFormat::BC5RGSnorm, 16, 4, 4, isBCFormatSupported, 2);
        AddCompressedFormat(wgpu::TextureFormat::BC5RGUnorm, 16, 4, 4, isBCFormatSupported, 2);
        AddCompressedFormat(wgpu::TextureFormat::BC6HRGBFloat, 16, 4, 4, isBCFormatSupported, 3);
        AddCompressedFormat(wgpu::TextureFormat::BC6HRGBUfloat, 16, 4, 4, isBCFormatSupported, 3);
        AddCompressedFormat(wgpu::TextureFormat::BC7RGBAUnorm, 16, 4, 4, isBCFormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::BC7RGBAUnormSrgb, 16, 4, 4, isBCFormatSupported, 4, wgpu::TextureFormat::BC7RGBAUnorm);

        // ETC2/EAC compressed formats
        bool isETC2FormatSupported = device->IsFeatureEnabled(Feature::TextureCompressionETC2);
        AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8Unorm, 8, 4, 4, isETC2FormatSupported, 3);
        AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8UnormSrgb, 8, 4, 4, isETC2FormatSupported, 3, wgpu::TextureFormat::ETC2RGB8Unorm);
        AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8A1Unorm, 8, 4, 4, isETC2FormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::ETC2RGB8A1UnormSrgb, 8, 4, 4, isETC2FormatSupported, 4, wgpu::TextureFormat::ETC2RGB8A1Unorm);
        AddCompressedFormat(wgpu::TextureFormat::ETC2RGBA8Unorm, 16, 4, 4, isETC2FormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::ETC2RGBA8UnormSrgb, 16, 4, 4, isETC2FormatSupported, 4, wgpu::TextureFormat::ETC2RGBA8Unorm);
        AddCompressedFormat(wgpu::TextureFormat::EACR11Unorm, 8, 4, 4, isETC2FormatSupported, 1);
        AddCompressedFormat(wgpu::TextureFormat::EACR11Snorm, 8, 4, 4, isETC2FormatSupported, 1);
        AddCompressedFormat(wgpu::TextureFormat::EACRG11Unorm, 16, 4, 4, isETC2FormatSupported, 2);
        AddCompressedFormat(wgpu::TextureFormat::EACRG11Snorm, 16, 4, 4, isETC2FormatSupported, 2);

        // ASTC compressed formats
        bool isASTCFormatSupported = device->IsFeatureEnabled(Feature::TextureCompressionASTC);
        AddCompressedFormat(wgpu::TextureFormat::ASTC4x4Unorm, 16, 4, 4, isASTCFormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::ASTC4x4UnormSrgb, 16, 4, 4, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC4x4Unorm);
        AddCompressedFormat(wgpu::TextureFormat::ASTC5x4Unorm, 16, 5, 4, isASTCFormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::ASTC5x4UnormSrgb, 16, 5, 4, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC5x4Unorm);
        AddCompressedFormat(wgpu::TextureFormat::ASTC5x5Unorm, 16, 5, 5, isASTCFormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::ASTC5x5UnormSrgb, 16, 5, 5, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC5x5Unorm);
        AddCompressedFormat(wgpu::TextureFormat::ASTC6x5Unorm, 16, 6, 5, isASTCFormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::ASTC6x5UnormSrgb, 16, 6, 5, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC6x5Unorm);
        AddCompressedFormat(wgpu::TextureFormat::ASTC6x6Unorm, 16, 6, 6, isASTCFormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::ASTC6x6UnormSrgb, 16, 6, 6, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC6x6Unorm);
        AddCompressedFormat(wgpu::TextureFormat::ASTC8x5Unorm, 16, 8, 5, isASTCFormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::ASTC8x5UnormSrgb, 16, 8, 5, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC8x5Unorm);
        AddCompressedFormat(wgpu::TextureFormat::ASTC8x6Unorm, 16, 8, 6, isASTCFormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::ASTC8x6UnormSrgb, 16, 8, 6, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC8x6Unorm);
        AddCompressedFormat(wgpu::TextureFormat::ASTC8x8Unorm, 16, 8, 8, isASTCFormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::ASTC8x8UnormSrgb, 16, 8, 8, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC8x8Unorm);
        AddCompressedFormat(wgpu::TextureFormat::ASTC10x5Unorm, 16, 10, 5, isASTCFormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::ASTC10x5UnormSrgb, 16, 10, 5, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC10x5Unorm);
        AddCompressedFormat(wgpu::TextureFormat::ASTC10x6Unorm, 16, 10, 6, isASTCFormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::ASTC10x6UnormSrgb, 16, 10, 6, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC10x6Unorm);
        AddCompressedFormat(wgpu::TextureFormat::ASTC10x8Unorm, 16, 10, 8, isASTCFormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::ASTC10x8UnormSrgb, 16, 10, 8, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC10x8Unorm);
        AddCompressedFormat(wgpu::TextureFormat::ASTC10x10Unorm, 16, 10, 10, isASTCFormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::ASTC10x10UnormSrgb, 16, 10, 10, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC10x10Unorm);
        AddCompressedFormat(wgpu::TextureFormat::ASTC12x10Unorm, 16, 12, 10, isASTCFormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::ASTC12x10UnormSrgb, 16, 12, 10, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC12x10Unorm);
        AddCompressedFormat(wgpu::TextureFormat::ASTC12x12Unorm, 16, 12, 12, isASTCFormatSupported, 4);
        AddCompressedFormat(wgpu::TextureFormat::ASTC12x12UnormSrgb, 16, 12, 12, isASTCFormatSupported, 4, wgpu::TextureFormat::ASTC12x12Unorm);

        // multi-planar formats
        const bool isMultiPlanarFormatSupported = device->IsFeatureEnabled(Feature::MultiPlanarFormats);
        AddMultiAspectFormat(wgpu::TextureFormat::R8BG8Biplanar420Unorm, Aspect::Plane0 | Aspect::Plane1,
            wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::RG8Unorm, false, isMultiPlanarFormatSupported, false, 3);

        // 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.
        ASSERT(formatsSet.all());

        return table;
    }

}  // namespace dawn::native
