MCPcopy Create free account
hub / github.com/KhronosGroup/SPIRV-Tools / ValidateVariableInitializer

Function ValidateVariableInitializer

source/val/validate_memory.cpp:432–521  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

430}
431
432spv_result_t ValidateVariableInitializer(ValidationState_t& _,
433 const Instruction* inst,
434 spv::StorageClass storage_class,
435 uint32_t value_id) {
436 const bool untyped_pointer = inst->opcode() == spv::Op::OpUntypedVariableKHR;
437 const uint32_t initializer_index = untyped_pointer ? 4u : 3u;
438 if (initializer_index < inst->operands().size()) {
439 const uint32_t initializer_id =
440 inst->GetOperandAs<uint32_t>(initializer_index);
441 const Instruction* initializer = _.FindDef(initializer_id);
442 const uint32_t storage_class_index = 2u;
443 const bool is_module_scope_var =
444 initializer &&
445 (initializer->opcode() == spv::Op::OpVariable ||
446 initializer->opcode() == spv::Op::OpUntypedVariableKHR) &&
447 (initializer->GetOperandAs<spv::StorageClass>(storage_class_index) !=
448 spv::StorageClass::Function);
449 const bool is_constant =
450 initializer && spvOpcodeIsConstant(initializer->opcode());
451 if (!initializer || !(is_constant || is_module_scope_var)) {
452 return _.diag(SPV_ERROR_INVALID_ID, inst)
453 << "Variable Initializer <id> " << _.getIdName(initializer_id)
454 << " is not a constant or module-scope variable.";
455 }
456 if (initializer->type_id() != value_id) {
457 return _.diag(SPV_ERROR_INVALID_ID, inst)
458 << "Initializer type must match the data type";
459 }
460 }
461
462 // Vulkan Appendix A: Check that if contains initializer, then
463 // storage class is Output, Private, or Function.
464 if (inst->operands().size() > initializer_index &&
465 storage_class != spv::StorageClass::Output &&
466 storage_class != spv::StorageClass::Private &&
467 storage_class != spv::StorageClass::Function) {
468 if (spvIsVulkanEnv(_.context()->target_env)) {
469 if (storage_class == spv::StorageClass::Workgroup) {
470 auto init_id = inst->GetOperandAs<uint32_t>(initializer_index);
471 auto init = _.FindDef(init_id);
472 if (init->opcode() != spv::Op::OpConstantNull) {
473 return _.diag(SPV_ERROR_INVALID_ID, inst)
474 << _.VkErrorID(4734) << "OpVariable, <id> "
475 << _.getIdName(inst->id())
476 << ", initializers are limited to OpConstantNull in "
477 "Workgroup "
478 "storage class";
479 }
480 } else if (storage_class != spv::StorageClass::Output &&
481 storage_class != spv::StorageClass::Private &&
482 storage_class != spv::StorageClass::Function) {
483 return _.diag(SPV_ERROR_INVALID_ID, inst)
484 << _.VkErrorID(4651) << "OpVariable, <id> "
485 << _.getIdName(inst->id())
486 << ", has a disallowed initializer & storage class "
487 << "combination.\n"
488 << "From " << spvLogStringForEnv(_.context()->target_env)
489 << " spec:\n"

Callers 1

ValidateVariableFunction · 0.85

Calls 13

spvOpcodeIsConstantFunction · 0.85
spvIsVulkanEnvFunction · 0.85
spvLogStringForEnvFunction · 0.85
operandsMethod · 0.80
FindDefMethod · 0.80
diagMethod · 0.80
getIdNameMethod · 0.80
VkErrorIDMethod · 0.80
opcodeMethod · 0.45
sizeMethod · 0.45
type_idMethod · 0.45
contextMethod · 0.45

Tested by

no test coverage detected