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

#include <string>

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

namespace spvtools {
namespace val {
namespace {

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return plane_size;
}

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

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

// Checks ImageOperand bitfield and respective operands.
spv_result_t ValidateImageOperands(ValidationState_t& _,
                                   const Instruction* inst,
                                   const ImageTypeInfo& info, uint32_t mask,
                                   uint32_t word_index) {
  static const bool kAllImageOperandsHandled = CheckAllImageOperandsHandled();
  (void)kAllImageOperandsHandled;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return SPV_SUCCESS;
}

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

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

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

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

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

  return SPV_SUCCESS;
}

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

    default: { return false; }
  }

  return false;
}

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

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

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

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

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

  return SPV_SUCCESS;
}

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

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

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

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

  // Dim is checked elsewhere.

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

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

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

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

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

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

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

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

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

  // Format and Access Qualifier are also checked elsewhere.

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

  return SPV_SUCCESS;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  if (inst->words().size() <= 5) {
    assert(IsImplicitLod(opcode));
    return SPV_SUCCESS;
  }

  const uint32_t mask = inst->word(5);

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

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

  return SPV_SUCCESS;
}

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

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

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

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

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

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

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

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

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

  if (inst->words().size() <= 6) {
    assert(IsImplicitLod(opcode));
    return SPV_SUCCESS;
  }

  const uint32_t mask = inst->word(6);
  if (spv_result_t result =
          ValidateImageOperands(_, inst, info, mask, /* word_index = */ 7))
    return result;

  return SPV_SUCCESS;
}

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

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

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

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

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

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

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

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

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

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

  if (inst->words().size() <= 5) return SPV_SUCCESS;

  const uint32_t mask = inst->word(5);
  if (spv_result_t result =
          ValidateImageOperands(_, inst, info, mask, /* word_index = */ 6))
    return result;

  return SPV_SUCCESS;
}

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

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

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

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

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

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

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

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

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

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

  if (inst->words().size() <= 6) return SPV_SUCCESS;

  const uint32_t mask = inst->word(6);
  if (spv_result_t result =
          ValidateImageOperands(_, inst, info, mask, /* word_index = */ 7))
    return result;

  return SPV_SUCCESS;
}

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

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

#if 0
  // TODO(atgoo@github.com) Disabled until the spec is clarified.
  if (_.GetDimension(actual_result_type) != 4) {
    return _.diag(SPV_ERROR_INVALID_DATA, inst)
           << "Expected " << GetActualResultTypeStr(opcode)
           << " to have 4 components";
  }
#endif

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

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

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

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

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

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

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

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

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

  if (inst->words().size() <= 5) return SPV_SUCCESS;

  const uint32_t mask = inst->word(5);

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

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

  return SPV_SUCCESS;
}

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

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

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

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

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

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

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

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

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

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

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

  const uint32_t mask = inst->word(4);
  if (spv_result_t result =
          ValidateImageOperands(_, inst, info, mask, /* word_index = */ 5))
    return result;

  return SPV_SUCCESS;
}

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

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

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

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

  return SPV_SUCCESS;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

  return SPV_SUCCESS;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  const SpvOp opcode = inst->opcode();
  if (opcode == SpvOpImageQueryLevels) {
    if (info.dim != SpvDim1D && info.dim != SpvDim2D && info.dim != SpvDim3D &&
        info.dim != SpvDimCube) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst)
             << "Image 'Dim' must be 1D, 2D, 3D or Cube";
    }
  } else {
    assert(opcode == SpvOpImageQuerySamples);
    if (info.dim != SpvDim2D) {
      return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'Dim' must be 2D";
    }

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

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

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

  return SPV_SUCCESS;
}

}  // namespace

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

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

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

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

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

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

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

    case SpvOpImageWrite:
      return ValidateImageWrite(_, inst);

    case SpvOpImage:
      return ValidateImage(_, inst);

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

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

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

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

    case SpvOpImageSparseTexelsResident:
      return ValidateImageSparseTexelsResident(_, inst);

    default:
      break;
  }

  return SPV_SUCCESS;
}

}  // namespace val
}  // namespace spvtools
