// 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 "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, EncodingContext* encodingContext)
        : ProgrammablePassEncoder(device, encodingContext, PassType::Render),
          mDisableBaseVertex(device->IsToggleEnabled(Toggle::DisableBaseVertex)),
          mDisableBaseInstance(device->IsToggleEnabled(Toggle::DisableBaseInstance)) {
    }

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

    void RenderEncoderBase::Draw(uint32_t vertexCount,
                                 uint32_t instanceCount,
                                 uint32_t firstVertex,
                                 uint32_t firstInstance) {
        mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
            if (IsValidationEnabled()) {
                if (mDisableBaseInstance && firstInstance != 0) {
                    return DAWN_VALIDATION_ERROR("Non-zero first instance not supported");
                }
            }

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

            return {};
        });
    }

    void RenderEncoderBase::DrawIndexed(uint32_t indexCount,
                                        uint32_t instanceCount,
                                        uint32_t firstIndex,
                                        int32_t baseVertex,
                                        uint32_t firstInstance) {
        mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
            if (IsValidationEnabled()) {
                if (mDisableBaseInstance && firstInstance != 0) {
                    return DAWN_VALIDATION_ERROR("Non-zero first instance not supported");
                }
                if (mDisableBaseVertex && baseVertex != 0) {
                    return DAWN_VALIDATION_ERROR("Non-zero base vertex not supported");
                }
            }

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

            return {};
        });
    }

    void RenderEncoderBase::DrawIndirect(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));

                if (indirectOffset % 4 != 0) {
                    return DAWN_VALIDATION_ERROR("Indirect offset must be a multiple of 4");
                }

                if (indirectOffset >= indirectBuffer->GetSize() ||
                    indirectOffset + kDrawIndirectSize > indirectBuffer->GetSize()) {
                    return DAWN_VALIDATION_ERROR("Indirect offset out of bounds");
                }
            }

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

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

            return {};
        });
    }

    void RenderEncoderBase::DrawIndexedIndirect(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));

                // Indexed indirect draws need a compute-shader based validation check that the
                // range of indices is contained inside the index buffer on Metal. Disallow them as
                // unsafe until the validation is implemented.
                if (GetDevice()->IsToggleEnabled(Toggle::DisallowUnsafeAPIs)) {
                    return DAWN_VALIDATION_ERROR(
                        "DrawIndexedIndirect is disallowed because it doesn't validate that the "
                        "index "
                        "range is valid yet.");
                }

                if (indirectOffset % 4 != 0) {
                    return DAWN_VALIDATION_ERROR("Indirect offset must be a multiple of 4");
                }

                if ((indirectOffset >= indirectBuffer->GetSize() ||
                     indirectOffset + kDrawIndexedIndirectSize > indirectBuffer->GetSize())) {
                    return DAWN_VALIDATION_ERROR("Indirect offset out of bounds");
                }
            }

            DrawIndexedIndirectCmd* cmd =
                allocator->Allocate<DrawIndexedIndirectCmd>(Command::DrawIndexedIndirect);
            cmd->indirectBuffer = indirectBuffer;
            cmd->indirectOffset = indirectOffset;

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

            return {};
        });
    }

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

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

            return {};
        });
    }

    void RenderEncoderBase::SetIndexBufferWithFormat(BufferBase* buffer, wgpu::IndexFormat format,
                                                     uint64_t offset, uint64_t size) {
        GetDevice()->EmitDeprecationWarning(
            "RenderEncoderBase::SetIndexBufferWithFormat is deprecated. Use "
            "RenderEncoderBase::SetIndexBuffer instead.");
        SetIndexBuffer(buffer, format, offset, size);
    }

    void RenderEncoderBase::SetIndexBuffer(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));
                if (format == wgpu::IndexFormat::Undefined) {
                    return DAWN_VALIDATION_ERROR("Index format must be specified");
                }

                uint64_t bufferSize = buffer->GetSize();
                if (offset > bufferSize) {
                    return DAWN_VALIDATION_ERROR("Offset larger than the buffer size");
                }
                uint64_t remainingSize = bufferSize - offset;

                if (size == 0) {
                    size = remainingSize;
                } else {
                    if (size > remainingSize) {
                        return DAWN_VALIDATION_ERROR("Size + offset larger than the buffer size");
                    }
                }
            } else {
                if (size == 0) {
                    size = buffer->GetSize() - offset;
                }
            }

            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 {};
        });
    }

    void RenderEncoderBase::SetVertexBuffer(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));

                if (slot >= kMaxVertexBuffers) {
                    return DAWN_VALIDATION_ERROR("Vertex buffer slot out of bounds");
                }

                uint64_t bufferSize = buffer->GetSize();
                if (offset > bufferSize) {
                    return DAWN_VALIDATION_ERROR("Offset larger than the buffer size");
                }
                uint64_t remainingSize = bufferSize - offset;

                if (size == 0) {
                    size = remainingSize;
                } else {
                    if (size > remainingSize) {
                        return DAWN_VALIDATION_ERROR("Size + offset larger than the buffer size");
                    }
                }
            } else {
                if (size == 0) {
                    size = buffer->GetSize() - offset;
                }
            }

            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 {};
        });
    }

}  // namespace dawn_native
