// Copyright 2018 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/RenderPassEncoder.h"

#include "dawn/common/Constants.h"
#include "dawn/native/Buffer.h"
#include "dawn/native/CommandEncoder.h"
#include "dawn/native/CommandValidation.h"
#include "dawn/native/Commands.h"
#include "dawn/native/Device.h"
#include "dawn/native/ObjectType_autogen.h"
#include "dawn/native/QuerySet.h"
#include "dawn/native/RenderBundle.h"
#include "dawn/native/RenderPipeline.h"

#include <math.h>
#include <cstring>

namespace dawn::native {
    namespace {

        // Check the query at queryIndex is unavailable, otherwise it cannot be written.
        MaybeError ValidateQueryIndexOverwrite(QuerySetBase* querySet,
                                               uint32_t queryIndex,
                                               const QueryAvailabilityMap& queryAvailabilityMap) {
            auto it = queryAvailabilityMap.find(querySet);
            DAWN_INVALID_IF(it != queryAvailabilityMap.end() && it->second[queryIndex],
                            "Query index %u of %s is written to twice in a render pass.",
                            queryIndex, querySet);

            return {};
        }

    }  // namespace

    // The usage tracker is passed in here, because it is prepopulated with usages from the
    // BeginRenderPassCmd. If we had RenderPassEncoder responsible for recording the
    // command, then this wouldn't be necessary.
    RenderPassEncoder::RenderPassEncoder(DeviceBase* device,
                                         const RenderPassDescriptor* descriptor,
                                         CommandEncoder* commandEncoder,
                                         EncodingContext* encodingContext,
                                         RenderPassResourceUsageTracker usageTracker,
                                         Ref<AttachmentState> attachmentState,
                                         std::vector<TimestampWrite> timestampWritesAtEnd,
                                         uint32_t renderTargetWidth,
                                         uint32_t renderTargetHeight,
                                         bool depthReadOnly,
                                         bool stencilReadOnly)
        : RenderEncoderBase(device,
                            descriptor->label,
                            encodingContext,
                            std::move(attachmentState),
                            depthReadOnly,
                            stencilReadOnly),
          mCommandEncoder(commandEncoder),
          mRenderTargetWidth(renderTargetWidth),
          mRenderTargetHeight(renderTargetHeight),
          mOcclusionQuerySet(descriptor->occlusionQuerySet),
          mTimestampWritesAtEnd(std::move(timestampWritesAtEnd)) {
        mUsageTracker = std::move(usageTracker);
        TrackInDevice();
    }

    RenderPassEncoder::RenderPassEncoder(DeviceBase* device,
                                         CommandEncoder* commandEncoder,
                                         EncodingContext* encodingContext,
                                         ErrorTag errorTag)
        : RenderEncoderBase(device, encodingContext, errorTag), mCommandEncoder(commandEncoder) {
    }

    RenderPassEncoder* RenderPassEncoder::MakeError(DeviceBase* device,
                                                    CommandEncoder* commandEncoder,
                                                    EncodingContext* encodingContext) {
        return new RenderPassEncoder(device, commandEncoder, encodingContext, ObjectBase::kError);
    }

    void RenderPassEncoder::DestroyImpl() {
        RenderEncoderBase::DestroyImpl();
        // Ensure that the pass has exited. This is done for passes only since validation requires
        // they exit before destruction while bundles do not.
        mEncodingContext->EnsurePassExited(this);
    }

    ObjectType RenderPassEncoder::GetType() const {
        return ObjectType::RenderPassEncoder;
    }

    void RenderPassEncoder::TrackQueryAvailability(QuerySetBase* querySet, uint32_t queryIndex) {
        DAWN_ASSERT(querySet != nullptr);

        // Track the query availability with true on render pass for rewrite validation and query
        // reset on render pass on Vulkan
        mUsageTracker.TrackQueryAvailability(querySet, queryIndex);

        // Track it again on command encoder for zero-initializing when resolving unused queries.
        mCommandEncoder->TrackQueryAvailability(querySet, queryIndex);
    }

