|
33 | 33 | #include "error_message/error_strings.h"
|
34 | 34 | #include "utils/image_utils.h"
|
35 | 35 | #include "utils/math_utils.h"
|
| 36 | +#include "state_tracker/data_graph_pipeline_session_state.h" |
36 | 37 |
|
37 | 38 | // For given mem object, verify that it is not null or UNBOUND, if it is, report error. Return skip value.
|
38 | 39 | bool CoreChecks::VerifyBoundMemoryIsValid(const vvl::DeviceMemory *memory_state, const LogObjectList &objlist,
|
@@ -344,6 +345,15 @@ bool CoreChecks::HasExternalMemoryImportSupport(const vvl::Image &image, VkExter
|
344 | 345 | return (external_properties.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) != 0;
|
345 | 346 | }
|
346 | 347 |
|
| 348 | +bool CoreChecks::HasExternalMemoryImportSupport(const vvl::Tensor &tensor, VkExternalMemoryHandleTypeFlagBits handle_type) const { |
| 349 | + VkPhysicalDeviceExternalTensorInfoARM info = vku::InitStructHelper(); |
| 350 | + info.flags = tensor.create_info.flags; |
| 351 | + info.handleType = handle_type; |
| 352 | + VkExternalTensorPropertiesARM properties = vku::InitStructHelper(); |
| 353 | + dispatch_instance_->GetPhysicalDeviceExternalTensorPropertiesARM(physical_device, &info, &properties); |
| 354 | + return (properties.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) != 0; |
| 355 | +} |
| 356 | + |
347 | 357 | bool CoreChecks::PreCallValidateAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
|
348 | 358 | const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory,
|
349 | 359 | const ErrorObject &error_obj) const {
|
@@ -780,6 +790,8 @@ bool CoreChecks::ValidateInsertMemoryRange(const VulkanTypedHandle &typed_handle
|
780 | 790 | vuid = "VUID-VkBindAccelerationStructureMemoryInfoNV-memoryOffset-03621";
|
781 | 791 | } else if (typed_handle.type == kVulkanObjectTypeTensorARM) {
|
782 | 792 | vuid = "VUID-VkBindTensorMemoryInfoARM-memoryOffset-09713";
|
| 793 | + } else if (typed_handle.type == kVulkanObjectTypeDataGraphPipelineSessionARM) { |
| 794 | + vuid = "VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-memoryOffset-09787"; |
783 | 795 | } else {
|
784 | 796 | assert(false); // Unsupported object type
|
785 | 797 | }
|
@@ -1589,6 +1601,42 @@ bool CoreChecks::ValidateBindTensorMemoryARM(uint32_t bindInfoCount, const VkBin
|
1589 | 1601 | FormatHandle(bind_info.memory).c_str());
|
1590 | 1602 | }
|
1591 | 1603 | }
|
| 1604 | + |
| 1605 | + // Validate export memory handles. Check if the memory meets the tensor's external memory requirements |
| 1606 | + if (mem_info->IsExport() && (mem_info->export_handle_types & tensor_state->external_memory_handle_types) == 0) { |
| 1607 | + const LogObjectList objlist(bind_info.tensor, bind_info.memory); |
| 1608 | + skip |= LogError("VUID-VkBindTensorMemoryInfoARM-memory-09895", objlist, bind_info_loc.dot(Field::memory), |
| 1609 | + "(%s) has an external handleType of %s which does not include at least one " |
| 1610 | + "handle from VkTensorARM (%s) handleType %s.", |
| 1611 | + FormatHandle(bind_info.memory).c_str(), |
| 1612 | + string_VkExternalMemoryHandleTypeFlags(mem_info->export_handle_types).c_str(), |
| 1613 | + FormatHandle(bind_info.tensor).c_str(), |
| 1614 | + string_VkExternalMemoryHandleTypeFlags(tensor_state->external_memory_handle_types).c_str()); |
| 1615 | + } |
| 1616 | + |
| 1617 | + // Validate import memory handles |
| 1618 | + if (mem_info->IsImportAHB()) { |
| 1619 | + skip |= ValidateTensorImportedHandleANDROID(tensor_state->external_memory_handle_types, bind_info.memory, bind_info.tensor, bind_info_loc); |
| 1620 | + } else if (mem_info->IsImport()) { |
| 1621 | + if ((mem_info->import_handle_type.value() & tensor_state->external_memory_handle_types) == 0) { |
| 1622 | + const LogObjectList objlist(bind_info.tensor, bind_info.memory); |
| 1623 | + skip |= LogError("VUID-VkBindTensorMemoryInfoARM-memory-09896", objlist, bind_info_loc.dot(Field::memory), |
| 1624 | + "(%s) was created with an import operation with handleType of %s which " |
| 1625 | + "is not set in VkExternalMemoryTensorCreateInfoARM::handleTypes (%s) for (%s)", |
| 1626 | + FormatHandle(bind_info.memory).c_str(), |
| 1627 | + string_VkExternalMemoryHandleTypeFlagBits(mem_info->import_handle_type.value()), |
| 1628 | + string_VkExternalMemoryHandleTypeFlags(tensor_state->external_memory_handle_types).c_str(), |
| 1629 | + FormatHandle(bind_info.tensor).c_str()); |
| 1630 | + } |
| 1631 | + // Check if buffer can be bound to memory imported from specific handle type |
| 1632 | + if (!HasExternalMemoryImportSupport(*tensor_state, mem_info->import_handle_type.value())) { |
| 1633 | + const LogObjectList objlist(bind_info.tensor, bind_info.memory); |
| 1634 | + skip |= LogError( |
| 1635 | + "VUID-VkImportMemoryWin32HandleInfoKHR-handleType-09861", objlist, bind_info_loc.dot(Field::memory), |
| 1636 | + "(%s) was imported from handleType %s but VkExternalTensorProperties does not report it as importable.", |
| 1637 | + FormatHandle(bind_info.memory).c_str(), string_VkExternalMemoryHandleTypeFlagBits(mem_info->import_handle_type.value())); |
| 1638 | + } |
| 1639 | + } |
1592 | 1640 | }
|
1593 | 1641 | return skip;
|
1594 | 1642 | }
|
@@ -2686,3 +2734,104 @@ bool CoreChecks::PreCallValidateBindTensorMemoryARM(VkDevice device, uint32_t bi
|
2686 | 2734 | skip |= ValidateBindTensorMemoryARM(bindInfoCount, pBindInfos, error_obj);
|
2687 | 2735 | return skip;
|
2688 | 2736 | }
|
| 2737 | + |
| 2738 | +bool CoreChecks::ValidateBindDataGraphPipelineSessionMemoryARM(const VkBindDataGraphPipelineSessionMemoryInfoARM &bind_info, |
| 2739 | + const Location &bind_info_loc) const { |
| 2740 | + bool skip = false; |
| 2741 | + auto session_state = Get<vvl::DataGraphPipelineSession>(bind_info.session); |
| 2742 | + ASSERT_AND_RETURN_SKIP(session_state); |
| 2743 | + const LogObjectList objlist(bind_info.session, bind_info.memory); |
| 2744 | + |
| 2745 | + const auto& bp_requirements = session_state->BindPointReqs(); |
| 2746 | + const auto bpr_match = std::find_if(bp_requirements.begin(), bp_requirements.end(), [bind_info](const VkDataGraphPipelineSessionBindPointRequirementARM& bpr) { |
| 2747 | + return bpr.bindPoint == bind_info.bindPoint; |
| 2748 | + }); |
| 2749 | + if (bpr_match == bp_requirements.end()) { |
| 2750 | + std::stringstream required_bindpoints; |
| 2751 | + for (auto &bpr : bp_requirements) { |
| 2752 | + if (!required_bindpoints.str().empty()) { |
| 2753 | + required_bindpoints << ", "; |
| 2754 | + } |
| 2755 | + required_bindpoints << string_VkDataGraphPipelineSessionBindPointARM(bpr.bindPoint); |
| 2756 | + } |
| 2757 | + skip |= LogError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-bindPoint-09786", objlist, |
| 2758 | + bind_info_loc.dot(Field::bindPoint), "bindPoint (%s) not found in requirements (%s).", |
| 2759 | + string_VkDataGraphPipelineSessionBindPointARM(bind_info.bindPoint), required_bindpoints.str().c_str()); |
| 2760 | + } else { |
| 2761 | + if (bind_info.objectIndex > bpr_match->numObjects) { |
| 2762 | + skip |= |
| 2763 | + LogError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-objectIndex-09805", objlist, |
| 2764 | + bind_info_loc.dot(Field::objectIndex), |
| 2765 | + "(%" PRIu32 ") is greater than numObjects (%" PRIu32 ") defined for bindPoint (%s)", bind_info.objectIndex, |
| 2766 | + bpr_match->numObjects, string_VkDataGraphPipelineSessionBindPointARM(bind_info.bindPoint)); |
| 2767 | + } |
| 2768 | + } |
| 2769 | + |
| 2770 | + /* no point continuing if the bindpoint isn't valid: either not found or the index will cause a buffer overrun later on */ |
| 2771 | + if (skip) { |
| 2772 | + return true; |
| 2773 | + } |
| 2774 | + |
| 2775 | + const auto& mem_reqs_map = session_state->MemReqsMap(); |
| 2776 | + const auto &bound_memory_map = session_state->BoundMemoryMap(); |
| 2777 | + if (bound_memory_map.find(bind_info.bindPoint) != bound_memory_map.end()) { |
| 2778 | + for (const auto &bound_mem : bound_memory_map.at(bind_info.bindPoint)) { |
| 2779 | + if (bound_mem.memory_state->VkHandle() == bind_info.memory) { |
| 2780 | + skip |= LogError( |
| 2781 | + "VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-session-09785", objlist, bind_info_loc.dot(Field::bindPoint), |
| 2782 | + "attempting to bind %s to %s which has already been bound to %s.", FormatHandle(bind_info.memory).c_str(), |
| 2783 | + FormatHandle(session_state->Handle()).c_str(), FormatHandle(bound_mem.memory_state->Handle()).c_str()); |
| 2784 | + } |
| 2785 | + } |
| 2786 | + } |
| 2787 | + |
| 2788 | + auto mem_info = Get<vvl::DeviceMemory>(bind_info.memory); |
| 2789 | + ASSERT_AND_RETURN_SKIP(mem_info); |
| 2790 | + skip |= ValidateInsertMemoryRange(VulkanTypedHandle(bind_info.session, kVulkanObjectTypeDataGraphPipelineSessionARM), *mem_info, |
| 2791 | + bind_info.memoryOffset, bind_info_loc.dot(Field::memoryOffset)); |
| 2792 | + if (mem_reqs_map.find(bind_info.bindPoint) != mem_reqs_map.end()) { |
| 2793 | + const auto &mem_reqs = mem_reqs_map.at(bind_info.bindPoint)[bind_info.objectIndex]; |
| 2794 | + skip |= ValidateMemoryTypes(*mem_info, mem_reqs.memoryTypeBits, bind_info_loc.dot(Field::session), |
| 2795 | + "VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-memory-09788"); |
| 2796 | + if (SafeModulo(bind_info.memoryOffset, mem_reqs.alignment) != 0) { |
| 2797 | + skip |= LogError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-memoryOffset-09789", objlist, |
| 2798 | + bind_info_loc.dot(Field::memoryOffset), |
| 2799 | + "(%" PRIu64 ") must be an integer multiple of the alignment member (%" PRIu64 |
| 2800 | + ") of the VkMemoryRequirements structure returned from a call to " |
| 2801 | + "vkGetDataGraphPipelineSessionMemoryRequirementsARM with session", |
| 2802 | + bind_info.memoryOffset, mem_reqs.alignment); |
| 2803 | + } |
| 2804 | + if (mem_reqs.size > (mem_info->allocate_info.allocationSize - bind_info.memoryOffset)) { |
| 2805 | + skip |= LogError( |
| 2806 | + "VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-size-09790", objlist, bind_info_loc.dot(Field::allocationSize), |
| 2807 | + "(%" PRIu64 ") minus memoryOffset (%" PRIu64 ") is less than VkMemoryRequirements::size (%" PRIu64 ").", |
| 2808 | + mem_info->allocate_info.allocationSize, bind_info.memoryOffset, mem_reqs.size); |
| 2809 | + } |
| 2810 | + } |
| 2811 | + // Validate compatible protected session and memory |
| 2812 | + if ((session_state->Unprotected() == false) && (mem_info->unprotected == true)) { |
| 2813 | + const char *vuid = "VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-session-09791"; |
| 2814 | + skip |= LogError(vuid, objlist, bind_info_loc.dot(Field::memory), |
| 2815 | + "(%s) was not created with protected memory but the VkDataGraphPipelineSessionARM (%s) was " |
| 2816 | + "set to use protected memory.", |
| 2817 | + FormatHandle(bind_info.memory).c_str(), FormatHandle(bind_info.session).c_str()); |
| 2818 | + } else if ((session_state->Unprotected() == true) && (mem_info->unprotected == false)) { |
| 2819 | + const char *vuid = "VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-session-09792"; |
| 2820 | + skip |= LogError(vuid, objlist, bind_info_loc.dot(Field::memory), |
| 2821 | + "(%s) was created with protected memory but the VkDataGraphPipelineSessionARM (%s) was not " |
| 2822 | + "set to use protected memory.", |
| 2823 | + FormatHandle(bind_info.memory).c_str(), FormatHandle(bind_info.session).c_str()); |
| 2824 | + } |
| 2825 | + |
| 2826 | + return skip; |
| 2827 | +} |
| 2828 | + |
| 2829 | +bool CoreChecks::PreCallValidateBindDataGraphPipelineSessionMemoryARM(VkDevice device, uint32_t bindInfoCount, |
| 2830 | + const VkBindDataGraphPipelineSessionMemoryInfoARM *pBindInfos, |
| 2831 | + const ErrorObject &error_obj) const { |
| 2832 | + bool skip = false; |
| 2833 | + for (uint32_t i = 0; i < bindInfoCount; i++) { |
| 2834 | + skip |= ValidateBindDataGraphPipelineSessionMemoryARM(pBindInfos[i], error_obj.location.dot(Field::pBindInfos, i)); |
| 2835 | + } |
| 2836 | + return skip; |
| 2837 | +} |
0 commit comments