// 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 "common/Constants.h"
#include "common/Log.h"
#include "dawn_native/Buffer.h"
#include "dawn_native/BufferLocation.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,
                                         EncodingContext* encodingContext,
                                         Ref<AttachmentState> attachmentState)
        : ProgrammablePassEncoder(device, encodingContext),
          mAttachmentState(std::move(attachmentState)),
          mDisableBaseVertex(device->IsToggleEnabled(Toggle::DisableBaseVertex)),
          mDisableBaseInstance(device->IsToggleEnabled(Toggle::DisableBaseInstance)) {
    }

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

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

    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 Draw(%u, %u, %u, %u).", 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 DrawIndexed(%u, %u, %u, %i, %u).", 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 DrawIndirect(%s, %u).", 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()) {
                    cmd->indirectBufferLocation = BufferLocation::New();
                    mIndirectDrawMetadata.AddIndexedIndirectDraw(
                        mCommandBufferState.GetIndexFormat(),
                        mCommandBufferState.GetIndexBufferSize(), indirectBuffer, indirectOffset,
                        cmd->indirectBufferLocation.Get());
                } else {
                    cmd->indirectBufferLocation =
                        BufferLocation::New(indirectBuffer, indirectOffset);
                }

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

                return {};
            },
            "encoding DrawIndexedIndirect(%s, %u).", 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);
                }

                mCommandBufferState.SetRenderPipeline(pipeline);

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

                return {};
            },
            "encoding SetPipeline(%s).", 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_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;

                    // Temporarily treat 0 as undefined for size, and give a warning
                    // TODO(dawn:1058): Remove this if block
                    if (size == 0) {
                        size = wgpu::kWholeSize;
                        GetDevice()->EmitDeprecationWarning(
                            "Using size=0 to indicate default binding size for setIndexBuffer "
                            "is deprecated. In the future it will result in a zero-size binding. "
                            "Use `undefined` (wgpu::kWholeSize) or just omit the parameter "
                            "instead.");
                    }

                    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 SetIndexBuffer(%s, %s, %u, %u).", 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;

                    // Temporarily treat 0 as undefined for size, and give a warning
                    // TODO(dawn:1058): Remove this if block
                    if (size == 0) {
                        size = wgpu::kWholeSize;
                        GetDevice()->EmitDeprecationWarning(
                            "Using size=0 to indicate default binding size for setVertexBuffer "
                            "is deprecated. In the future it will result in a zero-size binding. "
                            "Use `undefined` (wgpu::kWholeSize) or just omit the parameter "
                            "instead.");
                    }

                    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 SetVertexBuffer(%u, %s, %u, %u).", 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);
                mUsageTracker.AddBindGroup(group);

                return {};
            },
            "encoding SetBindGroup(%u, %s, %u).", groupIndexIn, group, dynamicOffsetCount);
    }

}  // namespace dawn_native