    void RenderPassEncoder::APIEnd() {
        if (mEncodingContext->TryEncode(
                this,
                [&](CommandAllocator* allocator) -> MaybeError {
                    if (IsValidationEnabled()) {
                        DAWN_TRY(ValidateProgrammableEncoderEnd());

                        DAWN_INVALID_IF(
                            mOcclusionQueryActive,
                            "Render pass %s ended with incomplete occlusion query index %u of %s.",
                            this, mCurrentOcclusionQueryIndex, mOcclusionQuerySet.Get());
                    }

                    EndRenderPassCmd* cmd =
                        allocator->Allocate<EndRenderPassCmd>(Command::EndRenderPass);
                    // The query availability has already been updated at the beginning of render
                    // pass, and no need to do update here.
                    cmd->timestampWrites = std::move(mTimestampWritesAtEnd);

                    DAWN_TRY(mEncodingContext->ExitRenderPass(this, std::move(mUsageTracker),
                                                              mCommandEncoder.Get(),
                                                              std::move(mIndirectDrawMetadata)));
                    return {};
                },
                "encoding %s.End().", this)) {
        }
    }

    void RenderPassEncoder::APIEndPass() {
        GetDevice()->EmitDeprecationWarning("endPass() has been deprecated. Use end() instead.");
        APIEnd();
    }

