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

#include "common/VertexFormatUtils.h"
#include "dawn_native/metal/DeviceMTL.h"
#include "dawn_native/metal/PipelineLayoutMTL.h"
#include "dawn_native/metal/ShaderModuleMTL.h"
#include "dawn_native/metal/TextureMTL.h"
#include "dawn_native/metal/UtilsMetal.h"

namespace dawn_native { namespace metal {

    namespace {
        MTLVertexFormat VertexFormatType(wgpu::VertexFormat format) {
            switch (format) {
                case wgpu::VertexFormat::Uint8x2:
                    return MTLVertexFormatUChar2;
                case wgpu::VertexFormat::Uint8x4:
                    return MTLVertexFormatUChar4;
                case wgpu::VertexFormat::Sint8x2:
                    return MTLVertexFormatChar2;
                case wgpu::VertexFormat::Sint8x4:
                    return MTLVertexFormatChar4;
                case wgpu::VertexFormat::Unorm8x2:
                    return MTLVertexFormatUChar2Normalized;
                case wgpu::VertexFormat::Unorm8x4:
                    return MTLVertexFormatUChar4Normalized;
                case wgpu::VertexFormat::Snorm8x2:
                    return MTLVertexFormatChar2Normalized;
                case wgpu::VertexFormat::Snorm8x4:
                    return MTLVertexFormatChar4Normalized;
                case wgpu::VertexFormat::Uint16x2:
                    return MTLVertexFormatUShort2;
                case wgpu::VertexFormat::Uint16x4:
                    return MTLVertexFormatUShort4;
                case wgpu::VertexFormat::Sint16x2:
                    return MTLVertexFormatShort2;
                case wgpu::VertexFormat::Sint16x4:
                    return MTLVertexFormatShort4;
                case wgpu::VertexFormat::Unorm16x2:
                    return MTLVertexFormatUShort2Normalized;
                case wgpu::VertexFormat::Unorm16x4:
                    return MTLVertexFormatUShort4Normalized;
                case wgpu::VertexFormat::Snorm16x2:
                    return MTLVertexFormatShort2Normalized;
                case wgpu::VertexFormat::Snorm16x4:
                    return MTLVertexFormatShort4Normalized;
                case wgpu::VertexFormat::Float16x2:
                    return MTLVertexFormatHalf2;
                case wgpu::VertexFormat::Float16x4:
                    return MTLVertexFormatHalf4;
                case wgpu::VertexFormat::Float32:
                    return MTLVertexFormatFloat;
                case wgpu::VertexFormat::Float32x2:
                    return MTLVertexFormatFloat2;
                case wgpu::VertexFormat::Float32x3:
                    return MTLVertexFormatFloat3;
                case wgpu::VertexFormat::Float32x4:
                    return MTLVertexFormatFloat4;
                case wgpu::VertexFormat::Uint32:
                    return MTLVertexFormatUInt;
                case wgpu::VertexFormat::Uint32x2:
                    return MTLVertexFormatUInt2;
                case wgpu::VertexFormat::Uint32x3:
                    return MTLVertexFormatUInt3;
                case wgpu::VertexFormat::Uint32x4:
                    return MTLVertexFormatUInt4;
                case wgpu::VertexFormat::Sint32:
                    return MTLVertexFormatInt;
                case wgpu::VertexFormat::Sint32x2:
                    return MTLVertexFormatInt2;
                case wgpu::VertexFormat::Sint32x3:
                    return MTLVertexFormatInt3;
                case wgpu::VertexFormat::Sint32x4:
                    return MTLVertexFormatInt4;
                default:
                    UNREACHABLE();
            }
        }

        MTLVertexStepFunction InputStepModeFunction(wgpu::InputStepMode mode) {
            switch (mode) {
                case wgpu::InputStepMode::Vertex:
                    return MTLVertexStepFunctionPerVertex;
                case wgpu::InputStepMode::Instance:
                    return MTLVertexStepFunctionPerInstance;
            }
        }

