// Copyright (c) 2018 Google LLC.
//
// 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 "source/val/validate.h"

#include <algorithm>

#include "source/opcode.h"
#include "source/spirv_target_env.h"
#include "source/val/instruction.h"
#include "source/val/validation_state.h"

namespace spvtools {
namespace val {
namespace {

spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) {
  const auto entry_point_id = inst->GetOperandAs<uint32_t>(1);
  auto entry_point = _.FindDef(entry_point_id);
  if (!entry_point || SpvOpFunction != entry_point->opcode()) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "OpEntryPoint Entry Point <id> '" << _.getIdName(entry_point_id)
           << "' is not a function.";
  }

  // Only check the shader execution models
  const SpvExecutionModel execution_model =
      inst->GetOperandAs<SpvExecutionModel>(0);
  if (execution_model != SpvExecutionModelKernel) {
    const auto entry_point_type_id = entry_point->GetOperandAs<uint32_t>(3);
    const auto entry_point_type = _.FindDef(entry_point_type_id);
    if (!entry_point_type || 3 != entry_point_type->words().size()) {
      return _.diag(SPV_ERROR_INVALID_ID, inst)
             << _.VkErrorID(4633) << "OpEntryPoint Entry Point <id> '"
             << _.getIdName(entry_point_id)
             << "'s function parameter count is not zero.";
    }
  }

  auto return_type = _.FindDef(entry_point->type_id());
  if (!return_type || SpvOpTypeVoid != return_type->opcode()) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << _.VkErrorID(4633) << "OpEntryPoint Entry Point <id> '"
           << _.getIdName(entry_point_id)
           << "'s function return type is not void.";
  }

  const auto* execution_modes = _.GetExecutionModes(entry_point_id);
  if (_.HasCapability(SpvCapabilityShader)) {
    switch (execution_model) {
      case SpvExecutionModelFragment:
        if (execution_modes &&
            execution_modes->count(SpvExecutionModeOriginUpperLeft) &&
            execution_modes->count(SpvExecutionModeOriginLowerLeft)) {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Fragment execution model entry points can only specify "
                    "one of OriginUpperLeft or OriginLowerLeft execution "
                    "modes.";
        }
        if (!execution_modes ||
            (!execution_modes->count(SpvExecutionModeOriginUpperLeft) &&
             !execution_modes->count(SpvExecutionModeOriginLowerLeft))) {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Fragment execution model entry points require either an "
                    "OriginUpperLeft or OriginLowerLeft execution mode.";
        }
        if (execution_modes &&
            1 < std::count_if(execution_modes->begin(), execution_modes->end(),
                              [](const SpvExecutionMode& mode) {
                                switch (mode) {
                                  case SpvExecutionModeDepthGreater:
                                  case SpvExecutionModeDepthLess:
                                  case SpvExecutionModeDepthUnchanged:
                                    return true;
                                  default:
                                    return false;
                                }
                              })) {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Fragment execution model entry points can specify at most "
                    "one of DepthGreater, DepthLess or DepthUnchanged "
                    "execution modes.";
        }
        if (execution_modes &&
            1 < std::count_if(
                    execution_modes->begin(), execution_modes->end(),
                    [](const SpvExecutionMode& mode) {
                      switch (mode) {
                        case SpvExecutionModePixelInterlockOrderedEXT:
                        case SpvExecutionModePixelInterlockUnorderedEXT:
                        case SpvExecutionModeSampleInterlockOrderedEXT:
                        case SpvExecutionModeSampleInterlockUnorderedEXT:
                        case SpvExecutionModeShadingRateInterlockOrderedEXT:
                        case SpvExecutionModeShadingRateInterlockUnorderedEXT:
                          return true;
                        default:
                          return false;
                      }
                    })) {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Fragment execution model entry points can specify at most "
                    "one fragment shader interlock execution mode.";
        }
        break;
      case SpvExecutionModelTessellationControl:
      case SpvExecutionModelTessellationEvaluation:
        if (execution_modes &&
            1 < std::count_if(execution_modes->begin(), execution_modes->end(),
                              [](const SpvExecutionMode& mode) {
                                switch (mode) {
                                  case SpvExecutionModeSpacingEqual:
                                  case SpvExecutionModeSpacingFractionalEven:
                                  case SpvExecutionModeSpacingFractionalOdd:
                                    return true;
                                  default:
                                    return false;
                                }
                              })) {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Tessellation execution model entry points can specify at "
                    "most one of SpacingEqual, SpacingFractionalOdd or "
                    "SpacingFractionalEven execution modes.";
        }
        if (execution_modes &&
            1 < std::count_if(execution_modes->begin(), execution_modes->end(),
                              [](const SpvExecutionMode& mode) {
                                switch (mode) {
                                  case SpvExecutionModeTriangles:
                                  case SpvExecutionModeQuads:
                                  case SpvExecutionModeIsolines:
                                    return true;
                                  default:
                                    return false;
                                }
                              })) {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Tessellation execution model entry points can specify at "
                    "most one of Triangles, Quads or Isolines execution modes.";
        }
        if (execution_modes &&
            1 < std::count_if(execution_modes->begin(), execution_modes->end(),
                              [](const SpvExecutionMode& mode) {
                                switch (mode) {
                                  case SpvExecutionModeVertexOrderCw:
                                  case SpvExecutionModeVertexOrderCcw:
                                    return true;
                                  default:
                                    return false;
                                }
                              })) {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Tessellation execution model entry points can specify at "
                    "most one of VertexOrderCw or VertexOrderCcw execution "
                    "modes.";
        }
        break;
      case SpvExecutionModelGeometry:
        if (!execution_modes ||
            1 != std::count_if(execution_modes->begin(), execution_modes->end(),
                               [](const SpvExecutionMode& mode) {
                                 switch (mode) {
                                   case SpvExecutionModeInputPoints:
                                   case SpvExecutionModeInputLines:
                                   case SpvExecutionModeInputLinesAdjacency:
                                   case SpvExecutionModeTriangles:
                                   case SpvExecutionModeInputTrianglesAdjacency:
                                     return true;
                                   default:
                                     return false;
                                 }
                               })) {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Geometry execution model entry points must specify "
                    "exactly one of InputPoints, InputLines, "
                    "InputLinesAdjacency, Triangles or InputTrianglesAdjacency "
                    "execution modes.";
        }
        if (!execution_modes ||
            1 != std::count_if(execution_modes->begin(), execution_modes->end(),
                               [](const SpvExecutionMode& mode) {
                                 switch (mode) {
                                   case SpvExecutionModeOutputPoints:
                                   case SpvExecutionModeOutputLineStrip:
                                   case SpvExecutionModeOutputTriangleStrip:
                                     return true;
                                   default:
                                     return false;
                                 }
                               })) {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Geometry execution model entry points must specify "
                    "exactly one of OutputPoints, OutputLineStrip or "
                    "OutputTriangleStrip execution modes.";
        }
        break;
      default:
        break;
    }
  }