    void RenderPassEncoder::APISetStencilReference(uint32_t reference) {
        mEncodingContext->TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                SetStencilReferenceCmd* cmd =
                    allocator->Allocate<SetStencilReferenceCmd>(Command::SetStencilReference);
                cmd->reference = reference;

                return {};
            },
            "encoding %s.SetStencilReference(%u).", this, reference);
    }

    void RenderPassEncoder::APISetBlendConstant(const Color* color) {
        mEncodingContext->TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                SetBlendConstantCmd* cmd =
                    allocator->Allocate<SetBlendConstantCmd>(Command::SetBlendConstant);
                cmd->color = *color;

                return {};
            },
            "encoding %s.SetBlendConstant(%s).", this, color);
    }

    void RenderPassEncoder::APISetViewport(float x,
                                           float y,
                                           float width,
                                           float height,
                                           float minDepth,
                                           float maxDepth) {
        mEncodingContext->TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                if (IsValidationEnabled()) {
                    DAWN_INVALID_IF(
                        (isnan(x) || isnan(y) || isnan(width) || isnan(height) || isnan(minDepth) ||
                         isnan(maxDepth)),
                        "A parameter of the viewport (x: %f, y: %f, width: %f, height: %f, "
                        "minDepth: %f, maxDepth: %f) is NaN.",
                        x, y, width, height, minDepth, maxDepth);

                    DAWN_INVALID_IF(
                        x < 0 || y < 0 || width < 0 || height < 0,
                        "Viewport bounds (x: %f, y: %f, width: %f, height: %f) contains a negative "
                        "value.",
                        x, y, width, height);

                    DAWN_INVALID_IF(
                        x + width > mRenderTargetWidth || y + height > mRenderTargetHeight,
                        "Viewport bounds (x: %f, y: %f, width: %f, height: %f) are not contained "
                        "in "
                        "the render target dimensions (%u x %u).",
                        x, y, width, height, mRenderTargetWidth, mRenderTargetHeight);

                    // Check for depths being in [0, 1] and min <= max in 3 checks instead of 5.
                    DAWN_INVALID_IF(minDepth < 0 || minDepth > maxDepth || maxDepth > 1,
                                    "Viewport minDepth (%f) and maxDepth (%f) are not in [0, 1] or "
                                    "minDepth was "
                                    "greater than maxDepth.",
                                    minDepth, maxDepth);
                }

                SetViewportCmd* cmd = allocator->Allocate<SetViewportCmd>(Command::SetViewport);
                cmd->x = x;
                cmd->y = y;
                cmd->width = width;
                cmd->height = height;
                cmd->minDepth = minDepth;
                cmd->maxDepth = maxDepth;

                return {};
            },
            "encoding %s.SetViewport(%f, %f, %f, %f, %f, %f).", this, x, y, width, height, minDepth,
            maxDepth);
    }

    void RenderPassEncoder::APISetScissorRect(uint32_t x,
                                              uint32_t y,
                                              uint32_t width,
                                              uint32_t height) {
        mEncodingContext->TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                if (IsValidationEnabled()) {
                    DAWN_INVALID_IF(
                        width > mRenderTargetWidth || height > mRenderTargetHeight ||
                            x > mRenderTargetWidth - width || y > mRenderTargetHeight - height,
                        "Scissor rect (x: %u, y: %u, width: %u, height: %u) is not contained in "
                        "the render target dimensions (%u x %u).",
                        x, y, width, height, mRenderTargetWidth, mRenderTargetHeight);
                }

                SetScissorRectCmd* cmd =
                    allocator->Allocate<SetScissorRectCmd>(Command::SetScissorRect);
                cmd->x = x;
                cmd->y = y;
                cmd->width = width;
                cmd->height = height;

                return {};
            },
            "encoding %s.SetScissorRect(%u, %u, %u, %u).", this, x, y, width, height);
    }

    void RenderPassEncoder::APIExecuteBundles(uint32_t count,
                                              RenderBundleBase* const* renderBundles) {
        mEncodingContext->TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                if (IsValidationEnabled()) {
                    const AttachmentState* attachmentState = GetAttachmentState();
                    bool depthReadOnlyInPass = IsDepthReadOnly();
                    bool stencilReadOnlyInPass = IsStencilReadOnly();
                    for (uint32_t i = 0; i < count; ++i) {
                        DAWN_TRY(GetDevice()->ValidateObject(renderBundles[i]));

                        // TODO(dawn:563): Give more detail about why the states are incompatible.
                        DAWN_INVALID_IF(
                            attachmentState != renderBundles[i]->GetAttachmentState(),
                            "Attachment state of renderBundles[%i] (%s) is not compatible with "
                            "attachment state of %s.",
                            i, renderBundles[i], this);

                        bool depthReadOnlyInBundle = renderBundles[i]->IsDepthReadOnly();
                        DAWN_INVALID_IF(
                            depthReadOnlyInPass && !depthReadOnlyInBundle,
                            "DepthReadOnly (%u) of renderBundle[%i] (%s) is not compatible "
                            "with DepthReadOnly (%u) of %s.",
                            depthReadOnlyInBundle, i, renderBundles[i], depthReadOnlyInPass, this);

                        bool stencilReadOnlyInBundle = renderBundles[i]->IsStencilReadOnly();
                        DAWN_INVALID_IF(stencilReadOnlyInPass && !stencilReadOnlyInBundle,
                                        "StencilReadOnly (%u) of renderBundle[%i] (%s) is not "
                                        "compatible with StencilReadOnly (%u) of %s.",
                                        stencilReadOnlyInBundle, i, renderBundles[i],
                                        stencilReadOnlyInPass, this);
                    }
                }

                mCommandBufferState = CommandBufferStateTracker{};

                ExecuteBundlesCmd* cmd =
                    allocator->Allocate<ExecuteBundlesCmd>(Command::ExecuteBundles);
                cmd->count = count;

                Ref<RenderBundleBase>* bundles =
                    allocator->AllocateData<Ref<RenderBundleBase>>(count);
                for (uint32_t i = 0; i < count; ++i) {
                    bundles[i] = renderBundles[i];

                    const RenderPassResourceUsage& usages = bundles[i]->GetResourceUsage();
                    for (uint32_t i = 0; i < usages.buffers.size(); ++i) {
                        mUsageTracker.BufferUsedAs(usages.buffers[i], usages.bufferUsages[i]);
                    }

                    for (uint32_t i = 0; i < usages.textures.size(); ++i) {
                        mUsageTracker.AddRenderBundleTextureUsage(usages.textures[i],
                                                                  usages.textureUsages[i]);
                    }

                    if (IsValidationEnabled()) {
                        mIndirectDrawMetadata.AddBundle(renderBundles[i]);
                    }
                }

                return {};
            },
            "encoding %s.ExecuteBundles(%u, ...).", this, count);
    }

    void RenderPassEncoder::APIBeginOcclusionQuery(uint32_t queryIndex) {
        mEncodingContext->TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                if (IsValidationEnabled()) {
                    DAWN_INVALID_IF(mOcclusionQuerySet.Get() == nullptr,
                                    "The occlusionQuerySet in RenderPassDescriptor is not set.");

                    // The type of querySet has been validated by ValidateRenderPassDescriptor

                    DAWN_INVALID_IF(queryIndex >= mOcclusionQuerySet->GetQueryCount(),
                                    "Query index (%u) exceeds the number of queries (%u) in %s.",
                                    queryIndex, mOcclusionQuerySet->GetQueryCount(),
                                    mOcclusionQuerySet.Get());

                    DAWN_INVALID_IF(mOcclusionQueryActive,
                                    "An occlusion query (%u) in %s is already active.",
                                    mCurrentOcclusionQueryIndex, mOcclusionQuerySet.Get());

                    DAWN_TRY_CONTEXT(
                        ValidateQueryIndexOverwrite(mOcclusionQuerySet.Get(), queryIndex,
                                                    mUsageTracker.GetQueryAvailabilityMap()),
                        "validating the occlusion query index (%u) in %s", queryIndex,
                        mOcclusionQuerySet.Get());
                }

                // Record the current query index for endOcclusionQuery.
                mCurrentOcclusionQueryIndex = queryIndex;
                mOcclusionQueryActive = true;

                BeginOcclusionQueryCmd* cmd =
                    allocator->Allocate<BeginOcclusionQueryCmd>(Command::BeginOcclusionQuery);
                cmd->querySet = mOcclusionQuerySet.Get();
                cmd->queryIndex = queryIndex;

                return {};
            },
            "encoding %s.BeginOcclusionQuery(%u).", this, queryIndex);
    }

    void RenderPassEncoder::APIEndOcclusionQuery() {
        mEncodingContext->TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                if (IsValidationEnabled()) {
                    DAWN_INVALID_IF(!mOcclusionQueryActive, "No occlusion queries are active.");
                }

                TrackQueryAvailability(mOcclusionQuerySet.Get(), mCurrentOcclusionQueryIndex);

                mOcclusionQueryActive = false;

                EndOcclusionQueryCmd* cmd =
                    allocator->Allocate<EndOcclusionQueryCmd>(Command::EndOcclusionQuery);
                cmd->querySet = mOcclusionQuerySet.Get();
                cmd->queryIndex = mCurrentOcclusionQueryIndex;

                return {};
            },
            "encoding %s.EndOcclusionQuery().", this);
    }

    void RenderPassEncoder::APIWriteTimestamp(QuerySetBase* querySet, uint32_t queryIndex) {
        mEncodingContext->TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                if (IsValidationEnabled()) {
                    DAWN_TRY(ValidateTimestampQuery(GetDevice(), querySet, queryIndex));
                    DAWN_TRY_CONTEXT(
                        ValidateQueryIndexOverwrite(querySet, queryIndex,
                                                    mUsageTracker.GetQueryAvailabilityMap()),
                        "validating the timestamp query index (%u) of %s", queryIndex, querySet);
                }

                TrackQueryAvailability(querySet, queryIndex);

                WriteTimestampCmd* cmd =
                    allocator->Allocate<WriteTimestampCmd>(Command::WriteTimestamp);
                cmd->querySet = querySet;
                cmd->queryIndex = queryIndex;

                return {};
            },
            "encoding %s.WriteTimestamp(%s, %u).", this, querySet, queryIndex);
    }

}  // namespace dawn::native
