// 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/opcode.h"
#include "source/spirv_constant.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 spv::ImageOperandsMask::XXX cases are
// handled in this module. If spv::ImageOperandsMask::XXX list changes, this
// function will fail the build. For all other purposes this is a placeholder
// function.
bool CheckAllImageOperandsHandled() {
  spv::ImageOperandsMask enum_val = spv::ImageOperandsMask::Bias;

  // 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 = spv::ImageOperandsMask::Lod;

  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 spv::ImageOperandsMask::MaskNone:
      return false;
    case spv::ImageOperandsMask::Bias:
    case spv::ImageOperandsMask::Lod:
    case spv::ImageOperandsMask::Grad:
    case spv::ImageOperandsMask::ConstOffset:
    case spv::ImageOperandsMask::Offset:
    case spv::ImageOperandsMask::ConstOffsets:
    case spv::ImageOperandsMask::Sample:
    case spv::ImageOperandsMask::MinLod:

    // TODO(dneto): Support image operands related to the Vulkan memory model.
    // https://gitlab.khronos.org/spirv/spirv-tools/issues/32
    case spv::ImageOperandsMask::MakeTexelAvailableKHR:
    case spv::ImageOperandsMask::MakeTexelVisibleKHR:
    case spv::ImageOperandsMask::NonPrivateTexelKHR:
    case spv::ImageOperandsMask::VolatileTexelKHR:
    case spv::ImageOperandsMask::SignExtend:
    case spv::ImageOperandsMask::ZeroExtend:
    // TODO(jaebaek): Move this line properly after handling image offsets
    //                operand. This line temporarily fixes CI failure that
    //                blocks other PRs.
    // https://github.com/KhronosGroup/SPIRV-Tools/issues/4565
    case spv::ImageOperandsMask::Offsets:
    case spv::ImageOperandsMask::Nontemporal:
      return true;
  }
  return false;
}

// Used by GetImageTypeInfo. See OpTypeImage spec for more information.
struct ImageTypeInfo {
  uint32_t sampled_type = 0;
  spv::Dim dim = spv::Dim::Max;
  uint32_t depth = 0;
  uint32_t arrayed = 0;
  uint32_t multisampled = 0;
  uint32_t sampled = 0;
  spv::ImageFormat format = spv::ImageFormat::Max;
  spv::AccessQualifier access_qualifier = spv::AccessQualifier::Max;
};

// 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() == spv::Op::OpTypeSampledImage) {
    inst = _.FindDef(inst->word(2));
    assert(inst);
  }

  if (inst->opcode() != spv::Op::OpTypeImage) 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<spv::Dim>(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<spv::ImageFormat>(inst->word(8));
  info->access_qualifier =
      num_words < 10 ? spv::AccessQualifier::Max
                     : static_cast<spv::AccessQualifier>(inst->word(9));
  return true;
}

bool IsImplicitLod(spv::Op opcode) {
  switch (opcode) {
    case spv::Op::OpImageSampleImplicitLod:
    case spv::Op::OpImageSampleDrefImplicitLod:
    case spv::Op::OpImageSampleProjImplicitLod:
    case spv::Op::OpImageSampleProjDrefImplicitLod:
    case spv::Op::OpImageSparseSampleImplicitLod:
    case spv::Op::OpImageSparseSampleDrefImplicitLod:
    case spv::Op::OpImageSparseSampleProjImplicitLod:
    case spv::Op::OpImageSparseSampleProjDrefImplicitLod:
      return true;
    default:
      break;
  }
  return false;
}

bool IsExplicitLod(spv::Op opcode) {
  switch (opcode) {
    case spv::Op::OpImageSampleExplicitLod:
    case spv::Op::OpImageSampleDrefExplicitLod:
    case spv::Op::OpImageSampleProjExplicitLod:
    case spv::Op::OpImageSampleProjDrefExplicitLod:
    case spv::Op::OpImageSparseSampleExplicitLod:
    case spv::Op::OpImageSparseSampleDrefExplicitLod:
    case spv::Op::OpImageSparseSampleProjExplicitLod:
    case spv::Op::OpImageSparseSampleProjDrefExplicitLod:
      return true;
    default:
      break;
  }
  return false;
}

bool IsValidLodOperand(const ValidationState_t& _, spv::Op opcode) {
  switch (opcode) {
    case spv::Op::OpImageRead:
    case spv::Op::OpImageWrite:
    case spv::Op::OpImageSparseRead:
      return _.HasCapability(spv::Capability::ImageReadWriteLodAMD);
    default:
      return IsExplicitLod(opcode);
  }
}

bool IsValidGatherLodBiasAMD(const ValidationState_t& _, spv::Op opcode) {
  switch (opcode) {
    case spv::Op::OpImageGather:
    case spv::Op::OpImageSparseGather:
      return _.HasCapability(spv::Capability::ImageGatherBiasLodAMD);
    default:
      break;
  }
  return false;
}

// Signed or Unsigned Integer Format
bool IsIntImageFormat(spv::ImageFormat format) {
  switch (format) {
    case spv::ImageFormat::Rgba32i:
    case spv::ImageFormat::Rgba16i:
    case spv::ImageFormat::Rgba8i:
    case spv::ImageFormat::R32i:
    case spv::ImageFormat::Rg32i:
    case spv::ImageFormat::Rg16i:
    case spv::ImageFormat::Rg8i:
    case spv::ImageFormat::R16i:
    case spv::ImageFormat::R8i:
    case spv::ImageFormat::Rgba32ui:
    case spv::ImageFormat::Rgba16ui:
    case spv::ImageFormat::Rgba8ui:
    case spv::ImageFormat::R32ui:
    case spv::ImageFormat::Rgb10a2ui:
    case spv::ImageFormat::Rg32ui:
    case spv::ImageFormat::Rg16ui:
    case spv::ImageFormat::Rg8ui:
    case spv::ImageFormat::R16ui:
    case spv::ImageFormat::R8ui:
    case spv::ImageFormat::R64ui:
    case spv::ImageFormat::R64i:
      return true;
    default:
      break;
  }
  return false;
}

bool IsInt64ImageFormat(spv::ImageFormat format) {
  switch (format) {
    case spv::ImageFormat::R64ui:
    case spv::ImageFormat::R64i:
      return true;
    default:
      break;
  }
  return false;
}

bool IsSignedIntImageFormat(spv::ImageFormat format) {
  switch (format) {
    case spv::ImageFormat::Rgba32i:
    case spv::ImageFormat::Rgba16i:
    case spv::ImageFormat::Rgba8i:
    case spv::ImageFormat::R32i:
    case spv::ImageFormat::Rg32i:
    case spv::ImageFormat::Rg16i:
    case spv::ImageFormat::Rg8i:
    case spv::ImageFormat::R16i:
    case spv::ImageFormat::R8i:
    case spv::ImageFormat::R64i:
      return true;
    default:
      break;
  }
  return false;
}

bool IsFloatImageFormat(spv::ImageFormat format) {
  switch (format) {
    case spv::ImageFormat::Rgba32f:
    case spv::ImageFormat::Rgba16f:
    case spv::ImageFormat::R32f:
    case spv::ImageFormat::Rgba8:
    case spv::ImageFormat::Rgba8Snorm:
    case spv::ImageFormat::Rg32f:
    case spv::ImageFormat::Rg16f:
    case spv::ImageFormat::R11fG11fB10f:
    case spv::ImageFormat::R16f:
    case spv::ImageFormat::Rgba16:
    case spv::ImageFormat::Rgb10A2:
    case spv::ImageFormat::Rg16:
    case spv::ImageFormat::Rg8:
    case spv::ImageFormat::R16:
    case spv::ImageFormat::R8:
    case spv::ImageFormat::Rgba16Snorm:
    case spv::ImageFormat::Rg16Snorm:
    case spv::ImageFormat::Rg8Snorm:
    case spv::ImageFormat::R16Snorm:
    case spv::ImageFormat::R8Snorm:
      return true;
    default:
      break;
  }
  return false;
}

bool IsImageSparse(spv::Op opcode) {
  switch (opcode) {
    case spv::Op::OpImageSparseSampleImplicitLod:
    case spv::Op::OpImageSparseSampleExplicitLod:
    case spv::Op::OpImageSparseSampleDrefImplicitLod:
    case spv::Op::OpImageSparseSampleDrefExplicitLod:
    case spv::Op::OpImageSparseSampleProjImplicitLod:
    case spv::Op::OpImageSparseSampleProjExplicitLod:
    case spv::Op::OpImageSparseSampleProjDrefImplicitLod:
    case spv::Op::OpImageSparseSampleProjDrefExplicitLod:
    case spv::Op::OpImageSparseFetch:
    case spv::Op::OpImageSparseGather:
    case spv::Op::OpImageSparseDrefGather:
    case spv::Op::OpImageSparseTexelsResident:
    case spv::Op::OpImageSparseRead:
      return true;
    default:
      break;
  }
  return false;
}