        MTLPrimitiveType MTLPrimitiveTopology(wgpu::PrimitiveTopology primitiveTopology) {
            switch (primitiveTopology) {
                case wgpu::PrimitiveTopology::PointList:
                    return MTLPrimitiveTypePoint;
                case wgpu::PrimitiveTopology::LineList:
                    return MTLPrimitiveTypeLine;
                case wgpu::PrimitiveTopology::LineStrip:
                    return MTLPrimitiveTypeLineStrip;
                case wgpu::PrimitiveTopology::TriangleList:
                    return MTLPrimitiveTypeTriangle;
                case wgpu::PrimitiveTopology::TriangleStrip:
                    return MTLPrimitiveTypeTriangleStrip;
            }
        }

        MTLPrimitiveTopologyClass MTLInputPrimitiveTopology(
            wgpu::PrimitiveTopology primitiveTopology) {
            switch (primitiveTopology) {
                case wgpu::PrimitiveTopology::PointList:
                    return MTLPrimitiveTopologyClassPoint;
                case wgpu::PrimitiveTopology::LineList:
                case wgpu::PrimitiveTopology::LineStrip:
                    return MTLPrimitiveTopologyClassLine;
                case wgpu::PrimitiveTopology::TriangleList:
                case wgpu::PrimitiveTopology::TriangleStrip:
                    return MTLPrimitiveTopologyClassTriangle;
            }
        }

        MTLBlendFactor MetalBlendFactor(wgpu::BlendFactor factor, bool alpha) {
            switch (factor) {
                case wgpu::BlendFactor::Zero:
                    return MTLBlendFactorZero;
                case wgpu::BlendFactor::One:
                    return MTLBlendFactorOne;
                case wgpu::BlendFactor::Src:
                    return MTLBlendFactorSourceColor;
                case wgpu::BlendFactor::OneMinusSrc:
                    return MTLBlendFactorOneMinusSourceColor;
                case wgpu::BlendFactor::SrcAlpha:
                    return MTLBlendFactorSourceAlpha;
                case wgpu::BlendFactor::OneMinusSrcAlpha:
                    return MTLBlendFactorOneMinusSourceAlpha;
                case wgpu::BlendFactor::Dst:
                    return MTLBlendFactorDestinationColor;
                case wgpu::BlendFactor::OneMinusDst:
                    return MTLBlendFactorOneMinusDestinationColor;
                case wgpu::BlendFactor::DstAlpha:
                    return MTLBlendFactorDestinationAlpha;
                case wgpu::BlendFactor::OneMinusDstAlpha:
                    return MTLBlendFactorOneMinusDestinationAlpha;
                case wgpu::BlendFactor::SrcAlphaSaturated:
                    return MTLBlendFactorSourceAlphaSaturated;
                case wgpu::BlendFactor::Constant:
                    return alpha ? MTLBlendFactorBlendAlpha : MTLBlendFactorBlendColor;
                case wgpu::BlendFactor::OneMinusConstant:
                    return alpha ? MTLBlendFactorOneMinusBlendAlpha
                                 : MTLBlendFactorOneMinusBlendColor;

                // Deprecated blend factors should be normalized prior to this call.
                case wgpu::BlendFactor::SrcColor:
                case wgpu::BlendFactor::OneMinusSrcColor:
                case wgpu::BlendFactor::DstColor:
                case wgpu::BlendFactor::OneMinusDstColor:
                case wgpu::BlendFactor::BlendColor:
                case wgpu::BlendFactor::OneMinusBlendColor:
                    UNREACHABLE();
            }
        }

        MTLBlendOperation MetalBlendOperation(wgpu::BlendOperation operation) {
            switch (operation) {
                case wgpu::BlendOperation::Add:
                    return MTLBlendOperationAdd;
                case wgpu::BlendOperation::Subtract:
                    return MTLBlendOperationSubtract;
                case wgpu::BlendOperation::ReverseSubtract:
                    return MTLBlendOperationReverseSubtract;
                case wgpu::BlendOperation::Min:
                    return MTLBlendOperationMin;
                case wgpu::BlendOperation::Max:
                    return MTLBlendOperationMax;
            }
        }

