// Copyright (c) 2017 Google Inc.
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights
// reserved.
//
// 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.

// Validates correctness of image instructions.

#include <string>

#include "source/diagnostic.h"
#include "source/opcode.h"
#include "source/spirv_target_env.h"
#include "source/util/bitutils.h"
#include "source/val/instruction.h"
#include "source/val/validate.h"
#include "source/val/validate_scopes.h"
#include "source/val/validation_state.h"

namespace spvtools {
namespace val {
namespace {

// Performs compile time check that all SpvImageOperandsXXX cases are handled in
// this module. If SpvImageOperandsXXX list changes, this function will fail the
// build.
// For all other purposes this is a placeholder function.
bool CheckAllImageOperandsHandled() {
  SpvImageOperandsMask enum_val = SpvImageOperandsBiasMask;

  // Some improvised code to prevent the compiler from considering enum_val
  // constant and optimizing the switch away.
  uint32_t stack_var = 0;
  if (reinterpret_cast<uintptr_t>(&stack_var) % 256)
    enum_val = SpvImageOperandsLodMask;

  switch (enum_val) {
    // Please update the validation rules in this module if you are changing
    // the list of image operands, and add new enum values to this switch.
    case SpvImageOperandsMaskNone:
      return false;
    case SpvImageOperandsBiasMask:
    case SpvImageOperandsLodMask:
    case SpvImageOperandsGradMask:
    case SpvImageOperandsConstOffsetMask:
    case SpvImageOperandsOffsetMask:
    case SpvImageOperandsConstOffsetsMask:
    case SpvImageOperandsSampleMask:
    case SpvImageOperandsMinLodMask:

    // TODO(dneto): Support image operands related to the Vulkan memory model.
    // https://gitlab.khronos.org/spirv/spirv-tools/issues/32
    case SpvImageOperandsMakeTexelAvailableKHRMask:
    case SpvImageOperandsMakeTexelVisibleKHRMask:
    case SpvImageOperandsNonPrivateTexelKHRMask:
    case SpvImageOperandsVolatileTexelKHRMask:
    case SpvImageOperandsSignExtendMask:
    case SpvImageOperandsZeroExtendMask:
      return true;
  }
  return false;
}

// Used by GetImageTypeInfo. See OpTypeImage spec for more information.
struct ImageTypeInfo {
  uint32_t sampled_type = 0;
  SpvDim dim = SpvDimMax;
  uint32_t depth = 0;
  uint32_t arrayed = 0;
  uint32_t multisampled = 0;
  uint32_t sampled = 0;
  SpvImageFormat format = SpvImageFormatMax;
  SpvAccessQualifier access_qualifier = SpvAccessQualifierMax;
};

// Provides information on image type. |id| should be object of either
// OpTypeImage or OpTypeSampledImage type. Returns false in case of failure
// (not a valid id, failed to parse the instruction, etc).
bool GetImageTypeInfo(const ValidationState_t& _, uint32_t id,
                      ImageTypeInfo* info) {
  if (!id || !info) return false;

  const Instruction* inst = _.FindDef(id);
  assert(inst);

  if (inst->opcode() == SpvOpTypeSampledImage) {
    inst = _.FindDef(inst->word(2));
    assert(inst);
  }

  if (inst->opcode() != SpvOpTypeImage) return false;

  const size_t num_words = inst->words().size();
  if (num_words != 9 && num_words != 10) return false;

  info->sampled_type = inst->word(2);
  info->dim = static_cast<SpvDim>(inst->word(3));
  info->depth = inst->word(4);
  info->arrayed = inst->word(5);
  info->multisampled = inst->word(6);
  info->sampled = inst->word(7);
  info->format = static_cast<SpvImageFormat>(inst->word(8));
  info->access_qualifier = num_words < 10
                               ? SpvAccessQualifierMax
                               : static_cast<SpvAccessQualifier>(inst->word(9));
  return true;
}

bool IsImplicitLod(SpvOp opcode) {
  switch (opcode) {
    case SpvOpImageSampleImplicitLod:
    case SpvOpImageSampleDrefImplicitLod:
    case SpvOpImageSampleProjImplicitLod:
    case SpvOpImageSampleProjDrefImplicitLod:
    case SpvOpImageSparseSampleImplicitLod:
    case SpvOpImageSparseSampleDrefImplicitLod:
    case SpvOpImageSparseSampleProjImplicitLod:
    case SpvOpImageSparseSampleProjDrefImplicitLod:
      return true;
    default:
      break;
  }
  return false;
}

bool IsExplicitLod(SpvOp opcode) {
  switch (opcode) {
    case SpvOpImageSampleExplicitLod:
    case SpvOpImageSampleDrefExplicitLod:
    case SpvOpImageSampleProjExplicitLod:
    case SpvOpImageSampleProjDrefExplicitLod:
    case SpvOpImageSparseSampleExplicitLod:
    case SpvOpImageSparseSampleDrefExplicitLod:
    case SpvOpImageSparseSampleProjExplicitLod:
    case SpvOpImageSparseSampleProjDrefExplicitLod:
      return true;
    default:
      break;
  }
  return false;
}

bool IsValidLodOperand(const ValidationState_t& _, SpvOp opcode) {
  switch (opcode) {
    case SpvOpImageRead:
    case SpvOpImageWrite:
    case SpvOpImageSparseRead:
      return _.HasCapability(SpvCapabilityImageReadWriteLodAMD);
    default:
      return IsExplicitLod(opcode);
  }
}

bool IsValidGatherLodBiasAMD(const ValidationState_t& _, SpvOp opcode) {
  switch (opcode) {
    case SpvOpImageGather:
    case SpvOpImageSparseGather:
      return _.HasCapability(SpvCapabilityImageGatherBiasLodAMD);
    default:
      break;
  }
  return false;
}

// Returns true if the opcode is a Image instruction which applies
// homogenous projection to the coordinates.
bool IsProj(SpvOp opcode) {
  switch (opcode) {
    case SpvOpImageSampleProjImplicitLod:
    case SpvOpImageSampleProjDrefImplicitLod:
    case SpvOpImageSparseSampleProjImplicitLod:
    case SpvOpImageSparseSampleProjDrefImplicitLod:
    case SpvOpImageSampleProjExplicitLod:
    case SpvOpImageSampleProjDrefExplicitLod:
    case SpvOpImageSparseSampleProjExplicitLod:
    case SpvOpImageSparseSampleProjDrefExplicitLod:
      return true;
    default:
      break;
  }
  return false;
}

// Returns the number of components in a coordinate used to access a texel in
// a single plane of an image with the given parameters.
uint32_t GetPlaneCoordSize(const ImageTypeInfo& info) {
  uint32_t plane_size = 0;
  // If this switch breaks your build, please add new values below.
  switch (info.dim) {
    case SpvDim1D:
    case SpvDimBuffer:
      plane_size = 1;
      break;
    case SpvDim2D:
    case SpvDimRect:
    case SpvDimSubpassData:
      plane_size = 2;
      break;
    case SpvDim3D:
    case SpvDimCube:
      // For Cube direction vector is used instead of UV.
      plane_size = 3;
      break;
    case SpvDimMax:
      assert(0);
      break;
  }

  return plane_size;
}

// Returns minimal number of coordinates based on image dim, arrayed and whether
// the instruction uses projection coordinates.
uint32_t GetMinCoordSize(SpvOp opcode, const ImageTypeInfo& info) {
  if (info.dim == SpvDimCube &&
      (opcode == SpvOpImageRead || opcode == SpvOpImageWrite ||
       opcode == SpvOpImageSparseRead)) {
    // These opcodes use UV for Cube, not direction vector.
    return 3;
  }

  return GetPlaneCoordSize(info) + info.arrayed + (IsProj(opcode) ? 1 : 0);
}

// Checks ImageOperand bitfield and respective operands.
// word_index is the index of the first word after the image-operand mask word.
spv_result_t ValidateImageOperands(ValidationState_t& _,
                                   const Instruction* inst,
                                   const ImageTypeInfo& info,
                                   uint32_t word_index) {
  static const bool kAllImageOperandsHandled = CheckAllImageOperandsHandled();
  (void)kAllImageOperandsHandled;

  const SpvOp opcode = inst->opcode();
  const size_t num_words = inst->words().size();

  const bool have_explicit_mask = (word_index - 1 < num_words);
  const uint32_t mask = have_explicit_mask ? inst->word(word_index - 1) : 0u;

  if (have_explicit_mask) {
    // NonPrivate, Volatile, SignExtend, ZeroExtend take no operand words.
    const uint32_t mask_bits_having_operands =
        mask & ~uint32_t(SpvImageOperandsNonPrivateTexelKHRMask |
                         SpvImageOperandsVolatileTexelKHRMask |
                         SpvImageOperandsSignExtendMask |
                         SpvImageOperandsZeroExtendMask);
    size_t expected_num_image_operand_words =
        spvtools::utils::CountSetBits(mask_bits_having_operands);
    if (mask & SpvImageOperandsGradMask) {
      // Grad uses two words.
      ++expected_num_image_operand_words;
    }

    if (expected_num_image_operand_words != num_words - word_index) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Number of image operand ids doesn't correspond to the bit "
                "mask";
    }
  } else if (num_words != word_index - 1) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Number of image operand ids doesn't correspond to the bit mask";
  }

