// Copyright (c) 2018 The Khronos Group Inc.
// Copyright (c) 2018 Valve Corporation
// Copyright (c) 2018 LunarG Inc.
//
// 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 LIBSPIRV_OPT_INST_BINDLESS_CHECK_PASS_H_
#define LIBSPIRV_OPT_INST_BINDLESS_CHECK_PASS_H_

#include "instrument_pass.h"

namespace spvtools {
namespace opt {

// This class/pass is designed to support the bindless (descriptor indexing)
// GPU-assisted validation layer of
// https://github.com/KhronosGroup/Vulkan-ValidationLayers. Its internal and
// external design may change as the layer evolves.
class InstBindlessCheckPass : public InstrumentPass {
 public:
  InstBindlessCheckPass(uint32_t shader_id)
      : InstrumentPass(0, shader_id, true, true) {}

  ~InstBindlessCheckPass() override = default;

  // See optimizer.hpp for pass user documentation.
  Status Process() override;

  const char* name() const override { return "inst-bindless-check-pass"; }

 private:
  void GenDescCheckCode(BasicBlock::iterator ref_inst_itr,
                        UptrVectorIterator<BasicBlock> ref_block_itr,
                        uint32_t stage_idx,
                        std::vector<std::unique_ptr<BasicBlock>>* new_blocks);

  uint32_t GenDescCheckFunctionId();

  uint32_t GenDescCheckCall(uint32_t inst_idx, uint32_t stage_idx,
                            uint32_t var_id, uint32_t index_id,
                            uint32_t byte_offset, InstructionBuilder* builder);

  // Analysis data for descriptor reference components, generated by
  // AnalyzeDescriptorReference. It is necessary and sufficient for further
  // analysis and regeneration of the reference.
  typedef struct RefAnalysis {
    uint32_t desc_load_id{0};
    uint32_t image_id{0};
    uint32_t load_id{0};
    uint32_t ptr_id{0};
    uint32_t var_id{0};
    uint32_t set{0};
    uint32_t binding{0};
    uint32_t desc_idx_id{0};
    uint32_t strg_class{0};
    Instruction* ref_inst{nullptr};
  } RefAnalysis;

  // Return size of type |ty_id| in bytes. Use |matrix_stride| and |col_major|
  // for matrix type, or for vector type if vector is |in_matrix|.
  uint32_t ByteSize(uint32_t ty_id, uint32_t matrix_stride, bool col_major,
                    bool in_matrix);

  // Return stride of type |ty_id| with decoration |stride_deco|. Return 0
  // if not found
  uint32_t FindStride(uint32_t ty_id, uint32_t stride_deco);

  // Generate index of last byte referenced by buffer reference |ref|
  uint32_t GenLastByteIdx(RefAnalysis* ref, InstructionBuilder* builder);

  // Clone original image computation starting at |image_id| into |builder|.
  // This may generate more than one instruction if necessary.
  uint32_t CloneOriginalImage(uint32_t image_id, InstructionBuilder* builder);

  // Clone original original reference encapsulated by |ref| into |builder|.
  // This may generate more than one instruction if necessary.
  uint32_t CloneOriginalReference(RefAnalysis* ref,
                                  InstructionBuilder* builder);

  // If |inst| references through an image, return the id of the image it
  // references through. Else return 0.
  uint32_t GetImageId(Instruction* inst);

  // Get pointee type inst of pointer value |ptr_inst|.
  Instruction* GetPointeeTypeInst(Instruction* ptr_inst);

  // Analyze descriptor reference |ref_inst| and save components into |ref|.
  // Return true if |ref_inst| is a descriptor reference, false otherwise.
  bool AnalyzeDescriptorReference(Instruction* ref_inst, RefAnalysis* ref);

  // Generate instrumentation code for generic test result |check_id|, starting
  // with |builder| of block |new_blk_ptr|, adding new blocks to |new_blocks|.
  // Generate conditional branch to a valid or invalid branch. Generate valid
  // block which does original reference |ref|. Generate invalid block which
  // writes debug error output utilizing |ref|, |error_id|, |length_id| and
  // |stage_idx|. Generate merge block for valid and invalid branches. Kill
  // original reference.
  void GenCheckCode(uint32_t check_id, RefAnalysis* ref,
                    std::vector<std::unique_ptr<BasicBlock>>* new_blocks);

  // Initialize state for instrumenting bindless checking
  void InitializeInstBindlessCheck();

  // Apply GenDescIdxCheckCode to every instruction in module. Then apply
  // GenDescInitCheckCode to every instruction in module.
  Pass::Status ProcessImpl();

  // Mapping from variable to descriptor set
  std::unordered_map<uint32_t, uint32_t> var2desc_set_;

  // Mapping from variable to binding
  std::unordered_map<uint32_t, uint32_t> var2binding_;

  uint32_t check_desc_func_id_{0};
};

}  // namespace opt
}  // namespace spvtools

#endif  // LIBSPIRV_OPT_INST_BINDLESS_CHECK_PASS_H_