// Returns true if the opcode is a Image instruction which applies
// homogenous projection to the coordinates.
bool IsProj(spv::Op opcode) {
  switch (opcode) {
    case spv::Op::OpImageSampleProjImplicitLod:
    case spv::Op::OpImageSampleProjDrefImplicitLod:
    case spv::Op::OpImageSparseSampleProjImplicitLod:
    case spv::Op::OpImageSparseSampleProjDrefImplicitLod:
    case spv::Op::OpImageSampleProjExplicitLod:
    case spv::Op::OpImageSampleProjDrefExplicitLod:
    case spv::Op::OpImageSparseSampleProjExplicitLod:
    case spv::Op::OpImageSparseSampleProjDrefExplicitLod:
      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 spv::Dim::Dim1D:
    case spv::Dim::Buffer:
      plane_size = 1;
      break;
    case spv::Dim::Dim2D:
    case spv::Dim::Rect:
    case spv::Dim::SubpassData:
    case spv::Dim::TileImageDataEXT:
      plane_size = 2;
      break;
    case spv::Dim::Dim3D:
    case spv::Dim::Cube:
      // For Cube direction vector is used instead of UV.
      plane_size = 3;
      break;
    case spv::Dim::Max:
    default:
      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(spv::Op opcode, const ImageTypeInfo& info) {
  if (info.dim == spv::Dim::Cube &&
      (opcode == spv::Op::OpImageRead || opcode == spv::Op::OpImageWrite ||
       opcode == spv::Op::OpImageSparseRead)) {
    // These opcodes use UV for Cube, not direction vector.
    return 3;
  }

  if (opcode == spv::Op::OpImageQueryLod) {
    return GetPlaneCoordSize(info);
  }

  if (opcode == spv::Op::OpImageTexelPointer) {
    if (info.arrayed == 0) {
      return GetPlaneCoordSize(info);
    } else if (info.dim == spv::Dim::Dim1D) {
      return 2;
    } else if (info.dim == spv::Dim::Cube || info.dim == spv::Dim::Dim2D) {
      return 3;
    } else {
      assert(false);
      return 0;  // caught elsewhere
    }
  }

  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 spv::Op 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(spv::ImageOperandsMask::NonPrivateTexelKHR |
                         spv::ImageOperandsMask::VolatileTexelKHR |
                         spv::ImageOperandsMask::SignExtend |
                         spv::ImageOperandsMask::ZeroExtend |
                         spv::ImageOperandsMask::Nontemporal);
    size_t expected_num_image_operand_words =
        spvtools::utils::CountSetBits(mask_bits_having_operands);
    if (mask & uint32_t(spv::ImageOperandsMask::Grad)) {
      // 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 & uint32_t(spv::ImageOperandsMask::Sample)))) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Image Operand Sample is required for operation on "
              "multi-sampled image";
  }

  // The following OpTypeImage checks are done here as they depend of if the
  // SignExtend and ZeroExtend are used to override the signedness
  const bool is_sign_extend =
      mask & uint32_t(spv::ImageOperandsMask::SignExtend);
  const bool is_zero_extend =
      mask & uint32_t(spv::ImageOperandsMask::ZeroExtend);
  if (spvIsVulkanEnv(_.context()->target_env)) {
    if (info.format != spv::ImageFormat::Unknown &&
        _.IsIntScalarType(info.sampled_type)) {
      const bool is_format_signed = IsSignedIntImageFormat(info.format);
      const bool is_sampled_type_signed =
          _.IsSignedIntScalarType(info.sampled_type);
      // (vkspec.html#spirvenv-image-signedness) has order signedness is set by
      const bool effective_sampled_type_signed =
          is_sign_extend ? true
                         : (is_zero_extend ? false : is_sampled_type_signed);
      if (is_format_signed != effective_sampled_type_signed) {
        std::string err_info = "";
        if (is_sign_extend) {
          err_info = " (SignExtend makes the access as signed)";
        } else if (is_zero_extend) {
          err_info = " (ZeroExtend makes the access as unsigned)";
        }
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << _.VkErrorID(4965) << "Image Format signedness ("
               << (is_format_signed ? "signed" : "unsigned")
               << ") does not match Sample Type operand" << err_info << ".";
      }
    }
  }

  // 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 & uint32_t(spv::ImageOperandsMask::Offset |
                          spv::ImageOperandsMask::ConstOffset |
                          spv::ImageOperandsMask::ConstOffsets |
                          spv::ImageOperandsMask::Offsets)) > 1) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Image Operands Offset, ConstOffset, ConstOffsets, Offsets "
              "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 & uint32_t(spv::ImageOperandsMask::Bias)) {
    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 bias_type_id = _.GetTypeId(inst->word(word_index++));
    if (!_.IsFloatScalarType(bias_type_id, 32)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image Operand Bias to be a 32-bit float scalar";
    }

    if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D &&
        info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand Bias requires 'Dim' parameter to be 1D, 2D, 3D "
                "or Cube";
    }

    // - |Sample| operand is required to have MS != 0
    // - |Sample| is only allowed with [Fetch, Write, or Read]
    // - |Bias| can only be used with |ImplicitLod| opcodes
    // Multisampled is already checked in all cases
  }

  if (mask & uint32_t(spv::ImageOperandsMask::Lod)) {
    if (!is_valid_lod_operand && opcode != spv::Op::OpImageFetch &&
        opcode != spv::Op::OpImageSparseFetch &&
        !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 & uint32_t(spv::ImageOperandsMask::Grad)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand bits Lod and Grad cannot be set at the same "
                "time";
    }

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

    if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D &&
        info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand Lod requires 'Dim' parameter to be 1D, 2D, 3D "
                "or Cube";
    }

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

  if (mask & uint32_t(spv::ImageOperandsMask::Grad)) {
    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) ||
        _.GetBitWidth(dx_type_id) != 32 ||
        !_.IsFloatScalarOrVectorType(dy_type_id) ||
        _.GetBitWidth(dy_type_id) != 32) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected both Image Operand Grad ids to be 32-bit 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;
    }

    // - |Sample| operand is required to have MS != 0
    // - |Sample| is only allowed with [Fetch, Write, or Read]
    // - |Grad| can only be used with |ExplicitLod| opcodes
    // Multisampled is already checked in all cases
  }

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

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

    if (!spvOpcodeIsConstant(_.GetIdOpcode(offset_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(offset_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 & uint32_t(spv::ImageOperandsMask::Offset)) {
    if (info.dim == spv::Dim::Cube) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand Offset cannot be used with Cube Image 'Dim'";
    }

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

    const uint32_t plane_size = GetPlaneCoordSize(info);
    const uint32_t offset_size = _.GetDimension(offset_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 (!_.options()->before_hlsl_legalization &&
        spvIsVulkanEnv(_.context()->target_env) &&
        !_.options()->allow_offset_texture_operand) {
      if (opcode != spv::Op::OpImageGather &&
          opcode != spv::Op::OpImageDrefGather &&
          opcode != spv::Op::OpImageSparseGather &&
          opcode != spv::Op::OpImageSparseDrefGather &&
          opcode != spv::Op::OpImageGatherQCOM) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << _.VkErrorID(10213)
               << "Image Operand Offset can only be used with "
                  "OpImage*Gather operations."
               << _.MissingFeature("maintenance8 feature",
                                   "--allow-offset-texture-operand", false);
      }
    }
  }

  if (mask & uint32_t(spv::ImageOperandsMask::ConstOffsets)) {
    if (opcode != spv::Op::OpImageGather &&
        opcode != spv::Op::OpImageDrefGather &&
        opcode != spv::Op::OpImageSparseGather &&
        opcode != spv::Op::OpImageSparseDrefGather &&
        opcode != spv::Op::OpImageGatherQCOM) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand ConstOffsets can only be used with "
                "OpImageGather and OpImageDrefGather";
    }

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

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

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

    uint64_t array_size = 0;
    if (!_.EvalConstantValUint64(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 ||
        _.GetBitWidth(component_type) != 32) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image Operand ConstOffsets array components to be a "
                "32-bit int vectors of size 2";
    }

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

  if (mask & uint32_t(spv::ImageOperandsMask::Sample)) {
    if (opcode != spv::Op::OpImageFetch && opcode != spv::Op::OpImageRead &&
        opcode != spv::Op::OpImageWrite &&
        opcode != spv::Op::OpImageSparseFetch &&
        opcode != spv::Op::OpImageSparseRead) {
      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 sample_type_id = _.GetTypeId(inst->word(word_index++));
    if (!_.IsIntScalarType(sample_type_id, 32)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image Operand Sample to be a 32-bit int scalar";
    }
  }

  if (mask & uint32_t(spv::ImageOperandsMask::MinLod)) {
    if (!is_implicit_lod && !(mask & uint32_t(spv::ImageOperandsMask::Grad))) {
      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 minlod_type_id = _.GetTypeId(inst->word(word_index++));
    if (!_.IsFloatScalarType(minlod_type_id, 32)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Image Operand MinLod to be a 32-bit float scalar";
    }

    if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D &&
        info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) {
      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 & uint32_t(spv::ImageOperandsMask::MakeTexelAvailableKHR)) {
    // Checked elsewhere: capability and memory model are correct.
    if (opcode != spv::Op::OpImageWrite) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand MakeTexelAvailableKHR can only be used with Op"
             << spvOpcodeString(spv::Op::OpImageWrite) << ": Op"
             << spvOpcodeString(opcode);
    }

    if (!(mask & uint32_t(spv::ImageOperandsMask::NonPrivateTexelKHR))) {
      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 & uint32_t(spv::ImageOperandsMask::MakeTexelVisibleKHR)) {
    // Checked elsewhere: capability and memory model are correct.
    if (opcode != spv::Op::OpImageRead &&
        opcode != spv::Op::OpImageSparseRead) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image Operand MakeTexelVisibleKHR can only be used with Op"
             << spvOpcodeString(spv::Op::OpImageRead) << " or Op"
             << spvOpcodeString(spv::Op::OpImageSparseRead) << ": Op"
             << spvOpcodeString(opcode);
    }

    if (!(mask & uint32_t(spv::ImageOperandsMask::NonPrivateTexelKHR))) {
      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;
  }

  // Checked elsewhere: SPIR-V 1.4 version or later.
  if (is_sign_extend || is_zero_extend) {
    // We don't have enough information to know what the |texel value 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 (opcode == spv::Op::OpImageWrite) {
      // OpImageWrite has no result type.
      // TODO - Add Validation
    } else if (IsImageSparse(opcode)) {
      // Sparse image read/sample return a struct.
      // TODO - Add Validation
    } else {
      if (is_sign_extend && !_.IsIntScalarOrVectorType(inst->type_id())) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "Using SignExtend, but result type is not a scalar or vector "
                  "integer type.";
      } else if (is_zero_extend &&
                 !_.IsUnsignedIntScalarOrVectorType(inst->type_id())) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "Using ZeroExtend, but result type is a signed integer type.";
      }
    }
  }

  if (mask & uint32_t(spv::ImageOperandsMask::Offsets)) {
    // TODO: add validation
  }

  if (mask & uint32_t(spv::ImageOperandsMask::Nontemporal)) {
    // Checked elsewhere: SPIR-V 1.6 version or later.
  }

  return SPV_SUCCESS;
}