  if (info.multisampled & (0 == (mask & SpvImageOperandsSampleMask))) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Image Operand Sample is required for operation on "
              "multi-sampled image";
  }

  // After this point, only set bits in the image operands mask can cause
  // the module to be invalid.
  if (mask == 0) return SPV_SUCCESS;

  if (spvtools::utils::CountSetBits(
          mask & (SpvImageOperandsOffsetMask | SpvImageOperandsConstOffsetMask |
                  SpvImageOperandsConstOffsetsMask)) > 1) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << _.VkErrorID(4662)
           << "Image Operands Offset, ConstOffset, ConstOffsets cannot be used "
           << "together";
  }

  const bool is_implicit_lod = IsImplicitLod(opcode);
  const bool is_explicit_lod = IsExplicitLod(opcode);
  const bool is_valid_lod_operand = IsValidLodOperand(_, opcode);
  const bool is_valid_gather_lod_bias_amd = IsValidGatherLodBiasAMD(_, opcode);

  // The checks should be done in the order of definition of OperandImage.

  if (mask & SpvImageOperandsBiasMask) {
    if (!is_implicit_lod && !is_valid_gather_lod_bias_amd) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand Bias can only be used with ImplicitLod opcodes";
    }

    const uint32_t type_id = _.GetTypeId(inst->word(word_index++));
    if (!_.IsFloatScalarType(type_id)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image Operand Bias to be float scalar";
    }

    if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D &&
        info.dim != SpvDimCube) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand Bias requires 'Dim' parameter to be 1D, 2D, 3D "
                "or Cube";
    }

    // Multisampled is already checked.
  }

  if (mask & SpvImageOperandsLodMask) {
    if (!is_valid_lod_operand && opcode != SpvOpImageFetch &&
        opcode != SpvOpImageSparseFetch && !is_valid_gather_lod_bias_amd) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand Lod can only be used with ExplicitLod opcodes "
             << "and OpImageFetch";
    }

    if (mask & SpvImageOperandsGradMask) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand bits Lod and Grad cannot be set at the same "
                "time";
    }

    const uint32_t type_id = _.GetTypeId(inst->word(word_index++));
    if (is_explicit_lod || is_valid_gather_lod_bias_amd) {
      if (!_.IsFloatScalarType(type_id)) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "Expected Image Operand Lod to be float scalar when used "
               << "with ExplicitLod";
      }
    } else {
      if (!_.IsIntScalarType(type_id)) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "Expected Image Operand Lod to be int scalar when used with "
               << "OpImageFetch";
      }
    }

    if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D &&
        info.dim != SpvDimCube) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand Lod requires 'Dim' parameter to be 1D, 2D, 3D "
                "or Cube";
    }

    // Multisampled is already checked.
  }

  if (mask & SpvImageOperandsGradMask) {
    if (!is_explicit_lod) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand Grad can only be used with ExplicitLod opcodes";
    }

    const uint32_t dx_type_id = _.GetTypeId(inst->word(word_index++));
    const uint32_t dy_type_id = _.GetTypeId(inst->word(word_index++));
    if (!_.IsFloatScalarOrVectorType(dx_type_id) ||
        !_.IsFloatScalarOrVectorType(dy_type_id)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected both Image Operand Grad ids to be float scalars or "
             << "vectors";
    }

    const uint32_t plane_size = GetPlaneCoordSize(info);
    const uint32_t dx_size = _.GetDimension(dx_type_id);
    const uint32_t dy_size = _.GetDimension(dy_type_id);
    if (plane_size != dx_size) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image Operand Grad dx to have " << plane_size
             << " components, but given " << dx_size;
    }

    if (plane_size != dy_size) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image Operand Grad dy to have " << plane_size
             << " components, but given " << dy_size;
    }

    // Multisampled is already checked.
  }

  if (mask & SpvImageOperandsConstOffsetMask) {
    if (info.dim == SpvDimCube) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand ConstOffset cannot be used with Cube Image "
                "'Dim'";
    }

    const uint32_t id = inst->word(word_index++);
    const uint32_t type_id = _.GetTypeId(id);
    if (!_.IsIntScalarOrVectorType(type_id)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image Operand ConstOffset to be int scalar or "
             << "vector";
    }

    if (!spvOpcodeIsConstant(_.GetIdOpcode(id))) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image Operand ConstOffset to be a const object";
    }

    const uint32_t plane_size = GetPlaneCoordSize(info);
    const uint32_t offset_size = _.GetDimension(type_id);
    if (plane_size != offset_size) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image Operand ConstOffset to have " << plane_size
             << " components, but given " << offset_size;
    }
  }

  if (mask & SpvImageOperandsOffsetMask) {
    if (info.dim == SpvDimCube) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand Offset cannot be used with Cube Image 'Dim'";
    }

    const uint32_t id = inst->word(word_index++);
    const uint32_t type_id = _.GetTypeId(id);
    if (!_.IsIntScalarOrVectorType(type_id)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image Operand Offset to be int scalar or "
             << "vector";
    }

    const uint32_t plane_size = GetPlaneCoordSize(info);
    const uint32_t offset_size = _.GetDimension(type_id);
    if (plane_size != offset_size) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image Operand Offset to have " << plane_size
             << " components, but given " << offset_size;
    }
  }

  if (mask & SpvImageOperandsConstOffsetsMask) {
    if (opcode != SpvOpImageGather && opcode != SpvOpImageDrefGather &&
        opcode != SpvOpImageSparseGather &&
        opcode != SpvOpImageSparseDrefGather) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand ConstOffsets can only be used with "
                "OpImageGather and OpImageDrefGather";
    }

    if (info.dim == SpvDimCube) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand ConstOffsets cannot be used with Cube Image "
                "'Dim'";
    }

    const uint32_t id = inst->word(word_index++);
    const uint32_t type_id = _.GetTypeId(id);
    const Instruction* type_inst = _.FindDef(type_id);
    assert(type_inst);

    if (type_inst->opcode() != SpvOpTypeArray) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image Operand ConstOffsets to be an array of size 4";
    }

    uint64_t array_size = 0;
    if (!_.GetConstantValUint64(type_inst->word(3), &array_size)) {
      assert(0 && "Array type definition is corrupt");
    }

    if (array_size != 4) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image Operand ConstOffsets to be an array of size 4";
    }

    const uint32_t component_type = type_inst->word(2);
    if (!_.IsIntVectorType(component_type) ||
        _.GetDimension(component_type) != 2) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image Operand ConstOffsets array componenets to be "
                "int vectors of size 2";
    }

    if (!spvOpcodeIsConstant(_.GetIdOpcode(id))) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image Operand ConstOffsets to be a const object";
    }
  }

  if (mask & SpvImageOperandsSampleMask) {
    if (opcode != SpvOpImageFetch && opcode != SpvOpImageRead &&
        opcode != SpvOpImageWrite && opcode != SpvOpImageSparseFetch &&
        opcode != SpvOpImageSparseRead) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand Sample can only be used with OpImageFetch, "
             << "OpImageRead, OpImageWrite, OpImageSparseFetch and "
             << "OpImageSparseRead";
    }

    if (info.multisampled == 0) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand Sample requires non-zero 'MS' parameter";
    }

    const uint32_t type_id = _.GetTypeId(inst->word(word_index++));
    if (!_.IsIntScalarType(type_id)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image Operand Sample to be int scalar";
    }
  }

  if (mask & SpvImageOperandsMinLodMask) {
    if (!is_implicit_lod && !(mask & SpvImageOperandsGradMask)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand MinLod can only be used with ImplicitLod "
             << "opcodes or together with Image Operand Grad";
    }

    const uint32_t type_id = _.GetTypeId(inst->word(word_index++));
    if (!_.IsFloatScalarType(type_id)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image Operand MinLod to be float scalar";
    }

    if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D &&
        info.dim != SpvDimCube) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand MinLod requires 'Dim' parameter to be 1D, 2D, "
                "3D or Cube";
    }

    if (info.multisampled != 0) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand MinLod requires 'MS' parameter to be 0";
    }
  }

  if (mask & SpvImageOperandsMakeTexelAvailableKHRMask) {
    // Checked elsewhere: capability and memory model are correct.
    if (opcode != SpvOpImageWrite) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand MakeTexelAvailableKHR can only be used with Op"
             << spvOpcodeString(SpvOpImageWrite) << ": Op"
             << spvOpcodeString(opcode);
    }

    if (!(mask & SpvImageOperandsNonPrivateTexelKHRMask)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand MakeTexelAvailableKHR requires "
                "NonPrivateTexelKHR is also specified: Op"
             << spvOpcodeString(opcode);
    }

    const auto available_scope = inst->word(word_index++);
    if (auto error = ValidateMemoryScope(_, inst, available_scope))
      return error;
  }

  if (mask & SpvImageOperandsMakeTexelVisibleKHRMask) {
    // Checked elsewhere: capability and memory model are correct.
    if (opcode != SpvOpImageRead && opcode != SpvOpImageSparseRead) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand MakeTexelVisibleKHR can only be used with Op"
             << spvOpcodeString(SpvOpImageRead) << " or Op"
             << spvOpcodeString(SpvOpImageSparseRead) << ": Op"
             << spvOpcodeString(opcode);
    }

    if (!(mask & SpvImageOperandsNonPrivateTexelKHRMask)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand MakeTexelVisibleKHR requires NonPrivateTexelKHR "
                "is also specified: Op"
             << spvOpcodeString(opcode);
    }

    const auto visible_scope = inst->word(word_index++);
    if (auto error = ValidateMemoryScope(_, inst, visible_scope)) return error;
  }

  if (mask & SpvImageOperandsSignExtendMask) {
    // Checked elsewhere: SPIR-V 1.4 version or later.

    // "The texel value is converted to the target value via sign extension.
    // Only valid when the texel type is a scalar or vector of integer type."
    //
    // We don't have enough information to know what the texel type is.
    // In OpenCL, knowledge is deferred until runtime: the image SampledType is
    // void, and the Format is Unknown.
    // In Vulkan, the texel type is only known in all cases by the pipeline
    // setup.
  }

  if (mask & SpvImageOperandsZeroExtendMask) {
    // Checked elsewhere: SPIR-V 1.4 version or later.

    // "The texel value is converted to the target value via zero extension.
    // Only valid when the texel type is a scalar or vector of integer type."
    //
    // We don't have enough information to know what the texel type is.
    // In OpenCL, knowledge is deferred until runtime: the image SampledType is
    // void, and the Format is Unknown.
    // In Vulkan, the texel type is only known in all cases by the pipeline
    // setup.
  }

  return SPV_SUCCESS;
}

