// 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/vulkan/FencedDeleter.h"

#include "dawn_native/vulkan/DeviceVk.h"

namespace dawn_native::vulkan {

    FencedDeleter::FencedDeleter(Device* device) : mDevice(device) {
    }

    FencedDeleter::~FencedDeleter() {
        ASSERT(mBuffersToDelete.Empty());
        ASSERT(mDescriptorPoolsToDelete.Empty());
        ASSERT(mFramebuffersToDelete.Empty());
        ASSERT(mImagesToDelete.Empty());
        ASSERT(mImageViewsToDelete.Empty());
        ASSERT(mMemoriesToDelete.Empty());
        ASSERT(mPipelinesToDelete.Empty());
        ASSERT(mPipelineLayoutsToDelete.Empty());
        ASSERT(mQueryPoolsToDelete.Empty());
        ASSERT(mRenderPassesToDelete.Empty());
        ASSERT(mSamplersToDelete.Empty());
        ASSERT(mSemaphoresToDelete.Empty());
        ASSERT(mShaderModulesToDelete.Empty());
        ASSERT(mSurfacesToDelete.Empty());
        ASSERT(mSwapChainsToDelete.Empty());
    }

    void FencedDeleter::DeleteWhenUnused(VkBuffer buffer) {
        mBuffersToDelete.Enqueue(buffer, mDevice->GetPendingCommandSerial());
    }

    void FencedDeleter::DeleteWhenUnused(VkDescriptorPool pool) {
        mDescriptorPoolsToDelete.Enqueue(pool, mDevice->GetPendingCommandSerial());
    }

    void FencedDeleter::DeleteWhenUnused(VkDeviceMemory memory) {
        mMemoriesToDelete.Enqueue(memory, mDevice->GetPendingCommandSerial());
    }

    void FencedDeleter::DeleteWhenUnused(VkFramebuffer framebuffer) {
        mFramebuffersToDelete.Enqueue(framebuffer, mDevice->GetPendingCommandSerial());
    }

    void FencedDeleter::DeleteWhenUnused(VkImage image) {
        mImagesToDelete.Enqueue(image, mDevice->GetPendingCommandSerial());
    }

    void FencedDeleter::DeleteWhenUnused(VkImageView view) {
        mImageViewsToDelete.Enqueue(view, mDevice->GetPendingCommandSerial());
    }

    void FencedDeleter::DeleteWhenUnused(VkPipeline pipeline) {
        mPipelinesToDelete.Enqueue(pipeline, mDevice->GetPendingCommandSerial());
    }

    void FencedDeleter::DeleteWhenUnused(VkPipelineLayout layout) {
        mPipelineLayoutsToDelete.Enqueue(layout, mDevice->GetPendingCommandSerial());
    }

    void FencedDeleter::DeleteWhenUnused(VkQueryPool querypool) {
        mQueryPoolsToDelete.Enqueue(querypool, mDevice->GetPendingCommandSerial());
    }

    void FencedDeleter::DeleteWhenUnused(VkRenderPass renderPass) {
        mRenderPassesToDelete.Enqueue(renderPass, mDevice->GetPendingCommandSerial());
    }

    void FencedDeleter::DeleteWhenUnused(VkSampler sampler) {
        mSamplersToDelete.Enqueue(sampler, mDevice->GetPendingCommandSerial());
    }

    void FencedDeleter::DeleteWhenUnused(VkSemaphore semaphore) {
        mSemaphoresToDelete.Enqueue(semaphore, mDevice->GetPendingCommandSerial());
    }

    void FencedDeleter::DeleteWhenUnused(VkShaderModule module) {
        mShaderModulesToDelete.Enqueue(module, mDevice->GetPendingCommandSerial());
    }

    void FencedDeleter::DeleteWhenUnused(VkSurfaceKHR surface) {
        mSurfacesToDelete.Enqueue(surface, mDevice->GetPendingCommandSerial());
    }

    void FencedDeleter::DeleteWhenUnused(VkSwapchainKHR swapChain) {
        mSwapChainsToDelete.Enqueue(swapChain, mDevice->GetPendingCommandSerial());
    }

