// Copyright 2020 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_D3D12_STAGINGDESCRIPTORALLOCATOR_H_
#define DAWNNATIVE_D3D12_STAGINGDESCRIPTORALLOCATOR_H_

#include "dawn_native/Error.h"

#include "dawn_native/d3d12/CPUDescriptorHeapAllocationD3D12.h"

#include <vector>

// |StagingDescriptorAllocator| allocates a fixed-size block of descriptors from a CPU
// descriptor heap pool.
// Internally, it manages a list of heaps using a fixed-size block allocator. The fixed-size
// block allocator is backed by a list of free blocks (free-list). The heap is in one of two
// states: AVAILABLE or not. To allocate, the next free block is removed from the free-list
// and the corresponding heap offset is returned. The AVAILABLE heap always has room for
// at-least one free block. If no AVAILABLE heap exists, a new heap is created and inserted
// back into the pool to be immediately used. To deallocate, the block corresponding to the
// offset is inserted back into the free-list.
namespace dawn_native::d3d12 {

    class Device;

    class StagingDescriptorAllocator {
      public:
        StagingDescriptorAllocator() = default;
        StagingDescriptorAllocator(Device* device,
                                   uint32_t descriptorCount,
                                   uint32_t heapSize,
                                   D3D12_DESCRIPTOR_HEAP_TYPE heapType);
        ~StagingDescriptorAllocator();

        ResultOrError<CPUDescriptorHeapAllocation> AllocateCPUDescriptors();

        // Will call Deallocate when the serial is passed.
        ResultOrError<CPUDescriptorHeapAllocation> AllocateTransientCPUDescriptors();

        void Deallocate(CPUDescriptorHeapAllocation* allocation);

        uint32_t GetSizeIncrement() const;

        void Tick(ExecutionSerial completedSerial);

      private:
        using Index = uint16_t;

        struct NonShaderVisibleBuffer {
            ComPtr<ID3D12DescriptorHeap> heap;
            std::vector<Index> freeBlockIndices;
        };

        MaybeError AllocateCPUHeap();

        Index GetFreeBlockIndicesSize() const;

        std::vector<uint32_t> mAvailableHeaps;  // Indices into the pool.
        std::vector<NonShaderVisibleBuffer> mPool;

        Device* mDevice;

        uint32_t mSizeIncrement;  // Size of the descriptor (in bytes).
        uint32_t mBlockSize;      // Size of the block of descriptors (in bytes).
        uint32_t mHeapSize;       // Size of the heap (in number of descriptors).

        D3D12_DESCRIPTOR_HEAP_TYPE mHeapType;

        SerialQueue<ExecutionSerial, CPUDescriptorHeapAllocation> mAllocationsToDelete;
    };

}  // namespace dawn_native::d3d12

#endif  // DAWNNATIVE_D3D12_STAGINGDESCRIPTORALLOCATOR_H_
