| /* |
| * Copyright (c) 2025 The Khronos Group Inc. |
| * Copyright (C) 2025 Arm Limited. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| */ |
| |
| #include "layer_validation_tests.h" |
| #include "pipeline_helper.h" |
| #include "descriptor_helper.h" |
| #include "data_graph_objects.h" |
| #include "generated/pnext_chain_extraction.h" |
| #include "../layers/utils/vk_struct_compare.h" |
| #include <vector> |
| |
| class NegativeDataGraph : public DataGraphTest {}; |
| |
| TEST_F(NegativeDataGraph, CreateDataGraphPipelinesFeatureNotEnabled) { |
| TEST_DESCRIPTION("Try to create a DataGraphPipeline when the dataGraph feature is not enabled"); |
| // add all the requirements of InitBasicDataGraph except dataGraph |
| SetTargetApiVersion(VK_API_VERSION_1_4); |
| AddRequiredExtensions(VK_ARM_TENSORS_EXTENSION_NAME); |
| AddRequiredExtensions(VK_ARM_DATA_GRAPH_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::tensors); |
| AddRequiredFeature(vkt::Feature::dataGraphShaderModule); |
| AddRequiredFeature(vkt::Feature::shaderTensorAccess); |
| AddRequiredFeature(vkt::Feature::vulkanMemoryModel); |
| AddRequiredFeature(vkt::Feature::shaderInt8); |
| RETURN_IF_SKIP(Init()); |
| |
| // this error is generated by the spirv verification, which runs already in the constructor |
| m_errorMonitor->SetAllowedFailureMsg("VUID-VkShaderModuleCreateInfo-pCode-08740"); |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCreateDataGraphPipelinesARM-dataGraph-09760"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, CreateDataGraphPipelinesDeferredOperationNotNull) { |
| TEST_DESCRIPTION("Try to create a DataGraphPipeline when deferredOperation is not VK_NULL_HANDLE"); |
| InitBasicDataGraph(); |
| AddRequiredExtensions(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline_helper(*this); |
| VkDeferredOperationKHR deferred_operation; |
| vk::CreateDeferredOperationKHR(*m_device, nullptr, &deferred_operation); |
| VkPipeline pipeline; |
| m_errorMonitor->SetDesiredError("VUID-vkCreateDataGraphPipelinesARM-deferredOperation-09761"); |
| vk::CreateDataGraphPipelinesARM(*m_device, deferred_operation, VK_NULL_HANDLE, 1, &pipeline_helper.pipeline_ci_, nullptr, |
| &pipeline); |
| m_errorMonitor->VerifyFound(); |
| vk::DestroyDeferredOperationKHR(*m_device, deferred_operation, nullptr); |
| } |
| |
| TEST_F(NegativeDataGraph, CreateDataGraphPipelinesDeferredOperationWrongFlags) { |
| TEST_DESCRIPTION("Try to create a DataGraphPipeline with deferredOperation and invalid pipeline flags"); |
| InitBasicDataGraph(); |
| AddRequiredExtensions(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineCreationCacheControl); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline_helper(*this); |
| VkDeferredOperationKHR deferred_operation; |
| vk::CreateDeferredOperationKHR(*m_device, nullptr, &deferred_operation); |
| VkPipeline pipeline; |
| |
| // set the wrong flags in the pipeline create info |
| pipeline_helper.pipeline_ci_.flags |= VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT; |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCreateDataGraphPipelinesARM-deferredOperation-09916"); |
| // this is also triggered because deferredOperations currently MUST be NULL |
| m_errorMonitor->SetDesiredError("VUID-vkCreateDataGraphPipelinesARM-deferredOperation-09761"); |
| vk::CreateDataGraphPipelinesARM(*m_device, deferred_operation, VK_NULL_HANDLE, 1, &pipeline_helper.pipeline_ci_, nullptr, |
| &pipeline); |
| m_errorMonitor->VerifyFound(); |
| vk::DestroyDeferredOperationKHR(*m_device, deferred_operation, nullptr); |
| } |
| |
| TEST_F(NegativeDataGraph, CreateDataGraphPipelinesInvalidFlags) { |
| TEST_DESCRIPTION("Try to create a DataGraphPipeline with invalid flags in create_info"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| auto set_info = [](vkt::dg::DataGraphPipelineHelper& pipeline) { |
| pipeline.pipeline_ci_.flags = VK_PIPELINE_CREATE_2_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR; |
| }; |
| vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0, "VUID-VkDataGraphPipelineCreateInfoARM-flags-09764"); |
| } |
| |
| TEST_F(NegativeDataGraph, CreateDataGraphPipelinesNoProtectedAccessButFeatureNotEnabled) { |
| TEST_DESCRIPTION( |
| "Try to create a DataGraphPipeline where flags include VK_PIPELINE_CREATE_2_NO_PROTECTED_ACCESS_BIT_EXT but " |
| "pipelineProtectedAccess is not enabled"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| auto set_info = [](vkt::dg::DataGraphPipelineHelper& pipeline) { |
| pipeline.pipeline_ci_.flags = VK_PIPELINE_CREATE_2_NO_PROTECTED_ACCESS_BIT_EXT; |
| }; |
| vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0, |
| "VUID-VkDataGraphPipelineCreateInfoARM-pipelineProtectedAccess-09772"); |
| } |
| |
| TEST_F(NegativeDataGraph, CreateDataGraphPipelinesProtectedAccessOnlyButFeatureNotEnabled) { |
| TEST_DESCRIPTION( |
| "Try to create a DataGraphPipeline where flags include VK_PIPELINE_CREATE_2_PROTECTED_ACCESS_ONLY_BIT_EXT but " |
| "pipelineProtectedAccess is not enabled"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| auto set_info = [](vkt::dg::DataGraphPipelineHelper& pipeline) { |
| pipeline.pipeline_ci_.flags = VK_PIPELINE_CREATE_2_PROTECTED_ACCESS_ONLY_BIT_EXT; |
| }; |
| vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0, |
| "VUID-VkDataGraphPipelineCreateInfoARM-pipelineProtectedAccess-09772"); |
| } |
| |
| TEST_F(NegativeDataGraph, CreateDataGraphPipelinesBothProtectedAccessBits) { |
| TEST_DESCRIPTION( |
| "Try to create a DataGraphPipeline where flags include both VK_PIPELINE_CREATE_2_NO_PROTECTED_ACCESS_BIT_EXT and " |
| "VK_PIPELINE_CREATE_2_PROTECTED_ACCESS_ONLY_BIT_EXT"); |
| InitBasicDataGraph(); |
| AddRequiredExtensions(VK_EXT_PIPELINE_PROTECTED_ACCESS_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::pipelineProtectedAccess); |
| RETURN_IF_SKIP(Init()); |
| |
| auto set_info = [](vkt::dg::DataGraphPipelineHelper& pipeline) { |
| pipeline.pipeline_ci_.flags = |
| VK_PIPELINE_CREATE_2_NO_PROTECTED_ACCESS_BIT_EXT | VK_PIPELINE_CREATE_2_PROTECTED_ACCESS_ONLY_BIT_EXT; |
| }; |
| vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0, "VUID-VkDataGraphPipelineCreateInfoARM-flags-09773"); |
| } |
| |
| TEST_F(NegativeDataGraph, CreateDataGraphPipelinesStageCreationFeedbackCountNotZero) { |
| TEST_DESCRIPTION( |
| "Try to create a DataGraphPipeline where pNext contains a VkPipelineCreationFeedbackCreateInfo structure but the " |
| "pipelineStageCreationFeedbackCount is not 0"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPipelineCreationFeedback creation_feedback; |
| VkPipelineCreationFeedbackCreateInfo creation_feedback_create_info = vku::InitStructHelper(); |
| creation_feedback_create_info.pPipelineCreationFeedback = &creation_feedback; |
| creation_feedback_create_info.pipelineStageCreationFeedbackCount = 1; |
| creation_feedback_create_info.pPipelineStageCreationFeedbacks = &creation_feedback; |
| auto set_info = [&](vkt::dg::DataGraphPipelineHelper& pipeline) { |
| pipeline.shader_module_ci_.pNext = &creation_feedback_create_info; |
| }; |
| vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0, "VUID-VkDataGraphPipelineCreateInfoARM-pNext-09804"); |
| } |
| |
| TEST_F(NegativeDataGraph, CreateDataGraphPipelinesPushConstantCountNotZero) { |
| TEST_DESCRIPTION( |
| "Try to create a DataGraphPipeline where the layout was created with a non-zero pushConstantRangeCount and non-NULL " |
| "pushConstRange"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| std::vector<VkPushConstantRange> pcr = {{VK_SHADER_STAGE_ALL, 0, sizeof(uint32_t)}}; |
| auto set_info = [&](vkt::dg::DataGraphPipelineHelper& pipeline) { pipeline.CreatePipelineLayout(pcr); }; |
| vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0, "VUID-VkDataGraphPipelineCreateInfoARM-layout-09767"); |
| } |
| |
| TEST_F(NegativeDataGraph, CreateDataGraphPipelinesUpdateAfterBindFeatureNotEnabled) { |
| TEST_DESCRIPTION( |
| "Try to create a DataGraphPipeline where the descriptorSetLayout used sets the BIND_AFTER_USE_BIT but the " |
| "dataGraphUpdateAfterBind is not enabled"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| auto set_info = [&](vkt::dg::DataGraphPipelineHelper& pipeline) { |
| pipeline.descriptor_set_.reset(new OneOffDescriptorSet(pipeline.device_, pipeline.descriptor_set_layout_bindings_, |
| VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, nullptr, |
| VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT)); |
| pipeline.CreatePipelineLayout(); |
| }; |
| vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0, |
| "VUID-VkDataGraphPipelineCreateInfoARM-dataGraphUpdateAfterBind-09768"); |
| } |
| |
| TEST_F(NegativeDataGraph, CreateDataGraphPipelinesMutableDescriptor) { |
| TEST_DESCRIPTION("Try to create a DataGraphPipeline with a MUTABLE descriptor (not allowed in datagraph)"); |
| InitBasicDataGraph(); |
| AddRequiredExtensions(VK_EXT_MUTABLE_DESCRIPTOR_TYPE_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::mutableDescriptorType); |
| RETURN_IF_SKIP(Init()); |
| |
| VkDescriptorType types[] = {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE}; |
| VkMutableDescriptorTypeListEXT mutable_descriptor_type_list = {1, types}; |
| |
| VkMutableDescriptorTypeCreateInfoEXT mutable_descriptor_info = vku::InitStructHelper(); |
| mutable_descriptor_info.mutableDescriptorTypeListCount = 1; |
| mutable_descriptor_info.pMutableDescriptorTypeLists = &mutable_descriptor_type_list; |
| |
| auto set_info = [&](vkt::dg::DataGraphPipelineHelper& pipeline) { |
| pipeline.descriptor_set_layout_bindings_[0].descriptorType = |
| VK_DESCRIPTOR_TYPE_MUTABLE_EXT; // the pipeline sets this to tensor |
| pipeline.descriptor_set_.reset( |
| new OneOffDescriptorSet(pipeline.device_, pipeline.descriptor_set_layout_bindings_, 0, &mutable_descriptor_info)); |
| pipeline.CreatePipelineLayout(); |
| }; |
| vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0, "VUID-VkDataGraphPipelineCreateInfoARM-pSetLayouts-09770"); |
| } |
| |
| TEST_F(NegativeDataGraph, CreateDataGraphPipelinesEarlyReturnFlagCacheControlNotEnabled) { |
| TEST_DESCRIPTION( |
| "Try to create a DataGraphPipeline when flags contains VK_PIPELINE_CREATE_2_EARLY_RETURN_ON_FAILURE_BIT_KHR but the " |
| "pipelineCreationCacheControl feature is not enabled"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| auto set_info = [](vkt::dg::DataGraphPipelineHelper& pipeline) { |
| pipeline.pipeline_ci_.flags = VK_PIPELINE_CREATE_2_EARLY_RETURN_ON_FAILURE_BIT_KHR; |
| }; |
| vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0, |
| "VUID-VkDataGraphPipelineCreateInfoARM-pipelineCreationCacheControl-09871"); |
| } |
| |
| TEST_F(NegativeDataGraph, CreateDataGraphPipelinesFailOnPipelineCompileFlagCacheControlNotEnabled) { |
| TEST_DESCRIPTION( |
| "Try to create a DataGraphPipeline when flags contains VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_KHR but " |
| "the pipelineCreationCacheControl feature is not enabled"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| auto set_info = [](vkt::dg::DataGraphPipelineHelper& pipeline) { |
| pipeline.pipeline_ci_.flags = VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_KHR; |
| }; |
| vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0, |
| "VUID-VkDataGraphPipelineCreateInfoARM-pipelineCreationCacheControl-09871"); |
| } |
| |
| TEST_F(NegativeDataGraph, CreateDataGraphPipelinesTypeMismatch) { |
| TEST_DESCRIPTION( |
| "Try to create a DataGraphPipeline where the descriptor slot in layout does not match the resource item used in the Shader " |
| "Module"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::HelperParameters params; |
| params.desc_type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; // should be tensor |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| // 2 tensors, 2 errors |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-layout-09769"); |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-layout-09769"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| static void InitDefaultComputePipeline(CreateComputePipelineHelper& pipeline, VkRenderFramework* framework) { |
| std::vector<VkDescriptorSetLayoutBinding> bindings = { |
| {0, VK_DESCRIPTOR_TYPE_TENSOR_ARM, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}, |
| {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr}}; |
| |
| pipeline.cs_ = VkShaderObj::CreateFromGLSL(framework, kMinimalTensorGlsl, VK_SHADER_STAGE_COMPUTE_BIT); |
| pipeline.dsl_bindings_.resize(bindings.size()); |
| memcpy(pipeline.dsl_bindings_.data(), bindings.data(), bindings.size() * sizeof(VkDescriptorSetLayoutBinding)); |
| pipeline.CreateComputePipeline(); |
| } |
| |
| TEST_F(NegativeDataGraph, GetDataGraphPipelinePropertiesPipelineNotCreatedWithCreateDataGraphPipeline) { |
| TEST_DESCRIPTION( |
| "Try to get the datagraph pipeline properties for a pipeline not created with vkCreateDataGraphPipelinesARM (i.e. created " |
| "with vkCreateComputePipeline)"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| CreateComputePipelineHelper pipeline(*m_device); |
| InitDefaultComputePipeline(pipeline, this); |
| VkDataGraphPipelineInfoARM pipeline_info = vku::InitStructHelper(); |
| pipeline_info.dataGraphPipeline = pipeline; |
| |
| // query with `pData` null, to get back the required `dataSize`. Enough to trigger the VUID |
| VkDataGraphPipelinePropertyQueryResultARM query_result; |
| query_result = vku::InitStructHelper(); |
| query_result.property = VK_DATA_GRAPH_PIPELINE_PROPERTY_CREATION_LOG_ARM; |
| query_result.pData = nullptr; |
| query_result.dataSize = 0; |
| uint32_t prop_count = 1; |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineInfoARM-dataGraphPipeline-09803"); |
| EXPECT_NE(VK_SUCCESS, vk::GetDataGraphPipelinePropertiesARM(m_device->handle(), &pipeline_info, prop_count, &query_result)); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, GetDataGraphPipelinePropertiesDuplicatedProperty) { |
| TEST_DESCRIPTION("Duplicate property in datagraph pipeline properties request"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| // query with `pData` null, to get back the required `dataSize`. Enough to trigger the VUID |
| VkDataGraphPipelineInfoARM pipeline_info = vku::InitStructHelper(); |
| pipeline_info.dataGraphPipeline = pipeline; |
| std::array<VkDataGraphPipelinePropertyQueryResultARM, 3> query_results; |
| // properties 0 and 2 are the same: error |
| query_results[0] = vku::InitStructHelper(); |
| query_results[0].property = VK_DATA_GRAPH_PIPELINE_PROPERTY_CREATION_LOG_ARM; |
| query_results[0].pData = nullptr; |
| query_results[0].dataSize = 0; |
| query_results[1] = vku::InitStructHelper(); |
| query_results[1].property = VK_DATA_GRAPH_PIPELINE_PROPERTY_IDENTIFIER_ARM; |
| query_results[1].pData = nullptr; |
| query_results[1].dataSize = 0; |
| query_results[2] = vku::InitStructHelper(); |
| query_results[2].property = VK_DATA_GRAPH_PIPELINE_PROPERTY_CREATION_LOG_ARM; |
| query_results[2].pData = nullptr; |
| query_results[2].dataSize = 0; |
| |
| m_errorMonitor->SetDesiredError("VUID-vkGetDataGraphPipelinePropertiesARM-pProperties-09889"); |
| vk::GetDataGraphPipelinePropertiesARM(m_device->handle(), &pipeline_info, query_results.size(), query_results.data()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, SessionCreateInfoInvalidGraphPipeline) { |
| TEST_DESCRIPTION( |
| "Try to create a DataGraphPipelineSession where the dataGraphPipeline member of VkDataGraphPipelineSessionCreateInfoARM " |
| "was " |
| "not created by vkCreateDataGraphPipelinesARM"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| CreateComputePipelineHelper pipeline(*m_device); |
| InitDefaultComputePipeline(pipeline, this); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| |
| VkDataGraphPipelineSessionARM session; |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineSessionCreateInfoARM-dataGraphPipeline-09781"); |
| vk::CreateDataGraphPipelineSessionARM(*m_device, &session_ci, nullptr, &session); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, SessionCreateInfoProtectedMemoryFeatureNotEnabled) { |
| TEST_DESCRIPTION( |
| "Try to create a DataGraphPipelineSession where the flags member of VkDataGraphPipelineSessionCreateInfoARM contains " |
| "VK_DATA_GRAPH_PIPELINE_SESSION_CREATE_PROTECTED_BIT_ARM but the protectedMemory feature is not enabled"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| session_ci.flags = VK_DATA_GRAPH_PIPELINE_SESSION_CREATE_PROTECTED_BIT_ARM; |
| |
| VkDataGraphPipelineSessionARM session; |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineSessionCreateInfoARM-protectedMemory-09782"); |
| vk::CreateDataGraphPipelineSessionARM(*m_device, &session_ci, nullptr, &session); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, SessionGetMemoryRequirementsBindPointNotGottenPrior) { |
| TEST_DESCRIPTION( |
| "Try to get the memory requirements for a session without a prior call to " |
| "vkGetDataGraphPipelineSessionBindPointRequirementsARM"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| |
| VkDataGraphPipelineSessionMemoryRequirementsInfoARM session_mem_reqs = vku::InitStructHelper(); |
| session_mem_reqs.session = session; |
| session_mem_reqs.bindPoint = VK_DATA_GRAPH_PIPELINE_SESSION_BIND_POINT_TRANSIENT_ARM; |
| |
| VkMemoryRequirements2 mem_reqs = vku::InitStructHelper(); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkGetDataGraphPipelineSessionMemoryRequirementsARM-bindPoint-09784"); |
| vk::GetDataGraphPipelineSessionMemoryRequirementsARM(*m_device, &session_mem_reqs, &mem_reqs); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, BindSessionTwice) { |
| TEST_DESCRIPTION("Try to create a bind DataGraphPipelineSession on the same bindpoint twice"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount()); |
| session.AllocSessionMem(device_mem); |
| |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| |
| // bind again to trigger error |
| m_errorMonitor->SetDesiredError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-session-09785"); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, BindSessionMemoryOffsetLargerThanSize) { |
| TEST_DESCRIPTION( |
| "Try to create a bind DataGraphPipelineSession to DeviceMemory at an offset which is larger than the allocated memory " |
| "size"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount()); |
| session.AllocSessionMem(device_mem); |
| |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| auto& mem_req = session.MemReqs()[0]; |
| session_bind_infos[0].memoryOffset = mem_req.memoryRequirements.size + 2 * mem_req.memoryRequirements.alignment; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-memoryOffset-09787"); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, BindSessionMemoryInvalidMemoryBits) { |
| TEST_DESCRIPTION( |
| "Try to create a bind DataGraphPipelineSession on a memory type who's memoryTypeBits is incompatible with the required " |
| "bits"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount()); |
| auto& bind_point_reqs = session.BindPointReqs(); |
| auto& mem_reqs = session.MemReqs(); |
| for (uint32_t i = 0; i < bind_point_reqs.size(); i++) { |
| if (bind_point_reqs[i].bindPointType != VK_DATA_GRAPH_PIPELINE_SESSION_BIND_POINT_TYPE_MEMORY_ARM) { |
| continue; |
| } |
| |
| VkMemoryAllocateInfo session_alloc_info = vku::InitStructHelper(); |
| session_alloc_info.allocationSize = mem_reqs[i].memoryRequirements.size; |
| if (!m_device->Physical().SetMemoryType(~mem_reqs[i].memoryRequirements.memoryTypeBits, &session_alloc_info, 0)) { |
| GTEST_SKIP() << "Memory type not found"; |
| } |
| device_mem[i] = vkt::DeviceMemory(*m_device, session_alloc_info); |
| } |
| |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| m_errorMonitor->SetDesiredError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-memory-09788"); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, BindSessionMemoryInvalidOffsetAlignment) { |
| TEST_DESCRIPTION( |
| "Try to create a bind DataGraphPipelineSession at an offset which is not an integer multiple of the required alignment"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount()); |
| session.AllocSessionMem(device_mem, false, 2); |
| |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| auto& mem_reqs = session.MemReqs(); |
| session_bind_infos[0].memoryOffset = mem_reqs[0].memoryRequirements.alignment - 1; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-memoryOffset-09789"); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, BindSessionMemoryTooSmall) { |
| TEST_DESCRIPTION("Try to create a bind DataGraphPipelineSession to device memory which is too small"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount()); |
| session.AllocSessionMem(device_mem, false, 1, -1); |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-size-09790"); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, BindProtectedSessionToUnprotectedMemory) { |
| TEST_DESCRIPTION("Try to bind a protected DataGraphPipelineSession to unprotected memory"); |
| InitBasicDataGraph(); |
| AddRequiredFeature(vkt::Feature::protectedMemory); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.flags = VK_DATA_GRAPH_PIPELINE_SESSION_CREATE_PROTECTED_BIT_ARM; |
| session_ci.dataGraphPipeline = pipeline; |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| // allocate unprotected memory |
| std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount()); |
| auto& mem_reqs = session.MemReqs(); |
| for (uint32_t i = 0; i < mem_reqs.size(); i++) { |
| VkMemoryAllocateInfo session_alloc_info = vku::InitStructHelper(); |
| session_alloc_info.allocationSize = mem_reqs[i].memoryRequirements.size; |
| auto memoryTypeBits = mem_reqs[i].memoryRequirements.memoryTypeBits; |
| if (!m_device->Physical().SetMemoryType(memoryTypeBits, &session_alloc_info, 0, VK_MEMORY_PROPERTY_PROTECTED_BIT)) { |
| GTEST_SKIP() << "Memory type not found"; |
| } |
| device_mem[i] = vkt::DeviceMemory(*m_device, session_alloc_info); |
| } |
| |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| m_errorMonitor->SetDesiredError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-session-09791"); |
| // we are using a different memory type from the session, which also causes an error with memoryBits |
| m_errorMonitor->SetAllowedFailureMsg("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-memory-09788"); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, BindUnprotectedSessionToProtectedMemory) { |
| TEST_DESCRIPTION("Try to bind an unprotected DataGraphPipelineSession to protected memory"); |
| InitBasicDataGraph(); |
| AddRequiredFeature(vkt::Feature::protectedMemory); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| // allocate protected memory |
| std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount()); |
| auto& mem_reqs = session.MemReqs(); |
| for (uint32_t i = 0; i < mem_reqs.size(); i++) { |
| VkMemoryAllocateInfo session_alloc_info = vku::InitStructHelper(); |
| session_alloc_info.allocationSize = mem_reqs[i].memoryRequirements.size; |
| auto memoryTypeBits = mem_reqs[i].memoryRequirements.memoryTypeBits; |
| if (!m_device->Physical().SetMemoryType(memoryTypeBits, &session_alloc_info, VK_MEMORY_PROPERTY_PROTECTED_BIT)) { |
| GTEST_SKIP() << "Memory type not found"; |
| } |
| device_mem[i] = vkt::DeviceMemory(*m_device, session_alloc_info); |
| } |
| |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| m_errorMonitor->SetDesiredError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-session-09792"); |
| // we are using a different memory type from the session, which also causes an error with memoryBits |
| m_errorMonitor->SetAllowedFailureMsg("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-memory-09788"); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, BindSessionObjectIndexTooLarge) { |
| TEST_DESCRIPTION( |
| "Try to bind a DataGraphPipelineSession when the resource index is larger than the numObjects for the bindPoint"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount()); |
| session.AllocSessionMem(device_mem); |
| |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| session_bind_infos[0].objectIndex = session.BindPointReqs()[0].numObjects + 1; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-objectIndex-09805"); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, BindSessionObjectWrongBindPoint) { |
| TEST_DESCRIPTION("Try to bind a DataGraphPipelineSession with the wrong bindpoint"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount()); |
| session.AllocSessionMem(device_mem); |
| |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| session_bind_infos[0].bindPoint = |
| static_cast<VkDataGraphPipelineSessionBindPointARM>(VK_DATA_GRAPH_PIPELINE_SESSION_BIND_POINT_MAX_ENUM_ARM - 1); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-bindPoint-09786"); |
| // VK_DATA_GRAPH_PIPELINE_SESSION_BIND_POINT_TRANSIENT_ARM is the only legal value for bindPoint, so whatever we |
| // put in place of it, we also trigger this implicit check: |
| m_errorMonitor->SetAllowedFailureMsg("VUID-VkBindDataGraphPipelineSessionMemoryInfoARM-bindPoint-parameter"); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, DestroySessionInUse) { |
| TEST_DESCRIPTION("Try destroying a datagraph pipeline session while it is in use"); |
| InitBasicDataGraph(); |
| AddRequiredFeature(vkt::Feature::timelineSemaphore); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount()); |
| session.AllocSessionMem(device_mem); |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0); |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0); |
| pipeline.descriptor_set_->UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1, |
| &pipeline.descriptor_set_.get()->set_, 0, nullptr); |
| vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr); |
| m_command_buffer.End(); |
| |
| VkSemaphoreTypeCreateInfo sem_type = vku::InitStructHelper(); |
| sem_type.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE; |
| sem_type.initialValue = 0; |
| VkSemaphoreCreateInfo create_sem = vku::InitStructHelper(&sem_type); |
| |
| vkt::Semaphore sem(*m_device, create_sem); |
| VkTimelineSemaphoreSubmitInfo timeline_info = vku::InitStructHelper(); |
| const uint64_t wait_value = 1; |
| timeline_info.waitSemaphoreValueCount = 1; |
| timeline_info.pWaitSemaphoreValues = &wait_value; |
| |
| VkPipelineStageFlags dst_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; |
| |
| VkSubmitInfo submit_info = vku::InitStructHelper(&timeline_info); |
| submit_info.waitSemaphoreCount = 1; |
| submit_info.pWaitSemaphores = &sem.handle(); |
| submit_info.pWaitDstStageMask = &dst_stage_mask; |
| submit_info.commandBufferCount = 1; |
| submit_info.pCommandBuffers = &m_command_buffer.handle(); |
| |
| vk::QueueSubmit(m_default_queue->handle(), 1, &submit_info, VK_NULL_HANDLE); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkDestroyDataGraphPipelineSessionARM-session-09793"); |
| vk::DestroyDataGraphPipelineSessionARM(*m_device, session, nullptr); |
| m_errorMonitor->VerifyFound(); |
| |
| VkSemaphoreSignalInfo signal_sem = vku::InitStructHelper(); |
| signal_sem.semaphore = sem; |
| signal_sem.value = 1; |
| vk::SignalSemaphore(*m_device, &signal_sem); |
| |
| m_default_queue->Wait(); |
| } |
| |
| TEST_F(NegativeDataGraph, DestroySessionCreatedWithDestroyWithoutCallbacks) { |
| TEST_DESCRIPTION("Try destroying without callbacks a datagraph pipeline session with callbacks"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| |
| VkDataGraphPipelineSessionARM session; |
| vk::CreateDataGraphPipelineSessionARM(*m_device, &session_ci, vkt::DefaultAllocator(), &session); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkDestroyDataGraphPipelineSessionARM-session-09794"); |
| vk::DestroyDataGraphPipelineSessionARM(*m_device, session, nullptr); |
| m_errorMonitor->VerifyFound(); |
| |
| vk::DestroyDataGraphPipelineSessionARM(*m_device, session, vkt::DefaultAllocator()); |
| |
| vk::CreateDataGraphPipelineSessionARM(*m_device, &session_ci, nullptr, &session); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkDestroyDataGraphPipelineSessionARM-session-09795"); |
| vk::DestroyDataGraphPipelineSessionARM(*m_device, session, vkt::DefaultAllocator()); |
| m_errorMonitor->VerifyFound(); |
| |
| vk::DestroyDataGraphPipelineSessionARM(*m_device, session, nullptr); |
| } |
| |
| TEST_F(NegativeDataGraph, DestroySessionCreatedWithoutDestroyWithCallbacks) { |
| TEST_DESCRIPTION("Try destroying with callbacks a datagraph pipeline session without callbacks"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| |
| VkDataGraphPipelineSessionARM session; |
| vk::CreateDataGraphPipelineSessionARM(*m_device, &session_ci, nullptr, &session); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkDestroyDataGraphPipelineSessionARM-session-09795"); |
| vk::DestroyDataGraphPipelineSessionARM(*m_device, session, vkt::DefaultAllocator()); |
| m_errorMonitor->VerifyFound(); |
| |
| vk::DestroyDataGraphPipelineSessionARM(*m_device, session, nullptr); |
| } |
| |
| TEST_F(NegativeDataGraph, CmdDispatchPipelineNotBound) { |
| TEST_DESCRIPTION( |
| "Try to add a CmdDispatchDataGraphARM to a command buffer when the pipeline was not bound to " |
| "VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount()); |
| session.AllocSessionMem(device_mem); |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0); |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0); |
| pipeline.descriptor_set_->UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1, |
| &pipeline.descriptor_set_.get()->set_, 0, nullptr); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-None-08606"); |
| vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeDataGraph, CmdDispatchDescriptorSetNotBound) { |
| TEST_DESCRIPTION("Try to dispatch a datagraph when the required descriptor set is not bound"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount()); |
| session.AllocSessionMem(device_mem); |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0); |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0); |
| pipeline.descriptor_set_->UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-None-08600"); |
| vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeDataGraph, CmdDispatchSessionNotBound) { |
| TEST_DESCRIPTION("Try dispatching a graph command when not all required session resources have been bound"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0); |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0); |
| pipeline.descriptor_set_->UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1, |
| &pipeline.descriptor_set_.get()->set_, 0, nullptr); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-session-09796"); |
| vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeDataGraph, CmdDispatchProtectedNoFaultUnsupportedUnprotectedCmdBufferProtectedTensor) { |
| TEST_DESCRIPTION( |
| "Try dispatching a datagraph with protected resources - bound pipeline tensors have VK_TENSOR_CREATE_PROTECTED_BIT_ARM set " |
| "- to an unprotected command buffer when protectedNoFault is not supported"); |
| InitBasicDataGraph(); |
| AddRequiredFeature(vkt::Feature::protectedMemory); |
| RETURN_IF_SKIP(Init()); |
| |
| VkPhysicalDeviceProtectedMemoryProperties protected_memory_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(protected_memory_properties); |
| if (protected_memory_properties.protectedNoFault) { |
| GTEST_SKIP() << "protectedNoFault is supported"; |
| } |
| |
| vkt::dg::HelperParameters params; |
| params.protected_tensors = true; |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount()); |
| session.AllocSessionMem(device_mem); |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0); |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0); |
| pipeline.descriptor_set_->UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1, |
| &pipeline.descriptor_set_.get()->set_, 0, nullptr); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-commandBuffer-09800"); |
| m_errorMonitor->SetDesiredError( |
| "VUID-vkCmdDispatchDataGraphARM-commandBuffer-09800"); // We are using 2 protected resources in this unprotected command |
| // buffer and so need to log the error twice |
| vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeDataGraph, CmdDispatchProtectedNoFaultUnsupportedProtectedCmdBufferUnprotectedTensor) { |
| TEST_DESCRIPTION( |
| "Try dispatching a datagraph with unprotected resources to a protected command buffer - command buffer created with " |
| "VK_COMMAND_POOL_CREATE_PROTECTED_BIT set - when protectedNoFault is not supported"); |
| InitBasicDataGraph(); |
| AddRequiredFeature(vkt::Feature::protectedMemory); |
| RETURN_IF_SKIP(InitFramework()); |
| RETURN_IF_SKIP(InitState(nullptr, nullptr, VK_COMMAND_POOL_CREATE_PROTECTED_BIT)); |
| |
| VkPhysicalDeviceProtectedMemoryProperties protected_memory_properties = vku::InitStructHelper(); |
| GetPhysicalDeviceProperties2(protected_memory_properties); |
| if (protected_memory_properties.protectedNoFault) { |
| GTEST_SKIP() << "protectedNoFault is supported"; |
| } |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| std::vector<vkt::DeviceMemory> device_mem(session.BindPointsCount()); |
| session.AllocSessionMem(device_mem); |
| |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0); |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0); |
| pipeline.descriptor_set_->UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1, |
| &pipeline.descriptor_set_.get()->set_, 0, nullptr); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-commandBuffer-09801"); |
| m_errorMonitor->SetDesiredError( |
| "VUID-vkCmdDispatchDataGraphARM-commandBuffer-09801"); // We are using 2 unprotected resources in this protected command |
| // buffer and so need to log the error twice |
| vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeDataGraph, CmdDispatchInvalidDescriptorNoUpdate) { |
| TEST_DESCRIPTION("Try dispatching a datagraph but the descriptor has not been updated"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline.Handle(); |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| auto& bind_point_reqs = session.BindPointReqs(); |
| std::vector<vkt::DeviceMemory> device_mem(bind_point_reqs.size()); |
| session.AllocSessionMem(device_mem); |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| |
| // update only 1 of 2 descriptors |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0); |
| pipeline.descriptor_set_->UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.Handle()); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_.handle(), 0, 1, |
| &pipeline.descriptor_set_.get()->set_, 0, nullptr); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-None-08114"); |
| vk::CmdDispatchDataGraphARM(m_command_buffer, session.handle(), nullptr); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeDataGraph, CmdDispatchInvalidDescriptorDeletedObject) { |
| TEST_DESCRIPTION("Try dispatching a datagraph but the tensor or the view are destroyed before dispatch"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| // 2 runs: 1st time delete the tensor, 2nd the view, both make the descriptor invalid |
| for (uint32_t i = 0; i < 2; i++) { |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline.Handle(); |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| auto& bind_point_reqs = session.BindPointReqs(); |
| std::vector<vkt::DeviceMemory> device_mem(bind_point_reqs.size()); |
| session.AllocSessionMem(device_mem); |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0); |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0); |
| pipeline.descriptor_set_->UpdateDescriptorSets(); |
| |
| // deleting either of these 2 invalidates the descriptor |
| if (i == 0) { |
| pipeline.tensors_[0]->Destroy(); |
| } else { |
| pipeline.tensor_views_[0]->Destroy(); |
| } |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.Handle()); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_.handle(), 0, 1, |
| &pipeline.descriptor_set_.get()->set_, 0, nullptr); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-None-08114"); |
| vk::CmdDispatchDataGraphARM(m_command_buffer, session.handle(), nullptr); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| } |
| |
| TEST_F(NegativeDataGraph, CmdDispatchInvalidDescriptorBufferBit) { |
| TEST_DESCRIPTION( |
| "Try dispatching a datagraph with VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT set, but using descriptor sets."); |
| InitBasicDataGraph(); |
| AddRequiredFeature(vkt::Feature::dataGraphDescriptorBuffer); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.pipeline_ci_.flags |= VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT; |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline.Handle(); |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| auto& bind_point_reqs = session.BindPointReqs(); |
| std::vector<vkt::DeviceMemory> device_mem(bind_point_reqs.size()); |
| session.AllocSessionMem(device_mem); |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0); |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0); |
| pipeline.descriptor_set_->UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.Handle()); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_.handle(), 0, 1, |
| &pipeline.descriptor_set_.get()->set_, 0, nullptr); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-None-08115"); |
| vk::CmdDispatchDataGraphARM(m_command_buffer, session.handle(), nullptr); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeDataGraph, CmdDispatchMissingDescriptorBufferBit) { |
| TEST_DESCRIPTION( |
| "Try dispatching a datagraph with descriptor buffers but without the VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT."); |
| InitBasicDataGraph(); |
| AddRequiredExtensions(VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME); |
| AddRequiredExtensions(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::descriptorBuffer); |
| AddRequiredFeature(vkt::Feature::bufferDeviceAddress); |
| AddRequiredFeature(vkt::Feature::dataGraphDescriptorBuffer); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| |
| // create a pipeline layout with the required flags |
| VkDescriptorSetLayoutCreateInfo dslci = vku::InitStructHelper(); |
| dslci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT; |
| dslci.bindingCount = pipeline.descriptor_set_layout_bindings_.size(); |
| dslci.pBindings = pipeline.descriptor_set_layout_bindings_.data(); |
| |
| vkt::DescriptorSetLayout dsl(*m_device, dslci); |
| vkt::PipelineLayout pipeline_layout(*m_device, {&dsl}); |
| ASSERT_TRUE(pipeline_layout.initialized()); |
| |
| // set layout for descriptor buffer, but not the flags |
| // pipeline.pipeline_ci_.flags |= VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT; |
| pipeline.pipeline_ci_.layout = pipeline_layout; |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline.Handle(); |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| auto& bind_point_reqs = session.BindPointReqs(); |
| std::vector<vkt::DeviceMemory> device_mem(bind_point_reqs.size()); |
| session.AllocSessionMem(device_mem); |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0); |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0); |
| pipeline.descriptor_set_->UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.Handle()); |
| |
| vkt::Buffer buffer(*m_device, 4096, VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT, vkt::device_address); |
| VkDescriptorBufferBindingInfoEXT dbbi = vku::InitStructHelper(); |
| dbbi.address = buffer.Address(); |
| dbbi.usage = VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT; |
| |
| vk::CmdBindDescriptorBuffersEXT(m_command_buffer, 1, &dbbi); |
| |
| uint32_t index = 0; |
| VkDeviceSize offset = 0; |
| vk::CmdSetDescriptorBufferOffsetsEXT(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline_layout, 0, 1, &index, |
| &offset); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-None-08117"); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-None-08600"); |
| vk::CmdDispatchDataGraphARM(m_command_buffer, session.handle(), nullptr); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeDataGraph, ShaderModuleCreateInfoInvalidConstantID) { |
| TEST_DESCRIPTION( |
| "Try creating a datagraph pipeline where the VkDataGraphPipelineShaderModuleCreateInfoARM has a " |
| "VkDataGraphPipelineConstantARM whose id member is not valid"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| VkDataGraphPipelineConstantARM graph_pipeline_constant = vku::InitStructHelper(); |
| graph_pipeline_constant.id = 42; // Arbitrary value not used by OpGraphConstantARM in shader module |
| int constant_data = 42; |
| graph_pipeline_constant.pConstantData = &constant_data; |
| pipeline.shader_module_ci_.constantCount = 1; |
| pipeline.shader_module_ci_.pConstants = &graph_pipeline_constant; |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, TensorSparsitySuppliedMissingDescription) { |
| TEST_DESCRIPTION( |
| "Try creating a datagraph pipeline with a tensor sparsity structure but missing a tensor description structure"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph(); |
| |
| vkt::dg::HelperParameters params; |
| params.spirv_source = spirv_string.c_str(); |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| VkDataGraphPipelineConstantTensorSemiStructuredSparsityInfoARM tensor_sparsity = vku::InitStructHelper(); |
| tensor_sparsity.groupSize = 1; |
| |
| // GetConstant puts the correct description in the pNext, by overwriting it we lose the description and cause the error |
| VkDataGraphPipelineConstantARM constant = GetConstant(); |
| constant.pNext = &tensor_sparsity; |
| pipeline.shader_module_ci_.constantCount = 1; |
| pipeline.shader_module_ci_.pConstants = &constant; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineConstantARM-pNext-09775"); |
| // 9921 will also be triggered since we need a description for this |
| // Graph Constant ID and we are intentionally not passing one |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, TensorSparsityDimensionTooLarge) { |
| TEST_DESCRIPTION( |
| "Try creating a datagraph pipeline with a tensor sparsity structure but the supplied dimension is larger than the " |
| "dimensionCount in the tensor description supplied"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph(); |
| |
| vkt::dg::HelperParameters params; |
| params.spirv_source = spirv_string.c_str(); |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| VkTensorDescriptionARM constant_tensor_desc = DefaultConstantTensorDesc(); |
| |
| VkDataGraphPipelineConstantTensorSemiStructuredSparsityInfoARM tensor_sparsity = vku::InitStructHelper(); |
| tensor_sparsity.groupSize = 1; |
| tensor_sparsity.dimension = constant_tensor_desc.dimensionCount + 1; |
| constant_tensor_desc.pNext = &tensor_sparsity; |
| |
| VkDataGraphPipelineConstantARM constant = GetConstant(constant_tensor_desc); |
| pipeline.shader_module_ci_.constantCount = 1; |
| pipeline.shader_module_ci_.pConstants = &constant; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineConstantARM-pNext-09776"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, TensorSparsityDescriptionDimensionNotMultipleOfSparsityGroupSize) { |
| TEST_DESCRIPTION( |
| "Try creating a datagraph pipeline with a tensor sparsity structure but dimension[sparsity->dimension] is not a multiple " |
| "of sparsity->groupSize"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph(); |
| |
| vkt::dg::HelperParameters params; |
| params.spirv_source = spirv_string.c_str(); |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| VkTensorDescriptionARM constant_tensor_desc = DefaultConstantTensorDesc(); |
| |
| VkDataGraphPipelineConstantTensorSemiStructuredSparsityInfoARM tensor_sparsity = vku::InitStructHelper(); |
| tensor_sparsity.dimension = 2; |
| int64_t dim_2 = constant_tensor_desc.pDimensions[tensor_sparsity.dimension]; |
| ASSERT_TRUE((dim_2 >= 1) && (dim_2 <= static_cast<int64_t>(UINT32_MAX))); |
| tensor_sparsity.groupSize = |
| static_cast<uint32_t>(dim_2 - 1); // ensure that dim_2 (the sparsity dimension) is NOT a multiple of groupSize |
| constant_tensor_desc.pNext = &tensor_sparsity; |
| |
| VkDataGraphPipelineConstantARM constant = GetConstant(constant_tensor_desc); |
| pipeline.shader_module_ci_.constantCount = 1; |
| pipeline.shader_module_ci_.pConstants = &constant; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineConstantARM-pNext-09777"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, TensorSparsityDoubleDefinition) { |
| TEST_DESCRIPTION("Try creating a datagraph pipeline with a tensor sparsity defined twice for the same dimension"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph(); |
| |
| vkt::dg::HelperParameters params; |
| params.spirv_source = spirv_string.c_str(); |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| VkTensorDescriptionARM constant_tensor_desc = DefaultConstantTensorDesc(); |
| |
| // add 3 sparsity structures but 2 are for the same dimension -> ERROR |
| VkDataGraphPipelineConstantTensorSemiStructuredSparsityInfoARM tensor_sparsity0 = vku::InitStructHelper(); |
| tensor_sparsity0.groupSize = 1; |
| tensor_sparsity0.dimension = 2; |
| constant_tensor_desc.pNext = &tensor_sparsity0; |
| VkDataGraphPipelineConstantTensorSemiStructuredSparsityInfoARM tensor_sparsity1 = vku::InitStructHelper(); |
| tensor_sparsity1.groupSize = 2; |
| tensor_sparsity1.dimension = 3; |
| tensor_sparsity0.pNext = &tensor_sparsity1; |
| VkDataGraphPipelineConstantTensorSemiStructuredSparsityInfoARM tensor_sparsity2 = vku::InitStructHelper(); |
| tensor_sparsity2.groupSize = 2; |
| tensor_sparsity2.dimension = 2; |
| tensor_sparsity1.pNext = &tensor_sparsity2; |
| |
| VkDataGraphPipelineConstantARM constant = GetConstant(constant_tensor_desc); |
| pipeline.shader_module_ci_.constantCount = 1; |
| pipeline.shader_module_ci_.pConstants = &constant; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineConstantARM-pNext-09870"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, GraphConstantTensorWrongID) { |
| TEST_DESCRIPTION("Try creating a datagraph pipeline with a constant that has an id different from the spirv definition"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph(); |
| |
| vkt::dg::HelperParameters params; |
| params.spirv_source = spirv_string.c_str(); |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| VkTensorDescriptionARM desc = DefaultConstantTensorDesc(); |
| VkDataGraphPipelineConstantARM constant = GetConstant(desc); |
| constant.id = 42; |
| pipeline.shader_module_ci_.constantCount = 1; |
| pipeline.shader_module_ci_.pConstants = &constant; |
| |
| // 9921 triggered 2 times: |
| // - Vulkan pConstants[x].id = 42 has no correspondence in the spirv code |
| // - spirv OpGraphConstantARM has no correspondence in the Vulkan pConstants |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921"); |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, GraphConstantTensorWrongRank) { |
| TEST_DESCRIPTION( |
| "Try creating a datagraph pipeline with a constant based on a tensor with rank different from the spirv definition"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph(); |
| |
| vkt::dg::HelperParameters params; |
| params.spirv_source = spirv_string.c_str(); |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| // define a tensor with rank 3, the spirv has rank 4 |
| VkTensorDescriptionARM desc = vku::InitStructHelper(); |
| const std::vector<int64_t> dimensions{1, 2, 4}; |
| desc.tiling = VK_TENSOR_TILING_LINEAR_ARM; |
| desc.format = VK_FORMAT_R8_UINT; |
| desc.dimensionCount = dimensions.size(); |
| desc.pDimensions = dimensions.data(); |
| desc.usage = VK_TENSOR_USAGE_DATA_GRAPH_BIT_ARM; |
| |
| VkDataGraphPipelineConstantARM constant = GetConstant(desc); |
| pipeline.shader_module_ci_.constantCount = 1; |
| pipeline.shader_module_ci_.pConstants = &constant; |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, GraphConstantTensorWrongDimensions) { |
| TEST_DESCRIPTION( |
| "Try creating a datagraph pipeline with a constant based on a tensor with dimensions different from the spirv definition"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph(); |
| |
| vkt::dg::HelperParameters params; |
| params.spirv_source = spirv_string.c_str(); |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| // dim[3] is different from the spirv (4) |
| VkTensorDescriptionARM desc = vku::InitStructHelper(); |
| const std::vector<int64_t> dimensions{1, 2, 4, 1}; // dim[3] is 4 in the spirv |
| desc.tiling = VK_TENSOR_TILING_LINEAR_ARM; |
| desc.format = VK_FORMAT_R8_UINT; |
| desc.dimensionCount = dimensions.size(); |
| desc.pDimensions = dimensions.data(); |
| desc.usage = VK_TENSOR_USAGE_DATA_GRAPH_BIT_ARM; |
| |
| VkDataGraphPipelineConstantARM constant = GetConstant(desc); |
| pipeline.shader_module_ci_.constantCount = 1; |
| pipeline.shader_module_ci_.pConstants = &constant; |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, GraphConstantTensorWrongFormat) { |
| TEST_DESCRIPTION( |
| "Try creating a datagraph pipeline with a constant based on a tensor with format different from the spirv definition"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph(); |
| |
| vkt::dg::HelperParameters params; |
| params.spirv_source = spirv_string.c_str(); |
| |
| // try a few different formats, different for bit width, float encoding and type |
| // NOTE: VK_FORMAT_R8_SINT included as a sanity check: it is different only by sign from the actual format, |
| // meaning it is compatible, and it must NOT trigger the VU |
| for (auto format : |
| {VK_FORMAT_R8_SINT, VK_FORMAT_R8_BOOL_ARM, VK_FORMAT_R32_SINT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R8_SFLOAT_FPENCODING_FLOAT8E4M3_ARM}) { |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| VkTensorDescriptionARM desc = DefaultConstantTensorDesc(); |
| desc.format = format; |
| VkDataGraphPipelineConstantARM constant = GetConstant(desc); |
| pipeline.shader_module_ci_.constantCount = 1; |
| pipeline.shader_module_ci_.pConstants = &constant; |
| |
| if (format == VK_FORMAT_R8_SINT) { |
| // INT check must not consider the sign, as required by TOSA function specifications |
| pipeline.CreateDataGraphPipeline(); |
| } else { |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| } |
| |
| TEST_F(NegativeDataGraph, GraphConstantTensorMissingDescription) { |
| TEST_DESCRIPTION("Try creating a datagraph pipeline with a constant that is missing the tensor description"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph(); |
| |
| vkt::dg::HelperParameters params; |
| params.spirv_source = spirv_string.c_str(); |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| // GetConstant puts the correct description in the pNext, remove it to cause the error |
| VkDataGraphPipelineConstantARM constant = GetConstant(); |
| constant.pNext = nullptr; |
| pipeline.shader_module_ci_.constantCount = 1; |
| pipeline.shader_module_ci_.pConstants = &constant; |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, GraphConstantTensorWrongTiling) { |
| TEST_DESCRIPTION("Try creating a datagraph pipeline with a constant which corresponds to a tensor with the incorrect tiling"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph(); |
| |
| vkt::dg::HelperParameters params; |
| params.spirv_source = spirv_string.c_str(); |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| VkTensorDescriptionARM desc = DefaultConstantTensorDesc(); |
| desc.tiling = VK_TENSOR_TILING_OPTIMAL_ARM; // should be VK_TENSOR_TILING_LINEAR_ARM |
| VkDataGraphPipelineConstantARM constant = GetConstant(desc); |
| pipeline.shader_module_ci_.constantCount = 1; |
| pipeline.shader_module_ci_.pConstants = &constant; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineConstantARM-pNext-09917"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, GraphConstantTensorMissingUsageFlags) { |
| TEST_DESCRIPTION("Try creating a datagraph pipeline with a constant based on a tensor with the incorrect usage flags"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvConstantDataGraph(); |
| |
| vkt::dg::HelperParameters params; |
| params.spirv_source = spirv_string.c_str(); |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| VkTensorDescriptionARM desc = DefaultConstantTensorDesc(); |
| desc.usage = VK_TENSOR_USAGE_SHADER_BIT_ARM; // should be VK_TENSOR_USAGE_DATA_GRAPH_BIT_ARM |
| VkDataGraphPipelineConstantARM constant = GetConstant(desc); |
| pipeline.shader_module_ci_.constantCount = 1; |
| pipeline.shader_module_ci_.pConstants = &constant; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineConstantARM-id-09850"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, ResourceTensorWrongDescriptorSet) { |
| TEST_DESCRIPTION("Try creating a datagraph pipeline with a resource with descriptorSet different from the spirv definition"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| |
| // incorrect descriptorSet on one resource |
| pipeline.resources_[0].descriptorSet = 42; |
| |
| // 9923 triggered 2 times: |
| // - Vulkan pResourceInfos[x].descriptorSet = 42 has no correspondence in the spirv code |
| // - spirv OpVariable has no correspondence in the Vulkan pResourceInfos |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, ResourceTensorWrongBinding) { |
| TEST_DESCRIPTION("Try creating a datagraph pipeline with a resource with binding different from the spirv definition"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| |
| // incorrect binding on one resource |
| pipeline.resources_[0].binding = 42; |
| |
| // 9923 triggered 2 times: |
| // - Vulkan pResourceInfos[x].binding = 42 has no correspondence in the spirv code |
| // - spirv OpVariable has no correspondence in the Vulkan pResourceInfos |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, ResourceTensorArrayElementNotZero) { |
| TEST_DESCRIPTION("Try creating a datagraph pipeline with a resource with arrayElement greater than zero"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| |
| // incorrect arrayElement on one resource |
| pipeline.resources_[0].arrayElement = 42; |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, ResourceTensorWrongRank) { |
| TEST_DESCRIPTION( |
| "Try creating a datagraph pipeline with a resource based on a tensor with rank different from the spirv definition"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| |
| // define a tensor with rank 3, the spirv has rank 4 |
| auto* desc = |
| const_cast<VkTensorDescriptionARM*>(vku::FindStructInPNextChain<VkTensorDescriptionARM>(pipeline.resources_[0].pNext)); |
| const std::vector<int64_t> dimensions{1, 4, 16}; |
| desc->dimensionCount = dimensions.size(); |
| desc->pDimensions = dimensions.data(); |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, ResourceTensorWrongDimensions) { |
| TEST_DESCRIPTION( |
| "Try creating a datagraph pipeline with a resource based on a tensor with dimensions different from the spirv definition"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| |
| // dim[3] is different from the spirv (4) |
| auto* desc = |
| const_cast<VkTensorDescriptionARM*>(vku::FindStructInPNextChain<VkTensorDescriptionARM>(pipeline.resources_[0].pNext)); |
| const std::vector<int64_t> dimensions{1, 8, 16, 1}; // dim[3] is 4 in the spirv |
| desc->dimensionCount = dimensions.size(); |
| desc->pDimensions = dimensions.data(); |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, ResourceTensorWrongFormat) { |
| TEST_DESCRIPTION( |
| "Try creating a datagraph pipeline with a resource based on a tensor with format different from the spirv definition"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| // try a few different formats, different for bit width, type and float encoding |
| // NOTE: VK_FORMAT_R8_SINT included as a sanity check: it is different only by sign from the actual format, |
| // meaning it is compatible, and it must NOT trigger the VU |
| for (auto format : |
| {VK_FORMAT_R8_SINT, VK_FORMAT_R8_BOOL_ARM, VK_FORMAT_R32_SINT, VK_FORMAT_R32_SFLOAT, VK_FORMAT_R8_SFLOAT_FPENCODING_FLOAT8E4M3_ARM}) { |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| |
| auto* desc = |
| const_cast<VkTensorDescriptionARM*>(vku::FindStructInPNextChain<VkTensorDescriptionARM>(pipeline.resources_[0].pNext)); |
| desc->format = format; |
| |
| if (format == VK_FORMAT_R8_SINT) { |
| // INT check must not consider the sign, as required by TOSA function specifications |
| pipeline.CreateDataGraphPipeline(); |
| } else { |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| } |
| |
| TEST_F(NegativeDataGraph, ResourceTensorMissingDescription) { |
| TEST_DESCRIPTION("Try creating a datagraph pipeline with a resource missing the tensor description"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| |
| // cut the connection to the tensor description |
| pipeline.resources_[0].pNext = nullptr; |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, ResourceTensorInvalidUsage) { |
| TEST_DESCRIPTION( |
| "Try creating a datagraph pipeline when the VkTensorDescriptionARM struct in the pNext of resources in resourceInfo do " |
| "not have a valid Usage member"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| |
| // set an incorrect usage in the tensor description |
| auto* desc = |
| const_cast<VkTensorDescriptionARM*>(vku::FindStructInPNextChain<VkTensorDescriptionARM>(pipeline.resources_[0].pNext)); |
| desc->usage = VK_TENSOR_USAGE_SHADER_BIT_ARM; // should be VK_TENSOR_USAGE_DATA_GRAPH_BIT_ARM |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineResourceInfoARM-descriptorSet-09851"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, SessionGetMemoryRequirementsIndexTooLarge) { |
| TEST_DESCRIPTION("Try to get the memory requirements for a session with an out-of-bounds value for objectIndex"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| |
| uint32_t bind_point_req_count = 0; |
| VkDataGraphPipelineSessionBindPointRequirementsInfoARM bind_point_req_info = vku::InitStructHelper(); |
| bind_point_req_info.session = session; |
| vk::GetDataGraphPipelineSessionBindPointRequirementsARM(*m_device, &bind_point_req_info, &bind_point_req_count, nullptr); |
| if (bind_point_req_count == 0) { |
| GTEST_FAIL() << "No bind points, " << IncorrectSpirvMessage; |
| } |
| std::vector<VkDataGraphPipelineSessionBindPointRequirementARM> bind_point_reqs(bind_point_req_count); |
| for (auto& bp_req : bind_point_reqs) { |
| bp_req = vku::InitStructHelper(); |
| } |
| vk::GetDataGraphPipelineSessionBindPointRequirementsARM(*m_device, &bind_point_req_info, &bind_point_req_count, |
| bind_point_reqs.data()); |
| |
| VkDataGraphPipelineSessionMemoryRequirementsInfoARM session_mem_reqs = vku::InitStructHelper(); |
| session_mem_reqs.session = session; |
| session_mem_reqs.bindPoint = bind_point_reqs[0].bindPoint; |
| session_mem_reqs.objectIndex = bind_point_reqs[0].numObjects; // one over the limit |
| |
| VkMemoryRequirements2 mem_reqs = vku::InitStructHelper(); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineSessionMemoryRequirementsInfoARM-objectIndex-09855"); |
| vk::GetDataGraphPipelineSessionMemoryRequirementsARM(*m_device, &session_mem_reqs, &mem_reqs); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, ShaderUsesSpecConstantsFeatureNotEnabled) { |
| TEST_DESCRIPTION( |
| "Try to create a datagraph with a VkSpecializationInfo used in the shader module when the feature is not enabled"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| const VkSpecializationMapEntry entry = { |
| 0, // id |
| 0, // offset |
| sizeof(uint32_t) // size |
| }; |
| uint32_t data = 0; |
| const VkSpecializationInfo specialization_info = { |
| 1, |
| &entry, |
| 1 * sizeof(uint32_t), |
| &data, |
| }; |
| pipeline.shader_module_ci_.pSpecializationInfo = &specialization_info; |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineShaderModuleCreateInfoARM-dataGraphSpecializationConstants-09849"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, ShaderSpirvUsesOpSpecFeatureNotEnabled) { |
| TEST_DESCRIPTION( |
| "Try to create a datagraph with a shader module which contains OpSpec commands when the feature is not enabled"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| // inject a dummy line in the spirv to trigger the error |
| vkt::dg::ModifiableShaderParameters spirv_params; |
| spirv_params.types = R"(%dummy_spec_constant = OpSpecConstant %uint 3)"; |
| const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvModifyableDataGraph(spirv_params); |
| |
| // ShaderModule in VkDataGraphPipelineShaderModuleCreateInfoARM::module |
| { |
| vkt::dg::HelperParameters params; |
| params.spirv_source = spirv_string.c_str(); |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineShaderModuleCreateInfoARM-dataGraphSpecializationConstants-09849"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // ShaderModule in the pNext chain of VkDataGraphPipelineCreateInfoARM |
| { |
| spvtools::SpirvTools tools{SPV_ENV_UNIVERSAL_1_6}; |
| std::vector<uint32_t> spirv_binary; |
| if (!tools.Assemble(spirv_string, &spirv_binary)) { |
| Monitor().SetError("Failed to compile SPIRV shader module"); |
| return; |
| } |
| VkShaderModuleCreateInfo shader_module_create_info = vku::InitStructHelper(); |
| shader_module_create_info.codeSize = spirv_binary.size() * sizeof(uint32_t); |
| shader_module_create_info.pCode = spirv_binary.data(); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| // the helper constructor adds the shader module as VkDataGraphPipelineShaderModuleCreateInfoARM::module, get rid of it |
| pipeline.shader_module_ci_.module = VK_NULL_HANDLE; |
| // add the shader info in pNext chain |
| vvl::PnextChainAdd(&pipeline.pipeline_ci_, &shader_module_create_info); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineShaderModuleCreateInfoARM-dataGraphSpecializationConstants-09849"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| TEST_F(NegativeDataGraph, DataGraphShaderModuleCreateInfoIncorrectName) { |
| TEST_DESCRIPTION( |
| "Create a datagraph pipeline where VkDataGraphPipelineShaderModuleCreateInfoARM::pName doesn't match the name in the spirv " |
| "code."); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.shader_module_ci_.pName = "NOT_the_correct_name"; |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineShaderModuleCreateInfoARM-pName-09872"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, DataGraphShaderModuleCreateInfoHasModuleAndShaderModuleCreateInfo) { |
| TEST_DESCRIPTION( |
| "Create a datagraph pipeline where VkDataGraphPipelineShaderModuleCreateInfoARM::module is not null, but it also includes " |
| "a VkShaderModuleCreateInfo structure in its pNext chain."); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| // the pipeline constructor adds the shader module in the "normal" way, as VkDataGraphPipelineShaderModuleCreateInfoARM::module |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| |
| // also add the same ShaderModule in the pNext chain |
| spvtools::SpirvTools tools{SPV_ENV_UNIVERSAL_1_6}; |
| const std::string& spirv_source = vkt::dg::DataGraphPipelineHelper::GetSpirvBasicDataGraph(); |
| std::vector<uint32_t> spirv_binary; |
| if (!tools.Assemble(spirv_source, &spirv_binary)) { |
| Monitor().SetError("Failed to compile SPIRV shader module"); |
| return; |
| } |
| VkShaderModuleCreateInfo shader_module_create_info = vku::InitStructHelper(); |
| shader_module_create_info.codeSize = spirv_binary.size() * sizeof(uint32_t); |
| shader_module_create_info.pCode = spirv_binary.data(); |
| |
| // add the shader info in VkDataGraphPipelineShaderModuleCreateInfoARM::pNext |
| { |
| pipeline.shader_module_ci_.pNext = &shader_module_create_info; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineShaderModuleCreateInfoARM-pNext-09873"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // add the shader info in VkDataGraphPipelineCreateInfoARM::pNext |
| { |
| // rearrange the pNext chain, we should get the same result |
| pipeline.shader_module_ci_.pNext = nullptr; |
| pipeline.pipeline_ci_.pNext = &shader_module_create_info; |
| shader_module_create_info.pNext = &pipeline.shader_module_ci_; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineShaderModuleCreateInfoARM-pNext-09873"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| TEST_F(NegativeDataGraph, DataGraphShaderModuleCreateInfoInvalidModule) { |
| TEST_DESCRIPTION( |
| "Create a datagraph pipeline where VkDataGraphPipelineShaderModuleCreateInfoARM::module is NULL and there is no " |
| "VkShaderModuleCreateInfo structure in its pNext chain."); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.shader_module_ci_.module = VK_NULL_HANDLE; |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineShaderModuleCreateInfoARM-pNext-09874"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, DataGraphShaderModuleCreateInfoDescriptorBufferNoFeature) { |
| TEST_DESCRIPTION("Create a datagraph pipeline with the flag for descriptor buffers but the feature is not enabled."); |
| InitBasicDataGraph(); |
| // NOT adding vkt::Feature::dataGraphDescriptorBuffer |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.pipeline_ci_.flags |= VK_PIPELINE_CREATE_2_DESCRIPTOR_BUFFER_BIT_EXT; |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-dataGraphDescriptorBuffer-09885"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, DataGraphShaderModuleNoFeature) { |
| TEST_DESCRIPTION("Try to create a datagraph without the dataGraphShaderModule feature."); |
| // add all the requirements of InitBasicDataGraph except dataGraphShaderModule |
| SetTargetApiVersion(VK_API_VERSION_1_4); |
| AddRequiredExtensions(VK_ARM_TENSORS_EXTENSION_NAME); |
| AddRequiredExtensions(VK_ARM_DATA_GRAPH_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::tensors); |
| AddRequiredFeature(vkt::Feature::dataGraph); |
| AddRequiredFeature(vkt::Feature::shaderTensorAccess); |
| AddRequiredFeature(vkt::Feature::vulkanMemoryModel); |
| AddRequiredFeature(vkt::Feature::shaderInt8); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-dataGraphShaderModule-09886"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, DataGraphWrongCreateInfoStructs) { |
| TEST_DESCRIPTION("None or too many of the required info structures passed in pNext of vkCreateDataGraphPipelinesARM."); |
| InitBasicDataGraph(); |
| AddRequiredFeature(vkt::Feature::pipelineCreationCacheControl); |
| RETURN_IF_SKIP(Init()); |
| |
| // none of the structs included |
| { |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.pipeline_ci_.pNext = nullptr; |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-pNext-09977"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // too many of the structs included |
| { |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| // a VkDataGraphPipelineShaderModuleCreateInfoARM is already included by the helper, add also |
| // a VkDataGraphPipelineIdentifierCreateInfoARM (can't have both) |
| VkDataGraphPipelineIdentifierCreateInfoARM pipeline_id = vku::InitStructHelper(); |
| constexpr uint8_t dummy_data = 1; |
| pipeline_id.identifierSize = 1; |
| pipeline_id.pIdentifier = &dummy_data; |
| vvl::PnextChainAdd(&pipeline.pipeline_ci_, &pipeline_id); |
| pipeline.pipeline_ci_.flags |= VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT; |
| pipeline.pipeline_ci_.pResourceInfos = nullptr; |
| pipeline.pipeline_ci_.resourceInfoCount = 0; |
| |
| VkPipelineCache pipeline_cache; |
| VkPipelineCacheCreateInfo cache_create_info = vku::InitStructHelper(); |
| cache_create_info.initialDataSize = 0; |
| VkResult err = vk::CreatePipelineCache(device(), &cache_create_info, nullptr, &pipeline_cache); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-pNext-09977"); |
| pipeline.CreateDataGraphPipeline(pipeline_cache); |
| m_errorMonitor->VerifyFound(); |
| vk::DestroyPipelineCache(device(), pipeline_cache, nullptr); |
| } |
| } |
| |
| TEST_F(NegativeDataGraph, DataGraphShaderModuleSpirvArrayWrongSize) { |
| TEST_DESCRIPTION("Create a datagraph with Vulkan resource arrays not matching the spirv."); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::HelperParameters params; |
| params.graph_variant = vkt::dg::GraphVariant::AddTensorArraySpirv; |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| // override the DataGraphPipelineHelper constructor: set the wrong array length and recreate the layout |
| pipeline.descriptor_set_layout_bindings_[0].descriptorCount = 1; // ERROR 9934: the spirv code defines an array of 2 |
| pipeline.descriptor_set_.reset(new OneOffDescriptorSet(pipeline.device_, pipeline.descriptor_set_layout_bindings_)); |
| pipeline.CreatePipelineLayout(); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-layout-09934"); |
| // tensor arrays also triggers VU 9923s (2 tensors, 2 errors) |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, DataGraphShaderModuleSpirvRuntimeArraySizeZero) { |
| TEST_DESCRIPTION("Create a datagraph where a Vulkan resource is a runtime array with count 0."); |
| InitBasicDataGraph(); |
| AddRequiredFeature(vkt::Feature::runtimeDescriptorArray); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::HelperParameters params; |
| params.graph_variant = vkt::dg::GraphVariant::AddRuntimeTensorArraySpirv; |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| // override the DataGraphPipelineHelper constructor: set the wrong array length and recreate the layout |
| pipeline.descriptor_set_layout_bindings_[0].descriptorCount = 0; // ERROR 9934: OpTypeRuntimeArray needs > 0 |
| pipeline.descriptor_set_.reset(new OneOffDescriptorSet(pipeline.device_, pipeline.descriptor_set_layout_bindings_)); |
| pipeline.CreatePipelineLayout(); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-layout-09934"); |
| // tensor arrays also triggers VU 9923s (2 tensors, 2 errors) |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, DataGraphTensorNoShape) { |
| TEST_DESCRIPTION("Create a datagraph using tensors without shape."); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| // input and output variables are tensors without a shape, rank only (%tensor_r4) |
| static const char* tensorNoShapeDataGraphSpirv = R"spirv( |
| OpCapability GraphARM |
| OpCapability TensorsARM |
| OpCapability Int8 |
| OpCapability Shader |
| OpCapability VulkanMemoryModel |
| OpCapability Matrix |
| OpExtension "SPV_ARM_graph" |
| OpExtension "SPV_ARM_tensors" |
| OpExtension "SPV_KHR_vulkan_memory_model" |
| %tosa = OpExtInstImport "TOSA.001000.1" |
| OpMemoryModel Logical Vulkan |
| OpName %main_arg_0 "main_arg_0" |
| OpName %main_res_0 "main_res_0" |
| OpDecorate %main_arg_0 Binding 0 |
| OpDecorate %main_arg_0 DescriptorSet 0 |
| OpDecorate %main_res_0 Binding 1 |
| OpDecorate %main_res_0 DescriptorSet 0 |
| %i8 = OpTypeInt 8 0 |
| %i32 = OpTypeInt 32 0 |
| %i32_0 = OpConstant %i32 0 |
| %i32_1 = OpConstant %i32 1 |
| %i32_2 = OpConstant %i32 2 |
| %i32_4 = OpConstant %i32 4 |
| %i32_arr_1 = OpTypeArray %i32 %i32_1 |
| %i32_arr_4 = OpTypeArray %i32 %i32_4 |
| %i32_arr_1_2 = OpConstantComposite %i32_arr_1 %i32_2 |
| %i32_arr_1_4 = OpConstantComposite %i32_arr_1 %i32_4 |
| %i32_2_tensor = OpTypeTensorARM %i32 %i32_1 %i32_arr_1_2 |
| %i32_4_tensor = OpTypeTensorARM %i32 %i32_1 %i32_arr_1_4 |
| %tensor_r4 = OpTypeTensorARM %i8 %i32_4 |
| %ptr_tensor_r4 = OpTypePointer UniformConstant %tensor_r4 |
| %i32_2_tensor_2_2 = OpConstantComposite %i32_2_tensor %i32_2 %i32_2 |
| %i32_4_tensor_0_0_0_0 = OpConstantComposite %i32_4_tensor %i32_0 %i32_0 %i32_0 %i32_0 |
| %main_arg_0 = OpVariable %ptr_tensor_r4 UniformConstant |
| %main_res_0 = OpVariable %ptr_tensor_r4 UniformConstant |
| %graph_type = OpTypeGraphARM 1 %tensor_r4 %tensor_r4 |
| OpGraphEntryPointARM %graph_0 "main" %main_arg_0 %main_res_0 |
| %graph_0 = OpGraphARM %graph_type |
| %in_0 = OpGraphInputARM %tensor_r4 %i32_0 |
| %op_0 = OpExtInst %tensor_r4 %tosa MAX_POOL2D %i32_2_tensor_2_2 %i32_2_tensor_2_2 %i32_4_tensor_0_0_0_0 %i32_0 %in_0 |
| %op_1 = OpExtInst %tensor_r4 %tosa MAX_POOL2D %i32_2_tensor_2_2 %i32_2_tensor_2_2 %i32_4_tensor_0_0_0_0 %i32_0 %op_0 |
| OpGraphSetOutputARM %op_1 %i32_0 |
| OpGraphEndARM |
| )spirv"; |
| |
| vkt::dg::HelperParameters params; |
| params.spirv_source = tensorNoShapeDataGraphSpirv; |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| // 2 tensors, 2 errors |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09919"); |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09919"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, DataGraphPipelineIdentifierNoFlag) { |
| TEST_DESCRIPTION("Create a datagraph with the ARM cache but the wrong flags."); |
| InitBasicDataGraph(); |
| AddRequiredFeature(vkt::Feature::pipelineCreationCacheControl); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| VkDataGraphPipelineIdentifierCreateInfoARM pipeline_id = vku::InitStructHelper(); |
| constexpr uint8_t dummy_data = 1; |
| pipeline_id.identifierSize = 1; |
| pipeline_id.pIdentifier = &dummy_data; |
| // replace the pNext chain, to remove the VkDataGraphPipelineShaderModuleCreateInfoARM added in the helper constructor |
| pipeline.pipeline_ci_.pNext = &pipeline_id; |
| // NOT setting VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT in the flags: ERROR |
| pipeline.pipeline_ci_.pResourceInfos = nullptr; |
| pipeline.pipeline_ci_.resourceInfoCount = 0; |
| |
| VkPipelineCache pipeline_cache; |
| VkPipelineCacheCreateInfo cache_create_info = vku::InitStructHelper(); |
| cache_create_info.initialDataSize = 0; |
| VkResult err = vk::CreatePipelineCache(device(), &cache_create_info, nullptr, &pipeline_cache); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-None-11840"); |
| pipeline.CreateDataGraphPipeline(pipeline_cache); |
| m_errorMonitor->VerifyFound(); |
| vk::DestroyPipelineCache(device(), pipeline_cache, nullptr); |
| } |
| |
| TEST_F(NegativeDataGraph, DataGraphPipelineIdentifierHasResources) { |
| TEST_DESCRIPTION("Create a datagraph with the ARM cache but resources info still included."); |
| InitBasicDataGraph(); |
| AddRequiredFeature(vkt::Feature::pipelineCreationCacheControl); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| VkDataGraphPipelineIdentifierCreateInfoARM pipeline_id = vku::InitStructHelper(); |
| constexpr uint8_t dummy_data = 1; |
| pipeline_id.identifierSize = 1; |
| pipeline_id.pIdentifier = &dummy_data; |
| // replace the pNext chain, to remove the VkDataGraphPipelineShaderModuleCreateInfoARM added in the helper constructor |
| pipeline.pipeline_ci_.pNext = &pipeline_id; |
| // set the correct flags, but leave pResourceInfos |
| pipeline.pipeline_ci_.flags |= VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT; |
| |
| VkPipelineCache pipeline_cache; |
| VkPipelineCacheCreateInfo cache_create_info = vku::InitStructHelper(); |
| cache_create_info.initialDataSize = 0; |
| VkResult err = vk::CreatePipelineCache(device(), &cache_create_info, nullptr, &pipeline_cache); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-None-12363"); |
| pipeline.CreateDataGraphPipeline(pipeline_cache); |
| m_errorMonitor->VerifyFound(); |
| vk::DestroyPipelineCache(device(), pipeline_cache, nullptr); |
| } |
| |
| TEST_F(NegativeDataGraph, DataGraphCreateInfoResourceCountZero) { |
| TEST_DESCRIPTION("Create a datagraph with the ARM cache, resource count is zero, but resource pointer is not null."); |
| InitBasicDataGraph(); |
| AddRequiredFeature(vkt::Feature::pipelineCreationCacheControl); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| VkDataGraphPipelineIdentifierCreateInfoARM pipeline_id = vku::InitStructHelper(); |
| constexpr uint8_t dummy_data = 1; |
| pipeline_id.identifierSize = 1; |
| pipeline_id.pIdentifier = &dummy_data; |
| // replace the pNext chain, to remove the VkDataGraphPipelineShaderModuleCreateInfoARM added in the helper constructor |
| pipeline.pipeline_ci_.pNext = &pipeline_id; |
| // set the correct flags, set resourceInfoCount to 0, but leave pResourceInfos |
| pipeline.pipeline_ci_.flags |= VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT; |
| pipeline.pipeline_ci_.resourceInfoCount = 0; |
| |
| VkPipelineCache pipeline_cache; |
| VkPipelineCacheCreateInfo cache_create_info = vku::InitStructHelper(); |
| cache_create_info.initialDataSize = 0; |
| VkResult err = vk::CreatePipelineCache(device(), &cache_create_info, nullptr, &pipeline_cache); |
| ASSERT_EQ(VK_SUCCESS, err); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-resourceInfoCount-12364"); |
| pipeline.CreateDataGraphPipeline(pipeline_cache); |
| m_errorMonitor->VerifyFound(); |
| vk::DestroyPipelineCache(device(), pipeline_cache, nullptr); |
| } |
| |
| TEST_F(NegativeDataGraph, DataGraphCreateInfoNullResources) { |
| TEST_DESCRIPTION("Create a datagraph but resource count is zero."); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.pipeline_ci_.pResourceInfos = nullptr; // this is to avoid VU 12364 |
| pipeline.pipeline_ci_.resourceInfoCount = 0; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-None-12365"); |
| // we also get 2x this because the spirv still includes 2 resources |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, DataGraphPipelineIdentifierNoCache) { |
| TEST_DESCRIPTION("Create a datagraph using the cache identifier but without a valid cache object."); |
| InitBasicDataGraph(); |
| AddRequiredFeature(vkt::Feature::pipelineCreationCacheControl); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| |
| // add the cache identifier object |
| VkDataGraphPipelineIdentifierCreateInfoARM pipeline_id = vku::InitStructHelper(); |
| constexpr uint8_t dummy_data = 1; |
| pipeline_id.identifierSize = 1; |
| pipeline_id.pIdentifier = &dummy_data; |
| vvl::PnextChainAdd(&pipeline.pipeline_ci_, &pipeline_id); |
| pipeline.pipeline_ci_.flags |= VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT; |
| |
| // ... but pass a NULL handle for the cache object |
| VkPipelineCache pipeline_cache = VK_NULL_HANDLE; |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCreateDataGraphPipelinesARM-pNext-09928"); |
| pipeline.CreateDataGraphPipeline(pipeline_cache); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, DataGraphOpGraphConstantARMNoShape) { |
| TEST_DESCRIPTION("Try to create a datagraph with an OpGraphConstantARM defined on a tensor without shape"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| // inject in the spirv a constant based on a shapeless tensor |
| vkt::dg::ModifiableShaderParameters spirv_params; |
| spirv_params.types = R"(%tensor_r4 = OpTypeTensorARM %uchar %uint_4 |
| %constant_no_shape = OpGraphConstantARM %tensor_r4 0)"; |
| spirv_params.instructions = "%dummy = OpExtInst %uchar_1_2_4_4_tensor %tosa ADD %op_1 %constant_no_shape"; |
| const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvModifyableDataGraph(spirv_params); |
| |
| vkt::dg::HelperParameters params; |
| params.spirv_source = spirv_string.c_str(); |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| VkDataGraphPipelineConstantARM constant = GetConstant(); |
| pipeline.shader_module_ci_.constantCount = 1; |
| pipeline.shader_module_ci_.pConstants = &constant; |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09920"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, DataGraphNoConstant) { |
| TEST_DESCRIPTION("Try to create a datagraph without a required constant."); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| // get spirv with 2 entrypoints; has a constant in entrypoint 2 |
| const std::string two_entrypoint_spirv = vkt::dg::DataGraphPipelineHelper::GetSpirvMultiEntryTwoDataGraph(); |
| |
| vkt::dg::HelperParameters params; |
| params.spirv_source = two_entrypoint_spirv.c_str(); |
| params.entrypoint = "entrypoint_2"; |
| // helper constructor does NOT initialize the constant |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, DataGraphOpGraphConstantARMNotTensor) { |
| TEST_DESCRIPTION("Try to create a datagraph with an OpGraphConstantARM that is not a tensor"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| // inject in the spirv constants based on a scalar, not tensors |
| vkt::dg::ModifiableShaderParameters spirv_params; |
| spirv_params.types = R"(%constant_scalar_min = OpGraphConstantARM %uint 0 |
| %constant_scalar_max = OpGraphConstantARM %uint 128)"; |
| spirv_params.instructions = |
| "%dummy = OpExtInst %uchar_1_2_4_4_tensor %tosa CLAMP %op_1 %constant_scalar_min %constant_scalar_max %uint_2"; |
| const std::string& spirv_string = vkt::dg::DataGraphPipelineHelper::GetSpirvModifyableDataGraph(spirv_params); |
| |
| vkt::dg::HelperParameters params; |
| params.spirv_source = spirv_string.c_str(); |
| |
| m_errorMonitor->SetDesiredError("VUID-VkShaderModuleCreateInfo-pCode-08737"); |
| VkShaderObj shader(*m_device, spirv_string.c_str(), VK_SHADER_STAGE_COMPUTE_BIT, SPV_ENV_VULKAN_1_4, SPV_SOURCE_ASM); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // NOTE: This is meant as a positive test for tensor arrays. |
| // Right now they are illegal, but they will be legal at some point. |
| // When this happens, remove the SetDesiredError and move to data_graph_positive.cpp |
| TEST_F(NegativeDataGraph, DataGraphShaderModuleSpirvArray) { |
| TEST_DESCRIPTION("Create a datagraph using a tensor array as input."); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| // currently tensor arrays are banned by VU 9923. The mock ICD doesn't create a pipeline, so we can still test |
| // successfully if we ignore it, but a real driver will actually try to create something illegal, and likely crash |
| if (!IsPlatformMockICD()) { |
| GTEST_SKIP() << "Test only supported by MockICD"; |
| } |
| |
| vkt::dg::HelperParameters params; |
| params.graph_variant = vkt::dg::GraphVariant::AddTensorArraySpirv; |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| // NOTE: This is meant as a positive test for tensor arrays. |
| // Right now they are illegal, but they will be legal at some point. |
| // When this happens, remove the SetDesiredError and move to data_graph_positive.cpp |
| TEST_F(NegativeDataGraph, DataGraphShaderModuleSpirvRuntimeArray) { |
| TEST_DESCRIPTION("Create a datagraph using a tensor runtime array as input."); |
| InitBasicDataGraph(); |
| AddRequiredFeature(vkt::Feature::runtimeDescriptorArray); |
| RETURN_IF_SKIP(Init()); |
| |
| // currently tensor arrays are banned by VU 9923. The mock ICD doesn't create a pipeline, so we can still test |
| // successfully if we ignore it, but a real driver will actually try to create something illegal, and likely crash |
| if (!IsPlatformMockICD()) { |
| GTEST_SKIP() << "Test only supported by MockICD"; |
| } |
| |
| { |
| // the helper constructs a layout with descriptorCount == 2, matching the size of the spirv array |
| vkt::dg::HelperParameters params; |
| params.graph_variant = vkt::dg::GraphVariant::AddRuntimeTensorArraySpirv; |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| // tensor arrays triggers VU 9923, we need to suppress it (2 tensors, 2 errors) |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| { |
| vkt::dg::HelperParameters params; |
| params.graph_variant = vkt::dg::GraphVariant::AddRuntimeTensorArraySpirv; |
| vkt::dg::DataGraphPipelineHelper pipeline(*this, params); |
| |
| // override the DataGraphPipelineHelper constructor: set a bigger element count, runtime array will handle this |
| pipeline.descriptor_set_layout_bindings_[0].descriptorCount = 3; |
| pipeline.descriptor_set_.reset(new OneOffDescriptorSet(pipeline.device_, pipeline.descriptor_set_layout_bindings_)); |
| pipeline.CreatePipelineLayout(); |
| |
| // tensor arrays triggers VU 9923, we need to suppress it (2 tensors, 2 errors) |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09923"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| TEST_F(NegativeDataGraph, CmdDispatchWrongPipeline) { |
| TEST_DESCRIPTION("Try to create a datagraph where session and command buffer are bound to different pipelines."); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| // make a _copy_ of the command buffer pipeline, so everything else checks out, but it's NOT the same object |
| VkDataGraphPipelineCreateInfoARM pipeline_ci = pipeline.pipeline_ci_; |
| vkt::Pipeline pipeline_copy(*m_device, pipeline_ci); |
| |
| // bind the session to the _copy_ pipeline |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline_copy.handle(); |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| // setup the command buffer with the _default_ pipeline, as usual. |
| auto& bind_point_reqs = session.BindPointReqs(); |
| std::vector<vkt::DeviceMemory> device_mem(bind_point_reqs.size()); |
| session.AllocSessionMem(device_mem); |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0); |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0); |
| pipeline.descriptor_set_->UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1, |
| &pipeline.descriptor_set_.get()->set_, 0, nullptr); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-dataGraphPipeline-09951"); |
| vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr); |
| m_command_buffer.End(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, CmdDispatchWrongTensorUsage) { |
| TEST_DESCRIPTION("Create and execute a datagraph where tensors have the wrong usage flag"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| auto& bind_point_reqs = session.BindPointReqs(); |
| std::vector<vkt::DeviceMemory> device_mem(bind_point_reqs.size()); |
| session.AllocSessionMem(device_mem); |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| |
| // pass a tensor with the wrong usage into the pipeline |
| VkTensorDescriptionARM wrong_desc = pipeline.GetTensorDesc(vkt::dg::TensorType::BASIC_SPIRV_IN); |
| wrong_desc.usage = VK_TENSOR_USAGE_SHADER_BIT_ARM; // should be VK_TENSOR_USAGE_DATA_GRAPH_BIT_ARM |
| vkt::Tensor wrong_tensor; |
| vkt::TensorView wrong_view; |
| pipeline.InitTensor(wrong_tensor, wrong_view, wrong_desc); |
| |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &wrong_view.handle(), 0); |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0); |
| pipeline.descriptor_set_->UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1, |
| &pipeline.descriptor_set_.get()->set_, 0, nullptr); |
| |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-pDescription-09900"); |
| vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |
| |
| TEST_F(NegativeDataGraph, BindPipelineCommandPoolFromWrongQueue) { |
| TEST_DESCRIPTION("Try to bind a datagraph pipeline with a command buffer using the wrong queue"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| InitRenderTarget(); |
| |
| // find a queue that doesn't support datagraph. Also require supporting either graphics |
| // or compute, to avoid "VUID-vkCmdBindPipeline-commandBuffer-cmdpool" |
| uint32_t queueFamilyIndex_no_datagraph_support = vvl::kU32Max; |
| const auto q_props = m_device->Physical().queue_properties_; |
| for (uint32_t i = 0; i < (uint32_t)q_props.size(); i++) { |
| if ((q_props[i].queueFlags & VK_QUEUE_DATA_GRAPH_BIT_ARM) == 0 && |
| (q_props[i].queueFlags & (VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT))) { |
| queueFamilyIndex_no_datagraph_support = i; |
| break; |
| } |
| } |
| if (queueFamilyIndex_no_datagraph_support == vvl::kU32Max) { |
| GTEST_SKIP() << "No queue found that doesn't support VK_QUEUE_DATA_GRAPH_BIT_ARM"; |
| } |
| vkt::CommandPool commandPool(*m_device, queueFamilyIndex_no_datagraph_support); |
| vkt::CommandBuffer commandBuffer(*m_device, commandPool); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| commandBuffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindPipeline-pipelineBindPoint-09910"); |
| vk::CmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline); |
| m_errorMonitor->VerifyFound(); |
| commandBuffer.End(); |
| } |
| |
| TEST_F(NegativeDataGraph, BindWrongBindPoint) { |
| TEST_DESCRIPTION("Try to bind a graphics pipeline to the datagraph bind point"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| InitRenderTarget(); |
| CreatePipelineHelper pipeline(*this); |
| pipeline.CreateGraphicsPipeline(); |
| |
| m_command_buffer.Begin(); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdBindPipeline-pipelineBindPoint-09911"); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, CmdDispatchWrongQueue) { |
| TEST_DESCRIPTION("Try to create a datagraph where the command buffer is allocated on a queue that does not support TOSA 1.0"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| // find a queue family that does NOT support TOSA |
| const VkQueueFamilyDataGraphPropertiesARM tosa_1_0_property{ |
| VK_STRUCTURE_TYPE_QUEUE_FAMILY_DATA_GRAPH_PROPERTIES_ARM, |
| nullptr, |
| {VK_PHYSICAL_DEVICE_DATA_GRAPH_PROCESSING_ENGINE_TYPE_DEFAULT_ARM, false}, |
| {VK_PHYSICAL_DEVICE_DATA_GRAPH_OPERATION_TYPE_SPIRV_EXTENDED_INSTRUCTION_SET_ARM, "TOSA.001000.1", 0}}; |
| uint32_t queue_without_tosa_1_0_idx = UINT32_MAX; |
| uint32_t n_queue_families; |
| vk::GetPhysicalDeviceQueueFamilyProperties(Gpu(), &n_queue_families, nullptr); |
| for (uint32_t qfi = 0; qfi < n_queue_families; qfi++) { |
| uint32_t n_properties; |
| ASSERT_TRUE(VK_SUCCESS == vk::GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(Gpu(), qfi, &n_properties, nullptr)); |
| std::vector<VkQueueFamilyDataGraphPropertiesARM> properties(n_properties, |
| {VK_STRUCTURE_TYPE_QUEUE_FAMILY_DATA_GRAPH_PROPERTIES_ARM}); |
| ASSERT_TRUE(VK_SUCCESS == |
| vk::GetPhysicalDeviceQueueFamilyDataGraphPropertiesARM(Gpu(), qfi, &n_properties, properties.data())); |
| |
| bool queue_supports_tosa_1_0 = false; |
| for (const auto& p : properties) { |
| if (CompareVkQueueFamilyDataGraphPropertiesARM(tosa_1_0_property, p)) { |
| queue_supports_tosa_1_0 = true; |
| break; |
| } |
| } |
| if (!queue_supports_tosa_1_0) { |
| queue_without_tosa_1_0_idx = qfi; |
| break; |
| } |
| } |
| |
| if (UINT32_MAX == queue_without_tosa_1_0_idx) { |
| GTEST_SKIP() << "All queues support TOSA, impossible to create the error condition, skip."; |
| } |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| pipeline.CreateDataGraphPipeline(); |
| |
| VkDataGraphPipelineSessionCreateInfoARM session_ci = vku::InitStructHelper(); |
| session_ci.dataGraphPipeline = pipeline; |
| vkt::DataGraphPipelineSession session(*m_device, session_ci); |
| session.GetMemoryReqs(); |
| CheckSessionMemory(session); |
| |
| auto& bind_point_reqs = session.BindPointReqs(); |
| std::vector<vkt::DeviceMemory> device_mem(bind_point_reqs.size()); |
| session.AllocSessionMem(device_mem); |
| auto session_bind_infos = InitSessionBindInfo(session, device_mem); |
| vk::BindDataGraphPipelineSessionMemoryARM(*m_device, session_bind_infos.size(), session_bind_infos.data()); |
| |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(0, &pipeline.tensor_views_[0]->handle(), 0); |
| pipeline.descriptor_set_->WriteDescriptorTensorInfo(1, &pipeline.tensor_views_[1]->handle(), 0); |
| pipeline.descriptor_set_->UpdateDescriptorSets(); |
| |
| m_command_buffer.Begin(); |
| vk::CmdBindPipeline(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline); |
| vk::CmdBindDescriptorSets(m_command_buffer, VK_PIPELINE_BIND_POINT_DATA_GRAPH_ARM, pipeline.pipeline_layout_, 0, 1, |
| &pipeline.descriptor_set_.get()->set_, 0, nullptr); |
| m_errorMonitor->SetDesiredError("VUID-vkCmdDispatchDataGraphARM-commandBuffer-09941"); |
| vk::CmdDispatchDataGraphARM(m_command_buffer, session, nullptr); |
| m_errorMonitor->VerifyFound(); |
| m_command_buffer.End(); |
| } |