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