// Copyright 2018 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_VULKAN_BINDGROUPLAYOUTVK_H_
#define DAWNNATIVE_VULKAN_BINDGROUPLAYOUTVK_H_

#include "dawn_native/BindGroupLayout.h"

#include "common/SlabAllocator.h"
#include "common/vulkan_platform.h"

#include <vector>

namespace dawn_native::vulkan {

    class BindGroup;
    struct DescriptorSetAllocation;
    class DescriptorSetAllocator;
    class Device;

    VkDescriptorType VulkanDescriptorType(const BindingInfo& bindingInfo);

    // In Vulkan descriptor pools have to be sized to an exact number of descriptors. This means
    // it's hard to have something where we can mix different types of descriptor sets because
    // we don't know if their vector of number of descriptors will be similar.
    //
    // That's why that in addition to containing the VkDescriptorSetLayout to create
    // VkDescriptorSets for its bindgroups, the layout also acts as an allocator for the descriptor
    // sets.
    //
    // The allocations is done with one pool per descriptor set, which is inefficient, but at least
    // the pools are reused when no longer used. Minimizing the number of descriptor pool allocation
    // is important because creating them can incur GPU memory allocation which is usually an
    // expensive syscall.
    class BindGroupLayout final : public BindGroupLayoutBase {
      public:
        static ResultOrError<Ref<BindGroupLayout>> Create(
            Device* device,
            const BindGroupLayoutDescriptor* descriptor,
            PipelineCompatibilityToken pipelineCompatibilityToken);

        BindGroupLayout(DeviceBase* device,
                        const BindGroupLayoutDescriptor* descriptor,
                        PipelineCompatibilityToken pipelineCompatibilityToken);

        VkDescriptorSetLayout GetHandle() const;

        ResultOrError<Ref<BindGroup>> AllocateBindGroup(Device* device,
                                                        const BindGroupDescriptor* descriptor);
        void DeallocateBindGroup(BindGroup* bindGroup,
                                 DescriptorSetAllocation* descriptorSetAllocation);

      private:
        ~BindGroupLayout() override;
        MaybeError Initialize();
        void DestroyImpl() override;

        // Dawn API
        void SetLabelImpl() override;

        VkDescriptorSetLayout mHandle = VK_NULL_HANDLE;

        SlabAllocator<BindGroup> mBindGroupAllocator;
        Ref<DescriptorSetAllocator> mDescriptorSetAllocator;
    };

}  // namespace dawn_native::vulkan

#endif  // DAWNNATIVE_VULKAN_BINDGROUPLAYOUTVK_H_
