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

#include "common/BitSetIterator.h"
#include "dawn_native/Device.h"
#include "dawn_native/InputState.h"
#include "dawn_native/RenderPassDescriptor.h"
#include "dawn_native/Texture.h"
#include "dawn_native/ValidationUtils_autogen.h"

namespace dawn_native {
    // Helper functions
    namespace {

        MaybeError ValidatePipelineStageDescriptor(const PipelineStageDescriptor* descriptor,
                                                   const PipelineLayoutBase* layout,
                                                   dawn::ShaderStage stage) {
            if (descriptor->entryPoint != std::string("main")) {
                return DAWN_VALIDATION_ERROR("Entry point must be \"main\"");
            }
            if (descriptor->module->GetExecutionModel() != stage) {
                return DAWN_VALIDATION_ERROR("Setting module with wrong stages");
            }
            if (!descriptor->module->IsCompatibleWithPipelineLayout(layout)) {
                return DAWN_VALIDATION_ERROR("Stage not compatible with layout");
            }
            return {};
        }

        MaybeError ValidateAttachmentsStateDescriptor(
            const AttachmentsStateDescriptor* descriptor) {
            if (descriptor->numColorAttachments > kMaxColorAttachments) {
                return DAWN_VALIDATION_ERROR("Color attachments number exceeds maximum");
            }

            if (descriptor->numColorAttachments == 0 && !descriptor->hasDepthStencilAttachment) {
                return DAWN_VALIDATION_ERROR("Should have at least one attachment");
            }

            if (descriptor->hasDepthStencilAttachment) {
                dawn::TextureFormat format = descriptor->depthStencilAttachment->format;
                DAWN_TRY(ValidateTextureFormat(format));

                if (!IsDepthStencilRenderableTextureFormat(format)) {
                    return DAWN_VALIDATION_ERROR(
                        "Depth stencil format must be depth-stencil renderable");
                }
            }

            for (uint32_t i = 0; i < descriptor->numColorAttachments; ++i) {
                dawn::TextureFormat format = descriptor->colorAttachments[i].format;
                DAWN_TRY(ValidateTextureFormat(format));

                if (!IsColorRenderableTextureFormat(format)) {
                    return DAWN_VALIDATION_ERROR("Color format must be color renderable");
                }
            }
            return {};
        }

        MaybeError ValidateBlendStateDescriptor(const BlendStateDescriptor* descriptor) {
            if (descriptor->nextInChain != nullptr) {
                return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
            }
            DAWN_TRY(ValidateBlendOperation(descriptor->alphaBlend.operation));
            DAWN_TRY(ValidateBlendFactor(descriptor->alphaBlend.srcFactor));
            DAWN_TRY(ValidateBlendFactor(descriptor->alphaBlend.dstFactor));
            DAWN_TRY(ValidateBlendOperation(descriptor->colorBlend.operation));
            DAWN_TRY(ValidateBlendFactor(descriptor->colorBlend.srcFactor));
            DAWN_TRY(ValidateBlendFactor(descriptor->colorBlend.dstFactor));
            DAWN_TRY(ValidateColorWriteMask(descriptor->colorWriteMask));
            return {};
        }

        MaybeError ValidateDepthStencilStateDescriptor(
            const DepthStencilStateDescriptor* descriptor) {
            if (descriptor->nextInChain != nullptr) {
                return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
            }
            DAWN_TRY(ValidateCompareFunction(descriptor->depthCompare));
            DAWN_TRY(ValidateCompareFunction(descriptor->front.compare));
            DAWN_TRY(ValidateStencilOperation(descriptor->front.stencilFailOp));
            DAWN_TRY(ValidateStencilOperation(descriptor->front.depthFailOp));
            DAWN_TRY(ValidateStencilOperation(descriptor->front.passOp));
            DAWN_TRY(ValidateCompareFunction(descriptor->back.compare));
            DAWN_TRY(ValidateStencilOperation(descriptor->back.stencilFailOp));
            DAWN_TRY(ValidateStencilOperation(descriptor->back.depthFailOp));
            DAWN_TRY(ValidateStencilOperation(descriptor->back.passOp));
            return {};
        }

    }  // anonymous namespace

    MaybeError ValidateRenderPipelineDescriptor(DeviceBase* device,
                                                const RenderPipelineDescriptor* descriptor) {
        if (descriptor->nextInChain != nullptr) {
            return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
        }

        if (descriptor->layout == nullptr) {
            return DAWN_VALIDATION_ERROR("Layout must not be null");
        }

        if (descriptor->inputState == nullptr) {
            return DAWN_VALIDATION_ERROR("Input state must not be null");
        }

        if (descriptor->depthStencilState == nullptr) {
            return DAWN_VALIDATION_ERROR("Depth stencil state must not be null");
        }

        for (uint32_t i = 0; i < descriptor->numBlendStates; ++i) {
            DAWN_TRY(ValidateBlendStateDescriptor(&descriptor->blendStates[i]));
        }

        DAWN_TRY(ValidateIndexFormat(descriptor->indexFormat));
        DAWN_TRY(ValidatePrimitiveTopology(descriptor->primitiveTopology));
        DAWN_TRY(ValidatePipelineStageDescriptor(descriptor->vertexStage, descriptor->layout,
                                                 dawn::ShaderStage::Vertex));
        DAWN_TRY(ValidatePipelineStageDescriptor(descriptor->fragmentStage, descriptor->layout,
                                                 dawn::ShaderStage::Fragment));
        DAWN_TRY(ValidateAttachmentsStateDescriptor(descriptor->attachmentsState));

        if ((descriptor->vertexStage->module->GetUsedVertexAttributes() &
             ~descriptor->inputState->GetAttributesSetMask())
                .any()) {
            return DAWN_VALIDATION_ERROR(
                "Pipeline vertex stage uses inputs not in the input state");
        }

        if (descriptor->sampleCount != 1) {
            return DAWN_VALIDATION_ERROR("Sample count must be one");
        }

        if (descriptor->numBlendStates > kMaxColorAttachments) {
            return DAWN_VALIDATION_ERROR("Blend states number exceeds maximum");
        }

        if (descriptor->attachmentsState->numColorAttachments != descriptor->numBlendStates) {
            return DAWN_VALIDATION_ERROR("Each color attachment should have blend state");
        }

        DAWN_TRY(ValidateDepthStencilStateDescriptor(descriptor->depthStencilState));

        return {};
    }

