// 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/DepthStencilState.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 {};
        }

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

        // TODO: validate depth stencil state
        return {};
    }

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

    DepthStencilStateBase* RenderPipelineBase::GetDepthStencilState() {
        return mDepthStencilState.Get();
    }

    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
