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

#include "common/Assert.h"
#include "common/Log.h"
#include "dawn_native/d3d12/D3D12Error.h"
#include "dawn_native/d3d12/DeviceD3D12.h"
#include "dawn_native/d3d12/PipelineLayoutD3D12.h"
#include "dawn_native/d3d12/PlatformFunctions.h"
#include "dawn_native/d3d12/ShaderModuleD3D12.h"
#include "dawn_native/d3d12/TextureD3D12.h"
#include "dawn_native/d3d12/UtilsD3D12.h"

#include <d3dcompiler.h>

namespace dawn_native { namespace d3d12 {

    namespace {
        DXGI_FORMAT VertexFormatType(wgpu::VertexFormat format) {
            switch (format) {
                case wgpu::VertexFormat::UChar2:
                    return DXGI_FORMAT_R8G8_UINT;
                case wgpu::VertexFormat::UChar4:
                    return DXGI_FORMAT_R8G8B8A8_UINT;
                case wgpu::VertexFormat::Char2:
                    return DXGI_FORMAT_R8G8_SINT;
                case wgpu::VertexFormat::Char4:
                    return DXGI_FORMAT_R8G8B8A8_SINT;
                case wgpu::VertexFormat::UChar2Norm:
                    return DXGI_FORMAT_R8G8_UNORM;
                case wgpu::VertexFormat::UChar4Norm:
                    return DXGI_FORMAT_R8G8B8A8_UNORM;
                case wgpu::VertexFormat::Char2Norm:
                    return DXGI_FORMAT_R8G8_SNORM;
                case wgpu::VertexFormat::Char4Norm:
                    return DXGI_FORMAT_R8G8B8A8_SNORM;
                case wgpu::VertexFormat::UShort2:
                    return DXGI_FORMAT_R16G16_UINT;
                case wgpu::VertexFormat::UShort4:
                    return DXGI_FORMAT_R16G16B16A16_UINT;
                case wgpu::VertexFormat::Short2:
                    return DXGI_FORMAT_R16G16_SINT;
                case wgpu::VertexFormat::Short4:
                    return DXGI_FORMAT_R16G16B16A16_SINT;
                case wgpu::VertexFormat::UShort2Norm:
                    return DXGI_FORMAT_R16G16_UNORM;
                case wgpu::VertexFormat::UShort4Norm:
                    return DXGI_FORMAT_R16G16B16A16_UNORM;
                case wgpu::VertexFormat::Short2Norm:
                    return DXGI_FORMAT_R16G16_SNORM;
                case wgpu::VertexFormat::Short4Norm:
                    return DXGI_FORMAT_R16G16B16A16_SNORM;
                case wgpu::VertexFormat::Half2:
                    return DXGI_FORMAT_R16G16_FLOAT;
                case wgpu::VertexFormat::Half4:
                    return DXGI_FORMAT_R16G16B16A16_FLOAT;
                case wgpu::VertexFormat::Float:
                    return DXGI_FORMAT_R32_FLOAT;
                case wgpu::VertexFormat::Float2:
                    return DXGI_FORMAT_R32G32_FLOAT;
                case wgpu::VertexFormat::Float3:
                    return DXGI_FORMAT_R32G32B32_FLOAT;
                case wgpu::VertexFormat::Float4:
                    return DXGI_FORMAT_R32G32B32A32_FLOAT;
                case wgpu::VertexFormat::UInt:
                    return DXGI_FORMAT_R32_UINT;
                case wgpu::VertexFormat::UInt2:
                    return DXGI_FORMAT_R32G32_UINT;
                case wgpu::VertexFormat::UInt3:
                    return DXGI_FORMAT_R32G32B32_UINT;
                case wgpu::VertexFormat::UInt4:
                    return DXGI_FORMAT_R32G32B32A32_UINT;
                case wgpu::VertexFormat::Int:
                    return DXGI_FORMAT_R32_SINT;
                case wgpu::VertexFormat::Int2:
                    return DXGI_FORMAT_R32G32_SINT;
                case wgpu::VertexFormat::Int3:
                    return DXGI_FORMAT_R32G32B32_SINT;
                case wgpu::VertexFormat::Int4:
                    return DXGI_FORMAT_R32G32B32A32_SINT;
            }
        }

        D3D12_INPUT_CLASSIFICATION InputStepModeFunction(wgpu::InputStepMode mode) {
            switch (mode) {
                case wgpu::InputStepMode::Vertex:
                    return D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
                case wgpu::InputStepMode::Instance:
                    return D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA;
            }
        }

