// Copyright 2019 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/RenderEncoderBase.h"

#include "dawn/common/Constants.h"
#include "dawn/common/Log.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/RenderPipeline.h"
#include "dawn/native/ValidationUtils_autogen.h"

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

namespace dawn::native {

    RenderEncoderBase::RenderEncoderBase(DeviceBase* device,
                                         const char* label,
                                         EncodingContext* encodingContext,
                                         Ref<AttachmentState> attachmentState,
                                         bool depthReadOnly,
                                         bool stencilReadOnly)
        : ProgrammableEncoder(device, label, encodingContext),
          mIndirectDrawMetadata(device->GetLimits()),
          mAttachmentState(std::move(attachmentState)),
          mDisableBaseVertex(device->IsToggleEnabled(Toggle::DisableBaseVertex)),
          mDisableBaseInstance(device->IsToggleEnabled(Toggle::DisableBaseInstance)) {
        mDepthReadOnly = depthReadOnly;
        mStencilReadOnly = stencilReadOnly;
    }

    RenderEncoderBase::RenderEncoderBase(DeviceBase* device,
                                         EncodingContext* encodingContext,
                                         ErrorTag errorTag)
        : ProgrammableEncoder(device, encodingContext, errorTag),
          mIndirectDrawMetadata(device->GetLimits()),
          mDisableBaseVertex(device->IsToggleEnabled(Toggle::DisableBaseVertex)),
          mDisableBaseInstance(device->IsToggleEnabled(Toggle::DisableBaseInstance)) {
    }

    void RenderEncoderBase::DestroyImpl() {
        // Remove reference to the attachment state so that we don't have lingering references to
        // it preventing it from being uncached in the device.
        mAttachmentState = nullptr;
    }

    const AttachmentState* RenderEncoderBase::GetAttachmentState() const {
        ASSERT(!IsError());
        ASSERT(mAttachmentState != nullptr);
        return mAttachmentState.Get();
    }

    bool RenderEncoderBase::IsDepthReadOnly() const {
        ASSERT(!IsError());
        return mDepthReadOnly;
    }

    bool RenderEncoderBase::IsStencilReadOnly() const {
        ASSERT(!IsError());
        return mStencilReadOnly;
    }

    Ref<AttachmentState> RenderEncoderBase::AcquireAttachmentState() {
        return std::move(mAttachmentState);
    }

