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