  if (spvIsVulkanEnv(_.context()->target_env)) {
    switch (execution_model) {
      case SpvExecutionModelGLCompute:
        if (!execution_modes ||
            !execution_modes->count(SpvExecutionModeLocalSize)) {
          bool ok = false;
          for (auto& i : _.ordered_instructions()) {
            if (i.opcode() == SpvOpDecorate) {
              if (i.operands().size() > 2) {
                if (i.GetOperandAs<SpvDecoration>(1) == SpvDecorationBuiltIn &&
                    i.GetOperandAs<SpvBuiltIn>(2) == SpvBuiltInWorkgroupSize) {
                  ok = true;
                  break;
                }
              }
            }
          }
          if (!ok) {
            return _.diag(SPV_ERROR_INVALID_DATA, inst)
                   << _.VkErrorID(4683)
                   << "In the Vulkan environment, GLCompute execution model "
                      "entry points require either the LocalSize execution "
                      "mode or an object decorated with WorkgroupSize must be "
                      "specified.";
          }
        }
        break;
      default:
        break;
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateExecutionMode(ValidationState_t& _,
                                   const Instruction* inst) {
  const auto entry_point_id = inst->GetOperandAs<uint32_t>(0);
  const auto found = std::find(_.entry_points().cbegin(),
                               _.entry_points().cend(), entry_point_id);
  if (found == _.entry_points().cend()) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "OpExecutionMode Entry Point <id> '"
           << _.getIdName(entry_point_id)
           << "' is not the Entry Point "
              "operand of an OpEntryPoint.";
  }

  const auto mode = inst->GetOperandAs<SpvExecutionMode>(1);
  if (inst->opcode() == SpvOpExecutionModeId) {
    size_t operand_count = inst->operands().size();
    for (size_t i = 2; i < operand_count; ++i) {
      const auto operand_id = inst->GetOperandAs<uint32_t>(2);
      const auto* operand_inst = _.FindDef(operand_id);
      if (mode == SpvExecutionModeSubgroupsPerWorkgroupId ||
          mode == SpvExecutionModeLocalSizeHintId ||
          mode == SpvExecutionModeLocalSizeId) {
        if (!spvOpcodeIsConstant(operand_inst->opcode())) {
          return _.diag(SPV_ERROR_INVALID_ID, inst)
                 << "For OpExecutionModeId all Extra Operand ids must be "
                    "constant "
                    "instructions.";
        }
      } else {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "OpExecutionModeId is only valid when the Mode operand is an "
                  "execution mode that takes Extra Operands that are id "
                  "operands.";
      }
    }
  } else if (mode == SpvExecutionModeSubgroupsPerWorkgroupId ||
             mode == SpvExecutionModeLocalSizeHintId ||
             mode == SpvExecutionModeLocalSizeId) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "OpExecutionMode is only valid when the Mode operand is an "
              "execution mode that takes no Extra Operands, or takes Extra "
              "Operands that are not id operands.";
  }

  const auto* models = _.GetExecutionModels(entry_point_id);
  switch (mode) {
    case SpvExecutionModeInvocations:
    case SpvExecutionModeInputPoints:
    case SpvExecutionModeInputLines:
    case SpvExecutionModeInputLinesAdjacency:
    case SpvExecutionModeInputTrianglesAdjacency:
    case SpvExecutionModeOutputLineStrip:
    case SpvExecutionModeOutputTriangleStrip:
      if (!std::all_of(models->begin(), models->end(),
                       [](const SpvExecutionModel& model) {
                         return model == SpvExecutionModelGeometry;
                       })) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "Execution mode can only be used with the Geometry execution "
                  "model.";
      }
      break;
    case SpvExecutionModeOutputPoints:
      if (!std::all_of(models->begin(), models->end(),
                       [&_](const SpvExecutionModel& model) {
                         switch (model) {
                           case SpvExecutionModelGeometry:
                             return true;
                           case SpvExecutionModelMeshNV:
                             return _.HasCapability(SpvCapabilityMeshShadingNV);
                           default:
                             return false;
                         }
                       })) {
        if (_.HasCapability(SpvCapabilityMeshShadingNV)) {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Execution mode can only be used with the Geometry or "
                    "MeshNV execution model.";
        } else {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Execution mode can only be used with the Geometry "
                    "execution "
                    "model.";
        }
      }
      break;
    case SpvExecutionModeSpacingEqual:
    case SpvExecutionModeSpacingFractionalEven:
    case SpvExecutionModeSpacingFractionalOdd:
    case SpvExecutionModeVertexOrderCw:
    case SpvExecutionModeVertexOrderCcw:
    case SpvExecutionModePointMode:
    case SpvExecutionModeQuads:
    case SpvExecutionModeIsolines:
      if (!std::all_of(
              models->begin(), models->end(),
              [](const SpvExecutionModel& model) {
                return (model == SpvExecutionModelTessellationControl) ||
                       (model == SpvExecutionModelTessellationEvaluation);
              })) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "Execution mode can only be used with a tessellation "
                  "execution model.";
      }
      break;
    case SpvExecutionModeTriangles:
      if (!std::all_of(models->begin(), models->end(),
                       [](const SpvExecutionModel& model) {
                         switch (model) {
                           case SpvExecutionModelGeometry:
                           case SpvExecutionModelTessellationControl:
                           case SpvExecutionModelTessellationEvaluation:
                             return true;
                           default:
                             return false;
                         }
                       })) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "Execution mode can only be used with a Geometry or "
                  "tessellation execution model.";
      }
      break;
    case SpvExecutionModeOutputVertices:
      if (!std::all_of(models->begin(), models->end(),
                       [&_](const SpvExecutionModel& model) {
                         switch (model) {
                           case SpvExecutionModelGeometry:
                           case SpvExecutionModelTessellationControl:
                           case SpvExecutionModelTessellationEvaluation:
                             return true;
                           case SpvExecutionModelMeshNV:
                             return _.HasCapability(SpvCapabilityMeshShadingNV);
                           default:
                             return false;
                         }
                       })) {
        if (_.HasCapability(SpvCapabilityMeshShadingNV)) {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Execution mode can only be used with a Geometry, "
                    "tessellation or MeshNV execution model.";
        } else {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Execution mode can only be used with a Geometry or "
                    "tessellation execution model.";
        }
      }
      break;
    case SpvExecutionModePixelCenterInteger:
    case SpvExecutionModeOriginUpperLeft:
    case SpvExecutionModeOriginLowerLeft:
    case SpvExecutionModeEarlyFragmentTests:
    case SpvExecutionModeDepthReplacing:
    case SpvExecutionModeDepthGreater:
    case SpvExecutionModeDepthLess:
    case SpvExecutionModeDepthUnchanged:
    case SpvExecutionModePixelInterlockOrderedEXT:
    case SpvExecutionModePixelInterlockUnorderedEXT:
    case SpvExecutionModeSampleInterlockOrderedEXT:
    case SpvExecutionModeSampleInterlockUnorderedEXT:
    case SpvExecutionModeShadingRateInterlockOrderedEXT:
    case SpvExecutionModeShadingRateInterlockUnorderedEXT:
      if (!std::all_of(models->begin(), models->end(),
                       [](const SpvExecutionModel& model) {
                         return model == SpvExecutionModelFragment;
                       })) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "Execution mode can only be used with the Fragment execution "
                  "model.";
      }
      break;
    case SpvExecutionModeLocalSizeHint:
    case SpvExecutionModeVecTypeHint:
    case SpvExecutionModeContractionOff:
    case SpvExecutionModeLocalSizeHintId:
      if (!std::all_of(models->begin(), models->end(),
                       [](const SpvExecutionModel& model) {
                         return model == SpvExecutionModelKernel;
                       })) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "Execution mode can only be used with the Kernel execution "
                  "model.";
      }
      break;
    case SpvExecutionModeLocalSize:
    case SpvExecutionModeLocalSizeId:
      if (!std::all_of(models->begin(), models->end(),
                       [&_](const SpvExecutionModel& model) {
                         switch (model) {
                           case SpvExecutionModelKernel:
                           case SpvExecutionModelGLCompute:
                             return true;
                           case SpvExecutionModelTaskNV:
                           case SpvExecutionModelMeshNV:
                             return _.HasCapability(SpvCapabilityMeshShadingNV);
                           default:
                             return false;
                         }
                       })) {
        if (_.HasCapability(SpvCapabilityMeshShadingNV)) {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Execution mode can only be used with a Kernel, GLCompute, "
                    "MeshNV, or TaskNV execution model.";
        } else {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << "Execution mode can only be used with a Kernel or "
                    "GLCompute "
                    "execution model.";
        }
      }
    default:
      break;
  }

  if (spvIsVulkanEnv(_.context()->target_env)) {
    if (mode == SpvExecutionModeOriginLowerLeft) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << _.VkErrorID(4653)
             << "In the Vulkan environment, the OriginLowerLeft execution mode "
                "must not be used.";
    }
    if (mode == SpvExecutionModePixelCenterInteger) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << _.VkErrorID(4654)
             << "In the Vulkan environment, the PixelCenterInteger execution "
                "mode must not be used.";
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateMemoryModel(ValidationState_t& _,
                                 const Instruction* inst) {
  // Already produced an error if multiple memory model instructions are
  // present.
  if (_.memory_model() != SpvMemoryModelVulkanKHR &&
      _.HasCapability(SpvCapabilityVulkanMemoryModelKHR)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "VulkanMemoryModelKHR capability must only be specified if "
              "the VulkanKHR memory model is used.";
  }

  if (spvIsOpenCLEnv(_.context()->target_env)) {
    if ((_.addressing_model() != SpvAddressingModelPhysical32) &&
        (_.addressing_model() != SpvAddressingModelPhysical64)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Addressing model must be Physical32 or Physical64 "
             << "in the OpenCL environment.";
    }
    if (_.memory_model() != SpvMemoryModelOpenCL) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Memory model must be OpenCL in the OpenCL environment.";
    }
  }

  if (spvIsVulkanEnv(_.context()->target_env)) {
    if ((_.addressing_model() != SpvAddressingModelLogical) &&
        (_.addressing_model() != SpvAddressingModelPhysicalStorageBuffer64)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << _.VkErrorID(4635)
             << "Addressing model must be Logical or PhysicalStorageBuffer64 "
             << "in the Vulkan environment.";
    }
  }
  return SPV_SUCCESS;
}

}  // namespace

spv_result_t ModeSettingPass(ValidationState_t& _, const Instruction* inst) {
  switch (inst->opcode()) {
    case SpvOpEntryPoint:
      if (auto error = ValidateEntryPoint(_, inst)) return error;
      break;
    case SpvOpExecutionMode:
    case SpvOpExecutionModeId:
      if (auto error = ValidateExecutionMode(_, inst)) return error;
      break;
    case SpvOpMemoryModel:
      if (auto error = ValidateMemoryModel(_, inst)) return error;
      break;
    default:
      break;
  }
  return SPV_SUCCESS;
}

}  // namespace val
}  // namespace spvtools