// Validate OpImage*Proj* instructions
spv_result_t ValidateImageProj(ValidationState_t& _, const Instruction* inst,
                               const ImageTypeInfo& info) {
  if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D &&
      info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Rect) {
    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";
  }

  return SPV_SUCCESS;
}

// Validate OpImage*Read and OpImage*Write instructions
spv_result_t ValidateImageReadWrite(ValidationState_t& _,
                                    const Instruction* inst,
                                    const ImageTypeInfo& info) {
  if (info.sampled == 2) {
    if (info.dim == spv::Dim::Dim1D &&
        !_.HasCapability(spv::Capability::Image1D)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Capability Image1D is required to access storage image";
    } else if (info.dim == spv::Dim::Rect &&
               !_.HasCapability(spv::Capability::ImageRect)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Capability ImageRect is required to access storage image";
    } else if (info.dim == spv::Dim::Buffer &&
               !_.HasCapability(spv::Capability::ImageBuffer)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Capability ImageBuffer is required to access storage image";
    } else if (info.dim == spv::Dim::Cube && info.arrayed == 1 &&
               !_.HasCapability(spv::Capability::ImageCubeArray)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Capability ImageCubeArray is required to access "
             << "storage image";
    }

    if (info.multisampled == 1 && info.arrayed == 1 && info.sampled == 2 &&
        !_.HasCapability(spv::Capability::ImageMSArray)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Capability ImageMSArray is required to access storage "
             << "image";
    }
  } else if (info.sampled != 0) {
    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(spv::Op opcode) {
  switch (opcode) {
    case spv::Op::OpImageSparseSampleImplicitLod:
    case spv::Op::OpImageSparseSampleExplicitLod:
    case spv::Op::OpImageSparseSampleDrefImplicitLod:
    case spv::Op::OpImageSparseSampleDrefExplicitLod:
    case spv::Op::OpImageSparseSampleProjImplicitLod:
    case spv::Op::OpImageSparseSampleProjExplicitLod:
    case spv::Op::OpImageSparseSampleProjDrefImplicitLod:
    case spv::Op::OpImageSparseSampleProjDrefExplicitLod:
    case spv::Op::OpImageSparseFetch:
    case spv::Op::OpImageSparseGather:
    case spv::Op::OpImageSparseDrefGather:
    case spv::Op::OpImageSparseTexelsResident:
    case spv::Op::OpImageSparseRead: {
      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 spv::Op opcode = inst->opcode();

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

    if (!type_inst || type_inst->opcode() != spv::Op::OpTypeStruct) {
      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(spv::Op 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";
  }

  const auto target_env = _.context()->target_env;
  if (spvIsVulkanEnv(target_env)) {
    if (!_.IsFloatScalarType(info.sampled_type, 32) &&
        !_.IsIntScalarType(info.sampled_type, 32) &&
        !_.IsIntScalarType(info.sampled_type, 64)) {
      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 spv::Op sampled_type_opcode = _.GetIdOpcode(info.sampled_type);
    if (sampled_type_opcode != spv::Op::OpTypeVoid &&
        sampled_type_opcode != spv::Op::OpTypeInt &&
        sampled_type_opcode != spv::Op::OpTypeFloat) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Sampled Type to be either void or"
             << " numerical scalar type";
    }
  }

  // Universal checks on image type operands
  // Dim and Format and Access Qualifier are 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 (info.multisampled > 1) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Invalid MS " << info.multisampled << " (must be 0 or 1)";
  }

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

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

    if (info.format != spv::ImageFormat::Unknown) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Dim SubpassData requires format Unknown";
    }
  } else if (info.dim == spv::Dim::TileImageDataEXT) {
    if (_.IsVoidType(info.sampled_type)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Dim TileImageDataEXT requires Sampled Type to be not "
                "OpTypeVoid";
    }
    if (info.sampled != 2) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Dim TileImageDataEXT requires Sampled to be 2";
    }
    if (info.format != spv::ImageFormat::Unknown) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Dim TileImageDataEXT requires format Unknown";
    }
    if (info.depth != 0) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Dim TileImageDataEXT requires Depth to be 0";
    }
    if (info.arrayed != 0) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Dim TileImageDataEXT requires Arrayed to be 0";
    }
  } else {
    if (info.multisampled && (info.sampled == 2) &&
        !_.HasCapability(spv::Capability::StorageImageMultisample)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Capability StorageImageMultisample is required when using "
                "multisampled storage image";
    }
  }

  if (spvIsOpenCLEnv(target_env)) {
    if ((info.arrayed == 1) && (info.dim != spv::Dim::Dim1D) &&
        (info.dim != spv::Dim::Dim2D)) {
      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 != 0) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "MS must be 0 in the OpenCL environment.";
    }

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

    if (info.access_qualifier == spv::AccessQualifier::Max) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "In the OpenCL environment, the optional Access Qualifier"
             << " must be present.";
    }
  }

  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 (info.dim == spv::Dim::SubpassData && info.arrayed != 0) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << _.VkErrorID(6214)
             << "Dim SubpassData requires Arrayed to be 0 in the Vulkan "
                "environment";
    }

    if (info.dim == spv::Dim::Rect) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << _.VkErrorID(9638)
             << "Dim must not be Rect in the Vulkan environment";
    }

    // Can't check signedness here due to image operands (SignExtend or
    // ZeroExtend) ability to overridesampled type
    if (info.format != spv::ImageFormat::Unknown) {
      // validated above so can assume this is a
      // 32-bit float, 32-bit int, or 64-bit int
      const bool is_int = _.IsIntScalarType(info.sampled_type);
      const bool is_float = !is_int;
      if ((is_float && !IsFloatImageFormat(info.format)) ||
          (is_int && !IsIntImageFormat(info.format))) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << _.VkErrorID(4965)
               << "Image Format type does not match Sample Type operand ("
               << (is_int ? "integer" : "float") << ")";
      } else if (is_int) {
        const uint32_t bit_width = _.GetBitWidth(info.sampled_type);
        // format check above to be int
        if ((bit_width == 32 && IsInt64ImageFormat(info.format)) ||
            (bit_width == 64 && !IsInt64ImageFormat(info.format))) {
          return _.diag(SPV_ERROR_INVALID_DATA, inst)
                 << _.VkErrorID(4965)
                 << "Image Format width does not match Sample Type "
                    "operand (bit width of "
                 << bit_width << ")";
        }
      }
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateTypeSampledImage(ValidationState_t& _,
                                      const Instruction* inst) {
  const uint32_t image_type = inst->word(2);
  if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) {
    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 Dim is TileImageDataEXT, Sampled must be 2 and this is validated
  // elsewhere.
  if ((info.sampled != 0) && (info.sampled != 1)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << _.VkErrorID(4657)
           << "Sampled image type requires an image type with \"Sampled\" "
              "operand set to 0 or 1";
  }

  // This covers both OpTypeSampledImage and OpSampledImage.
  if (_.version() >= SPV_SPIRV_VERSION_WORD(1, 6) &&
      info.dim == spv::Dim::Buffer) {
    return _.diag(SPV_ERROR_INVALID_ID, inst)
           << "In SPIR-V 1.6 or later, sampled image dimension must not be "
              "Buffer";
  }

  return SPV_SUCCESS;
}