        D3D12_PRIMITIVE_TOPOLOGY D3D12PrimitiveTopology(wgpu::PrimitiveTopology primitiveTopology) {
            switch (primitiveTopology) {
                case wgpu::PrimitiveTopology::PointList:
                    return D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
                case wgpu::PrimitiveTopology::LineList:
                    return D3D_PRIMITIVE_TOPOLOGY_LINELIST;
                case wgpu::PrimitiveTopology::LineStrip:
                    return D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
                case wgpu::PrimitiveTopology::TriangleList:
                    return D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
                case wgpu::PrimitiveTopology::TriangleStrip:
                    return D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
            }
        }

        D3D12_PRIMITIVE_TOPOLOGY_TYPE D3D12PrimitiveTopologyType(
            wgpu::PrimitiveTopology primitiveTopology) {
            switch (primitiveTopology) {
                case wgpu::PrimitiveTopology::PointList:
                    return D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT;
                case wgpu::PrimitiveTopology::LineList:
                case wgpu::PrimitiveTopology::LineStrip:
                    return D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE;
                case wgpu::PrimitiveTopology::TriangleList:
                case wgpu::PrimitiveTopology::TriangleStrip:
                    return D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
            }
        }

        D3D12_CULL_MODE D3D12CullMode(wgpu::CullMode mode) {
            switch (mode) {
                case wgpu::CullMode::None:
                    return D3D12_CULL_MODE_NONE;
                case wgpu::CullMode::Front:
                    return D3D12_CULL_MODE_FRONT;
                case wgpu::CullMode::Back:
                    return D3D12_CULL_MODE_BACK;
            }
        }

        D3D12_BLEND D3D12Blend(wgpu::BlendFactor factor) {
            switch (factor) {
                case wgpu::BlendFactor::Zero:
                    return D3D12_BLEND_ZERO;
                case wgpu::BlendFactor::One:
                    return D3D12_BLEND_ONE;
                case wgpu::BlendFactor::SrcColor:
                    return D3D12_BLEND_SRC_COLOR;
                case wgpu::BlendFactor::OneMinusSrcColor:
                    return D3D12_BLEND_INV_SRC_COLOR;
                case wgpu::BlendFactor::SrcAlpha:
                    return D3D12_BLEND_SRC_ALPHA;
                case wgpu::BlendFactor::OneMinusSrcAlpha:
                    return D3D12_BLEND_INV_SRC_ALPHA;
                case wgpu::BlendFactor::DstColor:
                    return D3D12_BLEND_DEST_COLOR;
                case wgpu::BlendFactor::OneMinusDstColor:
                    return D3D12_BLEND_INV_DEST_COLOR;
                case wgpu::BlendFactor::DstAlpha:
                    return D3D12_BLEND_DEST_ALPHA;
                case wgpu::BlendFactor::OneMinusDstAlpha:
                    return D3D12_BLEND_INV_DEST_ALPHA;
                case wgpu::BlendFactor::SrcAlphaSaturated:
                    return D3D12_BLEND_SRC_ALPHA_SAT;
                case wgpu::BlendFactor::BlendColor:
                    return D3D12_BLEND_BLEND_FACTOR;
                case wgpu::BlendFactor::OneMinusBlendColor:
                    return D3D12_BLEND_INV_BLEND_FACTOR;
            }
        }

        D3D12_BLEND_OP D3D12BlendOperation(wgpu::BlendOperation operation) {
            switch (operation) {
                case wgpu::BlendOperation::Add:
                    return D3D12_BLEND_OP_ADD;
                case wgpu::BlendOperation::Subtract:
                    return D3D12_BLEND_OP_SUBTRACT;
                case wgpu::BlendOperation::ReverseSubtract:
                    return D3D12_BLEND_OP_REV_SUBTRACT;
                case wgpu::BlendOperation::Min:
                    return D3D12_BLEND_OP_MIN;
                case wgpu::BlendOperation::Max:
                    return D3D12_BLEND_OP_MAX;
            }
        }

