// Copyright 2017 The NXT 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 "utils/BackendBinding.h"

#include "common/Assert.h"

#define GLFW_EXPOSE_NATIVE_WIN32
#include "GLFW/glfw3.h"
#include "GLFW/glfw3native.h"

#include <initializer_list>
#include <wrl.h>
#include <d3d12.h>
#include <dxgi1_4.h>
#ifdef _DEBUG
#include <dxgidebug.h>
#endif

using Microsoft::WRL::ComPtr;

namespace backend {
namespace d3d12 {
    void Init(ComPtr<ID3D12Device> d3d12Device, nxtProcTable* procs, nxtDevice* device);
    ComPtr<ID3D12CommandQueue> GetCommandQueue(nxtDevice device);
    void SetNextTexture(nxtDevice device, ComPtr<ID3D12Resource> resource);
    uint64_t GetSerial(const nxtDevice device);
    void NextSerial(nxtDevice device);
    void ExecuteCommandLists(nxtDevice device, std::initializer_list<ID3D12CommandList*> commandLists);
    void WaitForSerial(nxtDevice device, uint64_t serial);
    void OpenCommandList(nxtDevice device, ComPtr<ID3D12GraphicsCommandList>* commandList);
}
}

namespace utils {

    class D3D12Binding : public BackendBinding {
        public:
            void SetupGLFWWindowHints() override {
                glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
            }

            void GetProcAndDevice(nxtProcTable* procs, nxtDevice* device) override {
                uint32_t dxgiFactoryFlags = 0;
#ifdef _DEBUG
                // Enable the debug layer (requires the Graphics Tools "optional feature").
                // NOTE: Enabling the debug layer after device creation will invalidate the active device.
                {
                    ComPtr<ID3D12Debug> debugController;
                    if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) {
                        debugController->EnableDebugLayer();

                        // Enable additional debug layers.
                        dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG;
                    }

                    ComPtr<IDXGIDebug1> dxgiDebug;
                    if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(&dxgiDebug)))) {
                        dxgiDebug->ReportLiveObjects(DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_FLAGS(DXGI_DEBUG_RLO_ALL));
                    }
                }
