Skip to content

Commit a969631

Browse files
stefano-bucciarelli-armchemis01
authored andcommitted
layers: New VK_ARM_data_graph extension - Part 2: layers+tests
- not all VUs implemented Co-authored-by: Chetan Mistry <chetan.mistry@arm.com> Co-authored-by: Stefano Bucciarelli <stefano.bucciarelli@arm.com>
1 parent 681e1f4 commit a969631

29 files changed

+2599
-41
lines changed

BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ vvl_sources = [
121121
"layers/core_checks/cc_cmd_buffer.cpp",
122122
"layers/core_checks/cc_cmd_buffer_dynamic.cpp",
123123
"layers/core_checks/cc_copy_blit_resolve.cpp",
124+
"layers/core_checks/cc_data_graph.cpp",
124125
"layers/core_checks/cc_descriptor.cpp",
125126
"layers/core_checks/cc_device.cpp",
126127
"layers/core_checks/cc_device_memory.cpp",

layers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ target_sources(vvl PRIVATE
217217
core_checks/cc_cmd_buffer.cpp
218218
core_checks/cc_copy_blit_resolve.cpp
219219
core_checks/core_validation.h
220+
core_checks/cc_data_graph.cpp
220221
core_checks/cc_descriptor.cpp
221222
core_checks/cc_device.cpp
222223
core_checks/cc_device_memory.cpp

layers/core_checks/cc_android.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,21 @@ bool CoreChecks::ValidateImageImportedHandleANDROID(VkExternalMemoryHandleTypeFl
460460
return skip;
461461
}
462462

463+
bool CoreChecks::ValidateTensorImportedHandleANDROID(VkExternalMemoryHandleTypeFlags handle_types, VkDeviceMemory memory,
464+
VkTensorARM tensor, const Location &loc) const {
465+
bool skip = false;
466+
if ((handle_types & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) == 0) {
467+
const LogObjectList objlist(tensor, memory);
468+
skip |= LogError("VUID-VkBindTensorMemoryInfoARM-memory-09897", objlist, loc.dot(Field::memory),
469+
"(%s) was created with an AHB import operation which is not set "
470+
"VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID in the VkTensorARM (%s) "
471+
"VkExternalMemoryTensorCreateInfoARM::handleTypes (%s)",
472+
FormatHandle(memory).c_str(), FormatHandle(tensor).c_str(),
473+
string_VkExternalMemoryHandleTypeFlags(handle_types).c_str());
474+
}
475+
return skip;
476+
}
477+
463478
// Validate creating an image with an external format
464479
bool CoreChecks::ValidateCreateImageANDROID(const VkImageCreateInfo &create_info, const Location &create_info_loc) const {
465480
bool skip = false;
@@ -617,6 +632,11 @@ bool CoreChecks::ValidateImageImportedHandleANDROID(VkExternalMemoryHandleTypeFl
617632
return false;
618633
}
619634

635+
bool CoreChecks::ValidateTensorImportedHandleANDROID(VkExternalMemoryHandleTypeFlags handle_types, VkDeviceMemory memory,
636+
VkTensorARM tensor, const Location &loc) const {
637+
return false;
638+
}
639+
620640
bool CoreChecks::ValidateCreateImageANDROID(const VkImageCreateInfo &create_info, const Location &create_info_loc) const {
621641
return false;
622642
}

layers/core_checks/cc_data_graph.cpp

Lines changed: 357 additions & 0 deletions
Large diffs are not rendered by default.

layers/core_checks/cc_device.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,10 @@ bool CoreChecks::ValidateDeviceQueueSupport(const Location &loc) const {
771771
vuid = "VUID-vkCreateGraphicsPipelines-device-09662";
772772
flags = VK_QUEUE_GRAPHICS_BIT;
773773
break;
774+
case Func::vkCreateDataGraphPipelinesARM:
775+
vuid = "VUID-vkCreateDataGraphPipelinesARM-device-09927";
776+
flags = VK_QUEUE_DATA_GRAPH_BIT_ARM;
777+
break;
774778
case Func::vkCreateQueryPool:
775779
vuid = "VUID-vkCreateQueryPool-device-09663";
776780
flags = VK_QUEUE_VIDEO_ENCODE_BIT_KHR | VK_QUEUE_VIDEO_DECODE_BIT_KHR | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_GRAPHICS_BIT;

layers/core_checks/cc_device_memory.cpp

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "error_message/error_strings.h"
3434
#include "utils/image_utils.h"
3535
#include "utils/math_utils.h"
36+
#include "state_tracker/data_graph_pipeline_session_state.h"
3637

3738
// For given mem object, verify that it is not null or UNBOUND, if it is, report error. Return skip value.
3839
bool CoreChecks::VerifyBoundMemoryIsValid(const vvl::DeviceMemory *memory_state, const LogObjectList &objlist,
@@ -344,6 +345,15 @@ bool CoreChecks::HasExternalMemoryImportSupport(const vvl::Image &image, VkExter
344345
return (external_properties.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) != 0;
345346
}
346347

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+
347357
bool CoreChecks::PreCallValidateAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
348358
const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory,
349359
const ErrorObject &error_obj) const {
@@ -780,6 +790,8 @@ bool CoreChecks::ValidateInsertMemoryRange(const VulkanTypedHandle &typed_handle
780790
vuid = "VUID-VkBindAccelerationStructureMemoryInfoNV-memoryOffset-03621";
781791
} else if (typed_handle.type == kVulkanObjectTypeTensorARM) {
782792
vuid = "VUID-VkBindTensorMemoryInfoARM-memoryOffset-09713";
793+
} else if (typed_handle.type == kVulkanObjectTypeDataGraphPipelineSessionARM) {
794+
vuid = "VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-memoryOffset-09787";
783795
} else {
784796
assert(false); // Unsupported object type
785797
}
@@ -1589,6 +1601,42 @@ bool CoreChecks::ValidateBindTensorMemoryARM(uint32_t bindInfoCount, const VkBin
15891601
FormatHandle(bind_info.memory).c_str());
15901602
}
15911603
}
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+
}
15921640
}
15931641
return skip;
15941642
}
@@ -2686,3 +2734,104 @@ bool CoreChecks::PreCallValidateBindTensorMemoryARM(VkDevice device, uint32_t bi
26862734
skip |= ValidateBindTensorMemoryARM(bindInfoCount, pBindInfos, error_obj);
26872735
return skip;
26882736
}
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+
}

