// Copyright 2017 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 DAWNNATIVE_BINDGROUPLAYOUT_H_
#define DAWNNATIVE_BINDGROUPLAYOUT_H_

#include "common/Constants.h"
#include "common/Math.h"
#include "common/SlabAllocator.h"
#include "dawn_native/CachedObject.h"
#include "dawn_native/Error.h"
#include "dawn_native/Forward.h"

#include "dawn_native/dawn_platform.h"

#include <array>
#include <bitset>

namespace dawn_native {

    MaybeError ValidateBindGroupLayoutDescriptor(DeviceBase*,
                                                 const BindGroupLayoutDescriptor* descriptor);

    MaybeError ValidateBindingTypeWithShaderStageVisibility(
        wgpu::BindingType bindingType,
        wgpu::ShaderStage shaderStageVisibility);

    class BindGroupLayoutBase : public CachedObject {
      public:
        BindGroupLayoutBase(DeviceBase* device, const BindGroupLayoutDescriptor* descriptor);
        ~BindGroupLayoutBase() override;

        static BindGroupLayoutBase* MakeError(DeviceBase* device);

        struct LayoutBindingInfo {
            std::array<wgpu::ShaderStage, kMaxBindingsPerGroup> visibilities;
            std::array<wgpu::BindingType, kMaxBindingsPerGroup> types;
            std::array<wgpu::TextureComponentType, kMaxBindingsPerGroup> textureComponentTypes;
            std::array<wgpu::TextureViewDimension, kMaxBindingsPerGroup> textureDimensions;
            std::bitset<kMaxBindingsPerGroup> hasDynamicOffset;
            std::bitset<kMaxBindingsPerGroup> multisampled;
            std::bitset<kMaxBindingsPerGroup> mask;
        };
        const LayoutBindingInfo& GetBindingInfo() const;

        // Functors necessary for the unordered_set<BGLBase*>-based cache.
        struct HashFunc {
            size_t operator()(const BindGroupLayoutBase* bgl) const;
        };
        struct EqualityFunc {
            bool operator()(const BindGroupLayoutBase* a, const BindGroupLayoutBase* b) const;
        };

        uint32_t GetBindingCount() const;
        uint32_t GetDynamicBufferCount() const;
        uint32_t GetDynamicUniformBufferCount() const;
        uint32_t GetDynamicStorageBufferCount() const;

        struct BufferBindingData {
            uint64_t offset;
            uint64_t size;
        };

        struct BindingDataPointers {
            BufferBindingData* const bufferData = nullptr;
            Ref<ObjectBase>* const bindings = nullptr;
        };

        // Compute the amount of space / alignment required to store bindings for a bind group of
        // this layout.
        size_t GetBindingDataSize() const;
        static constexpr size_t GetBindingDataAlignment() {
            static_assert(alignof(Ref<ObjectBase>) <= alignof(BufferBindingData), "");
            return alignof(BufferBindingData);
        }

        BindingDataPointers ComputeBindingDataPointers(void* dataStart) const;

      protected:
        template <typename BindGroup>
        SlabAllocator<BindGroup> MakeFrontendBindGroupAllocator(size_t size) {
            return SlabAllocator<BindGroup>(
                size,  // bytes
                Align(sizeof(BindGroup), GetBindingDataAlignment()) + GetBindingDataSize(),  // size
                std::max(alignof(BindGroup), GetBindingDataAlignment())  // alignment
            );
        }

      private:
        BindGroupLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag);

        LayoutBindingInfo mBindingInfo;
        uint32_t mBindingCount = 0;
        uint32_t mBufferCount = 0;
        uint32_t mDynamicUniformBufferCount = 0;
        uint32_t mDynamicStorageBufferCount = 0;
    };

}  // namespace dawn_native

#endif  // DAWNNATIVE_BINDGROUPLAYOUT_H_