    void RenderEncoderBase::APIDraw(uint32_t vertexCount,
                                    uint32_t instanceCount,
                                    uint32_t firstVertex,
                                    uint32_t firstInstance) {
        mEncodingContext->TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                if (IsValidationEnabled()) {
                    DAWN_TRY(mCommandBufferState.ValidateCanDraw());

                    DAWN_INVALID_IF(mDisableBaseInstance && firstInstance != 0,
                                    "First instance (%u) must be zero.", firstInstance);

                    DAWN_TRY(mCommandBufferState.ValidateBufferInRangeForVertexBuffer(vertexCount,
                                                                                      firstVertex));
                    DAWN_TRY(mCommandBufferState.ValidateBufferInRangeForInstanceBuffer(
                        instanceCount, firstInstance));
                }

                DrawCmd* draw = allocator->Allocate<DrawCmd>(Command::Draw);
                draw->vertexCount = vertexCount;
                draw->instanceCount = instanceCount;
                draw->firstVertex = firstVertex;
                draw->firstInstance = firstInstance;

                return {};
            },
            "encoding %s.Draw(%u, %u, %u, %u).", this, vertexCount, instanceCount, firstVertex,
            firstInstance);
    }

    void RenderEncoderBase::APIDrawIndexed(uint32_t indexCount,
                                           uint32_t instanceCount,
                                           uint32_t firstIndex,
                                           int32_t baseVertex,
                                           uint32_t firstInstance) {
        mEncodingContext->TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                if (IsValidationEnabled()) {
                    DAWN_TRY(mCommandBufferState.ValidateCanDrawIndexed());

                    DAWN_INVALID_IF(mDisableBaseInstance && firstInstance != 0,
                                    "First instance (%u) must be zero.", firstInstance);

                    DAWN_INVALID_IF(mDisableBaseVertex && baseVertex != 0,
                                    "Base vertex (%u) must be zero.", baseVertex);

                    DAWN_TRY(
                        mCommandBufferState.ValidateIndexBufferInRange(indexCount, firstIndex));

                    // Although we don't know actual vertex access range in CPU, we still call the
                    // ValidateBufferInRangeForVertexBuffer in order to deal with those vertex step
                    // mode vertex buffer with an array stride of zero.
                    DAWN_TRY(mCommandBufferState.ValidateBufferInRangeForVertexBuffer(0, 0));
                    DAWN_TRY(mCommandBufferState.ValidateBufferInRangeForInstanceBuffer(
                        instanceCount, firstInstance));
                }

                DrawIndexedCmd* draw = allocator->Allocate<DrawIndexedCmd>(Command::DrawIndexed);
                draw->indexCount = indexCount;
                draw->instanceCount = instanceCount;
                draw->firstIndex = firstIndex;
                draw->baseVertex = baseVertex;
                draw->firstInstance = firstInstance;

                return {};
            },
            "encoding %s.DrawIndexed(%u, %u, %u, %i, %u).", this, indexCount, instanceCount,
            firstIndex, baseVertex, firstInstance);
    }

    void RenderEncoderBase::APIDrawIndirect(BufferBase* indirectBuffer, uint64_t indirectOffset) {
        mEncodingContext->TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                if (IsValidationEnabled()) {
                    DAWN_TRY(GetDevice()->ValidateObject(indirectBuffer));
                    DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect));
                    DAWN_TRY(mCommandBufferState.ValidateCanDraw());

                    DAWN_INVALID_IF(indirectOffset % 4 != 0,
                                    "Indirect offset (%u) is not a multiple of 4.", indirectOffset);

                    DAWN_INVALID_IF(
                        indirectOffset >= indirectBuffer->GetSize() ||
                            kDrawIndirectSize > indirectBuffer->GetSize() - indirectOffset,
                        "Indirect offset (%u) is out of bounds of indirect buffer %s size (%u).",
                        indirectOffset, indirectBuffer, indirectBuffer->GetSize());
                }

                DrawIndirectCmd* cmd = allocator->Allocate<DrawIndirectCmd>(Command::DrawIndirect);
                cmd->indirectBuffer = indirectBuffer;
                cmd->indirectOffset = indirectOffset;

                mUsageTracker.BufferUsedAs(indirectBuffer, wgpu::BufferUsage::Indirect);

                return {};
            },
            "encoding %s.DrawIndirect(%s, %u).", this, indirectBuffer, indirectOffset);
    }

    void RenderEncoderBase::APIDrawIndexedIndirect(BufferBase* indirectBuffer,
                                                   uint64_t indirectOffset) {
        mEncodingContext->TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                if (IsValidationEnabled()) {
                    DAWN_TRY(GetDevice()->ValidateObject(indirectBuffer));
                    DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect));
                    DAWN_TRY(mCommandBufferState.ValidateCanDrawIndexed());

                    DAWN_INVALID_IF(indirectOffset % 4 != 0,
                                    "Indirect offset (%u) is not a multiple of 4.", indirectOffset);

                    DAWN_INVALID_IF(
                        (indirectOffset >= indirectBuffer->GetSize() ||
                         kDrawIndexedIndirectSize > indirectBuffer->GetSize() - indirectOffset),
                        "Indirect offset (%u) is out of bounds of indirect buffer %s size (%u).",
                        indirectOffset, indirectBuffer, indirectBuffer->GetSize());
                }

                DrawIndexedIndirectCmd* cmd =
                    allocator->Allocate<DrawIndexedIndirectCmd>(Command::DrawIndexedIndirect);
                if (IsValidationEnabled()) {
                    // Later, EncodeIndirectDrawValidationCommands will allocate a scratch storage
                    // buffer which will store the validated indirect data. The buffer and offset
                    // will be updated to point to it.
                    // |EncodeIndirectDrawValidationCommands| is called at the end of encoding the
                    // render pass, while the |cmd| pointer is still valid.
                    cmd->indirectBuffer = nullptr;

                    mIndirectDrawMetadata.AddIndexedIndirectDraw(
                        mCommandBufferState.GetIndexFormat(),
                        mCommandBufferState.GetIndexBufferSize(), indirectBuffer, indirectOffset,
                        cmd);
                } else {
                    cmd->indirectBuffer = indirectBuffer;
                    cmd->indirectOffset = indirectOffset;
                }

                // TODO(crbug.com/dawn/1166): Adding the indirectBuffer is needed for correct usage
                // validation, but it will unecessarily transition to indirectBuffer usage in the
                // backend.
                mUsageTracker.BufferUsedAs(indirectBuffer, wgpu::BufferUsage::Indirect);

                return {};
            },
            "encoding %s.DrawIndexedIndirect(%s, %u).", this, indirectBuffer, indirectOffset);
    }

    void RenderEncoderBase::APISetPipeline(RenderPipelineBase* pipeline) {
        mEncodingContext->TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                if (IsValidationEnabled()) {
                    DAWN_TRY(GetDevice()->ValidateObject(pipeline));

                    // TODO(dawn:563): More detail about why the states are incompatible would be
                    // nice.
                    DAWN_INVALID_IF(
                        pipeline->GetAttachmentState() != mAttachmentState.Get(),
                        "Attachment state of %s is not compatible with the attachment state of %s",
                        pipeline, this);

                    DAWN_INVALID_IF(pipeline->WritesDepth() && mDepthReadOnly,
                                    "%s writes depth while %s's depthReadOnly is true", pipeline,
                                    this);

                    DAWN_INVALID_IF(pipeline->WritesStencil() && mStencilReadOnly,
                                    "%s writes stencil while %s's stencilReadOnly is true",
                                    pipeline, this);
                }

                mCommandBufferState.SetRenderPipeline(pipeline);

                SetRenderPipelineCmd* cmd =
                    allocator->Allocate<SetRenderPipelineCmd>(Command::SetRenderPipeline);
                cmd->pipeline = pipeline;

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

    void RenderEncoderBase::APISetIndexBuffer(BufferBase* buffer,
                                              wgpu::IndexFormat format,
                                              uint64_t offset,
                                              uint64_t size) {
        mEncodingContext->TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                if (IsValidationEnabled()) {
                    DAWN_TRY(GetDevice()->ValidateObject(buffer));
                    DAWN_TRY(ValidateCanUseAs(buffer, wgpu::BufferUsage::Index));

                    DAWN_TRY(ValidateIndexFormat(format));

                    DAWN_INVALID_IF(format == wgpu::IndexFormat::Undefined,
                                    "Index format must be specified");

                    DAWN_INVALID_IF(offset % uint64_t(IndexFormatSize(format)) != 0,
                                    "Index buffer offset (%u) is not a multiple of the size (%u) "
                                    "of %s.",
                                    offset, IndexFormatSize(format), format);

                    uint64_t bufferSize = buffer->GetSize();
                    DAWN_INVALID_IF(offset > bufferSize,
                                    "Index buffer offset (%u) is larger than the size (%u) of %s.",
                                    offset, bufferSize, buffer);

                    uint64_t remainingSize = bufferSize - offset;

                    if (size == wgpu::kWholeSize) {
                        size = remainingSize;
                    } else {
                        DAWN_INVALID_IF(size > remainingSize,
                                        "Index buffer range (offset: %u, size: %u) doesn't fit in "
                                        "the size (%u) of "
                                        "%s.",
                                        offset, size, bufferSize, buffer);
                    }
                } else {
                    if (size == wgpu::kWholeSize) {
                        DAWN_ASSERT(buffer->GetSize() >= offset);
                        size = buffer->GetSize() - offset;
                    }
                }

                mCommandBufferState.SetIndexBuffer(format, size);

                SetIndexBufferCmd* cmd =
                    allocator->Allocate<SetIndexBufferCmd>(Command::SetIndexBuffer);
                cmd->buffer = buffer;
                cmd->format = format;
                cmd->offset = offset;
                cmd->size = size;

                mUsageTracker.BufferUsedAs(buffer, wgpu::BufferUsage::Index);

                return {};
            },
            "encoding %s.SetIndexBuffer(%s, %s, %u, %u).", this, buffer, format, offset, size);
    }

    void RenderEncoderBase::APISetVertexBuffer(uint32_t slot,
                                               BufferBase* buffer,
                                               uint64_t offset,
                                               uint64_t size) {
        mEncodingContext->TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                if (IsValidationEnabled()) {
                    DAWN_TRY(GetDevice()->ValidateObject(buffer));
                    DAWN_TRY(ValidateCanUseAs(buffer, wgpu::BufferUsage::Vertex));

                    DAWN_INVALID_IF(slot >= kMaxVertexBuffers,
                                    "Vertex buffer slot (%u) is larger the maximum (%u)", slot,
                                    kMaxVertexBuffers - 1);

                    DAWN_INVALID_IF(offset % 4 != 0,
                                    "Vertex buffer offset (%u) is not a multiple of 4", offset);

                    uint64_t bufferSize = buffer->GetSize();
                    DAWN_INVALID_IF(offset > bufferSize,
                                    "Vertex buffer offset (%u) is larger than the size (%u) of %s.",
                                    offset, bufferSize, buffer);

                    uint64_t remainingSize = bufferSize - offset;

                    if (size == wgpu::kWholeSize) {
                        size = remainingSize;
                    } else {
                        DAWN_INVALID_IF(size > remainingSize,
                                        "Vertex buffer range (offset: %u, size: %u) doesn't fit in "
                                        "the size (%u) "
                                        "of %s.",
                                        offset, size, bufferSize, buffer);
                    }
                } else {
                    if (size == wgpu::kWholeSize) {
                        DAWN_ASSERT(buffer->GetSize() >= offset);
                        size = buffer->GetSize() - offset;
                    }
                }

                mCommandBufferState.SetVertexBuffer(VertexBufferSlot(uint8_t(slot)), size);

                SetVertexBufferCmd* cmd =
                    allocator->Allocate<SetVertexBufferCmd>(Command::SetVertexBuffer);
                cmd->slot = VertexBufferSlot(static_cast<uint8_t>(slot));
                cmd->buffer = buffer;
                cmd->offset = offset;
                cmd->size = size;

                mUsageTracker.BufferUsedAs(buffer, wgpu::BufferUsage::Vertex);

                return {};
            },
            "encoding %s.SetVertexBuffer(%u, %s, %u, %u).", this, slot, buffer, offset, size);
    }

    void RenderEncoderBase::APISetBindGroup(uint32_t groupIndexIn,
                                            BindGroupBase* group,
                                            uint32_t dynamicOffsetCount,
                                            const uint32_t* dynamicOffsets) {
        mEncodingContext->TryEncode(
            this,
            [&](CommandAllocator* allocator) -> MaybeError {
                BindGroupIndex groupIndex(groupIndexIn);

                if (IsValidationEnabled()) {
                    DAWN_TRY(ValidateSetBindGroup(groupIndex, group, dynamicOffsetCount,
                                                  dynamicOffsets));
                }

                RecordSetBindGroup(allocator, groupIndex, group, dynamicOffsetCount,
                                   dynamicOffsets);
                mCommandBufferState.SetBindGroup(groupIndex, group, dynamicOffsetCount,
                                                 dynamicOffsets);
                mUsageTracker.AddBindGroup(group);

                return {};
            },
            // TODO(dawn:1190): For unknown reasons formatting this message fails if `group` is used
            // as a string value in the message. This despite the exact same code working as
            // intended in ComputePassEncoder::APISetBindGroup. Replacing with a static [BindGroup]
            // until the reason for the failure can be determined.
            "encoding %s.SetBindGroup(%u, [BindGroup], %u, ...).", this, groupIndexIn,
            dynamicOffsetCount);
    }

}  // namespace dawn::native