bool IsAllowedSampledImageOperand(spv::Op opcode, ValidationState_t& _) {
  switch (opcode) {
    case spv::Op::OpSampledImage:
    case spv::Op::OpImageSampleImplicitLod:
    case spv::Op::OpImageSampleExplicitLod:
    case spv::Op::OpImageSampleDrefImplicitLod:
    case spv::Op::OpImageSampleDrefExplicitLod:
    case spv::Op::OpImageSampleProjImplicitLod:
    case spv::Op::OpImageSampleProjExplicitLod:
    case spv::Op::OpImageSampleProjDrefImplicitLod:
    case spv::Op::OpImageSampleProjDrefExplicitLod:
    case spv::Op::OpImageGather:
    case spv::Op::OpImageDrefGather:
    case spv::Op::OpImage:
    case spv::Op::OpImageQueryLod:
    case spv::Op::OpImageSparseSampleImplicitLod:
    case spv::Op::OpImageSparseSampleExplicitLod:
    case spv::Op::OpImageSparseSampleDrefImplicitLod:
    case spv::Op::OpImageSparseSampleDrefExplicitLod:
    case spv::Op::OpImageSparseGather:
    case spv::Op::OpImageSparseDrefGather:
    case spv::Op::OpCopyObject:
    case spv::Op::OpImageSampleWeightedQCOM:
    case spv::Op::OpImageBoxFilterQCOM:
    case spv::Op::OpImageBlockMatchSSDQCOM:
    case spv::Op::OpImageBlockMatchSADQCOM:
    case spv::Op::OpImageBlockMatchWindowSADQCOM:
    case spv::Op::OpImageBlockMatchWindowSSDQCOM:
    case spv::Op::OpImageBlockMatchGatherSADQCOM:
    case spv::Op::OpImageBlockMatchGatherSSDQCOM:
    case spv::Op::OpImageGatherQCOM:
    case spv::Op::OpImageSampleFootprintNV:
      return true;
    case spv::Op::OpStore:
      if (_.HasCapability(spv::Capability::BindlessTextureNV)) return true;
      return false;
    default:
      return false;
  }
}

