// 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.

#ifndef SRC_DAWN_NATIVE_FORMAT_H_
#define SRC_DAWN_NATIVE_FORMAT_H_

#include <array>

#include "dawn/native/dawn_platform.h"

#include "dawn/common/TypedInteger.h"
#include "dawn/common/ityp_array.h"
#include "dawn/common/ityp_bitset.h"
#include "dawn/native/EnumClassBitmasks.h"
#include "dawn/native/Error.h"
#include "dawn/native/Subresource.h"

// About multi-planar formats.
//
// Dawn supports additional multi-planar formats when the multiplanar-formats extension is enabled.
// When enabled, Dawn treats planar data as sub-resources (ie. 1 sub-resource == 1 view == 1 plane).
// A multi-planar format name encodes the channel mapping and order of planes. For example,
// R8BG8Biplanar420Unorm is YUV 4:2:0 where Plane 0 = R8, and Plane 1 = BG8.
//
// Requirements:
// * Plane aspects cannot be combined with color, depth, or stencil aspects.
// * Only compatible multi-planar formats of planes can be used with multi-planar texture
// formats.
// * Can't access multiple planes without creating per plane views (no color conversion).
// * Multi-planar format cannot be written or read without a per plane view.
//
// TODO(dawn:551): Consider moving this comment.

namespace dawn::native {

enum class Aspect : uint8_t;
class DeviceBase;

// This mirrors wgpu::TextureSampleType as a bitmask instead.
enum class SampleTypeBit : uint8_t {
    None = 0x0,
    Float = 0x1,
    UnfilterableFloat = 0x2,
    Depth = 0x4,
    Sint = 0x8,
    Uint = 0x10,
};

// Converts an wgpu::TextureComponentType to its bitmask representation.
SampleTypeBit ToSampleTypeBit(wgpu::TextureComponentType type);
// Converts an wgpu::TextureSampleType to its bitmask representation.
SampleTypeBit SampleTypeToSampleTypeBit(wgpu::TextureSampleType sampleType);

struct TexelBlockInfo {
    uint32_t byteSize;
    uint32_t width;
    uint32_t height;
};

struct AspectInfo {
    TexelBlockInfo block;
    // TODO(crbug.com/dawn/367): Replace TextureComponentType with TextureSampleType, or make it
    // an internal Dawn enum.
    wgpu::TextureComponentType baseType;
    SampleTypeBit supportedSampleTypes;
    wgpu::TextureFormat format = wgpu::TextureFormat::Undefined;
};

// The number of formats Dawn knows about. Asserts in BuildFormatTable ensure that this is the
// exact number of known format.
static constexpr uint32_t kKnownFormatCount = 96;

using FormatIndex = TypedInteger<struct FormatIndexT, uint32_t>;

struct Format;
using FormatTable = ityp::array<FormatIndex, Format, kKnownFormatCount>;

// A wgpu::TextureFormat along with all the information about it necessary for validation.
struct Format {
    wgpu::TextureFormat format;

    // TODO(crbug.com/dawn/1332): These members could be stored in a Format capability matrix.
    bool isRenderable;
    bool isCompressed;
    // A format can be known but not supported because it is part of a disabled extension.
    bool isSupported;
    bool supportsStorageUsage;
    bool supportsMultisample;
    bool supportsResolveTarget;
    Aspect aspects;
    // Only used for renderable color formats, number of color channels.
    uint8_t componentCount;

    bool IsColor() const;
    bool HasDepth() const;
    bool HasStencil() const;
    bool HasDepthOrStencil() const;

    // IsMultiPlanar() returns true if the format allows selecting a plane index. This is only
    // allowed by multi-planar formats (ex. NV12).
    bool IsMultiPlanar() const;

    const AspectInfo& GetAspectInfo(wgpu::TextureAspect aspect) const;
    const AspectInfo& GetAspectInfo(Aspect aspect) const;

    // The index of the format in the list of all known formats: a unique number for each format
    // in [0, kKnownFormatCount)
    FormatIndex GetIndex() const;

    // baseFormat represents the memory layout of the format.
    // If two formats has the same baseFormat, they could copy to and be viewed as the other
    // format. Currently two formats have the same baseFormat if they differ only in sRGB-ness.
    wgpu::TextureFormat baseFormat;

    // Returns true if the formats are copy compatible.
    // Currently means they differ only in sRGB-ness.
    bool CopyCompatibleWith(const Format& format) const;

    // Returns true if the formats are texture view format compatible.
    // Currently means they differ only in sRGB-ness.
    bool ViewCompatibleWith(const Format& format) const;

  private:
    // Used to store the aspectInfo for one or more planes. For single plane "color" formats,
    // only the first aspect info or aspectInfo[0] is valid. For depth-stencil, the first aspect
    // info is depth and the second aspect info is stencil. For multi-planar formats,
    // aspectInfo[i] is the ith plane.
    std::array<AspectInfo, kMaxPlanesPerFormat> aspectInfo;

    friend FormatTable BuildFormatTable(const DeviceBase* device);
};

class FormatSet : public ityp::bitset<FormatIndex, kKnownFormatCount> {
    using Base = ityp::bitset<FormatIndex, kKnownFormatCount>;

  public:
    using Base::Base;
    using Base::operator[];

    bool operator[](const Format& format) const;
    typename Base::reference operator[](const Format& format);
};

// Implementation details of the format table in the device.

// Returns the index of a format in the FormatTable.
FormatIndex ComputeFormatIndex(wgpu::TextureFormat format);
// Builds the format table with the extensions enabled on the device.
FormatTable BuildFormatTable(const DeviceBase* device);

}  // namespace dawn::native

namespace dawn {

template <>
struct IsDawnBitmask<dawn::native::SampleTypeBit> {
    static constexpr bool enable = true;
};

}  // namespace dawn

#endif  // SRC_DAWN_NATIVE_FORMAT_H_