    void FencedDeleter::Tick(ExecutionSerial completedSerial) {
        VkDevice vkDevice = mDevice->GetVkDevice();
        VkInstance instance = mDevice->GetVkInstance();

        // Buffers and images must be deleted before memories because it is invalid to free memory
        // that still have resources bound to it.
        for (VkBuffer buffer : mBuffersToDelete.IterateUpTo(completedSerial)) {
            mDevice->fn.DestroyBuffer(vkDevice, buffer, nullptr);
        }
        mBuffersToDelete.ClearUpTo(completedSerial);
        for (VkImage image : mImagesToDelete.IterateUpTo(completedSerial)) {
            mDevice->fn.DestroyImage(vkDevice, image, nullptr);
        }
        mImagesToDelete.ClearUpTo(completedSerial);

        for (VkDeviceMemory memory : mMemoriesToDelete.IterateUpTo(completedSerial)) {
            mDevice->fn.FreeMemory(vkDevice, memory, nullptr);
        }
        mMemoriesToDelete.ClearUpTo(completedSerial);

        for (VkPipelineLayout layout : mPipelineLayoutsToDelete.IterateUpTo(completedSerial)) {
            mDevice->fn.DestroyPipelineLayout(vkDevice, layout, nullptr);
        }
        mPipelineLayoutsToDelete.ClearUpTo(completedSerial);

        for (VkRenderPass renderPass : mRenderPassesToDelete.IterateUpTo(completedSerial)) {
            mDevice->fn.DestroyRenderPass(vkDevice, renderPass, nullptr);
        }
        mRenderPassesToDelete.ClearUpTo(completedSerial);

        for (VkFramebuffer framebuffer : mFramebuffersToDelete.IterateUpTo(completedSerial)) {
            mDevice->fn.DestroyFramebuffer(vkDevice, framebuffer, nullptr);
        }
        mFramebuffersToDelete.ClearUpTo(completedSerial);

        for (VkImageView view : mImageViewsToDelete.IterateUpTo(completedSerial)) {
            mDevice->fn.DestroyImageView(vkDevice, view, nullptr);
        }
        mImageViewsToDelete.ClearUpTo(completedSerial);

        for (VkShaderModule module : mShaderModulesToDelete.IterateUpTo(completedSerial)) {
            mDevice->fn.DestroyShaderModule(vkDevice, module, nullptr);
        }
        mShaderModulesToDelete.ClearUpTo(completedSerial);

        for (VkPipeline pipeline : mPipelinesToDelete.IterateUpTo(completedSerial)) {
            mDevice->fn.DestroyPipeline(vkDevice, pipeline, nullptr);
        }
        mPipelinesToDelete.ClearUpTo(completedSerial);

        // Vulkan swapchains must be destroyed before their corresponding VkSurface
        for (VkSwapchainKHR swapChain : mSwapChainsToDelete.IterateUpTo(completedSerial)) {
            mDevice->fn.DestroySwapchainKHR(vkDevice, swapChain, nullptr);
        }
        mSwapChainsToDelete.ClearUpTo(completedSerial);
        for (VkSurfaceKHR surface : mSurfacesToDelete.IterateUpTo(completedSerial)) {
            mDevice->fn.DestroySurfaceKHR(instance, surface, nullptr);
        }
        mSurfacesToDelete.ClearUpTo(completedSerial);

        for (VkSemaphore semaphore : mSemaphoresToDelete.IterateUpTo(completedSerial)) {
            mDevice->fn.DestroySemaphore(vkDevice, semaphore, nullptr);
        }
        mSemaphoresToDelete.ClearUpTo(completedSerial);

        for (VkDescriptorPool pool : mDescriptorPoolsToDelete.IterateUpTo(completedSerial)) {
            mDevice->fn.DestroyDescriptorPool(vkDevice, pool, nullptr);
        }
        mDescriptorPoolsToDelete.ClearUpTo(completedSerial);

        for (VkQueryPool pool : mQueryPoolsToDelete.IterateUpTo(completedSerial)) {
            mDevice->fn.DestroyQueryPool(vkDevice, pool, nullptr);
        }
        mQueryPoolsToDelete.ClearUpTo(completedSerial);

        for (VkSampler sampler : mSamplersToDelete.IterateUpTo(completedSerial)) {
            mDevice->fn.DestroySampler(vkDevice, sampler, nullptr);
        }
        mSamplersToDelete.ClearUpTo(completedSerial);
    }

}  // namespace dawn_native::vulkan