        MTLColorWriteMask MetalColorWriteMask(wgpu::ColorWriteMask writeMask,
                                              bool isDeclaredInFragmentShader) {
            if (!isDeclaredInFragmentShader) {
                return MTLColorWriteMaskNone;
            }

            MTLColorWriteMask mask = MTLColorWriteMaskNone;

            if (writeMask & wgpu::ColorWriteMask::Red) {
                mask |= MTLColorWriteMaskRed;
            }
            if (writeMask & wgpu::ColorWriteMask::Green) {
                mask |= MTLColorWriteMaskGreen;
            }
            if (writeMask & wgpu::ColorWriteMask::Blue) {
                mask |= MTLColorWriteMaskBlue;
            }
            if (writeMask & wgpu::ColorWriteMask::Alpha) {
                mask |= MTLColorWriteMaskAlpha;
            }

            return mask;
        }

        void ComputeBlendDesc(MTLRenderPipelineColorAttachmentDescriptor* attachment,
                              const ColorTargetState* state,
                              bool isDeclaredInFragmentShader) {
            attachment.blendingEnabled = state->blend != nullptr;
            if (attachment.blendingEnabled) {
                attachment.sourceRGBBlendFactor =
                    MetalBlendFactor(state->blend->color.srcFactor, false);
                attachment.destinationRGBBlendFactor =
                    MetalBlendFactor(state->blend->color.dstFactor, false);
                attachment.rgbBlendOperation = MetalBlendOperation(state->blend->color.operation);
                attachment.sourceAlphaBlendFactor =
                    MetalBlendFactor(state->blend->alpha.srcFactor, true);
                attachment.destinationAlphaBlendFactor =
                    MetalBlendFactor(state->blend->alpha.dstFactor, true);
                attachment.alphaBlendOperation = MetalBlendOperation(state->blend->alpha.operation);
            }
            attachment.writeMask =
                MetalColorWriteMask(state->writeMask, isDeclaredInFragmentShader);
        }

        MTLStencilOperation MetalStencilOperation(wgpu::StencilOperation stencilOperation) {
            switch (stencilOperation) {
                case wgpu::StencilOperation::Keep:
                    return MTLStencilOperationKeep;
                case wgpu::StencilOperation::Zero:
                    return MTLStencilOperationZero;
                case wgpu::StencilOperation::Replace:
                    return MTLStencilOperationReplace;
                case wgpu::StencilOperation::Invert:
                    return MTLStencilOperationInvert;
                case wgpu::StencilOperation::IncrementClamp:
                    return MTLStencilOperationIncrementClamp;
                case wgpu::StencilOperation::DecrementClamp:
                    return MTLStencilOperationDecrementClamp;
                case wgpu::StencilOperation::IncrementWrap:
                    return MTLStencilOperationIncrementWrap;
                case wgpu::StencilOperation::DecrementWrap:
                    return MTLStencilOperationDecrementWrap;
            }
        }

