| /* |
| * 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 <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, 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 when a descriptor has type VK_DESCRIPTOR_TYPE_MUTABLE"); |
| 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, PipelineResourceInfoInvalidArrayElement) { |
| TEST_DESCRIPTION("Try to create a datagraph pipeline where arrayElement in resources is not set to 0"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| auto set_info = [&](vkt::dg::DataGraphPipelineHelper &pipeline) { pipeline.resources_.back().arrayElement = 1; }; |
| vkt::dg::DataGraphPipelineHelper::OneshotTest(*this, set_info, 0, "VUID-VkDataGraphPipelineResourceInfoARM-arrayElement-09779"); |
| } |
| |
| 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(); |
| create_sem.pNext = &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(); |
| submit_info.pNext = &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-09799"); |
| 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 command 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-09797"); |
| 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 command 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 command with unprotected resoures 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, 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-VkDataGraphPipelineShaderModuleCreateInfoARM-id-09774"); |
| 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 and 9850 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"); |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineConstantARM-id-09850"); |
| 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; |
| |
| // VU 9921 and 9774 overlap about the ID. |
| m_errorMonitor->SetDesiredError("VUID-RuntimeSpirv-pNext-09921"); |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineShaderModuleCreateInfoARM-id-09774"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, GraphConstantTensorWrongRank) { |
| TEST_DESCRIPTION("Try creating a datagraph pipeline with a constant based on a tensor with a 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 sign, bit width, and type |
| for (auto format : {VK_FORMAT_R8_SINT, VK_FORMAT_R32_UINT, VK_FORMAT_R32_SFLOAT}) { |
| 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; |
| |
| 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; |
| |
| // VU 9921 and 9850 overlap about the existence of a VkTensorDescriptionARM. |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineConstantARM-id-09850"); |
| 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, ResourceIsTensorMissingDescription) { |
| TEST_DESCRIPTION( |
| "Try creating a datagraph pipeline when the resources in resourceInfo do not have a VkTensorDescriptionARM in the pNext " |
| "chain"); |
| InitBasicDataGraph(); |
| RETURN_IF_SKIP(Init()); |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| |
| for (auto &resource : pipeline.resources_) { |
| resource.pNext = nullptr; |
| // each incorrect resource generates a separate error |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineResourceInfoARM-descriptorSet-09851"); |
| } |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeDataGraph, ResourceIsTensorInvalidUsage) { |
| 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()); |
| |
| VkTensorDescriptionARM desc = DefaultDesc(); |
| desc.usage = VK_TENSOR_USAGE_SHADER_BIT_ARM; // should be VK_TENSOR_USAGE_DATA_GRAPH_BIT_ARM |
| |
| vkt::dg::DataGraphPipelineHelper pipeline(*this); |
| |
| for (auto &resource : pipeline.resources_) { |
| resource.pNext = &desc; |
| // each incorrect resource generates a separate error |
| 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-09763"); |
| 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 another dummy one |
| 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; |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-pNext-09763"); |
| // it's either this error with resources defined, or VU if no resources |
| m_errorMonitor->SetAllowedFailureMsg("VUID-VkDataGraphPipelineCreateInfoARM-resourceInfoCount-arraylength"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| } |
| |
| 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"); |
| // currently tensor arrays are effectively banned by this VU, we need to suppress it |
| m_errorMonitor->SetAllowedFailureMsg("VUID-VkDataGraphPipelineResourceInfoARM-arrayElement-09779"); |
| 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"); |
| // currently tensor arrays are effectively banned by this VU, we need to suppress it |
| m_errorMonitor->SetAllowedFailureMsg("VUID-VkDataGraphPipelineResourceInfoARM-arrayElement-09779"); |
| 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; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-None-11840"); |
| // currently we have a conflict with this implicit rule, it will go in a future update |
| m_errorMonitor->SetAllowedFailureMsg("VUID-VkDataGraphPipelineCreateInfoARM-resourceInfoCount-arraylength"); |
| pipeline.CreateDataGraphPipeline(); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| 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; |
| |
| m_errorMonitor->SetDesiredError("VUID-VkDataGraphPipelineCreateInfoARM-None-11841"); |
| pipeline.CreateDataGraphPipeline(); |
| 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(); |
| } |