// 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;
}

// 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;
  }

  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";
  }

  // 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";
    }

    // Multisampled is already checked.
  }

  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";
    }

    // Multisampled is already checked.
  }

  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;
    }

    // Multisampled is already checked.
  }

  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) {
        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) {
      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;
  }

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

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

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

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

  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";
  }

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

  const auto target_env = _.context()->target_env;
  if (spvIsVulkanEnv(target_env)) {
    if (!_.IsFloatScalarType(info.sampled_type, 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";
    }
  }

  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::OpImageSampleFootprintNV:
      return true;
    case spv::Op::OpStore:
      if (_.HasCapability(spv::Capability::BindlessTextureNV)) return true;
      return false;
    default:
      return false;
  }
}

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) {
  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, 2));
  if (!image_ptr || image_ptr->opcode() != spv::Op::OpTypePointer) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected Image to be OpTypePointer";
  }

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

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

  if (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 OpImageTexelPointer";
  }

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

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

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

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

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

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

  if (spvIsVulkanEnv(_.context()->target_env)) {
    if ((info.format != spv::ImageFormat::R64i) &&
        (info.format != spv::ImageFormat::R64ui) &&
        (info.format != spv::ImageFormat::R32f) &&
        (info.format != spv::ImageFormat::R32i) &&
        (info.format != spv::ImageFormat::R32ui) &&
        !((info.format == spv::ImageFormat::Rg16f ||
           info.format == spv::ImageFormat::Rgba16f) &&
          _.HasCapability(spv::Capability::AtomicFloat16VectorNV))) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << _.VkErrorID(4658)
             << "Expected the Image Format in Image to be R64i, R64ui, R32f, "
                "R32i, or R32ui for Vulkan environment";
    }
  }

  return SPV_SUCCESS;
}

spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) {
  const 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";
    }
  }

  const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
  if ((opcode == spv::Op::OpImageSampleExplicitLod ||
       opcode == spv::Op::OpImageSparseSampleExplicitLod) &&
      _.HasCapability(spv::Capability::Kernel)) {
    if (!_.IsFloatScalarOrVectorType(coord_type) &&
        !_.IsIntScalarOrVectorType(coord_type)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Coordinate to be int or float scalar or vector";
    }
  } else {
    if (!_.IsFloatScalarOrVectorType(coord_type)) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Expected Coordinate to be float scalar or vector";
    }
  }

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

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

  if (mask & 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);
  }

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

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

  if (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";
  }

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

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

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

  return SPV_SUCCESS;
}

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

  const 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";
  }

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

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

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

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

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

  if (spvIsVulkanEnv(_.context()->target_env)) {
    if (info.format == 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;

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

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

  // 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";
  }

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

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

  // The 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;
}

}  // 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:
      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:
      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);

    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:
      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
