// 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.

#ifndef DAWNNATIVE_COMMANDBUFFER_H_
#define DAWNNATIVE_COMMANDBUFFER_H_

#include "dawn_native/dawn_platform.h"

#include "dawn_native/Builder.h"
#include "dawn_native/CommandAllocator.h"
#include "dawn_native/Error.h"
#include "dawn_native/PassResourceUsage.h"
#include "dawn_native/RefCounted.h"

#include <memory>
#include <set>
#include <utility>

namespace dawn_native {

    class BindGroupBase;
    class BufferBase;
    class FramebufferBase;
    class DeviceBase;
    class PipelineBase;
    class RenderPassBase;
    class TextureBase;

    class CommandBufferBuilder;

    class CommandBufferBase : public RefCounted {
      public:
        CommandBufferBase(CommandBufferBuilder* builder);

        DeviceBase* GetDevice();

      private:
        DeviceBase* mDevice;
    };

    class CommandBufferBuilder : public Builder<CommandBufferBase> {
      public:
        CommandBufferBuilder(DeviceBase* device);
        ~CommandBufferBuilder();

        MaybeError ValidateGetResult();

        CommandIterator AcquireCommands();
        std::vector<PassResourceUsage> AcquirePassResourceUsage();

        // Dawn API
        void BeginComputePass();
        void BeginRenderPass(RenderPassDescriptorBase* info);
        void CopyBufferToBuffer(BufferBase* source,
                                uint32_t sourceOffset,
                                BufferBase* destination,
                                uint32_t destinationOffset,
                                uint32_t size);
        void CopyBufferToTexture(BufferBase* buffer,
                                 uint32_t bufferOffset,
                                 uint32_t rowPitch,
                                 TextureBase* texture,
                                 uint32_t x,
                                 uint32_t y,
                                 uint32_t z,
                                 uint32_t width,
                                 uint32_t height,
                                 uint32_t depth,
                                 uint32_t level,
                                 uint32_t slice);
        void CopyTextureToBuffer(TextureBase* texture,
                                 uint32_t x,
                                 uint32_t y,
                                 uint32_t z,
                                 uint32_t width,
                                 uint32_t height,
                                 uint32_t depth,
                                 uint32_t level,
                                 uint32_t slice,
                                 BufferBase* buffer,
                                 uint32_t bufferOffset,
                                 uint32_t rowPitch);
        void Dispatch(uint32_t x, uint32_t y, uint32_t z);
        void DrawArrays(uint32_t vertexCount,
                        uint32_t instanceCount,
                        uint32_t firstVertex,
                        uint32_t firstInstance);
        void DrawElements(uint32_t vertexCount,
                          uint32_t instanceCount,
                          uint32_t firstIndex,
                          uint32_t firstInstance);
        void EndComputePass();
        void EndRenderPass();
        void SetPushConstants(dawn::ShaderStageBit stages,
                              uint32_t offset,
                              uint32_t count,
                              const void* data);
        void SetComputePipeline(ComputePipelineBase* pipeline);
        void SetRenderPipeline(RenderPipelineBase* pipeline);
        void SetStencilReference(uint32_t reference);
        void SetBlendColor(float r, float g, float b, float a);
        void SetScissorRect(uint32_t x, uint32_t y, uint32_t width, uint32_t height);
        void SetBindGroup(uint32_t groupIndex, BindGroupBase* group);
        void SetIndexBuffer(BufferBase* buffer, uint32_t offset);

        template <typename T>
        void SetVertexBuffers(uint32_t startSlot,
                              uint32_t count,
                              T* const* buffers,
                              uint32_t const* offsets) {
            static_assert(std::is_base_of<BufferBase, T>::value, "");
            SetVertexBuffers(startSlot, count, reinterpret_cast<BufferBase* const*>(buffers),
                             offsets);
        }
        void SetVertexBuffers(uint32_t startSlot,
                              uint32_t count,
                              BufferBase* const* buffers,
                              uint32_t const* offsets);

        void TransitionBufferUsage(BufferBase* buffer, dawn::BufferUsageBit usage);

      private:
        friend class CommandBufferBase;

        CommandBufferBase* GetResultImpl() override;
        void MoveToIterator();

        MaybeError ValidateComputePass();
        MaybeError ValidateRenderPass(RenderPassDescriptorBase* renderPass);

        CommandAllocator mAllocator;
        CommandIterator mIterator;
        bool mWasMovedToIterator = false;
        bool mWereCommandsAcquired = false;
        bool mWerePassUsagesAcquired = false;

        std::vector<PassResourceUsage> mPassResourceUsages;
    };

}  // namespace dawn_native

#endif  // DAWNNATIVE_COMMANDBUFFER_H_