layers/core_checks/cc_drawdispatch.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1363,7 +1363,7 @@ bool CoreChecks::ValidateActionState(const LastBound &last_bound_state, const Dr
13631363
bool skip = false;
13641364
skip |= ValidateCmd(cb_state, loc);
13651365

1366-
// Quick verify that if there is no pipeine, the shade object is being used
1366+
// Quick verify that if there is no pipeline, the shader object is being used
13671367
if (!pipeline && !enabled_features.shaderObject) {
13681368
return LogError(vuid.pipeline_bound_08606, cb_state.GetObjectList(bind_point), loc,
13691369
"A valid %s pipeline must be bound with vkCmdBindPipeline before calling this command.",

layers/core_checks/cc_spirv.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ bool CoreChecks::ValidatePushConstantUsage(const spirv::Module &module_state, co
185185
return skip;
186186
}
187187

188-
static void TypeToDescriptorTypeSet(const spirv::Module &module_state, uint32_t type_id, uint32_t data_type_id,
189-
vvl::unordered_set<uint32_t> &descriptor_type_set) {
188+
void CoreChecks::TypeToDescriptorTypeSet(const spirv::Module &module_state, uint32_t type_id, uint32_t data_type_id,
189+
vvl::unordered_set<uint32_t> &descriptor_type_set) {
190190
const spirv::Instruction *type = module_state.FindDef(type_id);
191191
assert(type->Opcode() == spv::OpTypePointer || type->Opcode() == spv::OpTypeUntypedPointerKHR);
192192
bool is_storage_buffer = type->StorageClass() == spv::StorageClassStorageBuffer;

layers/core_checks/cc_synchronization.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,11 +1170,12 @@ bool CoreChecks::ValidateStageMasksAgainstQueueCapabilities(const LogObjectList
11701170
return skip;
11711171
}
11721172

1173-
static const std::array<std::pair<VkPipelineStageFlags2KHR, VkQueueFlags>, 4> metaFlags{
1173+
static const std::array<std::pair<VkPipelineStageFlags2KHR, VkQueueFlags>, 5> metaFlags{
11741174
{{VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT, VK_QUEUE_GRAPHICS_BIT},
11751175
{VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT, VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT},
11761176
{VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT, VK_QUEUE_GRAPHICS_BIT},
1177-
{VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT, VK_QUEUE_GRAPHICS_BIT}}};
1177+
{VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT, VK_QUEUE_GRAPHICS_BIT},
1178+
{VK_PIPELINE_STAGE_2_DATA_GRAPH_BIT_ARM, VK_QUEUE_DATA_GRAPH_BIT_ARM}}};
11781179

11791180
for (const auto &entry : metaFlags) {
11801181
if (((entry.first & stage_mask) != 0) && ((entry.second & queue_flags) == 0)) {

layers/core_checks/cc_tensor.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,9 @@ bool CoreChecks::ValidateTensorFormatUsage(VkFormat format, VkTensorUsageFlagsAR
4848
auto usage_bit = element.first;
4949
auto feature_bit = element.second;
5050
if (usage & usage_bit && !(tensor_feature_flags & feature_bit)) {
51-
skip |= LogError(vuid, device, loc.dot(Field::usage),
52-
"(%s) has bit (%s) set but format features (%s) does not include matching required bit (%s)",
51+
skip |= LogError(vuid, device, loc.dot(Field::usage), "(%s) has bit (%s) set but format features (%s) does not include matching required bit (%s)",
5352
string_VkTensorUsageFlagsARM(usage).c_str(), string_VkTensorUsageFlagsARM(usage_bit).c_str(),
54-
string_VkFormatFeatureFlags2(tensor_feature_flags).c_str(),
55-
string_VkFormatFeatureFlags2(feature_bit).c_str());
53+
string_VkTensorUsageFlagsARM(tensor_feature_flags).c_str(), string_VkTensorUsageFlagsARM(feature_bit).c_str());
5654
}
5755
}
5856

@@ -97,7 +95,7 @@ bool CoreChecks::ValidateTensorCreateInfo(const VkTensorCreateInfoARM &create_in
9795
const auto required_bits = VK_TENSOR_USAGE_SHADER_BIT_ARM | VK_TENSOR_USAGE_DATA_GRAPH_BIT_ARM;
9896
if ((description.usage & required_bits) == 0) {
9997
skip |= ValidateTensorFormatUsage(description.format, description.usage, description.tiling,
100-
"VUID-VkTensorCreateInfoARM-pDescription-09728", create_info_loc);
98+
"VUID-VkTensorCreateInfoARM-pDescription-09728", create_info_loc);
10199
}
102100

103101
return skip;

0 commit comments

Comments
 (0)