        NSRef<MTLDepthStencilDescriptor> MakeDepthStencilDesc(const DepthStencilState* descriptor) {
            NSRef<MTLDepthStencilDescriptor> mtlDepthStencilDescRef =
                AcquireNSRef([MTLDepthStencilDescriptor new]);
            MTLDepthStencilDescriptor* mtlDepthStencilDescriptor = mtlDepthStencilDescRef.Get();

            mtlDepthStencilDescriptor.depthCompareFunction =
                ToMetalCompareFunction(descriptor->depthCompare);
            mtlDepthStencilDescriptor.depthWriteEnabled = descriptor->depthWriteEnabled;

            if (StencilTestEnabled(descriptor)) {
                NSRef<MTLStencilDescriptor> backFaceStencilRef =
                    AcquireNSRef([MTLStencilDescriptor new]);
                MTLStencilDescriptor* backFaceStencil = backFaceStencilRef.Get();
                NSRef<MTLStencilDescriptor> frontFaceStencilRef =
                    AcquireNSRef([MTLStencilDescriptor new]);
                MTLStencilDescriptor* frontFaceStencil = frontFaceStencilRef.Get();

                backFaceStencil.stencilCompareFunction =
                    ToMetalCompareFunction(descriptor->stencilBack.compare);
                backFaceStencil.stencilFailureOperation =
                    MetalStencilOperation(descriptor->stencilBack.failOp);
                backFaceStencil.depthFailureOperation =
                    MetalStencilOperation(descriptor->stencilBack.depthFailOp);
                backFaceStencil.depthStencilPassOperation =
                    MetalStencilOperation(descriptor->stencilBack.passOp);
                backFaceStencil.readMask = descriptor->stencilReadMask;
                backFaceStencil.writeMask = descriptor->stencilWriteMask;

                frontFaceStencil.stencilCompareFunction =
                    ToMetalCompareFunction(descriptor->stencilFront.compare);
                frontFaceStencil.stencilFailureOperation =
                    MetalStencilOperation(descriptor->stencilFront.failOp);
                frontFaceStencil.depthFailureOperation =
                    MetalStencilOperation(descriptor->stencilFront.depthFailOp);
                frontFaceStencil.depthStencilPassOperation =
                    MetalStencilOperation(descriptor->stencilFront.passOp);
                frontFaceStencil.readMask = descriptor->stencilReadMask;
                frontFaceStencil.writeMask = descriptor->stencilWriteMask;

                mtlDepthStencilDescriptor.backFaceStencil = backFaceStencil;
                mtlDepthStencilDescriptor.frontFaceStencil = frontFaceStencil;
            }

            return mtlDepthStencilDescRef;
        }

        MTLWinding MTLFrontFace(wgpu::FrontFace face) {
            switch (face) {
                case wgpu::FrontFace::CW:
                    return MTLWindingClockwise;
                case wgpu::FrontFace::CCW:
                    return MTLWindingCounterClockwise;
            }
        }

        MTLCullMode ToMTLCullMode(wgpu::CullMode mode) {
            switch (mode) {
                case wgpu::CullMode::None:
                    return MTLCullModeNone;
                case wgpu::CullMode::Front:
                    return MTLCullModeFront;
                case wgpu::CullMode::Back:
                    return MTLCullModeBack;
            }
        }

    }  // anonymous namespace

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

