/*
 * 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();
}