        uint8_t D3D12RenderTargetWriteMask(wgpu::ColorWriteMask writeMask) {
            static_assert(static_cast<D3D12_COLOR_WRITE_ENABLE>(wgpu::ColorWriteMask::Red) ==
                              D3D12_COLOR_WRITE_ENABLE_RED,
                          "ColorWriteMask values must match");
            static_assert(static_cast<D3D12_COLOR_WRITE_ENABLE>(wgpu::ColorWriteMask::Green) ==
                              D3D12_COLOR_WRITE_ENABLE_GREEN,
                          "ColorWriteMask values must match");
            static_assert(static_cast<D3D12_COLOR_WRITE_ENABLE>(wgpu::ColorWriteMask::Blue) ==
                              D3D12_COLOR_WRITE_ENABLE_BLUE,
                          "ColorWriteMask values must match");
            static_assert(static_cast<D3D12_COLOR_WRITE_ENABLE>(wgpu::ColorWriteMask::Alpha) ==
                              D3D12_COLOR_WRITE_ENABLE_ALPHA,
                          "ColorWriteMask values must match");
            return static_cast<uint8_t>(writeMask);
        }

        D3D12_RENDER_TARGET_BLEND_DESC ComputeColorDesc(const ColorStateDescriptor* descriptor) {
            D3D12_RENDER_TARGET_BLEND_DESC blendDesc;
            blendDesc.BlendEnable = BlendEnabled(descriptor);
            blendDesc.SrcBlend = D3D12Blend(descriptor->colorBlend.srcFactor);
            blendDesc.DestBlend = D3D12Blend(descriptor->colorBlend.dstFactor);
            blendDesc.BlendOp = D3D12BlendOperation(descriptor->colorBlend.operation);
            blendDesc.SrcBlendAlpha = D3D12Blend(descriptor->alphaBlend.srcFactor);
            blendDesc.DestBlendAlpha = D3D12Blend(descriptor->alphaBlend.dstFactor);
            blendDesc.BlendOpAlpha = D3D12BlendOperation(descriptor->alphaBlend.operation);
            blendDesc.RenderTargetWriteMask = D3D12RenderTargetWriteMask(descriptor->writeMask);
            blendDesc.LogicOpEnable = false;
            blendDesc.LogicOp = D3D12_LOGIC_OP_NOOP;
            return blendDesc;
        }

        D3D12_STENCIL_OP StencilOp(wgpu::StencilOperation op) {
            switch (op) {
                case wgpu::StencilOperation::Keep:
                    return D3D12_STENCIL_OP_KEEP;
                case wgpu::StencilOperation::Zero:
                    return D3D12_STENCIL_OP_ZERO;
                case wgpu::StencilOperation::Replace:
                    return D3D12_STENCIL_OP_REPLACE;
                case wgpu::StencilOperation::IncrementClamp:
                    return D3D12_STENCIL_OP_INCR_SAT;
                case wgpu::StencilOperation::DecrementClamp:
                    return D3D12_STENCIL_OP_DECR_SAT;
                case wgpu::StencilOperation::Invert:
                    return D3D12_STENCIL_OP_INVERT;
                case wgpu::StencilOperation::IncrementWrap:
                    return D3D12_STENCIL_OP_INCR;
                case wgpu::StencilOperation::DecrementWrap:
                    return D3D12_STENCIL_OP_DECR;
            }
        }

        D3D12_DEPTH_STENCILOP_DESC StencilOpDesc(const StencilStateFaceDescriptor descriptor) {
            D3D12_DEPTH_STENCILOP_DESC desc;

            desc.StencilFailOp = StencilOp(descriptor.failOp);
            desc.StencilDepthFailOp = StencilOp(descriptor.depthFailOp);
            desc.StencilPassOp = StencilOp(descriptor.passOp);
            desc.StencilFunc = ToD3D12ComparisonFunc(descriptor.compare);

            return desc;
        }

        D3D12_DEPTH_STENCIL_DESC ComputeDepthStencilDesc(
            const DepthStencilStateDescriptor* descriptor) {
            D3D12_DEPTH_STENCIL_DESC mDepthStencilDescriptor;
            mDepthStencilDescriptor.DepthEnable = TRUE;
            mDepthStencilDescriptor.DepthWriteMask = descriptor->depthWriteEnabled
                                                         ? D3D12_DEPTH_WRITE_MASK_ALL
                                                         : D3D12_DEPTH_WRITE_MASK_ZERO;
            mDepthStencilDescriptor.DepthFunc = ToD3D12ComparisonFunc(descriptor->depthCompare);

            mDepthStencilDescriptor.StencilEnable = StencilTestEnabled(descriptor) ? TRUE : FALSE;
            mDepthStencilDescriptor.StencilReadMask =
                static_cast<UINT8>(descriptor->stencilReadMask);
            mDepthStencilDescriptor.StencilWriteMask =
                static_cast<UINT8>(descriptor->stencilWriteMask);

            mDepthStencilDescriptor.FrontFace = StencilOpDesc(descriptor->stencilFront);
            mDepthStencilDescriptor.BackFace = StencilOpDesc(descriptor->stencilBack);
            return mDepthStencilDescriptor;
        }

