/*
 * Copyright (c) 2023-2025 The Khronos Group Inc.
 * Copyright (c) 2023-2025 Valve Corporation
 * Copyright (c) 2023-2025 LunarG, Inc.
 *
 * 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 "../framework/layer_validation_tests.h"
#include "../framework/pipeline_helper.h"

class NegativeRobustness : public VkLayerTest {};

TEST_F(NegativeRobustness, PipelineRobustnessDisabled) {
    TEST_DESCRIPTION("Create a pipeline using VK_EXT_pipeline_robustness but with pipelineRobustness == VK_FALSE");

    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_EXT_PIPELINE_ROBUSTNESS_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::robustBufferAccess);
    AddRequiredFeature(vkt::Feature::robustBufferAccess2);
    RETURN_IF_SKIP(Init());

    {
        VkPipelineRobustnessCreateInfo pipeline_robustness_info = vku::InitStructHelper();
        pipeline_robustness_info.storageBuffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2;
        CreateComputePipelineHelper pipe(*this, &pipeline_robustness_info);

        m_errorMonitor->SetDesiredError("VUID-VkPipelineRobustnessCreateInfo-pipelineRobustness-06926");
        pipe.CreateComputePipeline();
        m_errorMonitor->VerifyFound();
    }

    {
        VkPipelineRobustnessCreateInfo pipeline_robustness_info = vku::InitStructHelper();
        pipeline_robustness_info.uniformBuffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2;
        CreateComputePipelineHelper pipe(*this, &pipeline_robustness_info);

        m_errorMonitor->SetDesiredError("VUID-VkPipelineRobustnessCreateInfo-pipelineRobustness-06927");
        pipe.CreateComputePipeline();
        m_errorMonitor->VerifyFound();
    }

    {
        VkPipelineRobustnessCreateInfo pipeline_robustness_info = vku::InitStructHelper();
        pipeline_robustness_info.vertexInputs = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2;
        CreateComputePipelineHelper pipe(*this, &pipeline_robustness_info);

        m_errorMonitor->SetDesiredError("VUID-VkPipelineRobustnessCreateInfo-pipelineRobustness-06928");
        pipe.CreateComputePipeline();
        m_errorMonitor->VerifyFound();
    }

    {
        VkPipelineRobustnessCreateInfo pipeline_robustness_info = vku::InitStructHelper();
        pipeline_robustness_info.images = VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_2;
        CreateComputePipelineHelper pipe(*this, &pipeline_robustness_info);

        m_errorMonitor->SetDesiredError("VUID-VkPipelineRobustnessCreateInfo-pipelineRobustness-06929");
        pipe.CreateComputePipeline();
        m_errorMonitor->VerifyFound();
    }
}

TEST_F(NegativeRobustness, PipelineRobustnessDisabledShaderStage) {
    TEST_DESCRIPTION("Use VkPipelineShaderStageCreateInfo to set robustness");

    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_EXT_PIPELINE_ROBUSTNESS_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::robustBufferAccess);
    AddRequiredFeature(vkt::Feature::robustBufferAccess2);
    RETURN_IF_SKIP(Init());

    CreateComputePipelineHelper pipe(*this);

    pipe.LateBindPipelineInfo();

    VkPipelineRobustnessCreateInfo pipeline_robustness_info = vku::InitStructHelper();
    pipeline_robustness_info.storageBuffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2;
    pipe.cp_ci_.stage.pNext = &pipeline_robustness_info;

    m_errorMonitor->SetDesiredError("VUID-VkPipelineRobustnessCreateInfo-pipelineRobustness-06926");
    pipe.CreateComputePipeline(false);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeRobustness, PipelineRobustnessDisabledShaderStageWithIdentifier) {
    TEST_DESCRIPTION("Use VkPipelineShaderStageCreateInfo to set robustness using a shader module identifier");

    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_EXT_PIPELINE_ROBUSTNESS_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME);
    AddRequiredExtensions(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::pipelineCreationCacheControl);
    AddRequiredFeature(vkt::Feature::shaderModuleIdentifier);
    AddRequiredFeature(vkt::Feature::robustBufferAccess);
    AddRequiredFeature(vkt::Feature::robustBufferAccess2);
    RETURN_IF_SKIP(Init());

    CreateComputePipelineHelper pipe(*this);

    pipe.LateBindPipelineInfo();

    VkPipelineShaderStageModuleIdentifierCreateInfoEXT sm_id_create_info = vku::InitStructHelper();
    VkShaderObj cs(*m_device, kMinimalShaderGlsl, VK_SHADER_STAGE_COMPUTE_BIT);

    VkShaderModuleIdentifierEXT get_identifier = vku::InitStructHelper();
    vk::GetShaderModuleIdentifierEXT(device(), cs, &get_identifier);
    sm_id_create_info.identifierSize = get_identifier.identifierSize;
    sm_id_create_info.pIdentifier = get_identifier.identifier;

    VkPipelineRobustnessCreateInfo pipeline_robustness_info = vku::InitStructHelper(&sm_id_create_info);
    pipeline_robustness_info.storageBuffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2;
    pipe.cp_ci_.stage.module = VK_NULL_HANDLE;
    pipe.cp_ci_.stage.pNext = &pipeline_robustness_info;
    pipe.cp_ci_.flags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;

    m_errorMonitor->SetDesiredError("VUID-VkPipelineRobustnessCreateInfo-pipelineRobustness-06926");
    pipe.CreateComputePipeline(false);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeRobustness, PipelineRobustnessRobustBufferAccess2Unsupported) {
    TEST_DESCRIPTION("Create a pipeline using VK_EXT_pipeline_robustness with robustBufferAccess2 being unsupported");

    SetTargetApiVersion(VK_API_VERSION_1_1);
    AddRequiredExtensions(VK_EXT_PIPELINE_ROBUSTNESS_EXTENSION_NAME);
    AddOptionalExtensions(VK_KHR_ROBUSTNESS_2_EXTENSION_NAME);
    AddOptionalExtensions(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME);

    RETURN_IF_SKIP(InitFramework());

    if (IsExtensionsEnabled(VK_KHR_ROBUSTNESS_2_EXTENSION_NAME) || IsExtensionsEnabled(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME)) {
        VkPhysicalDeviceRobustness2FeaturesKHR robustness2_features = vku::InitStructHelper();
        GetPhysicalDeviceFeatures2(robustness2_features);

        if (robustness2_features.robustBufferAccess2) {
            GTEST_SKIP() << "robustBufferAccess2 is supported";
        }
    }

    VkPhysicalDevicePipelineRobustnessFeaturesEXT pipeline_robustness_features = vku::InitStructHelper();
    auto features2 = GetPhysicalDeviceFeatures2(pipeline_robustness_features);

    if (!pipeline_robustness_features.pipelineRobustness) {
        GTEST_SKIP() << "pipelineRobustness is not supported";
    }

    RETURN_IF_SKIP(InitState(nullptr, &features2));

    {
        VkPipelineRobustnessCreateInfo pipeline_robustness_info = vku::InitStructHelper();
        CreateComputePipelineHelper pipe(*this, &pipeline_robustness_info);
        pipeline_robustness_info.storageBuffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2;

        m_errorMonitor->SetDesiredError("VUID-VkPipelineRobustnessCreateInfo-robustBufferAccess2-06931");
        pipe.CreateComputePipeline();
        m_errorMonitor->VerifyFound();
    }

    {
        VkPipelineRobustnessCreateInfo pipeline_robustness_info = vku::InitStructHelper();
        CreateComputePipelineHelper pipe(*this, &pipeline_robustness_info);
        pipeline_robustness_info.uniformBuffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2;

        m_errorMonitor->SetDesiredError("VUID-VkPipelineRobustnessCreateInfo-robustBufferAccess2-06932");
        pipe.CreateComputePipeline();
        m_errorMonitor->VerifyFound();
    }

    {
        VkPipelineRobustnessCreateInfo pipeline_robustness_info = vku::InitStructHelper();
        CreateComputePipelineHelper pipe(*this, &pipeline_robustness_info);
        pipeline_robustness_info.vertexInputs = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2;

        m_errorMonitor->SetDesiredError("VUID-VkPipelineRobustnessCreateInfo-robustBufferAccess2-06933");
        pipe.CreateComputePipeline();
        m_errorMonitor->VerifyFound();
    }
}

TEST_F(NegativeRobustness, PipelineRobustnessRobustImageAccess2Unsupported) {
    TEST_DESCRIPTION("Create a pipeline using VK_EXT_pipeline_robustness with robustImageAccess2 being unsupported");

    AddRequiredExtensions(VK_EXT_PIPELINE_ROBUSTNESS_EXTENSION_NAME);
    AddOptionalExtensions(VK_KHR_ROBUSTNESS_2_EXTENSION_NAME);
    AddOptionalExtensions(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME);

    SetTargetApiVersion(VK_API_VERSION_1_1);
    RETURN_IF_SKIP(InitFramework());

    if (IsExtensionsEnabled(VK_KHR_ROBUSTNESS_2_EXTENSION_NAME) || IsExtensionsEnabled(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME)) {
        VkPhysicalDeviceRobustness2FeaturesKHR robustness2_features = vku::InitStructHelper();
        GetPhysicalDeviceFeatures2(robustness2_features);

        if (robustness2_features.robustImageAccess2) {
            GTEST_SKIP() << "robustImageAccess2 is supported";
        }
    }

    VkPhysicalDevicePipelineRobustnessFeaturesEXT pipeline_robustness_features = vku::InitStructHelper();
    auto features2 = GetPhysicalDeviceFeatures2(pipeline_robustness_features);

    if (!pipeline_robustness_features.pipelineRobustness) {
        GTEST_SKIP() << "pipelineRobustness is not supported";
    }

    RETURN_IF_SKIP(InitState(nullptr, &features2));

    VkPipelineRobustnessCreateInfo pipeline_robustness_info = vku::InitStructHelper();
    CreateComputePipelineHelper pipe(*this, &pipeline_robustness_info);
    pipeline_robustness_info.images = VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_2;

    m_errorMonitor->SetDesiredError("VUID-VkPipelineRobustnessCreateInfo-robustImageAccess2-06934");
    pipe.CreateComputePipeline();
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeRobustness, PipelineRobustnessRobustImageAccessNotExposed) {
    TEST_DESCRIPTION("Check if VK_EXT_image_robustness is not exposed");

    SetTargetApiVersion(VK_API_VERSION_1_2);
    AddRequiredExtensions(VK_EXT_PIPELINE_ROBUSTNESS_EXTENSION_NAME);
    AddRequiredFeature(vkt::Feature::pipelineRobustness);
    RETURN_IF_SKIP(Init());
    if (DeviceValidationVersion() > VK_API_VERSION_1_2) {
        GTEST_SKIP() << "version 1.3 enables extensions which we don't want";
    }
    if (DeviceExtensionSupported(Gpu(), nullptr, VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME)) {
        GTEST_SKIP() << "VK_EXT_image_robustness is supported";
    }

    VkPipelineRobustnessCreateInfo pipeline_robustness_info = vku::InitStructHelper();
    CreateComputePipelineHelper pipe(*this, &pipeline_robustness_info);
    pipeline_robustness_info.images = VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS;

    m_errorMonitor->SetDesiredError("VUID-VkPipelineRobustnessCreateInfo-robustImageAccess-06930");
    pipe.CreateComputePipeline();
    m_errorMonitor->VerifyFound();
}