    MaybeError RenderPipeline::Initialize(const RenderPipelineDescriptor2* descriptor) {
        mMtlPrimitiveTopology = MTLPrimitiveTopology(GetPrimitiveTopology());
        mMtlFrontFace = MTLFrontFace(GetFrontFace());
        mMtlCullMode = ToMTLCullMode(GetCullMode());
        auto mtlDevice = ToBackend(GetDevice())->GetMTLDevice();

        NSRef<MTLRenderPipelineDescriptor> descriptorMTLRef =
            AcquireNSRef([MTLRenderPipelineDescriptor new]);
        MTLRenderPipelineDescriptor* descriptorMTL = descriptorMTLRef.Get();

        // TODO: MakeVertexDesc should be const in the future, so we don't need to call it here when
        // vertex pulling is enabled
        NSRef<MTLVertexDescriptor> vertexDesc = MakeVertexDesc();

        // Calling MakeVertexDesc first is important since it sets indices for packed bindings
        if (GetDevice()->IsToggleEnabled(Toggle::MetalEnableVertexPulling)) {
            vertexDesc = AcquireNSRef([MTLVertexDescriptor new]);
        }
        descriptorMTL.vertexDescriptor = vertexDesc.Get();

        ShaderModule* vertexModule = ToBackend(descriptor->vertex.module);
        const char* vertexEntryPoint = descriptor->vertex.entryPoint;
        ShaderModule::MetalFunctionData vertexData;

        const VertexState* vertexStatePtr = &descriptor->vertex;
        VertexState vertexState;
        if (vertexStatePtr == nullptr) {
            vertexState = {};
            vertexStatePtr = &vertexState;
        }

        DAWN_TRY(vertexModule->CreateFunction(vertexEntryPoint, SingleShaderStage::Vertex,
                                              ToBackend(GetLayout()), &vertexData, 0xFFFFFFFF, this,
                                              vertexStatePtr));

        descriptorMTL.vertexFunction = vertexData.function.Get();
        if (vertexData.needsStorageBufferLength) {
            mStagesRequiringStorageBufferLength |= wgpu::ShaderStage::Vertex;
        }

        ShaderModule* fragmentModule = ToBackend(descriptor->fragment->module);
        const char* fragmentEntryPoint = descriptor->fragment->entryPoint;
        ShaderModule::MetalFunctionData fragmentData;
        DAWN_TRY(fragmentModule->CreateFunction(fragmentEntryPoint, SingleShaderStage::Fragment,
                                                ToBackend(GetLayout()), &fragmentData,
                                                GetSampleMask()));

        descriptorMTL.fragmentFunction = fragmentData.function.Get();
        if (fragmentData.needsStorageBufferLength) {
            mStagesRequiringStorageBufferLength |= wgpu::ShaderStage::Fragment;
        }

        if (HasDepthStencilAttachment()) {
            wgpu::TextureFormat depthStencilFormat = GetDepthStencilFormat();
            const Format& internalFormat = GetDevice()->GetValidInternalFormat(depthStencilFormat);
            MTLPixelFormat metalFormat = MetalPixelFormat(depthStencilFormat);

            if (internalFormat.HasDepth()) {
                descriptorMTL.depthAttachmentPixelFormat = metalFormat;
            }
            if (internalFormat.HasStencil()) {
                descriptorMTL.stencilAttachmentPixelFormat = metalFormat;
            }
        }

        const auto& fragmentOutputsWritten =
            GetStage(SingleShaderStage::Fragment).metadata->fragmentOutputsWritten;
        for (ColorAttachmentIndex i : IterateBitSet(GetColorAttachmentsMask())) {
            descriptorMTL.colorAttachments[static_cast<uint8_t>(i)].pixelFormat =
                MetalPixelFormat(GetColorAttachmentFormat(i));
            const ColorTargetState* descriptor = GetColorTargetState(i);
            ComputeBlendDesc(descriptorMTL.colorAttachments[static_cast<uint8_t>(i)], descriptor,
                             fragmentOutputsWritten[i]);
        }

        descriptorMTL.inputPrimitiveTopology = MTLInputPrimitiveTopology(GetPrimitiveTopology());
        descriptorMTL.sampleCount = GetSampleCount();
        descriptorMTL.alphaToCoverageEnabled = IsAlphaToCoverageEnabled();

        {
            NSError* error = nullptr;
            mMtlRenderPipelineState =
                AcquireNSPRef([mtlDevice newRenderPipelineStateWithDescriptor:descriptorMTL
                                                                        error:&error]);
            if (error != nullptr) {
                NSLog(@" error => %@", error);
                return DAWN_INTERNAL_ERROR("Error creating rendering pipeline state");
            }
        }

        // Create depth stencil state and cache it, fetch the cached depth stencil state when we
        // call setDepthStencilState() for a given render pipeline in CommandEncoder, in order to
        // improve performance.
        NSRef<MTLDepthStencilDescriptor> depthStencilDesc =
            MakeDepthStencilDesc(GetDepthStencilState());
        mMtlDepthStencilState =
            AcquireNSPRef([mtlDevice newDepthStencilStateWithDescriptor:depthStencilDesc.Get()]);

        return {};
    }