        D3D12_INDEX_BUFFER_STRIP_CUT_VALUE ComputeIndexBufferStripCutValue(
            wgpu::PrimitiveTopology primitiveTopology,
            wgpu::IndexFormat indexFormat) {
            if (primitiveTopology != wgpu::PrimitiveTopology::TriangleStrip &&
                primitiveTopology != wgpu::PrimitiveTopology::LineStrip) {
                return D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED;
            }

            switch (indexFormat) {
                case wgpu::IndexFormat::Uint16:
                    return D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF;
                case wgpu::IndexFormat::Uint32:
                    return D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF;
                case wgpu::IndexFormat::Undefined:
                    return D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED;
            }
        }

    }  // anonymous namespace

    ResultOrError<RenderPipeline*> RenderPipeline::Create(
        Device* device,
        const RenderPipelineDescriptor* descriptor) {
        Ref<RenderPipeline> pipeline = AcquireRef(new RenderPipeline(device, descriptor));
        DAWN_TRY(pipeline->Initialize(descriptor));
        return pipeline.Detach();
    }

    MaybeError RenderPipeline::Initialize(const RenderPipelineDescriptor* descriptor) {
        Device* device = ToBackend(GetDevice());
        uint32_t compileFlags = 0;
#if defined(_DEBUG)
        // Enable better shader debugging with the graphics debugging tools.
        compileFlags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
#endif
        // SPRIV-cross does matrix multiplication expecting row major matrices
        compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;

        D3D12_GRAPHICS_PIPELINE_STATE_DESC descriptorD3D12 = {};

        PerStage<const char*> entryPoints;
        entryPoints[SingleShaderStage::Vertex] = descriptor->vertexStage.entryPoint;
        entryPoints[SingleShaderStage::Fragment] = descriptor->fragmentStage->entryPoint;

        PerStage<ShaderModule*> modules;
        modules[SingleShaderStage::Vertex] = ToBackend(descriptor->vertexStage.module);
        modules[SingleShaderStage::Fragment] = ToBackend(descriptor->fragmentStage->module);

        PerStage<D3D12_SHADER_BYTECODE*> shaders;
        shaders[SingleShaderStage::Vertex] = &descriptorD3D12.VS;
        shaders[SingleShaderStage::Fragment] = &descriptorD3D12.PS;

        PerStage<CompiledShader> compiledShader;
        wgpu::ShaderStage renderStages = wgpu::ShaderStage::Vertex | wgpu::ShaderStage::Fragment;
        for (auto stage : IterateStages(renderStages)) {
            DAWN_TRY_ASSIGN(compiledShader[stage],
                            modules[stage]->Compile(entryPoints[stage], stage,
                                                    ToBackend(GetLayout()), compileFlags));
            *shaders[stage] = compiledShader[stage].GetD3D12ShaderBytecode();
        }

        mFirstOffsetInfo = compiledShader[SingleShaderStage::Vertex].firstOffsetInfo;

        PipelineLayout* layout = ToBackend(GetLayout());

        descriptorD3D12.pRootSignature = layout->GetRootSignature();

        // D3D12 logs warnings if any empty input state is used
        std::array<D3D12_INPUT_ELEMENT_DESC, kMaxVertexAttributes> inputElementDescriptors;
        if (GetAttributeLocationsUsed().any()) {
            descriptorD3D12.InputLayout = ComputeInputLayout(&inputElementDescriptors);
        }

        descriptorD3D12.IBStripCutValue = ComputeIndexBufferStripCutValue(
            GetPrimitiveTopology(), GetVertexStateDescriptor()->indexFormat);

        descriptorD3D12.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
        descriptorD3D12.RasterizerState.CullMode = D3D12CullMode(GetCullMode());
        descriptorD3D12.RasterizerState.FrontCounterClockwise =
            (GetFrontFace() == wgpu::FrontFace::CCW) ? TRUE : FALSE;
        descriptorD3D12.RasterizerState.DepthBias = GetDepthBias();
        descriptorD3D12.RasterizerState.DepthBiasClamp = GetDepthBiasClamp();
        descriptorD3D12.RasterizerState.SlopeScaledDepthBias = GetDepthBiasSlopeScale();
        descriptorD3D12.RasterizerState.DepthClipEnable = TRUE;
        descriptorD3D12.RasterizerState.MultisampleEnable = (GetSampleCount() > 1) ? TRUE : FALSE;
        descriptorD3D12.RasterizerState.AntialiasedLineEnable = FALSE;
        descriptorD3D12.RasterizerState.ForcedSampleCount = 0;
        descriptorD3D12.RasterizerState.ConservativeRaster =
            D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;

        if (HasDepthStencilAttachment()) {
            descriptorD3D12.DSVFormat = D3D12TextureFormat(GetDepthStencilFormat());
        }

        for (ColorAttachmentIndex i : IterateBitSet(GetColorAttachmentsMask())) {
            descriptorD3D12.RTVFormats[static_cast<uint8_t>(i)] =
                D3D12TextureFormat(GetColorAttachmentFormat(i));
            descriptorD3D12.BlendState.RenderTarget[static_cast<uint8_t>(i)] =
                ComputeColorDesc(GetColorStateDescriptor(i));
        }
        descriptorD3D12.NumRenderTargets = static_cast<uint32_t>(GetColorAttachmentsMask().count());

        descriptorD3D12.BlendState.AlphaToCoverageEnable = descriptor->alphaToCoverageEnabled;
        descriptorD3D12.BlendState.IndependentBlendEnable = TRUE;

        descriptorD3D12.DepthStencilState =
            ComputeDepthStencilDesc(GetDepthStencilStateDescriptor());

        descriptorD3D12.SampleMask = GetSampleMask();
        descriptorD3D12.PrimitiveTopologyType = D3D12PrimitiveTopologyType(GetPrimitiveTopology());
        descriptorD3D12.SampleDesc.Count = GetSampleCount();
        descriptorD3D12.SampleDesc.Quality = 0;

        mD3d12PrimitiveTopology = D3D12PrimitiveTopology(GetPrimitiveTopology());

        DAWN_TRY(CheckHRESULT(device->GetD3D12Device()->CreateGraphicsPipelineState(
                                  &descriptorD3D12, IID_PPV_ARGS(&mPipelineState)),
                              "D3D12 create graphics pipeline state"));
        return {};
    }

