// 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)
           << "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
