// 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::Uint8x2:
                    return DXGI_FORMAT_R8G8_UINT;
                case wgpu::VertexFormat::Uint8x4:
                    return DXGI_FORMAT_R8G8B8A8_UINT;
                case wgpu::VertexFormat::Sint8x2:
                    return DXGI_FORMAT_R8G8_SINT;
                case wgpu::VertexFormat::Sint8x4:
                    return DXGI_FORMAT_R8G8B8A8_SINT;
                case wgpu::VertexFormat::Unorm8x2:
                    return DXGI_FORMAT_R8G8_UNORM;
                case wgpu::VertexFormat::Unorm8x4:
                    return DXGI_FORMAT_R8G8B8A8_UNORM;
                case wgpu::VertexFormat::Snorm8x2:
                    return DXGI_FORMAT_R8G8_SNORM;
                case wgpu::VertexFormat::Snorm8x4:
                    return DXGI_FORMAT_R8G8B8A8_SNORM;
                case wgpu::VertexFormat::Uint16x2:
                    return DXGI_FORMAT_R16G16_UINT;
                case wgpu::VertexFormat::Uint16x4:
                    return DXGI_FORMAT_R16G16B16A16_UINT;
                case wgpu::VertexFormat::Sint16x2:
                    return DXGI_FORMAT_R16G16_SINT;
                case wgpu::VertexFormat::Sint16x4:
                    return DXGI_FORMAT_R16G16B16A16_SINT;
                case wgpu::VertexFormat::Unorm16x2:
                    return DXGI_FORMAT_R16G16_UNORM;
                case wgpu::VertexFormat::Unorm16x4:
                    return DXGI_FORMAT_R16G16B16A16_UNORM;
                case wgpu::VertexFormat::Snorm16x2:
                    return DXGI_FORMAT_R16G16_SNORM;
                case wgpu::VertexFormat::Snorm16x4:
                    return DXGI_FORMAT_R16G16B16A16_SNORM;
                case wgpu::VertexFormat::Float16x2:
                    return DXGI_FORMAT_R16G16_FLOAT;
                case wgpu::VertexFormat::Float16x4:
                    return DXGI_FORMAT_R16G16B16A16_FLOAT;
                case wgpu::VertexFormat::Float32:
                    return DXGI_FORMAT_R32_FLOAT;
                case wgpu::VertexFormat::Float32x2:
                    return DXGI_FORMAT_R32G32_FLOAT;
                case wgpu::VertexFormat::Float32x3:
                    return DXGI_FORMAT_R32G32B32_FLOAT;
                case wgpu::VertexFormat::Float32x4:
                    return DXGI_FORMAT_R32G32B32A32_FLOAT;
                case wgpu::VertexFormat::Uint32:
                    return DXGI_FORMAT_R32_UINT;
                case wgpu::VertexFormat::Uint32x2:
                    return DXGI_FORMAT_R32G32_UINT;
                case wgpu::VertexFormat::Uint32x3:
                    return DXGI_FORMAT_R32G32B32_UINT;
                case wgpu::VertexFormat::Uint32x4:
                    return DXGI_FORMAT_R32G32B32A32_UINT;
                case wgpu::VertexFormat::Sint32:
                    return DXGI_FORMAT_R32_SINT;
                case wgpu::VertexFormat::Sint32x2:
                    return DXGI_FORMAT_R32G32_SINT;
                case wgpu::VertexFormat::Sint32x3:
                    return DXGI_FORMAT_R32G32B32_SINT;
                case wgpu::VertexFormat::Sint32x4:
                    return DXGI_FORMAT_R32G32B32A32_SINT;
                default:
                    UNREACHABLE();
            }
        }

        D3D12_INPUT_CLASSIFICATION VertexStepModeFunction(wgpu::VertexStepMode mode) {
            switch (mode) {
                case wgpu::VertexStepMode::Vertex:
                    return D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA;
                case wgpu::VertexStepMode::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::Src:
                    return D3D12_BLEND_SRC_COLOR;
                case wgpu::BlendFactor::OneMinusSrc:
                    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::Dst:
                    return D3D12_BLEND_DEST_COLOR;
                case wgpu::BlendFactor::OneMinusDst:
                    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::Constant:
                    return D3D12_BLEND_BLEND_FACTOR;
                case wgpu::BlendFactor::OneMinusConstant:
                    return D3D12_BLEND_INV_BLEND_FACTOR;
            }
        }

        // When a blend factor is defined for the alpha channel, any of the factors that don't
        // explicitly state that they apply to alpha should be treated as their explicitly-alpha
        // equivalents. See: https://github.com/gpuweb/gpuweb/issues/65
        D3D12_BLEND D3D12AlphaBlend(wgpu::BlendFactor factor) {
            switch (factor) {
                case wgpu::BlendFactor::Src:
                    return D3D12_BLEND_SRC_ALPHA;
                case wgpu::BlendFactor::OneMinusSrc:
                    return D3D12_BLEND_INV_SRC_ALPHA;
                case wgpu::BlendFactor::Dst:
                    return D3D12_BLEND_DEST_ALPHA;
                case wgpu::BlendFactor::OneMinusDst:
                    return D3D12_BLEND_INV_DEST_ALPHA;

                // Other blend factors translate to the same D3D12 enum as the color blend factors.
                default:
                    return D3D12Blend(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 ColorTargetState* state) {
            D3D12_RENDER_TARGET_BLEND_DESC blendDesc;
            blendDesc.BlendEnable = state->blend != nullptr;
            if (blendDesc.BlendEnable) {
                blendDesc.SrcBlend = D3D12Blend(state->blend->color.srcFactor);
                blendDesc.DestBlend = D3D12Blend(state->blend->color.dstFactor);
                blendDesc.BlendOp = D3D12BlendOperation(state->blend->color.operation);
                blendDesc.SrcBlendAlpha = D3D12AlphaBlend(state->blend->alpha.srcFactor);
                blendDesc.DestBlendAlpha = D3D12AlphaBlend(state->blend->alpha.dstFactor);
                blendDesc.BlendOpAlpha = D3D12BlendOperation(state->blend->alpha.operation);
            }
            blendDesc.RenderTargetWriteMask = D3D12RenderTargetWriteMask(state->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 StencilFaceState& 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 DepthStencilState* 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<Ref<RenderPipeline>> RenderPipeline::Create(
        Device* device,
        const RenderPipelineDescriptor* descriptor) {
        Ref<RenderPipeline> pipeline = AcquireRef(new RenderPipeline(device, descriptor));
        DAWN_TRY(pipeline->Initialize());
        return pipeline;
    }

    MaybeError RenderPipeline::Initialize() {
        Device* device = ToBackend(GetDevice());
        uint32_t compileFlags = 0;

        if (device->IsToggleEnabled(Toggle::EmitHLSLDebugSymbols)) {
            compileFlags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION;
        }

        // SPRIV-cross does matrix multiplication expecting row major matrices
        compileFlags |= D3DCOMPILE_PACK_MATRIX_ROW_MAJOR;

        // FXC can miscompile code that depends on special float values (NaN, INF, etc) when IEEE
        // strictness is not enabled. See crbug.com/tint/976.
        compileFlags |= D3DCOMPILE_IEEE_STRICTNESS;

        D3D12_GRAPHICS_PIPELINE_STATE_DESC descriptorD3D12 = {};

        PerStage<ProgrammableStage> pipelineStages = GetAllStages();

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

        PerStage<CompiledShader> compiledShader;

        for (auto stage : IterateStages(GetStageMask())) {
            DAWN_TRY_ASSIGN(compiledShader[stage],
                            ToBackend(pipelineStages[stage].module)
                                ->Compile(pipelineStages[stage].entryPoint.c_str(), 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(), GetStripIndexFormat());

        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(GetColorTargetState(i));
        }
        descriptorD3D12.NumRenderTargets = static_cast<uint32_t>(GetColorAttachmentsMask().count());

        descriptorD3D12.BlendState.AlphaToCoverageEnable = IsAlphaToCoverageEnabled();
        descriptorD3D12.BlendState.IndependentBlendEnable = TRUE;

        descriptorD3D12.DepthStencilState = ComputeDepthStencilDesc(GetDepthStencilState());

        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"));

        SetLabelImpl();

        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;
    }

    void RenderPipeline::SetLabelImpl() {
        SetDebugName(ToBackend(GetDevice()), GetPipelineState(), "Dawn_RenderPipeline", GetLabel());
    }

    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 = VertexStepModeFunction(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