// Checks some of the validation rules which are common to multiple opcodes.
spv_result_t ValidateImageCommon(ValidationState_t& _, const Instruction* inst,
                                 const ImageTypeInfo& info) {
  const SpvOp opcode = inst->opcode();
  if (IsProj(opcode)) {
    if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D &&
        info.dim != SpvDimRect) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image 'Dim' parameter to be 1D, 2D, 3D or Rect";
    }

    if (info.multisampled != 0) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image 'MS' parameter to be 0";
    }

    if (info.arrayed != 0) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image 'arrayed' parameter to be 0";
    }
  }

  if (opcode == SpvOpImageRead || opcode == SpvOpImageSparseRead ||
      opcode == SpvOpImageWrite) {
    if (info.sampled == 0) {
    } else if (info.sampled == 2) {
      if (info.dim == SpvDim1D && !_.HasCapability(SpvCapabilityImage1D)) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "Capability Image1D is required to access storage image";
      } else if (info.dim == SpvDimRect &&
                 !_.HasCapability(SpvCapabilityImageRect)) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "Capability ImageRect is required to access storage image";
      } else if (info.dim == SpvDimBuffer &&
                 !_.HasCapability(SpvCapabilityImageBuffer)) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "Capability ImageBuffer is required to access storage image";
      } else if (info.dim == SpvDimCube && info.arrayed == 1 &&
                 !_.HasCapability(SpvCapabilityImageCubeArray)) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "Capability ImageCubeArray is required to access "
               << "storage image";
      }

      if (info.multisampled == 1 &&
          !_.HasCapability(SpvCapabilityImageMSArray)) {
#if 0
        // TODO(atgoo@github.com) The description of this rule in the spec
        // is unclear and Glslang doesn't declare ImageMSArray. Need to clarify
        // and reenable.
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
            << "Capability ImageMSArray is required to access storage "
            << "image";
#endif
      }
    } else {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image 'Sampled' parameter to be 0 or 2";
    }
  }

  return SPV_SUCCESS;
}

// Returns true if opcode is *ImageSparse*, false otherwise.
bool IsSparse(SpvOp opcode) {
  switch (opcode) {
    case SpvOpImageSparseSampleImplicitLod:
    case SpvOpImageSparseSampleExplicitLod:
    case SpvOpImageSparseSampleDrefImplicitLod:
    case SpvOpImageSparseSampleDrefExplicitLod:
    case SpvOpImageSparseSampleProjImplicitLod:
    case SpvOpImageSparseSampleProjExplicitLod:
    case SpvOpImageSparseSampleProjDrefImplicitLod:
    case SpvOpImageSparseSampleProjDrefExplicitLod:
    case SpvOpImageSparseFetch:
    case SpvOpImageSparseGather:
    case SpvOpImageSparseDrefGather:
    case SpvOpImageSparseTexelsResident:
    case SpvOpImageSparseRead: {
      return true;
    }

    default: { return false; }
  }

  return false;
}

// Checks sparse image opcode result type and returns the second struct member.
// Returns inst.type_id for non-sparse image opcodes.
// Not valid for sparse image opcodes which do not return a struct.
spv_result_t GetActualResultType(ValidationState_t& _, const Instruction* inst,
                                 uint32_t* actual_result_type) {
  const SpvOp opcode = inst->opcode();

  if (IsSparse(opcode)) {
    const Instruction* const type_inst = _.FindDef(inst->type_id());
    assert(type_inst);

    if (!type_inst || type_inst->opcode() != SpvOpTypeStruct) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Result Type to be OpTypeStruct";
    }

    if (type_inst->words().size() != 4 ||
        !_.IsIntScalarType(type_inst->word(2))) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Result Type to be a struct containing an int "
                "scalar and a texel";
    }

    *actual_result_type = type_inst->word(3);
  } else {
    *actual_result_type = inst->type_id();
  }

  return SPV_SUCCESS;
}

// Returns a string describing actual result type of an opcode.
// Not valid for sparse image opcodes which do not return a struct.
const char* GetActualResultTypeStr(SpvOp opcode) {
  if (IsSparse(opcode)) return "Result Type's second member";
  return "Result Type";
}

spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
  assert(inst->type_id() == 0);

  ImageTypeInfo info;
  if (!GetImageTypeInfo(_, inst->word(1), &info)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Corrupt image type definition";
  }

  if (_.IsIntScalarType(info.sampled_type) &&
      (64 == _.GetBitWidth(info.sampled_type)) &&
      !_.HasCapability(SpvCapabilityInt64ImageEXT)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Capability Int64ImageEXT is required when using Sampled Type of "
              "64-bit int";
  }

  const auto target_env = _.context()->target_env;
  if (spvIsVulkanEnv(target_env)) {
    if ((!_.IsFloatScalarType(info.sampled_type) &&
         !_.IsIntScalarType(info.sampled_type)) ||
        ((32 != _.GetBitWidth(info.sampled_type)) &&
         (64 != _.GetBitWidth(info.sampled_type))) ||
        ((64 == _.GetBitWidth(info.sampled_type)) &&
         _.IsFloatScalarType(info.sampled_type))) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << _.VkErrorID(4656)
             << "Expected Sampled Type to be a 32-bit int, 64-bit int or "
                "32-bit float scalar type for Vulkan environment";
    }
  } else if (spvIsOpenCLEnv(target_env)) {
    if (!_.IsVoidType(info.sampled_type)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Sampled Type must be OpTypeVoid in the OpenCL environment.";
    }
  } else {
    const SpvOp sampled_type_opcode = _.GetIdOpcode(info.sampled_type);
    if (sampled_type_opcode != SpvOpTypeVoid &&
        sampled_type_opcode != SpvOpTypeInt &&
        sampled_type_opcode != SpvOpTypeFloat) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Sampled Type to be either void or"
             << " numerical scalar type";
    }
  }

  // Dim is checked elsewhere.

  if (info.depth > 2) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Invalid Depth " << info.depth << " (must be 0, 1 or 2)";
  }

  if (info.arrayed > 1) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Invalid Arrayed " << info.arrayed << " (must be 0 or 1)";
  }

  if (spvIsOpenCLEnv(target_env)) {
    if ((info.arrayed == 1) && (info.dim != SpvDim1D) &&
        (info.dim != SpvDim2D)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "In the OpenCL environment, Arrayed may only be set to 1 "
             << "when Dim is either 1D or 2D.";
    }
  }

  if (info.multisampled > 1) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Invalid MS " << info.multisampled << " (must be 0 or 1)";
  }

  if (spvIsOpenCLEnv(target_env)) {
    if (info.multisampled != 0) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "MS must be 0 in the OpenCL environment.";
    }
  }

  if (info.sampled > 2) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Invalid Sampled " << info.sampled << " (must be 0, 1 or 2)";
  }

  if (spvIsVulkanEnv(target_env)) {
    if (info.sampled == 0) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << _.VkErrorID(4657)
             << "Sampled must be 1 or 2 in the Vulkan environment.";
    }
  }

  if (spvIsOpenCLEnv(_.context()->target_env)) {
    if (info.sampled != 0) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Sampled must be 0 in the OpenCL environment.";
    }
  }

  if (info.dim == SpvDimSubpassData) {
    if (info.sampled != 2) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Dim SubpassData requires Sampled to be 2";
    }

    if (info.format != SpvImageFormatUnknown) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Dim SubpassData requires format Unknown";
    }
  }

  // Format and Access Qualifier are also checked elsewhere.

  if (spvIsOpenCLEnv(_.context()->target_env)) {
    if (info.access_qualifier == SpvAccessQualifierMax) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "In the OpenCL environment, the optional Access Qualifier"
             << " must be present.";
    }
  }

  if (info.multisampled && (info.sampled == 2) &&
      (info.dim != SpvDimSubpassData)) {
    if (!_.HasCapability(SpvCapabilityStorageImageMultisample)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Capability StorageImageMultisample is required when using "
                "multisampled storage image";
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateTypeSampledImage(ValidationState_t& _,
                                      const Instruction* inst) {
  const uint32_t image_type = inst->word(2);
  if (_.GetIdOpcode(image_type) != SpvOpTypeImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image to be of type OpTypeImage";
  }

  ImageTypeInfo info;
  if (!GetImageTypeInfo(_, image_type, &info)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Corrupt image type definition";
  }
  // OpenCL requires Sampled=0, checked elsewhere.
  // Vulkan uses the Sampled=1 case.
  if ((info.sampled != 0) && (info.sampled != 1)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Sampled image type requires an image type with \"Sampled\" "
              "operand set to 0 or 1";
  }

  return SPV_SUCCESS;
}

bool IsAllowedSampledImageOperand(SpvOp opcode) {
  switch (opcode) {
    case SpvOpSampledImage:
    case SpvOpImageSampleImplicitLod:
    case SpvOpImageSampleExplicitLod:
    case SpvOpImageSampleDrefImplicitLod:
    case SpvOpImageSampleDrefExplicitLod:
    case SpvOpImageSampleProjImplicitLod:
    case SpvOpImageSampleProjExplicitLod:
    case SpvOpImageSampleProjDrefImplicitLod:
    case SpvOpImageSampleProjDrefExplicitLod:
    case SpvOpImageGather:
    case SpvOpImageDrefGather:
    case SpvOpImage:
    case SpvOpImageQueryLod:
    case SpvOpImageSparseSampleImplicitLod:
    case SpvOpImageSparseSampleExplicitLod:
    case SpvOpImageSparseSampleDrefImplicitLod:
    case SpvOpImageSparseSampleDrefExplicitLod:
    case SpvOpImageSparseGather:
    case SpvOpImageSparseDrefGather:
    case SpvOpCopyObject:
      return true;
    default:
      return false;
  }
}

spv_result_t ValidateSampledImage(ValidationState_t& _,
                                  const Instruction* inst) {
  if (_.GetIdOpcode(inst->type_id()) != SpvOpTypeSampledImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Result Type to be OpTypeSampledImage.";
  }

  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
  if (_.GetIdOpcode(image_type) != SpvOpTypeImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image to be of type OpTypeImage.";
  }

  ImageTypeInfo info;
  if (!GetImageTypeInfo(_, image_type, &info)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Corrupt image type definition";
  }

  // TODO(atgoo@github.com) Check compatibility of result type and received
  // image.

  if (spvIsVulkanEnv(_.context()->target_env)) {
    if (info.sampled != 1) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image 'Sampled' parameter to be 1 "
             << "for Vulkan environment.";
    }
  } else {
    if (info.sampled != 0 && info.sampled != 1) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image 'Sampled' parameter to be 0 or 1";
    }
  }

  if (info.dim == SpvDimSubpassData) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image 'Dim' parameter to be not SubpassData.";
  }

  if (_.GetIdOpcode(_.GetOperandTypeId(inst, 3)) != SpvOpTypeSampler) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Sampler to be of type OpTypeSampler";
  }

  // We need to validate 2 things:
  // * All OpSampledImage instructions must be in the same block in which their
  // Result <id> are consumed.
  // * Result <id> from OpSampledImage instructions must not appear as operands
  // to OpPhi instructions or OpSelect instructions, or any instructions other
  // than the image lookup and query instructions specified to take an operand
  // whose type is OpTypeSampledImage.
  std::vector<Instruction*> consumers = _.getSampledImageConsumers(inst->id());
  if (!consumers.empty()) {
    for (auto consumer_instr : consumers) {
      const auto consumer_opcode = consumer_instr->opcode();
      if (consumer_instr->block() != inst->block()) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "All OpSampledImage instructions must be in the same block "
                  "in "
                  "which their Result <id> are consumed. OpSampledImage Result "
                  "Type <id> '"
               << _.getIdName(inst->id())
               << "' has a consumer in a different basic "
                  "block. The consumer instruction <id> is '"
               << _.getIdName(consumer_instr->id()) << "'.";
      }

      if (consumer_opcode == SpvOpPhi || consumer_opcode == SpvOpSelect) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "Result <id> from OpSampledImage instruction must not appear "
                  "as "
                  "operands of Op"
               << spvOpcodeString(static_cast<SpvOp>(consumer_opcode)) << "."
               << " Found result <id> '" << _.getIdName(inst->id())
               << "' as an operand of <id> '"
               << _.getIdName(consumer_instr->id()) << "'.";
      }

      if (!IsAllowedSampledImageOperand(consumer_opcode)) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "Result <id> from OpSampledImage instruction must not appear "
                  "as operand for Op"
               << spvOpcodeString(static_cast<SpvOp>(consumer_opcode))
               << ", since it is not specificed as taking an "
               << "OpTypeSampledImage."
               << " Found result <id> '" << _.getIdName(inst->id())
               << "' as an operand of <id> '"
               << _.getIdName(consumer_instr->id()) << "'.";
      }
    }
  }
  return SPV_SUCCESS;
}

