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

#include "dawn/native/d3d12/CommandAllocatorManager.h"

#include "dawn/native/d3d12/D3D12Error.h"
#include "dawn/native/d3d12/DeviceD3D12.h"

#include "dawn/common/Assert.h"
#include "dawn/common/BitSetIterator.h"

namespace dawn::native::d3d12 {

CommandAllocatorManager::CommandAllocatorManager(Device* device)
    : device(device), mAllocatorCount(0) {
    mFreeAllocators.set();
}

ResultOrError<ID3D12CommandAllocator*> CommandAllocatorManager::ReserveCommandAllocator() {
    // If there are no free allocators, get the oldest serial in flight and wait on it
    if (mFreeAllocators.none()) {
        const ExecutionSerial firstSerial = mInFlightCommandAllocators.FirstSerial();
        DAWN_TRY(device->WaitForSerial(firstSerial));
        DAWN_TRY(Tick(firstSerial));
    }

    ASSERT(mFreeAllocators.any());

    // Get the index of the first free allocator from the bitset
    unsigned int firstFreeIndex = *(IterateBitSet(mFreeAllocators).begin());

    if (firstFreeIndex >= mAllocatorCount) {
        ASSERT(firstFreeIndex == mAllocatorCount);
        mAllocatorCount++;
        DAWN_TRY(CheckHRESULT(
            device->GetD3D12Device()->CreateCommandAllocator(
                D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&mCommandAllocators[firstFreeIndex])),
            "D3D12 create command allocator"));
    }

    // Mark the command allocator as used
    mFreeAllocators.reset(firstFreeIndex);

    // Enqueue the command allocator. It will be scheduled for reset after the next
    // ExecuteCommandLists
    mInFlightCommandAllocators.Enqueue({mCommandAllocators[firstFreeIndex], firstFreeIndex},
                                       device->GetPendingCommandSerial());
    return mCommandAllocators[firstFreeIndex].Get();
}

MaybeError CommandAllocatorManager::Tick(ExecutionSerial lastCompletedSerial) {
    // Reset all command allocators that are no longer in flight
    for (auto it : mInFlightCommandAllocators.IterateUpTo(lastCompletedSerial)) {
        DAWN_TRY(CheckHRESULT(it.commandAllocator->Reset(), "D3D12 reset command allocator"));
        mFreeAllocators.set(it.index);
    }
    mInFlightCommandAllocators.ClearUpTo(lastCompletedSerial);
    return {};
}

}  // namespace dawn::native::d3d12