#endif

                ASSERT_SUCCESS(CreateDXGIFactory2(dxgiFactoryFlags, IID_PPV_ARGS(&factory)));
                ASSERT(GetHardwareAdapter(factory.Get(), &hardwareAdapter));
                ASSERT_SUCCESS(D3D12CreateDevice(
                    hardwareAdapter.Get(),
                    D3D_FEATURE_LEVEL_11_0,
                    IID_PPV_ARGS(&d3d12Device)
                ));

                backend::d3d12::Init(d3d12Device, procs, device);
                backendDevice = *device;
                commandQueue = backend::d3d12::GetCommandQueue(backendDevice);

                int width, height;
                glfwGetWindowSize(window, &width, &height);
                DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
                swapChainDesc.Width = width;
                swapChainDesc.Height = height;
                swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
                swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
                swapChainDesc.BufferCount = kFrameCount;
                swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
                swapChainDesc.SampleDesc.Count = 1;
                swapChainDesc.SampleDesc.Quality = 0;

                HWND win32Window = glfwGetWin32Window(window);
                ComPtr<IDXGISwapChain1> swapChain1;
                ASSERT_SUCCESS(factory->CreateSwapChainForHwnd(
                    commandQueue.Get(),
                    win32Window,
                    &swapChainDesc,
                    nullptr,
                    nullptr,
                    &swapChain1
                ));
                ASSERT_SUCCESS(swapChain1.As(&swapChain));

                for (uint32_t n = 0; n < kFrameCount; ++n) {
                    ASSERT_SUCCESS(swapChain->GetBuffer(n, IID_PPV_ARGS(&renderTargetResources[n])));
                }

                // Get the initial render target and arbitrarily choose a "previous" render target that's different
                previousRenderTargetIndex = renderTargetIndex = swapChain->GetCurrentBackBufferIndex();
                previousRenderTargetIndex = renderTargetIndex == 0 ? 1 : 0;

                // Initial the serial for all render targets
                const uint64_t initialSerial = backend::d3d12::GetSerial(backendDevice);
                for (uint32_t n = 0; n < kFrameCount; ++n) {
                    lastSerialRenderTargetWasUsed[n] = initialSerial;
                }

                // Transition the first frame to be a render target
                {
                    backend::d3d12::OpenCommandList(backendDevice, &commandList);

                    D3D12_RESOURCE_BARRIER resourceBarrier;
                    resourceBarrier.Transition.pResource = renderTargetResources[renderTargetIndex].Get();
                    resourceBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
                    resourceBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
                    resourceBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
                    resourceBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
                    resourceBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
                    commandList->ResourceBarrier(1, &resourceBarrier);
                    ASSERT_SUCCESS(commandList->Close());
                    backend::d3d12::ExecuteCommandLists(backendDevice, { commandList.Get() });

                    backend::d3d12::NextSerial(backendDevice);
                }

                backend::d3d12::SetNextTexture(backendDevice, renderTargetResources[renderTargetIndex]);
            }

            void SwapBuffers() override {
                // Transition current frame's render target for presenting
                {
                    backend::d3d12::OpenCommandList(backendDevice, &commandList);
                    D3D12_RESOURCE_BARRIER resourceBarrier;
                    resourceBarrier.Transition.pResource = renderTargetResources[renderTargetIndex].Get();
                    resourceBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
                    resourceBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
                    resourceBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
                    resourceBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
                    resourceBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
                    commandList->ResourceBarrier(1, &resourceBarrier);
                    ASSERT_SUCCESS(commandList->Close());
                    backend::d3d12::ExecuteCommandLists(backendDevice, { commandList.Get() });
                }

                ASSERT_SUCCESS(swapChain->Present(1, 0));

                // Transition last frame's render target back to being a render target
                {
                    backend::d3d12::OpenCommandList(backendDevice, &commandList);
                    D3D12_RESOURCE_BARRIER resourceBarrier;
                    resourceBarrier.Transition.pResource = renderTargetResources[previousRenderTargetIndex].Get();
                    resourceBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
                    resourceBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
                    resourceBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
                    resourceBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
                    resourceBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
                    commandList->ResourceBarrier(1, &resourceBarrier);
                    ASSERT_SUCCESS(commandList->Close());
                    backend::d3d12::ExecuteCommandLists(backendDevice, { commandList.Get() });
                }

                backend::d3d12::NextSerial(backendDevice);

                previousRenderTargetIndex = renderTargetIndex;
                renderTargetIndex = swapChain->GetCurrentBackBufferIndex();

                // If the next render target is not ready to be rendered yet, wait until it is ready.
                // If the last completed serial is less than the last requested serial for this render target,
                // then the commands previously executed on this render target have not yet completed
                backend::d3d12::WaitForSerial(backendDevice, lastSerialRenderTargetWasUsed[renderTargetIndex]);

                lastSerialRenderTargetWasUsed[renderTargetIndex] = backend::d3d12::GetSerial(backendDevice);

                // Tell the backend to render to the current render target
                backend::d3d12::SetNextTexture(backendDevice, renderTargetResources[renderTargetIndex]);
            }

        private:
            nxtDevice backendDevice = nullptr;

            static constexpr unsigned int kFrameCount = 2;

            // Initialization
            ComPtr<IDXGIFactory4> factory;
            ComPtr<IDXGIAdapter1> hardwareAdapter;
            ComPtr<ID3D12Device> d3d12Device;
            ComPtr<ID3D12CommandQueue> commandQueue;
            ComPtr<IDXGISwapChain3> swapChain;
            ComPtr<ID3D12Resource> renderTargetResources[kFrameCount];

            // Frame synchronization. Updated every frame
            uint32_t renderTargetIndex;
            uint32_t previousRenderTargetIndex;
            uint64_t lastSerialRenderTargetWasUsed[kFrameCount];
            ComPtr<ID3D12GraphicsCommandList> commandList;

            static void ASSERT_SUCCESS(HRESULT hr) {
                ASSERT(SUCCEEDED(hr));
            }

            static bool GetHardwareAdapter(IDXGIFactory4* factory, IDXGIAdapter1** hardwareAdapter) {
                *hardwareAdapter = nullptr;
                for (uint32_t adapterIndex = 0; ; ++adapterIndex) {
                    IDXGIAdapter1* adapter = nullptr;
                    if (factory->EnumAdapters1(adapterIndex, &adapter) == DXGI_ERROR_NOT_FOUND) {
                        break; // No more adapters to enumerate.
                    }

                    // Check to see if the adapter supports Direct3D 12, but don't create the actual device yet.
                    if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr))) {
                        *hardwareAdapter = adapter;
                        return true;
                    }
                    adapter->Release();
                }
                return false;
            }
    };

    BackendBinding* CreateD3D12Binding() {
        return new D3D12Binding;
    }

}