    RenderPipeline::~RenderPipeline() {
        ToBackend(GetDevice())->ReferenceUntilUnused(mPipelineState);
    }

    D3D12_PRIMITIVE_TOPOLOGY RenderPipeline::GetD3D12PrimitiveTopology() const {
        return mD3d12PrimitiveTopology;
    }

    ID3D12PipelineState* RenderPipeline::GetPipelineState() const {
        return mPipelineState.Get();
    }

    const FirstOffsetInfo& RenderPipeline::GetFirstOffsetInfo() const {
        return mFirstOffsetInfo;
    }

    D3D12_INPUT_LAYOUT_DESC RenderPipeline::ComputeInputLayout(
        std::array<D3D12_INPUT_ELEMENT_DESC, kMaxVertexAttributes>* inputElementDescriptors) {
        unsigned int count = 0;
        for (VertexAttributeLocation loc : IterateBitSet(GetAttributeLocationsUsed())) {
            D3D12_INPUT_ELEMENT_DESC& inputElementDescriptor = (*inputElementDescriptors)[count++];

            const VertexAttributeInfo& attribute = GetAttribute(loc);

            // If the HLSL semantic is TEXCOORDN the SemanticName should be "TEXCOORD" and the
            // SemanticIndex N
            inputElementDescriptor.SemanticName = "TEXCOORD";
            inputElementDescriptor.SemanticIndex = static_cast<uint8_t>(loc);
            inputElementDescriptor.Format = VertexFormatType(attribute.format);
            inputElementDescriptor.InputSlot = static_cast<uint8_t>(attribute.vertexBufferSlot);

            const VertexBufferInfo& input = GetVertexBuffer(attribute.vertexBufferSlot);

            inputElementDescriptor.AlignedByteOffset = attribute.offset;
            inputElementDescriptor.InputSlotClass = InputStepModeFunction(input.stepMode);
            if (inputElementDescriptor.InputSlotClass ==
                D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA) {
                inputElementDescriptor.InstanceDataStepRate = 0;
            } else {
                inputElementDescriptor.InstanceDataStepRate = 1;
            }
        }

        D3D12_INPUT_LAYOUT_DESC inputLayoutDescriptor;
        inputLayoutDescriptor.pInputElementDescs = &(*inputElementDescriptors)[0];
        inputLayoutDescriptor.NumElements = count;
        return inputLayoutDescriptor;
    }

}}  // namespace dawn_native::d3d12
