// 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 SRC_DAWN_NATIVE_COMMANDBUFFERSTATETRACKER_H_
#define SRC_DAWN_NATIVE_COMMANDBUFFERSTATETRACKER_H_

#include <vector>

#include "dawn/common/Constants.h"
#include "dawn/common/ityp_array.h"
#include "dawn/common/ityp_bitset.h"
#include "dawn/native/BindingInfo.h"
#include "dawn/native/Error.h"
#include "dawn/native/Forward.h"

namespace dawn::native {

    class CommandBufferStateTracker {
      public:
        // Non-state-modifying validation functions
        MaybeError ValidateCanDispatch();
        MaybeError ValidateCanDraw();
        MaybeError ValidateCanDrawIndexed();
        MaybeError ValidateBufferInRangeForVertexBuffer(uint32_t vertexCount, uint32_t firstVertex);
        MaybeError ValidateBufferInRangeForInstanceBuffer(uint32_t instanceCount,
                                                          uint32_t firstInstance);
        MaybeError ValidateIndexBufferInRange(uint32_t indexCount, uint32_t firstIndex);

        // State-modifying methods
        void SetComputePipeline(ComputePipelineBase* pipeline);
        void SetRenderPipeline(RenderPipelineBase* pipeline);
        void SetBindGroup(BindGroupIndex index,
                          BindGroupBase* bindgroup,
                          uint32_t dynamicOffsetCount,
                          const uint32_t* dynamicOffsets);
        void SetIndexBuffer(wgpu::IndexFormat format, uint64_t size);
        void SetVertexBuffer(VertexBufferSlot slot, uint64_t size);

        static constexpr size_t kNumAspects = 4;
        using ValidationAspects = std::bitset<kNumAspects>;

        BindGroupBase* GetBindGroup(BindGroupIndex index) const;
        const std::vector<uint32_t>& GetDynamicOffsets(BindGroupIndex index) const;
        bool HasPipeline() const;
        RenderPipelineBase* GetRenderPipeline() const;
        ComputePipelineBase* GetComputePipeline() const;
        PipelineLayoutBase* GetPipelineLayout() const;
        wgpu::IndexFormat GetIndexFormat() const;
        uint64_t GetIndexBufferSize() const;

      private:
        MaybeError ValidateOperation(ValidationAspects requiredAspects);
        void RecomputeLazyAspects(ValidationAspects aspects);
        MaybeError CheckMissingAspects(ValidationAspects aspects);

        void SetPipelineCommon(PipelineBase* pipeline);

        ValidationAspects mAspects;

        ityp::array<BindGroupIndex, BindGroupBase*, kMaxBindGroups> mBindgroups = {};
        ityp::array<BindGroupIndex, std::vector<uint32_t>, kMaxBindGroups> mDynamicOffsets = {};
        ityp::bitset<VertexBufferSlot, kMaxVertexBuffers> mVertexBufferSlotsUsed;
        bool mIndexBufferSet = false;
        wgpu::IndexFormat mIndexFormat;
        uint64_t mIndexBufferSize = 0;

        ityp::array<VertexBufferSlot, uint64_t, kMaxVertexBuffers> mVertexBufferSizes = {};

        PipelineLayoutBase* mLastPipelineLayout = nullptr;
        PipelineBase* mLastPipeline = nullptr;

        const RequiredBufferSizes* mMinBufferSizes = nullptr;
    };

}  // namespace dawn::native

#endif  // SRC_DAWN_NATIVE_COMMANDBUFFERSTATETRACKER_H_
