Checks ImageOperand bitfield and respective operands. word_index is the index of the first word after the image-operand mask word.
| 372 | // Checks ImageOperand bitfield and respective operands. |
| 373 | // word_index is the index of the first word after the image-operand mask word. |
| 374 | spv_result_t ValidateImageOperands(ValidationState_t& _, |
| 375 | const Instruction* inst, |
| 376 | const ImageTypeInfo& info, |
| 377 | uint32_t word_index) { |
| 378 | static const bool kAllImageOperandsHandled = CheckAllImageOperandsHandled(); |
| 379 | (void)kAllImageOperandsHandled; |
| 380 | |
| 381 | const spv::Op opcode = inst->opcode(); |
| 382 | const size_t num_words = inst->words().size(); |
| 383 | |
| 384 | const bool have_explicit_mask = (word_index - 1 < num_words); |
| 385 | const uint32_t mask = have_explicit_mask ? inst->word(word_index - 1) : 0u; |
| 386 | |
| 387 | if (have_explicit_mask) { |
| 388 | // NonPrivate, Volatile, SignExtend, ZeroExtend take no operand words. |
| 389 | const uint32_t mask_bits_having_operands = |
| 390 | mask & ~uint32_t(spv::ImageOperandsMask::NonPrivateTexelKHR | |
| 391 | spv::ImageOperandsMask::VolatileTexelKHR | |
| 392 | spv::ImageOperandsMask::SignExtend | |
| 393 | spv::ImageOperandsMask::ZeroExtend | |
| 394 | spv::ImageOperandsMask::Nontemporal); |
| 395 | size_t expected_num_image_operand_words = |
| 396 | spvtools::utils::CountSetBits(mask_bits_having_operands); |
| 397 | if (mask & uint32_t(spv::ImageOperandsMask::Grad)) { |
| 398 | // Grad uses two words. |
| 399 | ++expected_num_image_operand_words; |
| 400 | } |
| 401 | |
| 402 | if (expected_num_image_operand_words != num_words - word_index) { |
| 403 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 404 | << "Number of image operand ids doesn't correspond to the bit " |
| 405 | "mask"; |
| 406 | } |
| 407 | } else if (num_words != word_index - 1) { |
| 408 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 409 | << "Number of image operand ids doesn't correspond to the bit mask"; |
| 410 | } |
| 411 | |
| 412 | if (info.multisampled & |
| 413 | (0 == (mask & uint32_t(spv::ImageOperandsMask::Sample)))) { |
| 414 | return _.diag(SPV_ERROR_INVALID_DATA, inst) |
| 415 | << "Image Operand Sample is required for operation on " |
| 416 | "multi-sampled image"; |
| 417 | } |
| 418 | |
| 419 | // The following OpTypeImage checks are done here as they depend of if the |
| 420 | // SignExtend and ZeroExtend are used to override the signedness |
| 421 | const bool is_sign_extend = |
| 422 | mask & uint32_t(spv::ImageOperandsMask::SignExtend); |
| 423 | const bool is_zero_extend = |
| 424 | mask & uint32_t(spv::ImageOperandsMask::ZeroExtend); |
| 425 | if (spvIsVulkanEnv(_.context()->target_env)) { |
| 426 | if (info.format != spv::ImageFormat::Unknown && |
| 427 | _.IsIntScalarType(info.sampled_type)) { |
| 428 | const bool is_format_signed = IsSignedIntImageFormat(info.format); |
| 429 | const bool is_sampled_type_signed = |
| 430 | _.IsSignedIntScalarType(info.sampled_type); |
| 431 | // (vkspec.html#spirvenv-image-signedness) has order signedness is set by |
no test coverage detected