spv_result_t ValidateImageTexelPointer(ValidationState_t& _,
                                       const Instruction* inst) {
  const auto result_type = _.FindDef(inst->type_id());
  if (result_type->opcode() != SpvOpTypePointer) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Result Type to be OpTypePointer";
  }

  const auto storage_class = result_type->GetOperandAs<uint32_t>(1);
  if (storage_class != SpvStorageClassImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Result Type to be OpTypePointer whose Storage Class "
              "operand is Image";
  }

  const auto ptr_type = result_type->GetOperandAs<uint32_t>(2);
  const auto ptr_opcode = _.GetIdOpcode(ptr_type);
  if (ptr_opcode != SpvOpTypeInt && ptr_opcode != SpvOpTypeFloat &&
      ptr_opcode != SpvOpTypeVoid) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Result Type to be OpTypePointer whose Type operand "
              "must be a scalar numerical type or OpTypeVoid";
  }

  const auto image_ptr = _.FindDef(_.GetOperandTypeId(inst, 2));
  if (!image_ptr || image_ptr->opcode() != SpvOpTypePointer) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image to be OpTypePointer";
  }

  const auto image_type = image_ptr->GetOperandAs<uint32_t>(2);
  if (_.GetIdOpcode(image_type) != SpvOpTypeImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image to be OpTypePointer with Type OpTypeImage";
  }

  ImageTypeInfo info;
  if (!GetImageTypeInfo(_, image_type, &info)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Corrupt image type definition";
  }

  if (info.sampled_type != ptr_type) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image 'Sampled Type' to be the same as the Type "
              "pointed to by Result Type";
  }

  if (info.dim == SpvDimSubpassData) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Image Dim SubpassData cannot be used with OpImageTexelPointer";
  }

  const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
  if (!coord_type || !_.IsIntScalarOrVectorType(coord_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Coordinate to be integer scalar or vector";
  }

  uint32_t expected_coord_size = 0;
  if (info.arrayed == 0) {
    expected_coord_size = GetPlaneCoordSize(info);
  } else if (info.arrayed == 1) {
    switch (info.dim) {
      case SpvDim1D:
        expected_coord_size = 2;
        break;
      case SpvDimCube:
      case SpvDim2D:
        expected_coord_size = 3;
        break;
      default:
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "Expected Image 'Dim' must be one of 1D, 2D, or Cube when "
                  "Arrayed is 1";
        break;
    }
  }

  const uint32_t actual_coord_size = _.GetDimension(coord_type);
  if (expected_coord_size != actual_coord_size) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Coordinate to have " << expected_coord_size
           << " components, but given " << actual_coord_size;
  }

  const uint32_t sample_type = _.GetOperandTypeId(inst, 4);
  if (!sample_type || !_.IsIntScalarType(sample_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Sample to be integer scalar";
  }

  if (info.multisampled == 0) {
    uint64_t ms = 0;
    if (!_.GetConstantValUint64(inst->GetOperandAs<uint32_t>(4), &ms) ||
        ms != 0) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Sample for Image with MS 0 to be a valid <id> for "
                "the value 0";
    }
  }

  if (spvIsVulkanEnv(_.context()->target_env)) {
    if ((info.format != SpvImageFormatR64i) &&
        (info.format != SpvImageFormatR64ui) &&
        (info.format != SpvImageFormatR32f) &&
        (info.format != SpvImageFormatR32i) &&
        (info.format != SpvImageFormatR32ui)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << _.VkErrorID(4658)
             << "Expected the Image Format in Image to be R64i, R64ui, R32f, "
                "R32i, or R32ui for Vulkan environment";
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) {
  const SpvOp opcode = inst->opcode();
  uint32_t actual_result_type = 0;
  if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) {
    return error;
  }

  if (!_.IsIntVectorType(actual_result_type) &&
      !_.IsFloatVectorType(actual_result_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected " << GetActualResultTypeStr(opcode)
           << " to be int or float vector type";
  }

  if (_.GetDimension(actual_result_type) != 4) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected " << GetActualResultTypeStr(opcode)
           << " to have 4 components";
  }

  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
  if (_.GetIdOpcode(image_type) != SpvOpTypeSampledImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Sampled Image to be of type OpTypeSampledImage";
  }

  ImageTypeInfo info;
  if (!GetImageTypeInfo(_, image_type, &info)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Corrupt image type definition";
  }

  if (spv_result_t result = ValidateImageCommon(_, inst, info)) return result;

  if (info.multisampled) {
    // When using image operands, the Sample image operand is required if and
    // only if the image is multisampled (MS=1). The Sample image operand is
    // only allowed for fetch, read, and write.
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Sampling operation is invalid for multisample image";
  }

  if (_.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) {
    const uint32_t texel_component_type =
        _.GetComponentType(actual_result_type);
    if (texel_component_type != info.sampled_type) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image 'Sampled Type' to be the same as "
             << GetActualResultTypeStr(opcode) << " components";
    }
  }

  const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
  if ((opcode == SpvOpImageSampleExplicitLod ||
       opcode == SpvOpImageSparseSampleExplicitLod) &&
      _.HasCapability(SpvCapabilityKernel)) {
    if (!_.IsFloatScalarOrVectorType(coord_type) &&
        !_.IsIntScalarOrVectorType(coord_type)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Coordinate to be int or float scalar or vector";
    }
  } else {
    if (!_.IsFloatScalarOrVectorType(coord_type)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Coordinate to be float scalar or vector";
    }
  }

  const uint32_t min_coord_size = GetMinCoordSize(opcode, info);
  const uint32_t actual_coord_size = _.GetDimension(coord_type);
  if (min_coord_size > actual_coord_size) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Coordinate to have at least " << min_coord_size
           << " components, but given only " << actual_coord_size;
  }

  const uint32_t mask = inst->words().size() <= 5 ? 0 : inst->word(5);

  if (mask & SpvImageOperandsConstOffsetMask) {
    if (spvIsOpenCLEnv(_.context()->target_env)) {
      if (opcode == SpvOpImageSampleExplicitLod) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "ConstOffset image operand not allowed "
               << "in the OpenCL environment.";
      }
    }
  }

  if (spv_result_t result =
          ValidateImageOperands(_, inst, info, /* word_index = */ 6))
    return result;

  return SPV_SUCCESS;
}

spv_result_t ValidateImageDrefLod(ValidationState_t& _,
                                  const Instruction* inst) {
  const SpvOp opcode = inst->opcode();
  uint32_t actual_result_type = 0;
  if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) {
    return error;
  }

  if (!_.IsIntScalarType(actual_result_type) &&
      !_.IsFloatScalarType(actual_result_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected " << GetActualResultTypeStr(opcode)
           << " to be int or float scalar type";
  }

  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
  if (_.GetIdOpcode(image_type) != SpvOpTypeSampledImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Sampled Image to be of type OpTypeSampledImage";
  }

  ImageTypeInfo info;
  if (!GetImageTypeInfo(_, image_type, &info)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Corrupt image type definition";
  }

  if (spv_result_t result = ValidateImageCommon(_, inst, info)) return result;

  if (info.multisampled) {
    // When using image operands, the Sample image operand is required if and
    // only if the image is multisampled (MS=1). The Sample image operand is
    // only allowed for fetch, read, and write.
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Dref sampling operation is invalid for multisample image";
  }

  if (actual_result_type != info.sampled_type) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image 'Sampled Type' to be the same as "
           << GetActualResultTypeStr(opcode);
  }

  const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
  if (!_.IsFloatScalarOrVectorType(coord_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Coordinate to be float scalar or vector";
  }

  const uint32_t min_coord_size = GetMinCoordSize(opcode, info);
  const uint32_t actual_coord_size = _.GetDimension(coord_type);
  if (min_coord_size > actual_coord_size) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Coordinate to have at least " << min_coord_size
           << " components, but given only " << actual_coord_size;
  }

  const uint32_t dref_type = _.GetOperandTypeId(inst, 4);
  if (!_.IsFloatScalarType(dref_type) || _.GetBitWidth(dref_type) != 32) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Dref to be of 32-bit float type";
  }

  if (spv_result_t result =
          ValidateImageOperands(_, inst, info, /* word_index = */ 7))
    return result;

  return SPV_SUCCESS;
}