    MTLPrimitiveType RenderPipeline::GetMTLPrimitiveTopology() const {
        return mMtlPrimitiveTopology;
    }

    MTLWinding RenderPipeline::GetMTLFrontFace() const {
        return mMtlFrontFace;
    }

    MTLCullMode RenderPipeline::GetMTLCullMode() const {
        return mMtlCullMode;
    }

    void RenderPipeline::Encode(id<MTLRenderCommandEncoder> encoder) {
        [encoder setRenderPipelineState:mMtlRenderPipelineState.Get()];
    }

    id<MTLDepthStencilState> RenderPipeline::GetMTLDepthStencilState() {
        return mMtlDepthStencilState.Get();
    }

    uint32_t RenderPipeline::GetMtlVertexBufferIndex(VertexBufferSlot slot) const {
        ASSERT(slot < kMaxVertexBuffersTyped);
        return mMtlVertexBufferIndices[slot];
    }

    wgpu::ShaderStage RenderPipeline::GetStagesRequiringStorageBufferLength() const {
        return mStagesRequiringStorageBufferLength;
    }

    MTLVertexDescriptor* RenderPipeline::MakeVertexDesc() {
        MTLVertexDescriptor* mtlVertexDescriptor = [MTLVertexDescriptor new];

        // Vertex buffers are packed after all the buffers for the bind groups.
        uint32_t mtlVertexBufferIndex =
            ToBackend(GetLayout())->GetBufferBindingCount(SingleShaderStage::Vertex);

        for (VertexBufferSlot slot : IterateBitSet(GetVertexBufferSlotsUsed())) {
            const VertexBufferInfo& info = GetVertexBuffer(slot);

            MTLVertexBufferLayoutDescriptor* layoutDesc = [MTLVertexBufferLayoutDescriptor new];
            if (info.arrayStride == 0) {
                // For MTLVertexStepFunctionConstant, the stepRate must be 0,
                // but the arrayStride must NOT be 0, so we made up it with
                // max(attrib.offset + sizeof(attrib) for each attrib)
                size_t maxArrayStride = 0;
                for (VertexAttributeLocation loc : IterateBitSet(GetAttributeLocationsUsed())) {
                    const VertexAttributeInfo& attrib = GetAttribute(loc);
                    // Only use the attributes that use the current input
                    if (attrib.vertexBufferSlot != slot) {
                        continue;
                    }
                    maxArrayStride =
                        std::max(maxArrayStride,
                                 dawn::VertexFormatSize(attrib.format) + size_t(attrib.offset));
                }
                layoutDesc.stepFunction = MTLVertexStepFunctionConstant;
                layoutDesc.stepRate = 0;
                // Metal requires the stride must be a multiple of 4 bytes, align it with next
                // multiple of 4 if it's not.
                layoutDesc.stride = Align(maxArrayStride, 4);
            } else {
                layoutDesc.stepFunction = InputStepModeFunction(info.stepMode);
                layoutDesc.stepRate = 1;
                layoutDesc.stride = info.arrayStride;
            }

            mtlVertexDescriptor.layouts[mtlVertexBufferIndex] = layoutDesc;
            [layoutDesc release];

            mMtlVertexBufferIndices[slot] = mtlVertexBufferIndex;
            mtlVertexBufferIndex++;
        }

        for (VertexAttributeLocation loc : IterateBitSet(GetAttributeLocationsUsed())) {
            const VertexAttributeInfo& info = GetAttribute(loc);

            auto attribDesc = [MTLVertexAttributeDescriptor new];
            attribDesc.format = VertexFormatType(info.format);
            attribDesc.offset = info.offset;
            attribDesc.bufferIndex = mMtlVertexBufferIndices[info.vertexBufferSlot];
            mtlVertexDescriptor.attributes[static_cast<uint8_t>(loc)] = attribDesc;
            [attribDesc release];
        }

        return mtlVertexDescriptor;
    }

}}  // namespace dawn_native::metal
