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

Function ValidateVariableVulkanArray

source/val/validate_memory.cpp:793–861  ·  view source on GitHub ↗

Vulkan specific validation rules for OpTypeRuntimeArray

Source from the content-addressed store, hash-verified

791
792// Vulkan specific validation rules for OpTypeRuntimeArray
793spv_result_t ValidateVariableVulkanArray(ValidationState_t& _,
794 const Instruction* inst,
795 spv::StorageClass storage_class,
796 const Instruction& value_type,
797 uint32_t value_id) {
798 // OpTypeRuntimeArray should only ever be in a container like OpTypeStruct,
799 // so should never appear as a bare variable.
800 // Unless the module has the RuntimeDescriptorArray capability.
801 if (value_type.opcode() == spv::Op::OpTypeRuntimeArray) {
802 if (!_.HasCapability(spv::Capability::RuntimeDescriptorArray)) {
803 return _.diag(SPV_ERROR_INVALID_ID, inst)
804 << _.VkErrorID(4680) << "OpVariable, <id> "
805 << _.getIdName(inst->id())
806 << ", is attempting to create memory for an illegal type, "
807 << "OpTypeRuntimeArray.\nFor Vulkan OpTypeRuntimeArray can only "
808 << "appear as the final member of an OpTypeStruct, thus cannot "
809 << "be instantiated via OpVariable, unless the "
810 "RuntimeDescriptorArray Capability is declared";
811 } else {
812 // A bare variable OpTypeRuntimeArray is allowed in this context, but
813 // still need to check the storage class.
814 if (storage_class != spv::StorageClass::StorageBuffer &&
815 storage_class != spv::StorageClass::Uniform &&
816 storage_class != spv::StorageClass::UniformConstant) {
817 return _.diag(SPV_ERROR_INVALID_ID, inst)
818 << _.VkErrorID(4680)
819 << "For Vulkan with RuntimeDescriptorArray, a variable "
820 << "containing OpTypeRuntimeArray must have storage class of "
821 << "StorageBuffer, Uniform, or UniformConstant.";
822 }
823 }
824 }
825
826 // If an OpStruct has an OpTypeRuntimeArray somewhere within it, then it
827 // must either have the storage class StorageBuffer and be decorated
828 // with Block, or it must be in the Uniform storage class
829 if (value_type.opcode() == spv::Op::OpTypeStruct) {
830 if (DoesStructContainRTA(_, &value_type)) {
831 if (storage_class == spv::StorageClass::StorageBuffer ||
832 storage_class == spv::StorageClass::PhysicalStorageBuffer) {
833 if (!_.HasDecoration(value_id, spv::Decoration::Block)) {
834 return _.diag(SPV_ERROR_INVALID_ID, inst)
835 << _.VkErrorID(4680)
836 << "For Vulkan, an OpTypeStruct variable containing an "
837 << "OpTypeRuntimeArray must be decorated with Block if it "
838 << "has storage class StorageBuffer or "
839 "PhysicalStorageBuffer.";
840 }
841 } else if (storage_class == spv::StorageClass::Uniform) {
842 // BufferBlock Uniform were always allowed.
843 //
844 // Block Uniform use to be invalid, but Vulkan added
845 // VK_EXT_shader_uniform_buffer_unsized_array and now this is
846 // validated at runtime
847 //
848 // The uniform must have either the Block or BufferBlock decoration
849 // (see VUID-StandaloneSpirv-Uniform-06676)
850 } else {

Callers 1

ValidateVariableFunction · 0.85

Calls 8

DoesStructContainRTAFunction · 0.85
diagMethod · 0.80
VkErrorIDMethod · 0.80
getIdNameMethod · 0.80
opcodeMethod · 0.45
HasCapabilityMethod · 0.45
idMethod · 0.45
HasDecorationMethod · 0.45

Tested by

no test coverage detected