spv_result_t ValidateImageFetch(ValidationState_t& _, const Instruction* inst) {
  uint32_t actual_result_type = 0;
  if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) {
    return error;
  }

  const SpvOp opcode = inst->opcode();
  if (!_.IsIntVectorType(actual_result_type) &&
      !_.IsFloatVectorType(actual_result_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected " << GetActualResultTypeStr(opcode)
           << " to be int or float vector type";
  }

  if (_.GetDimension(actual_result_type) != 4) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected " << GetActualResultTypeStr(opcode)
           << " to have 4 components";
  }

  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
  if (_.GetIdOpcode(image_type) != SpvOpTypeImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image to be of type OpTypeImage";
  }

  ImageTypeInfo info;
  if (!GetImageTypeInfo(_, image_type, &info)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Corrupt image type definition";
  }

  if (_.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) {
    const uint32_t result_component_type =
        _.GetComponentType(actual_result_type);
    if (result_component_type != info.sampled_type) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image 'Sampled Type' to be the same as "
             << GetActualResultTypeStr(opcode) << " components";
    }
  }

  if (info.dim == SpvDimCube) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'Dim' cannot be Cube";
  }

  if (info.sampled != 1) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image 'Sampled' parameter to be 1";
  }

  const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
  if (!_.IsIntScalarOrVectorType(coord_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Coordinate to be int scalar or vector";
  }

  const uint32_t min_coord_size = GetMinCoordSize(opcode, info);
  const uint32_t actual_coord_size = _.GetDimension(coord_type);
  if (min_coord_size > actual_coord_size) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Coordinate to have at least " << min_coord_size
           << " components, but given only " << actual_coord_size;
  }

  if (spv_result_t result =
          ValidateImageOperands(_, inst, info, /* word_index = */ 6))
    return result;

  return SPV_SUCCESS;
}

spv_result_t ValidateImageGather(ValidationState_t& _,
                                 const Instruction* inst) {
  uint32_t actual_result_type = 0;
  if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type))
    return error;

  const SpvOp opcode = inst->opcode();
  if (!_.IsIntVectorType(actual_result_type) &&
      !_.IsFloatVectorType(actual_result_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected " << GetActualResultTypeStr(opcode)
           << " to be int or float vector type";
  }

  if (_.GetDimension(actual_result_type) != 4) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected " << GetActualResultTypeStr(opcode)
           << " to have 4 components";
  }

  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
  if (_.GetIdOpcode(image_type) != SpvOpTypeSampledImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Sampled Image to be of type OpTypeSampledImage";
  }

  ImageTypeInfo info;
  if (!GetImageTypeInfo(_, image_type, &info)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Corrupt image type definition";
  }

  if (info.multisampled) {
    // When using image operands, the Sample image operand is required if and
    // only if the image is multisampled (MS=1). The Sample image operand is
    // only allowed for fetch, read, and write.
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Gather operation is invalid for multisample image";
  }

  if (opcode == SpvOpImageDrefGather || opcode == SpvOpImageSparseDrefGather ||
      _.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) {
    const uint32_t result_component_type =
        _.GetComponentType(actual_result_type);
    if (result_component_type != info.sampled_type) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image 'Sampled Type' to be the same as "
             << GetActualResultTypeStr(opcode) << " components";
    }
  }

  if (info.dim != SpvDim2D && info.dim != SpvDimCube &&
      info.dim != SpvDimRect) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image 'Dim' cannot be Cube";
  }

  const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
  if (!_.IsFloatScalarOrVectorType(coord_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Coordinate to be float scalar or vector";
  }

  const uint32_t min_coord_size = GetMinCoordSize(opcode, info);
  const uint32_t actual_coord_size = _.GetDimension(coord_type);
  if (min_coord_size > actual_coord_size) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Coordinate to have at least " << min_coord_size
           << " components, but given only " << actual_coord_size;
  }

  if (opcode == SpvOpImageGather || opcode == SpvOpImageSparseGather) {
    const uint32_t component_index_type = _.GetOperandTypeId(inst, 4);
    if (!_.IsIntScalarType(component_index_type) ||
        _.GetBitWidth(component_index_type) != 32) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Component to be 32-bit int scalar";
    }
  } else {
    assert(opcode == SpvOpImageDrefGather ||
           opcode == SpvOpImageSparseDrefGather);
    const uint32_t dref_type = _.GetOperandTypeId(inst, 4);
    if (!_.IsFloatScalarType(dref_type) || _.GetBitWidth(dref_type) != 32) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Dref to be of 32-bit float type";
    }
  }

  if (spv_result_t result =
          ValidateImageOperands(_, inst, info, /* word_index = */ 7))
    return result;

  return SPV_SUCCESS;
}

spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) {
  const SpvOp opcode = inst->opcode();
  uint32_t actual_result_type = 0;
  if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) {
    return error;
  }

  if (!_.IsIntScalarOrVectorType(actual_result_type) &&
      !_.IsFloatScalarOrVectorType(actual_result_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected " << GetActualResultTypeStr(opcode)
           << " to be int or float scalar or vector type";
  }

  const auto target_env = _.context()->target_env;
  // Vulkan requires the result to be a 4-element int or float
  // vector.
  if (spvIsVulkanEnv(target_env)) {
    if (_.GetDimension(actual_result_type) != 4) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected " << GetActualResultTypeStr(opcode)
             << " to have 4 components";
    }
  }  // Check OpenCL below, after we get the image info.

  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
  if (_.GetIdOpcode(image_type) != SpvOpTypeImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image to be of type OpTypeImage";
  }

  ImageTypeInfo info;
  if (!GetImageTypeInfo(_, image_type, &info)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Corrupt image type definition";
  }

  if (spvIsOpenCLEnv(target_env)) {
    // In OpenCL, a read from a depth image returns a scalar float. In other
    // cases, the result is always a 4-element vector.
    // https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_Env.html#_data_format_for_reading_and_writing_images
    // https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_C.html#image-read-and-write-functions
    // The builtins for reading depth images are:
    //   float read_imagef(aQual image2d_depth_t image, int2 coord)
    //   float read_imagef(aQual image2d_array_depth_t image, int4 coord)
    if (info.depth) {
      if (!_.IsFloatScalarType(actual_result_type)) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "Expected " << GetActualResultTypeStr(opcode)
               << " from a depth image read to result in a scalar float value";
      }
    } else {
      if (_.GetDimension(actual_result_type) != 4) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "Expected " << GetActualResultTypeStr(opcode)
               << " to have 4 components";
      }
    }
  }

  if (info.dim == SpvDimSubpassData) {
    if (opcode == SpvOpImageSparseRead) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Dim SubpassData cannot be used with ImageSparseRead";
    }

    _.function(inst->function()->id())
        ->RegisterExecutionModelLimitation(
            SpvExecutionModelFragment,
            std::string("Dim SubpassData requires Fragment execution model: ") +
                spvOpcodeString(opcode));
  }

  if (_.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) {
    const uint32_t result_component_type =
        _.GetComponentType(actual_result_type);
    if (result_component_type != info.sampled_type) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image 'Sampled Type' to be the same as "
             << GetActualResultTypeStr(opcode) << " components";
    }
  }

  if (spv_result_t result = ValidateImageCommon(_, inst, info)) return result;

  const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
  if (!_.IsIntScalarOrVectorType(coord_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Coordinate to be int scalar or vector";
  }

  const uint32_t min_coord_size = GetMinCoordSize(opcode, info);
  const uint32_t actual_coord_size = _.GetDimension(coord_type);
  if (min_coord_size > actual_coord_size) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Coordinate to have at least " << min_coord_size
           << " components, but given only " << actual_coord_size;
  }

  if (spvIsVulkanEnv(_.context()->target_env)) {
    if (info.format == SpvImageFormatUnknown && info.dim != SpvDimSubpassData &&
        !_.HasCapability(SpvCapabilityStorageImageReadWithoutFormat)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Capability StorageImageReadWithoutFormat is required to "
             << "read storage image";
    }
  }

  const uint32_t mask = inst->words().size() <= 5 ? 0 : inst->word(5);

  if (mask & SpvImageOperandsConstOffsetMask) {
    if (spvIsOpenCLEnv(_.context()->target_env)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "ConstOffset image operand not allowed "
             << "in the OpenCL environment.";
    }
  }

  if (spv_result_t result =
          ValidateImageOperands(_, inst, info, /* word_index = */ 6))
    return result;

  return SPV_SUCCESS;
}