spv_result_t ValidateImageCoordinate(ValidationState_t& _,
                                     const Instruction* inst,
                                     const ImageTypeInfo& info,
                                     uint32_t word_index) {
  const spv::Op opcode = inst->opcode();
  const uint32_t coord_type = _.GetOperandTypeId(inst, word_index);

  const bool float_only =
      opcode == spv::Op::OpImageSampleImplicitLod ||
      opcode == spv::Op::OpImageSampleDrefImplicitLod ||
      opcode == spv::Op::OpImageSampleDrefExplicitLod ||
      opcode == spv::Op::OpImageSampleProjImplicitLod ||
      opcode == spv::Op::OpImageSampleProjExplicitLod ||
      opcode == spv::Op::OpImageSampleProjDrefImplicitLod ||
      opcode == spv::Op::OpImageSampleProjDrefExplicitLod ||
      opcode == spv::Op::OpImageGather ||
      opcode == spv::Op::OpImageGatherQCOM ||
      opcode == spv::Op::OpImageDrefGather ||
      opcode == spv::Op::OpImageQueryLod ||
      opcode == spv::Op::OpImageSparseSampleImplicitLod ||
      opcode == spv::Op::OpImageSparseSampleDrefImplicitLod ||
      opcode == spv::Op::OpImageSparseSampleDrefExplicitLod ||
      opcode == spv::Op::OpImageSparseGather ||
      opcode == spv::Op::OpImageSparseDrefGather;

  const bool int_only = opcode == spv::Op::OpImageFetch ||
                        opcode == spv::Op::OpImageSparseFetch ||
                        opcode == spv::Op::OpImageTexelPointer ||
                        opcode == spv::Op::OpUntypedImageTexelPointerEXT;

  const bool int_or_float = opcode == spv::Op::OpImageSampleExplicitLod ||
                            opcode == spv::Op::OpImageSparseSampleExplicitLod ||
                            opcode == spv::Op::OpImageRead ||
                            opcode == spv::Op::OpImageWrite ||
                            opcode == spv::Op::OpImageSparseRead;

  assert(float_only || int_only || int_or_float);

  if (float_only && !_.IsFloatScalarOrVectorType(coord_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Coordinate to be a 32-bit float scalar or vector";
  } else if (int_only && !_.IsIntScalarOrVectorType(coord_type)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Coordinate to be a 32-bit integer scalar or vector";
  } else if (int_or_float) {
    if (!_.IsFloatScalarOrVectorType(coord_type) &&
        !_.IsIntScalarOrVectorType(coord_type)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Coordinate to be a 32-bit integer or float scalar or "
                "vector";
    }
  }

  // Needs to be after we validate the scalar/vector
  if (_.GetBitWidth(coord_type) != 32) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Coordinate to be a 32-bit scalar or vector";
  }

  const uint32_t min_coord_size = GetMinCoordSize(opcode, info);
  const uint32_t actual_coord_size = _.GetDimension(coord_type);

  if (opcode == spv::Op::OpImageTexelPointer) {
    if (min_coord_size != actual_coord_size) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Coordinate to have " << min_coord_size
             << " components, but given " << actual_coord_size;
    }
  } else 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 (info.dim == spv::Dim::SubpassData) {
    const Instruction* coord_inst =
        _.FindDef(inst->GetOperandAs<uint32_t>(word_index));

    bool is_zero_vector = false;
    if (coord_inst->opcode() == spv::Op::OpConstantNull) {
      is_zero_vector = true;
    } else if (coord_inst->opcode() == spv::Op::OpConstantComposite) {
      // There is zero reason we should be allowing a OpSpecConstantComposite
      if (coord_inst->words().size() == 5) {
        uint64_t val_0 = 0;
        uint64_t val_1 = 0;
        if (_.EvalConstantValUint64(coord_inst->word(3), &val_0) &&
            _.EvalConstantValUint64(coord_inst->word(4), &val_1) &&
            val_0 == 0 && val_1 == 0) {
          is_zero_vector = true;
        }
      }
    }

    if (!is_zero_vector) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << _.VkErrorID(4660)
             << "Expected Coordinate for a SubpassData image to be a "
                "OpConstantComposite of (0,0) or OpConstantNull";
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateSampledImage(ValidationState_t& _,
                                  const Instruction* inst) {
  auto type_inst = _.FindDef(inst->type_id());
  if (type_inst->opcode() != spv::Op::OpTypeSampledImage) {
    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) != spv::Op::OpTypeImage) {
    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";
  }

  // Image operands must match except for depth.
  auto sampled_image_id = type_inst->GetOperandAs<uint32_t>(1);
  if (sampled_image_id != image_type) {
    ImageTypeInfo sampled_info;
    if (!GetImageTypeInfo(_, sampled_image_id, &sampled_info)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Corrupt image type definition";
    }
    if (info.sampled_type != sampled_info.sampled_type ||
        info.dim != sampled_info.dim || info.arrayed != sampled_info.arrayed ||
        info.multisampled != sampled_info.multisampled ||
        info.sampled != sampled_info.sampled ||
        info.format != sampled_info.format ||
        info.access_qualifier != sampled_info.access_qualifier) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image operands must match result image operands except for "
                "depth";
    }
  }

  if (spvIsVulkanEnv(_.context()->target_env)) {
    if (info.sampled != 1) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << _.VkErrorID(6671)
             << "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 == spv::Dim::SubpassData) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image 'Dim' parameter to be not SubpassData.";
  }

  if (_.GetIdOpcode(_.GetOperandTypeId(inst, 3)) != spv::Op::OpTypeSampler) {
    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 == spv::Op::OpPhi ||
          consumer_opcode == spv::Op::OpSelect) {
        return _.diag(SPV_ERROR_INVALID_ID, inst)
               << "Result <id> from OpSampledImage instruction must not appear "
                  "as "
                  "operands of Op"
               << spvOpcodeString(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(consumer_opcode)
               << ", since it is not specified as taking an "
               << "OpTypeSampledImage." << " Found result <id> "
               << _.getIdName(inst->id()) << " as an operand of <id> "
               << _.getIdName(consumer_instr->id()) << ".";
      }
    }
  }

  const Instruction* ld_inst;
  {
    int t_idx = inst->GetOperandAs<int>(2);
    ld_inst = _.FindDef(t_idx);
  }

  if (ld_inst->opcode() == spv::Op::OpLoad) {
    int texture_id = ld_inst->GetOperandAs<int>(2);  // variable to load
    _.RegisterQCOMImageProcessingTextureConsumer(texture_id, ld_inst, inst);
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateImageTexelPointer(ValidationState_t& _,
                                       const Instruction* inst) {
  bool isUntyped = (inst->opcode() == spv::Op::OpUntypedImageTexelPointerEXT);

  const auto result_type = _.FindDef(inst->type_id());
  if (result_type->opcode() != spv::Op::OpTypePointer &&
      result_type->opcode() != spv::Op::OpTypeUntypedPointerKHR) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Result Type to be a pointer";
  }

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

  uint32_t ptr_type = 0;
  if (result_type->opcode() == spv::Op::OpTypePointer) {
    ptr_type = result_type->GetOperandAs<uint32_t>(2);
    const auto ptr_opcode = _.GetIdOpcode(ptr_type);
    if (ptr_opcode != spv::Op::OpTypeInt &&
        ptr_opcode != spv::Op::OpTypeFloat &&
        ptr_opcode != spv::Op::OpTypeVoid &&
        !(ptr_opcode == spv::Op::OpTypeVector &&
          _.HasCapability(spv::Capability::AtomicFloat16VectorNV) &&
          _.IsFloat16Vector2Or4Type(ptr_type))) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Result Type to be a pointer whose Type operand "
                "must be a scalar numerical type or OpTypeVoid";
    }
  }

  const auto image_ptr =
      _.FindDef(_.GetOperandTypeId(inst, (isUntyped ? 3 : 2)));
  if (!image_ptr ||
      (isUntyped && image_ptr->opcode() != spv::Op::OpTypeUntypedPointerKHR) ||
      (!isUntyped && image_ptr->opcode() != spv::Op::OpTypePointer)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image to be "
           << (isUntyped ? "OpTypeUntypedPointerKHR" : "OpTypePointer");
  }

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

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

  if (result_type->opcode() == spv::Op::OpTypePointer &&
      info.sampled_type != ptr_type &&
      !(_.HasCapability(spv::Capability::AtomicFloat16VectorNV) &&
        _.IsFloat16Vector2Or4Type(ptr_type) &&
        _.GetIdOpcode(info.sampled_type) == spv::Op::OpTypeFloat &&
        ((_.GetDimension(ptr_type) == 2 &&
          info.format == spv::ImageFormat::Rg16f) ||
         (_.GetDimension(ptr_type) == 4 &&
          info.format == spv::ImageFormat::Rgba16f)))) {
    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 == spv::Dim::SubpassData) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Image Dim SubpassData cannot be used with "
           << (isUntyped ? "OpUntypedImageTexelPointerEXT"
                         : "OpImageTexelPointer");
  }

  if (info.dim == spv::Dim::TileImageDataEXT) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Image Dim TileImageDataEXT cannot be used with "
           << (isUntyped ? "OpUntypedImageTexelPointerEXT"
                         : "OpImageTexelPointer");
  }

  if (spv_result_t result = ValidateImageCoordinate(
          _, inst, info, /* word_index = */ (isUntyped ? 4 : 3)))
    return result;

  const uint32_t sample_type = _.GetOperandTypeId(inst, (isUntyped ? 5 : 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 (!_.EvalConstantValUint64(
            inst->GetOperandAs<uint32_t>(isUntyped ? 5 : 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)) {
    bool valid_format = info.format == spv::ImageFormat::R64i ||
                        info.format == spv::ImageFormat::R64ui ||
                        info.format == spv::ImageFormat::R32f ||
                        info.format == spv::ImageFormat::R32i ||
                        info.format == spv::ImageFormat::R32ui;
    if (!valid_format &&
        _.HasCapability(spv::Capability::AtomicFloat16VectorNV)) {
      valid_format = info.format == spv::ImageFormat::Rg16f ||
                     info.format == spv::ImageFormat::Rgba16f;
    }

    if (!valid_format) {
      const uint32_t vuid = isUntyped ? 11416 : 4658;
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << _.VkErrorID(vuid)
             << "Expected the Image Format in Image to be R64i, R64ui, R32f, "
                "R32i, or R32ui for Vulkan environment using Op"
             << spvOpcodeString(inst->opcode());
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) {
  const spv::Op 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) != spv::Op::OpTypeSampledImage) {
    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 (IsProj(opcode)) {
    if (spv_result_t result = ValidateImageProj(_, 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) != spv::Op::OpTypeVoid) {
    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";
    }
  }

  if (spv_result_t result =
          ValidateImageCoordinate(_, inst, info, /* word_index = */ 3))
    return result;

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

  if (mask & uint32_t(spv::ImageOperandsMask::ConstOffset)) {
    if (spvIsOpenCLEnv(_.context()->target_env)) {
      if (opcode == spv::Op::OpImageSampleExplicitLod) {
        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;
}

// Validates anything OpImage*Dref* instruction
spv_result_t ValidateImageDref(ValidationState_t& _, const Instruction* inst,
                               const ImageTypeInfo& info) {
  const uint32_t dref_type = _.GetOperandTypeId(inst, 4);
  if (!_.IsFloatScalarType(dref_type, 32)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Dref to be of 32-bit float type";
  }

  if (spvIsVulkanEnv(_.context()->target_env)) {
    if (info.dim == spv::Dim::Dim3D) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << _.VkErrorID(4777)
             << "In Vulkan, OpImage*Dref* instructions must not use images "
                "with a 3D Dim";
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateImageDrefLod(ValidationState_t& _,
                                  const Instruction* inst) {
  const spv::Op 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) != spv::Op::OpTypeSampledImage) {
    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 (IsProj(opcode)) {
    if (spv_result_t result = ValidateImageProj(_, 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);
  }

  if (spv_result_t result =
          ValidateImageCoordinate(_, inst, info, /* word_index = */ 3))
    return result;

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

  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 spv::Op 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) != spv::Op::OpTypeImage) {
    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) != spv::Op::OpTypeVoid) {
    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 == spv::Dim::Cube) {
    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";
  }

  if (spv_result_t result =
          ValidateImageCoordinate(_, inst, info, /* word_index = */ 3))
    return result;

  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 spv::Op 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) != spv::Op::OpTypeSampledImage) {
    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 == spv::Op::OpImageDrefGather ||
      opcode == spv::Op::OpImageSparseDrefGather ||
      _.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) {
    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 != spv::Dim::Dim2D && info.dim != spv::Dim::Cube &&
      info.dim != spv::Dim::Rect) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << _.VkErrorID(4777)
           << "Expected Image 'Dim' to be 2D, Cube, or Rect";
  }

  if (spv_result_t result =
          ValidateImageCoordinate(_, inst, info, /* word_index = */ 3))
    return result;

  unsigned n_additional_operands = 0;
  if (opcode == spv::Op::OpImageGather ||
      opcode == spv::Op::OpImageSparseGather ||
      opcode == spv::Op::OpImageGatherQCOM) {
    const uint32_t component = inst->GetOperandAs<uint32_t>(4);
    const uint32_t component_index_type = _.GetTypeId(component);
    if (!_.IsIntScalarType(component_index_type, 32)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Component to be 32-bit int scalar";
    }
    if (spvIsVulkanEnv(_.context()->target_env)) {
      if (!spvOpcodeIsConstant(_.GetIdOpcode(component))) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << _.VkErrorID(4664)
               << "Expected Component Operand to be a const object for Vulkan "
                  "environment";
      }
    }
    if (opcode == spv::Op::OpImageGatherQCOM) {
      const uint32_t mode = inst->GetOperandAs<uint32_t>(5);
      const uint32_t mode_index_type = _.GetTypeId(mode);
      if (!_.IsIntScalarType(mode_index_type) ||
          _.GetBitWidth(mode_index_type) != 32) {
        return _.diag(SPV_ERROR_INVALID_DATA, inst)
               << "Expected Mode to be 32-bit int scalar";
      }
      const spv::Op modeOpc = _.GetIdOpcode(mode);
      if (spvOpcodeIsConstant(modeOpc) && !spvOpcodeIsSpecConstant(modeOpc)) {
        uint64_t m_val = -1;
        if (_.EvalConstantValUint64(mode, &m_val)) {
          if (m_val == 0) {
            if (!_.HasCapability(spv::Capability::ImageGatherLinearQCOM)) {
              return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
                     << "Mode GatherModesGather4x1QCOM (== 0) requires "
                        "capability ImageGatherLinearQCOM.";
            }
          } else if (m_val < 4) {
            if (!_.HasCapability(
                    spv::Capability::ImageGatherExtendedModesQCOM)) {
              return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
                     << "Mode GatherModesGatherDQCOM (== "
                        "1)/GatherModesGatherH2QCOM (== 2"
                        ")/GatherModesGatherV2QCOM (== 3)"
                        " requires capability ImageGatherExtendedModesQCOM.";
            }
          } else {
            return _.diag(SPV_ERROR_INVALID_DATA, inst)
                   << "GatherModesGather4x1QCOM (== 0)/"
                      "GatherModesGatherDQCOM (== 1)/"
                      "GatherModesGatherH2QCOM (== 2)/"
                      "GatherModesGatherV2QCOM (== 3) "
                      "are the only supported modes.";
          }
        }
      }
      n_additional_operands += 1;
    }
  } else {
    assert(opcode == spv::Op::OpImageDrefGather ||
           opcode == spv::Op::OpImageSparseDrefGather);
    if (spv_result_t result = ValidateImageDref(_, inst, info)) return result;
  }

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

  return SPV_SUCCESS;
}

spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) {
  const spv::Op 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)
             << _.VkErrorID(4780) << "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) != spv::Op::OpTypeImage) {
    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";
      }
    }

    const uint32_t mask = inst->words().size() <= 5 ? 0 : inst->word(5);
    if (mask & uint32_t(spv::ImageOperandsMask::ConstOffset)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "ConstOffset image operand not allowed "
             << "in the OpenCL environment.";
    }
  }

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

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

  if (info.dim == spv::Dim::TileImageDataEXT) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Image Dim TileImageDataEXT cannot be used with "
           << spvOpcodeString(opcode);
  }

  if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) {
    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 = ValidateImageReadWrite(_, inst, info))
    return result;

  if (spv_result_t result =
          ValidateImageCoordinate(_, inst, info, /* word_index = */ 3))
    return result;

  if (spvIsVulkanEnv(_.context()->target_env)) {
    if (info.format == spv::ImageFormat::Unknown &&
        info.dim != spv::Dim::SubpassData &&
        !_.HasCapability(spv::Capability::StorageImageReadWithoutFormat)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Capability StorageImageReadWithoutFormat is required to "
             << "read storage image";
    }
  }

  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) != spv::Op::OpTypeImage) {
    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 == spv::Dim::SubpassData) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Image 'Dim' cannot be SubpassData";
  }

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

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

  if (spv_result_t result =
          ValidateImageCoordinate(_, inst, info, /* word_index = */ 1))
    return result;

  // because it needs to match with 'Sampled Type' the Texel can't be a boolean
  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 (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) {
    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 == spv::ImageFormat::Unknown &&
        info.dim != spv::Dim::SubpassData &&
        !_.HasCapability(spv::Capability::StorageImageWriteWithoutFormat)) {
      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) != spv::Op::OpTypeImage) {
    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() != spv::Op::OpTypeSampledImage) {
    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) != spv::Op::OpTypeImage) {
    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 spv::Dim::Dim1D:
      expected_num_components += 1;
      break;
    case spv::Dim::Dim2D:
    case spv::Dim::Cube:
      expected_num_components += 2;
      break;
    case spv::Dim::Dim3D:
      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, 32)) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Level of Detail to be a 32-bit 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) != spv::Op::OpTypeImage) {
    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 spv::Dim::Dim1D:
    case spv::Dim::Buffer:
      expected_num_components += 1;
      break;
    case spv::Dim::Dim2D:
    case spv::Dim::Cube:
    case spv::Dim::Rect:
      expected_num_components += 2;
      break;
    case spv::Dim::Dim3D:
      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 == spv::Dim::Dim1D || info.dim == spv::Dim::Dim2D ||
      info.dim == spv::Dim::Dim3D || info.dim == spv::Dim::Cube) {
    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";
  }

  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
  if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected operand 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 == spv::Dim::TileImageDataEXT) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Image 'Dim' cannot be TileImageDataEXT";
  }
  return SPV_SUCCESS;
}