    bool StencilTestEnabled(const DepthStencilStateDescriptor* mDepthStencilState) {
        return mDepthStencilState->back.compare != dawn::CompareFunction::Always ||
               mDepthStencilState->back.stencilFailOp != dawn::StencilOperation::Keep ||
               mDepthStencilState->back.depthFailOp != dawn::StencilOperation::Keep ||
               mDepthStencilState->back.passOp != dawn::StencilOperation::Keep ||
               mDepthStencilState->front.compare != dawn::CompareFunction::Always ||
               mDepthStencilState->front.stencilFailOp != dawn::StencilOperation::Keep ||
               mDepthStencilState->front.depthFailOp != dawn::StencilOperation::Keep ||
               mDepthStencilState->front.passOp != dawn::StencilOperation::Keep;
    }

    // RenderPipelineBase

    RenderPipelineBase::RenderPipelineBase(DeviceBase* device,
                                           const RenderPipelineDescriptor* descriptor)
        : PipelineBase(device,
                       descriptor->layout,
                       dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment),
          mDepthStencilState(*descriptor->depthStencilState),
          mIndexFormat(descriptor->indexFormat),
          mInputState(descriptor->inputState),
          mPrimitiveTopology(descriptor->primitiveTopology),
          mHasDepthStencilAttachment(descriptor->attachmentsState->hasDepthStencilAttachment) {
        if (mHasDepthStencilAttachment) {
            mDepthStencilFormat = descriptor->attachmentsState->depthStencilAttachment->format;
        }
        ExtractModuleData(dawn::ShaderStage::Vertex, descriptor->vertexStage->module);
        ExtractModuleData(dawn::ShaderStage::Fragment, descriptor->fragmentStage->module);

        for (uint32_t i = 0; i < descriptor->attachmentsState->numColorAttachments; ++i) {
            mColorAttachmentsSet.set(i);
            mBlendStates[i] = descriptor->blendStates[i];
            mColorAttachmentFormats[i] = descriptor->attachmentsState->colorAttachments[i].format;
        }

        // TODO(cwallez@chromium.org): Check against the shader module that the correct color
        // attachment are set?
    }

    const BlendStateDescriptor* RenderPipelineBase::GetBlendStateDescriptor(
        uint32_t attachmentSlot) {
        ASSERT(attachmentSlot < mBlendStates.size());
        return &mBlendStates[attachmentSlot];
    }

    const DepthStencilStateDescriptor* RenderPipelineBase::GetDepthStencilStateDescriptor() {
        return &mDepthStencilState;
    }

    dawn::IndexFormat RenderPipelineBase::GetIndexFormat() const {
        return mIndexFormat;
    }

    InputStateBase* RenderPipelineBase::GetInputState() {
        return mInputState.Get();
    }

    dawn::PrimitiveTopology RenderPipelineBase::GetPrimitiveTopology() const {
        return mPrimitiveTopology;
    }

    std::bitset<kMaxColorAttachments> RenderPipelineBase::GetColorAttachmentsMask() const {
        return mColorAttachmentsSet;
    }

    bool RenderPipelineBase::HasDepthStencilAttachment() const {
        return mHasDepthStencilAttachment;
    }

    dawn::TextureFormat RenderPipelineBase::GetColorAttachmentFormat(uint32_t attachment) const {
        return mColorAttachmentFormats[attachment];
    }

    dawn::TextureFormat RenderPipelineBase::GetDepthStencilFormat() const {
        ASSERT(mHasDepthStencilAttachment);
        return mDepthStencilFormat;
    }

    bool RenderPipelineBase::IsCompatibleWith(const RenderPassDescriptorBase* renderPass) const {
        // TODO(cwallez@chromium.org): This is called on every SetPipeline command. Optimize it for
        // example by caching some "attachment compatibility" object that would make the
        // compatibility check a single pointer comparison.

        if (renderPass->GetColorAttachmentMask() != mColorAttachmentsSet) {
            return false;
        }

        for (uint32_t i : IterateBitSet(mColorAttachmentsSet)) {
            if (renderPass->GetColorAttachment(i).view->GetTexture()->GetFormat() !=
                mColorAttachmentFormats[i]) {
                return false;
            }
        }

        if (renderPass->HasDepthStencilAttachment() != mHasDepthStencilAttachment) {
            return false;
        }

        if (mHasDepthStencilAttachment &&
            (renderPass->GetDepthStencilAttachment().view->GetTexture()->GetFormat() !=
             mDepthStencilFormat)) {
            return false;
        }

        return true;
    }

}  // namespace dawn_native