spv_result_t ValidateImageWrite(ValidationState_t& _, const Instruction* inst) {
  const uint32_t image_type = _.GetOperandTypeId(inst, 0);
  if (_.GetIdOpcode(image_type) != SpvOpTypeImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image to be of type OpTypeImage";
  }

  ImageTypeInfo info;
  if (!GetImageTypeInfo(_, image_type, &info)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Corrupt image type definition";
  }

  if (info.dim == SpvDimSubpassData) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Image 'Dim' cannot be SubpassData";
  }

  if (spv_result_t result = ValidateImageCommon(_, inst, info)) return result;

  const uint32_t coord_type = _.GetOperandTypeId(inst, 1);
  if (!_.IsIntScalarOrVectorType(coord_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Coordinate to be int scalar or vector";
  }

  const uint32_t min_coord_size = GetMinCoordSize(inst->opcode(), info);
  const uint32_t actual_coord_size = _.GetDimension(coord_type);
  if (min_coord_size > actual_coord_size) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Coordinate to have at least " << min_coord_size
           << " components, but given only " << actual_coord_size;
  }

  // TODO(atgoo@github.com) The spec doesn't explicitely say what the type
  // of texel should be.
  const uint32_t texel_type = _.GetOperandTypeId(inst, 2);
  if (!_.IsIntScalarOrVectorType(texel_type) &&
      !_.IsFloatScalarOrVectorType(texel_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Texel to be int or float vector or scalar";
  }

#if 0
  // TODO: See above.
  if (_.GetDimension(texel_type) != 4) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
        << "Expected Texel to have 4 components";
  }
#endif

  if (_.GetIdOpcode(info.sampled_type) != SpvOpTypeVoid) {
    const uint32_t texel_component_type = _.GetComponentType(texel_type);
    if (texel_component_type != info.sampled_type) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image 'Sampled Type' to be the same as Texel "
             << "components";
    }
  }

  if (spvIsVulkanEnv(_.context()->target_env)) {
    if (info.format == SpvImageFormatUnknown && info.dim != SpvDimSubpassData &&
        !_.HasCapability(SpvCapabilityStorageImageWriteWithoutFormat)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Capability StorageImageWriteWithoutFormat is required to "
                "write "
             << "to storage image";
    }
  }

  if (inst->words().size() > 4) {
    if (spvIsOpenCLEnv(_.context()->target_env)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Optional Image Operands are not allowed in the OpenCL "
             << "environment.";
    }
  }

  if (spv_result_t result =
          ValidateImageOperands(_, inst, info, /* word_index = */ 5))
    return result;

  return SPV_SUCCESS;
}

spv_result_t ValidateImage(ValidationState_t& _, const Instruction* inst) {
  const uint32_t result_type = inst->type_id();
  if (_.GetIdOpcode(result_type) != SpvOpTypeImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Result Type to be OpTypeImage";
  }

  const uint32_t sampled_image_type = _.GetOperandTypeId(inst, 2);
  const Instruction* sampled_image_type_inst = _.FindDef(sampled_image_type);
  assert(sampled_image_type_inst);

  if (sampled_image_type_inst->opcode() != SpvOpTypeSampledImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Sample Image to be of type OpTypeSampleImage";
  }

  if (sampled_image_type_inst->word(2) != result_type) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Sample Image image type to be equal to Result Type";
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateImageQuerySizeLod(ValidationState_t& _,
                                       const Instruction* inst) {
  const uint32_t result_type = inst->type_id();
  if (!_.IsIntScalarOrVectorType(result_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Result Type to be int scalar or vector type";
  }

  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
  if (_.GetIdOpcode(image_type) != SpvOpTypeImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image to be of type OpTypeImage";
  }

  ImageTypeInfo info;
  if (!GetImageTypeInfo(_, image_type, &info)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Corrupt image type definition";
  }

  uint32_t expected_num_components = info.arrayed;
  switch (info.dim) {
    case SpvDim1D:
      expected_num_components += 1;
      break;
    case SpvDim2D:
    case SpvDimCube:
      expected_num_components += 2;
      break;
    case SpvDim3D:
      expected_num_components += 3;
      break;
    default:
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image 'Dim' must be 1D, 2D, 3D or Cube";
  }

  if (info.multisampled != 0) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'MS' must be 0";
  }

  const auto target_env = _.context()->target_env;
  if (spvIsVulkanEnv(target_env)) {
    if (info.sampled != 1) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << _.VkErrorID(4659)
             << "OpImageQuerySizeLod must only consume an \"Image\" operand "
                "whose type has its \"Sampled\" operand set to 1";
    }
  }

  uint32_t result_num_components = _.GetDimension(result_type);
  if (result_num_components != expected_num_components) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Result Type has " << result_num_components << " components, "
           << "but " << expected_num_components << " expected";
  }

  const uint32_t lod_type = _.GetOperandTypeId(inst, 3);
  if (!_.IsIntScalarType(lod_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Level of Detail to be int scalar";
  }
  return SPV_SUCCESS;
}

spv_result_t ValidateImageQuerySize(ValidationState_t& _,
                                    const Instruction* inst) {
  const uint32_t result_type = inst->type_id();
  if (!_.IsIntScalarOrVectorType(result_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Result Type to be int scalar or vector type";
  }

  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
  if (_.GetIdOpcode(image_type) != SpvOpTypeImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image to be of type OpTypeImage";
  }

  ImageTypeInfo info;
  if (!GetImageTypeInfo(_, image_type, &info)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Corrupt image type definition";
  }

  uint32_t expected_num_components = info.arrayed;
  switch (info.dim) {
    case SpvDim1D:
    case SpvDimBuffer:
      expected_num_components += 1;
      break;
    case SpvDim2D:
    case SpvDimCube:
    case SpvDimRect:
      expected_num_components += 2;
      break;
    case SpvDim3D:
      expected_num_components += 3;
      break;
    default:
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image 'Dim' must be 1D, Buffer, 2D, Cube, 3D or Rect";
  }

  if (info.dim == SpvDim1D || info.dim == SpvDim2D || info.dim == SpvDim3D ||
      info.dim == SpvDimCube) {
    if (info.multisampled != 1 && info.sampled != 0 && info.sampled != 2) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image must have either 'MS'=1 or 'Sampled'=0 or 'Sampled'=2";
    }
  }

  uint32_t result_num_components = _.GetDimension(result_type);
  if (result_num_components != expected_num_components) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Result Type has " << result_num_components << " components, "
           << "but " << expected_num_components << " expected";
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateImageQueryFormatOrOrder(ValidationState_t& _,
                                             const Instruction* inst) {
  if (!_.IsIntScalarType(inst->type_id())) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Result Type to be int scalar type";
  }

  if (_.GetIdOpcode(_.GetOperandTypeId(inst, 2)) != SpvOpTypeImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected operand to be of type OpTypeImage";
  }
  return SPV_SUCCESS;
}