spv_result_t ValidateImageQueryLod(ValidationState_t& _,
                                   const Instruction* inst) {
  _.function(inst->function()->id())
      ->RegisterExecutionModelLimitation(
          [&](spv::ExecutionModel model, std::string* message) {
            if (model != spv::ExecutionModel::Fragment &&
                model != spv::ExecutionModel::GLCompute &&
                model != spv::ExecutionModel::MeshEXT &&
                model != spv::ExecutionModel::TaskEXT) {
              if (message) {
                *message = std::string(
                    "OpImageQueryLod requires Fragment, GLCompute, MeshEXT or "
                    "TaskEXT 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 &&
            (models->find(spv::ExecutionModel::GLCompute) != models->end() ||
             models->find(spv::ExecutionModel::MeshEXT) != models->end() ||
             models->find(spv::ExecutionModel::TaskEXT) != models->end()) &&
            (!modes ||
             (modes->find(spv::ExecutionMode::DerivativeGroupLinearKHR) ==
                  modes->end() &&
              modes->find(spv::ExecutionMode::DerivativeGroupQuadsKHR) ==
                  modes->end()))) {
          if (message) {
            *message = std::string(
                "OpImageQueryLod requires DerivativeGroupQuadsKHR "
                "or DerivativeGroupLinearKHR execution mode for GLCompute, "
                "MeshEXT or TaskEXT 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) != spv::Op::OpTypeSampledImage) {
    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 != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D &&
      info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Image 'Dim' must be 1D, 2D, 3D or Cube";
  }

  if (spv_result_t result =
          ValidateImageCoordinate(_, inst, info, /* word_index = */ 3))
    return result;

  // The operand 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) != spv::Op::OpTypeImage) {
    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 spv::Op opcode = inst->opcode();
  if (opcode == spv::Op::OpImageQueryLevels) {
    if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D &&
        info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) {
      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 == spv::Op::OpImageQuerySamples);
    if (info.dim != spv::Dim::Dim2D) {
      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;
}

spv_result_t ValidateImageProcessingQCOMDecoration(ValidationState_t& _, int id,
                                                   spv::Decoration decor) {
  const Instruction* si_inst = nullptr;
  const Instruction* ld_inst = _.FindDef(id);
  bool is_intf_obj = (ld_inst->opcode() == spv::Op::OpSampledImage);
  if (is_intf_obj == true) {
    si_inst = ld_inst;
    int t_idx = si_inst->GetOperandAs<int>(2);  // texture
    ld_inst = _.FindDef(t_idx);
  }
  if (ld_inst->opcode() != spv::Op::OpLoad) {
    return _.diag(SPV_ERROR_INVALID_DATA, ld_inst) << "Expect to see OpLoad";
  }
  int texture_id = ld_inst->GetOperandAs<int>(2);  // variable to load
  if (!_.HasDecoration(texture_id, decor)) {
    return _.diag(SPV_ERROR_INVALID_DATA, ld_inst)
           << "Missing decoration " << _.SpvDecorationString(decor);
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateImageProcessing2QCOMWindowDecoration(ValidationState_t& _,
                                                          int id) {
  const Instruction* ld_inst = _.FindDef(id);
  bool is_intf_obj = (ld_inst->opcode() != spv::Op::OpSampledImage);
  if (is_intf_obj == true) {
    if (ld_inst->opcode() != spv::Op::OpLoad) {
      return _.diag(SPV_ERROR_INVALID_DATA, ld_inst) << "Expect to see OpLoad";
    }
    int texture_id = ld_inst->GetOperandAs<int>(2);  // variable to load
    spv::Decoration decor = spv::Decoration::BlockMatchTextureQCOM;
    if (!_.HasDecoration(texture_id, decor)) {
      return _.diag(SPV_ERROR_INVALID_DATA, ld_inst)
             << "Missing decoration " << _.SpvDecorationString(decor);
    }
    decor = spv::Decoration::BlockMatchSamplerQCOM;
    if (!_.HasDecoration(texture_id, decor)) {
      return _.diag(SPV_ERROR_INVALID_DATA, ld_inst)
             << "Missing decoration " << _.SpvDecorationString(decor);
    }
  } else {
    const Instruction* si_inst = ld_inst;
    int t_idx = si_inst->GetOperandAs<int>(2);  // texture
    const Instruction* t_ld_inst = _.FindDef(t_idx);
    if (t_ld_inst->opcode() != spv::Op::OpLoad) {
      return _.diag(SPV_ERROR_INVALID_DATA, t_ld_inst)
             << "Expect to see OpLoad";
    }
    int texture_id = t_ld_inst->GetOperandAs<int>(2);  // variable to load
    spv::Decoration decor = spv::Decoration::BlockMatchTextureQCOM;
    if (!_.HasDecoration(texture_id, decor)) {
      return _.diag(SPV_ERROR_INVALID_DATA, ld_inst)
             << "Missing decoration " << _.SpvDecorationString(decor);
    }
    int s_idx = si_inst->GetOperandAs<int>(3);  // sampler
    const Instruction* s_ld_inst = _.FindDef(s_idx);
    if (s_ld_inst->opcode() != spv::Op::OpLoad) {
      return _.diag(SPV_ERROR_INVALID_DATA, s_ld_inst)
             << "Expect to see OpLoad";
    }
    int sampler_id = s_ld_inst->GetOperandAs<int>(2);  // variable to load
    decor = spv::Decoration::BlockMatchSamplerQCOM;
    if (!_.HasDecoration(sampler_id, decor)) {
      return _.diag(SPV_ERROR_INVALID_DATA, ld_inst)
             << "Missing decoration " << _.SpvDecorationString(decor);
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateImageProcessingQCOM(ValidationState_t& _,
                                         const Instruction* inst) {
  spv_result_t res = SPV_SUCCESS;
  const spv::Op opcode = inst->opcode();
  switch (opcode) {
    case spv::Op::OpImageSampleWeightedQCOM: {
      int wi_idx = inst->GetOperandAs<int>(4);  // weight
      res = ValidateImageProcessingQCOMDecoration(
          _, wi_idx, spv::Decoration::WeightTextureQCOM);
      break;
    }
    case spv::Op::OpImageBlockMatchSSDQCOM:
    case spv::Op::OpImageBlockMatchSADQCOM: {
      int tgt_idx = inst->GetOperandAs<int>(2);  // target
      res = ValidateImageProcessingQCOMDecoration(
          _, tgt_idx, spv::Decoration::BlockMatchTextureQCOM);
      if (res != SPV_SUCCESS) break;
      int ref_idx = inst->GetOperandAs<int>(4);  // reference
      res = ValidateImageProcessingQCOMDecoration(
          _, ref_idx, spv::Decoration::BlockMatchTextureQCOM);
      break;
    }
    case spv::Op::OpImageBlockMatchWindowSSDQCOM:
    case spv::Op::OpImageBlockMatchWindowSADQCOM: {
      int tgt_idx = inst->GetOperandAs<int>(2);  // target
      res = ValidateImageProcessing2QCOMWindowDecoration(_, tgt_idx);
      if (res != SPV_SUCCESS) break;
      int ref_idx = inst->GetOperandAs<int>(4);  // reference
      res = ValidateImageProcessing2QCOMWindowDecoration(_, ref_idx);
      break;
    }
    case spv::Op::OpImageBlockMatchGatherSSDQCOM:
    case spv::Op::OpImageBlockMatchGatherSADQCOM: {
      int tgt_idx = inst->GetOperandAs<int>(2);  // target
      res = ValidateImageProcessingQCOMDecoration(
          _, tgt_idx, spv::Decoration::BlockMatchTextureQCOM);
      if (res != SPV_SUCCESS) break;
      int ref_idx = inst->GetOperandAs<int>(4);  // reference
      res = ValidateImageProcessingQCOMDecoration(
          _, ref_idx, spv::Decoration::BlockMatchTextureQCOM);
      break;
    }
    default:
      break;
  }

  return res;
}

spv_result_t ValidateTileImageEXT(ValidationState_t& _,
                                  const Instruction* inst) {
  const spv::Op opcode = inst->opcode();

  const uint32_t result_type = inst->type_id();
  const char* result_type_str = GetActualResultTypeStr(opcode);
  if (opcode == spv::Op::OpColorAttachmentReadEXT) {
    if (!_.IsFloatScalarOrVectorType(result_type) &&
        !_.IsIntScalarOrVectorType(result_type)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected " << result_type_str
             << " to be int or float scalar or vector type";
    }

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

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

    if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) {
      const uint32_t result_component_type = _.GetComponentType(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 != spv::Dim::TileImageDataEXT) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image 'Dim' must be TileImageDataEXT";
    }
  } else if (opcode == spv::Op::OpDepthAttachmentReadEXT) {
    if (!_.IsFloatScalarType(result_type, 32)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected " << result_type_str
             << " to be a 32-bit floating-point type scalar";
    }
  } else {
    if (!_.IsIntScalarType(result_type, 32)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected " << result_type_str
             << " to be a 32-bit integer type scalar";
    }
  }

  size_t sample_word_index =
      opcode == spv::Op::OpColorAttachmentReadEXT ? 4 : 3;

  if (inst->words().size() == sample_word_index + 1) {
    const uint32_t sample_id = inst->word(sample_word_index);
    const uint32_t sample_type = _.GetTypeId(sample_id);
    if (!_.IsIntScalarType(sample_type, 32)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Sample to be a 32-bit int scalar";
    }
  }

  _.function(inst->function()->id())
      ->RegisterExecutionModelLimitation(
          spv::ExecutionModel::Fragment,
          spvOpcodeString(opcode) +
              std::string(" requires Fragment execution model"));

  return SPV_SUCCESS;
}

}  // namespace

// Validates correctness of image instructions.
spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) {
  const spv::Op opcode = inst->opcode();
  if (IsImplicitLod(opcode)) {
    _.function(inst->function()->id())
        ->RegisterExecutionModelLimitation([opcode](spv::ExecutionModel model,
                                                    std::string* message) {
          if (model != spv::ExecutionModel::Fragment &&
              model != spv::ExecutionModel::GLCompute &&
              model != spv::ExecutionModel::MeshEXT &&
              model != spv::ExecutionModel::TaskEXT) {
            if (message) {
              *message =
                  std::string(
                      "ImplicitLod instructions require Fragment, GLCompute, "
                      "MeshEXT or TaskEXT 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 &&
              (models->find(spv::ExecutionModel::GLCompute) != models->end() ||
               models->find(spv::ExecutionModel::MeshEXT) != models->end() ||
               models->find(spv::ExecutionModel::TaskEXT) != models->end()) &&
              (!modes ||
               (modes->find(spv::ExecutionMode::DerivativeGroupLinearKHR) ==
                    modes->end() &&
                modes->find(spv::ExecutionMode::DerivativeGroupQuadsKHR) ==
                    modes->end()))) {
            if (message) {
              *message = std::string(
                             "ImplicitLod instructions require "
                             "DerivativeGroupQuadsKHR "
                             "or DerivativeGroupLinearKHR execution mode for "
                             "GLCompute, "
                             "MeshEXT or TaskEXT execution model: ") +
                         spvOpcodeString(opcode);
            }
            return false;
          }
          return true;
        });
  }

  switch (opcode) {
    case spv::Op::OpTypeImage:
      return ValidateTypeImage(_, inst);
    case spv::Op::OpTypeSampledImage:
      return ValidateTypeSampledImage(_, inst);
    case spv::Op::OpSampledImage:
      return ValidateSampledImage(_, inst);
    case spv::Op::OpImageTexelPointer:
    case spv::Op::OpUntypedImageTexelPointerEXT:
      return ValidateImageTexelPointer(_, inst);

    case spv::Op::OpImageSampleImplicitLod:
    case spv::Op::OpImageSampleExplicitLod:
    case spv::Op::OpImageSampleProjImplicitLod:
    case spv::Op::OpImageSampleProjExplicitLod:
    case spv::Op::OpImageSparseSampleImplicitLod:
    case spv::Op::OpImageSparseSampleExplicitLod:
      return ValidateImageLod(_, inst);

    case spv::Op::OpImageSampleDrefImplicitLod:
    case spv::Op::OpImageSampleDrefExplicitLod:
    case spv::Op::OpImageSampleProjDrefImplicitLod:
    case spv::Op::OpImageSampleProjDrefExplicitLod:
    case spv::Op::OpImageSparseSampleDrefImplicitLod:
    case spv::Op::OpImageSparseSampleDrefExplicitLod:
      return ValidateImageDrefLod(_, inst);

    case spv::Op::OpImageFetch:
    case spv::Op::OpImageSparseFetch:
      return ValidateImageFetch(_, inst);

    case spv::Op::OpImageGather:
    case spv::Op::OpImageDrefGather:
    case spv::Op::OpImageSparseGather:
    case spv::Op::OpImageSparseDrefGather:
    case spv::Op::OpImageGatherQCOM:
      return ValidateImageGather(_, inst);

    case spv::Op::OpImageRead:
    case spv::Op::OpImageSparseRead:
      return ValidateImageRead(_, inst);

    case spv::Op::OpImageWrite:
      return ValidateImageWrite(_, inst);

    case spv::Op::OpImage:
      return ValidateImage(_, inst);

    case spv::Op::OpImageQueryFormat:
    case spv::Op::OpImageQueryOrder:
      return ValidateImageQueryFormatOrOrder(_, inst);

    case spv::Op::OpImageQuerySizeLod:
      return ValidateImageQuerySizeLod(_, inst);
    case spv::Op::OpImageQuerySize:
      return ValidateImageQuerySize(_, inst);
    case spv::Op::OpImageQueryLod:
      return ValidateImageQueryLod(_, inst);

    case spv::Op::OpImageQueryLevels:
    case spv::Op::OpImageQuerySamples:
      return ValidateImageQueryLevelsOrSamples(_, inst);

    case spv::Op::OpImageSparseSampleProjImplicitLod:
    case spv::Op::OpImageSparseSampleProjExplicitLod:
    case spv::Op::OpImageSparseSampleProjDrefImplicitLod:
    case spv::Op::OpImageSparseSampleProjDrefExplicitLod:
      return ValidateImageSparseLod(_, inst);

    case spv::Op::OpImageSparseTexelsResident:
      return ValidateImageSparseTexelsResident(_, inst);

    case spv::Op::OpImageSampleWeightedQCOM:
    case spv::Op::OpImageBoxFilterQCOM:
    case spv::Op::OpImageBlockMatchSSDQCOM:
    case spv::Op::OpImageBlockMatchSADQCOM:
    case spv::Op::OpImageBlockMatchWindowSADQCOM:
    case spv::Op::OpImageBlockMatchWindowSSDQCOM:
    case spv::Op::OpImageBlockMatchGatherSADQCOM:
    case spv::Op::OpImageBlockMatchGatherSSDQCOM:
      return ValidateImageProcessingQCOM(_, inst);

    case spv::Op::OpColorAttachmentReadEXT:
    case spv::Op::OpDepthAttachmentReadEXT:
    case spv::Op::OpStencilAttachmentReadEXT:
      return ValidateTileImageEXT(_, inst);

    default:
      break;
  }

  return SPV_SUCCESS;
}

bool IsImageInstruction(const spv::Op opcode) {
  switch (opcode) {
    case spv::Op::OpImageSampleImplicitLod:
    case spv::Op::OpImageSampleDrefImplicitLod:
    case spv::Op::OpImageSampleProjImplicitLod:
    case spv::Op::OpImageSampleProjDrefImplicitLod:
    case spv::Op::OpImageSparseSampleImplicitLod:
    case spv::Op::OpImageSparseSampleDrefImplicitLod:
    case spv::Op::OpImageSparseSampleProjImplicitLod:
    case spv::Op::OpImageSparseSampleProjDrefImplicitLod:

    case spv::Op::OpImageSampleExplicitLod:
    case spv::Op::OpImageSampleDrefExplicitLod:
    case spv::Op::OpImageSampleProjExplicitLod:
    case spv::Op::OpImageSampleProjDrefExplicitLod:
    case spv::Op::OpImageSparseSampleExplicitLod:
    case spv::Op::OpImageSparseSampleDrefExplicitLod:
    case spv::Op::OpImageSparseSampleProjExplicitLod:
    case spv::Op::OpImageSparseSampleProjDrefExplicitLod:

    case spv::Op::OpImage:
    case spv::Op::OpImageFetch:
    case spv::Op::OpImageSparseFetch:
    case spv::Op::OpImageGather:
    case spv::Op::OpImageDrefGather:
    case spv::Op::OpImageSparseGather:
    case spv::Op::OpImageSparseDrefGather:
    case spv::Op::OpImageRead:
    case spv::Op::OpImageSparseRead:
    case spv::Op::OpImageWrite:

    case spv::Op::OpImageQueryFormat:
    case spv::Op::OpImageQueryOrder:
    case spv::Op::OpImageQuerySizeLod:
    case spv::Op::OpImageQuerySize:
    case spv::Op::OpImageQueryLod:
    case spv::Op::OpImageQueryLevels:
    case spv::Op::OpImageQuerySamples:

    case spv::Op::OpImageSampleWeightedQCOM:
    case spv::Op::OpImageBoxFilterQCOM:
    case spv::Op::OpImageBlockMatchSSDQCOM:
    case spv::Op::OpImageBlockMatchSADQCOM:
    case spv::Op::OpImageBlockMatchWindowSADQCOM:
    case spv::Op::OpImageBlockMatchWindowSSDQCOM:
    case spv::Op::OpImageBlockMatchGatherSADQCOM:
    case spv::Op::OpImageBlockMatchGatherSSDQCOM:
    case spv::Op::OpImageGatherQCOM:
      return true;
    default:
      break;
  }
  return false;
}

spv_result_t ValidateQCOMImageProcessingTextureUsages(ValidationState_t& _,
                                                      const Instruction* inst) {
  const spv::Op opcode = inst->opcode();
  if (!IsImageInstruction(opcode)) return SPV_SUCCESS;

  switch (opcode) {
    case spv::Op::OpImageSampleWeightedQCOM:
    case spv::Op::OpImageBoxFilterQCOM:
    case spv::Op::OpImageBlockMatchSSDQCOM:
    case spv::Op::OpImageBlockMatchSADQCOM:
      break;
    case spv::Op::OpImageBlockMatchWindowSADQCOM:
    case spv::Op::OpImageBlockMatchWindowSSDQCOM:
    case spv::Op::OpImageBlockMatchGatherSADQCOM:
    case spv::Op::OpImageBlockMatchGatherSSDQCOM:
      break;
    default:
      for (size_t i = 0; i < inst->operands().size(); ++i) {
        int id = inst->GetOperandAs<int>(i);
        const Instruction* operand_inst = _.FindDef(id);
        if (operand_inst == nullptr) continue;
        if (operand_inst->opcode() == spv::Op::OpLoad) {
          if (_.IsQCOMImageProcessingTextureConsumer(id)) {
            return _.diag(SPV_ERROR_INVALID_DATA, inst)
                   << "Illegal use of QCOM image processing decorated texture";
          }
        }
        if (operand_inst->opcode() == spv::Op::OpSampledImage) {
          if (_.IsQCOMImageProcessingTextureConsumer(id)) {
            return _.diag(SPV_ERROR_INVALID_DATA, inst)
                   << "Illegal use of QCOM image processing decorated texture";
          }
        }
      }
      break;
  }
  return SPV_SUCCESS;
}

}  // namespace val
}  // namespace spvtools