spv_result_t ValidateImageQueryLod(ValidationState_t& _,
                                   const Instruction* inst) {
  _.function(inst->function()->id())
      ->RegisterExecutionModelLimitation(
          [&](SpvExecutionModel model, std::string* message) {
            if (model != SpvExecutionModelFragment &&
                model != SpvExecutionModelGLCompute) {
              if (message) {
                *message = std::string(
                    "OpImageQueryLod requires Fragment or GLCompute execution "
                    "model");
              }
              return false;
            }
            return true;
          });
  _.function(inst->function()->id())
      ->RegisterLimitation([](const ValidationState_t& state,
                              const Function* entry_point,
                              std::string* message) {
        const auto* models = state.GetExecutionModels(entry_point->id());
        const auto* modes = state.GetExecutionModes(entry_point->id());
        if (models->find(SpvExecutionModelGLCompute) != models->end() &&
            modes->find(SpvExecutionModeDerivativeGroupLinearNV) ==
                modes->end() &&
            modes->find(SpvExecutionModeDerivativeGroupQuadsNV) ==
                modes->end()) {
          if (message) {
            *message = std::string(
                "OpImageQueryLod requires DerivativeGroupQuadsNV "
                "or DerivativeGroupLinearNV execution mode for GLCompute "
                "execution model");
          }
          return false;
        }
        return true;
      });

  const uint32_t result_type = inst->type_id();
  if (!_.IsFloatVectorType(result_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Result Type to be float vector type";
  }

  if (_.GetDimension(result_type) != 2) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Result Type to have 2 components";
  }

  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
  if (_.GetIdOpcode(image_type) != SpvOpTypeSampledImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image operand to be of type OpTypeSampledImage";
  }

  ImageTypeInfo info;
  if (!GetImageTypeInfo(_, image_type, &info)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Corrupt image type definition";
  }

  if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D &&
      info.dim != SpvDimCube) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Image 'Dim' must be 1D, 2D, 3D or Cube";
  }

  const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
  if (_.HasCapability(SpvCapabilityKernel)) {
    if (!_.IsFloatScalarOrVectorType(coord_type) &&
        !_.IsIntScalarOrVectorType(coord_type)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Coordinate to be int or float scalar or vector";
    }
  } else {
    if (!_.IsFloatScalarOrVectorType(coord_type)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Coordinate to be float scalar or vector";
    }
  }

  const uint32_t min_coord_size = GetPlaneCoordSize(info);
  const uint32_t actual_coord_size = _.GetDimension(coord_type);
  if (min_coord_size > actual_coord_size) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Coordinate to have at least " << min_coord_size
           << " components, but given only " << actual_coord_size;
  }

  // The operad is a sampled image.
  // The sampled image type is already checked to be parameterized by an image
  // type with Sampled=0 or Sampled=1.  Vulkan bans Sampled=0, and so we have
  // Sampled=1.  So the validator already enforces Vulkan VUID 4659:
  //   OpImageQuerySizeLod must only consume an “Image” operand whose type has
  //   its "Sampled" operand set to 1
  return SPV_SUCCESS;
}

spv_result_t ValidateImageSparseLod(ValidationState_t& _,
                                    const Instruction* inst) {
  return _.diag(SPV_ERROR_INVALID_DATA, inst)
         << "Instruction reserved for future use, use of this instruction "
         << "is invalid";
}

spv_result_t ValidateImageQueryLevelsOrSamples(ValidationState_t& _,
                                               const Instruction* inst) {
  if (!_.IsIntScalarType(inst->type_id())) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Result Type to be int scalar type";
  }

  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
  if (_.GetIdOpcode(image_type) != SpvOpTypeImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image to be of type OpTypeImage";
  }

  ImageTypeInfo info;
  if (!GetImageTypeInfo(_, image_type, &info)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Corrupt image type definition";
  }

  const SpvOp opcode = inst->opcode();
  if (opcode == SpvOpImageQueryLevels) {
    if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D &&
        info.dim != SpvDimCube) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image 'Dim' must be 1D, 2D, 3D or Cube";
    }
    const auto target_env = _.context()->target_env;
    if (spvIsVulkanEnv(target_env)) {
      if (info.sampled != 1) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << _.VkErrorID(4659)
               << "OpImageQueryLevels must only consume an \"Image\" operand "
                  "whose type has its \"Sampled\" operand set to 1";
      }
    }
  } else {
    assert(opcode == SpvOpImageQuerySamples);
    if (info.dim != SpvDim2D) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'Dim' must be 2D";
    }

    if (info.multisampled != 1) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'MS' must be 1";
    }
  }
  return SPV_SUCCESS;
}

spv_result_t ValidateImageSparseTexelsResident(ValidationState_t& _,
                                               const Instruction* inst) {
  if (!_.IsBoolScalarType(inst->type_id())) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Result Type to be bool scalar type";
  }

  const uint32_t resident_code_type = _.GetOperandTypeId(inst, 2);
  if (!_.IsIntScalarType(resident_code_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Resident Code to be int scalar";
  }

  return SPV_SUCCESS;
}

}  // namespace

// Validates correctness of image instructions.
spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) {
  const SpvOp opcode = inst->opcode();
  if (IsImplicitLod(opcode)) {
    _.function(inst->function()->id())
        ->RegisterExecutionModelLimitation([opcode](SpvExecutionModel model,
                                                    std::string* message) {
          if (model != SpvExecutionModelFragment &&
              model != SpvExecutionModelGLCompute) {
            if (message) {
              *message =
                  std::string(
                      "ImplicitLod instructions require Fragment or GLCompute "
                      "execution model: ") +
                  spvOpcodeString(opcode);
            }
            return false;
          }
          return true;
        });
    _.function(inst->function()->id())
        ->RegisterLimitation([opcode](const ValidationState_t& state,
                                      const Function* entry_point,
                                      std::string* message) {
          const auto* models = state.GetExecutionModels(entry_point->id());
          const auto* modes = state.GetExecutionModes(entry_point->id());
          if (models->find(SpvExecutionModelGLCompute) != models->end() &&
              modes->find(SpvExecutionModeDerivativeGroupLinearNV) ==
                  modes->end() &&
              modes->find(SpvExecutionModeDerivativeGroupQuadsNV) ==
                  modes->end()) {
            if (message) {
              *message =
                  std::string(
                      "ImplicitLod instructions require DerivativeGroupQuadsNV "
                      "or DerivativeGroupLinearNV execution mode for GLCompute "
                      "execution model: ") +
                  spvOpcodeString(opcode);
            }
            return false;
          }
          return true;
        });
  }

  switch (opcode) {
    case SpvOpTypeImage:
      return ValidateTypeImage(_, inst);
    case SpvOpTypeSampledImage:
      return ValidateTypeSampledImage(_, inst);
    case SpvOpSampledImage:
      return ValidateSampledImage(_, inst);
    case SpvOpImageTexelPointer:
      return ValidateImageTexelPointer(_, inst);

    case SpvOpImageSampleImplicitLod:
    case SpvOpImageSampleExplicitLod:
    case SpvOpImageSampleProjImplicitLod:
    case SpvOpImageSampleProjExplicitLod:
    case SpvOpImageSparseSampleImplicitLod:
    case SpvOpImageSparseSampleExplicitLod:
      return ValidateImageLod(_, inst);

    case SpvOpImageSampleDrefImplicitLod:
    case SpvOpImageSampleDrefExplicitLod:
    case SpvOpImageSampleProjDrefImplicitLod:
    case SpvOpImageSampleProjDrefExplicitLod:
    case SpvOpImageSparseSampleDrefImplicitLod:
    case SpvOpImageSparseSampleDrefExplicitLod:
      return ValidateImageDrefLod(_, inst);

    case SpvOpImageFetch:
    case SpvOpImageSparseFetch:
      return ValidateImageFetch(_, inst);

    case SpvOpImageGather:
    case SpvOpImageDrefGather:
    case SpvOpImageSparseGather:
    case SpvOpImageSparseDrefGather:
      return ValidateImageGather(_, inst);

    case SpvOpImageRead:
    case SpvOpImageSparseRead:
      return ValidateImageRead(_, inst);

    case SpvOpImageWrite:
      return ValidateImageWrite(_, inst);

    case SpvOpImage:
      return ValidateImage(_, inst);

    case SpvOpImageQueryFormat:
    case SpvOpImageQueryOrder:
      return ValidateImageQueryFormatOrOrder(_, inst);

    case SpvOpImageQuerySizeLod:
      return ValidateImageQuerySizeLod(_, inst);
    case SpvOpImageQuerySize:
      return ValidateImageQuerySize(_, inst);
    case SpvOpImageQueryLod:
      return ValidateImageQueryLod(_, inst);

    case SpvOpImageQueryLevels:
    case SpvOpImageQuerySamples:
      return ValidateImageQueryLevelsOrSamples(_, inst);

    case SpvOpImageSparseSampleProjImplicitLod:
    case SpvOpImageSparseSampleProjExplicitLod:
    case SpvOpImageSparseSampleProjDrefImplicitLod:
    case SpvOpImageSparseSampleProjDrefExplicitLod:
      return ValidateImageSparseLod(_, inst);

    case SpvOpImageSparseTexelsResident:
      return ValidateImageSparseTexelsResident(_, inst);

    default:
      break;
  }

  return SPV_SUCCESS;
}

}  // namespace val
}  // namespace spvtools
