/*
 * Copyright (c) 2022-2026 The Khronos Group Inc.
 * Copyright (c) 2022-2026 RasterGrid Kft.
 * Modifications Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
 *
 * 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 "video_objects.h"

class NegativeVideoDecodeVP9 : public VkVideoLayerTest {};

TEST_F(NegativeVideoDecodeVP9, ProfileMissingCodecInfo) {
    TEST_DESCRIPTION("Test missing codec-specific structure in profile definition");

    RETURN_IF_SKIP(Init());

    VideoConfig config = GetConfigDecodeVP9();
    if (!config) {
        GTEST_SKIP() << "Test requires VP9 decode support";
    }

    VkVideoProfileInfoKHR profile = *config.Profile();
    profile.pNext = nullptr;

    // Missing codec-specific info for AV1 decode profile
    m_errorMonitor->SetDesiredError("VUID-VkVideoProfileInfoKHR-videoCodecOperation-10791");
    vk::GetPhysicalDeviceVideoCapabilitiesKHR(Gpu(), &profile, config.Caps());
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeVideoDecodeVP9, CapabilityQueryMissingChain) {
    TEST_DESCRIPTION("vkGetPhysicalDeviceVideoCapabilitiesKHR - missing return structures in chain");

    RETURN_IF_SKIP(Init());

    VideoConfig config = GetConfigDecodeVP9();
    if (!config) {
        GTEST_SKIP() << "Test requires VP9 decode support";
    }

    auto caps = vku::InitStruct<VkVideoCapabilitiesKHR>();
    auto decode_caps = vku::InitStruct<VkVideoDecodeCapabilitiesKHR>();
    auto decode_vp9_caps = vku::InitStruct<VkVideoDecodeVP9CapabilitiesKHR>();

    // Missing decode caps struct for decode profile
    m_errorMonitor->SetDesiredError("VUID-vkGetPhysicalDeviceVideoCapabilitiesKHR-pVideoProfile-07183");
    caps.pNext = &decode_vp9_caps;
    vk::GetPhysicalDeviceVideoCapabilitiesKHR(Gpu(), config.Profile(), &caps);
    m_errorMonitor->VerifyFound();

    // Missing VP9 decode caps struct for VP9 decode profile
    m_errorMonitor->SetDesiredError("VUID-vkGetPhysicalDeviceVideoCapabilitiesKHR-pVideoProfile-10792");
    caps.pNext = &decode_caps;
    vk::GetPhysicalDeviceVideoCapabilitiesKHR(Gpu(), config.Profile(), &caps);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeVideoDecodeVP9, CreateSessionVideoDecodeVP9NotEnabled) {
    TEST_DESCRIPTION("vkCreateVideoSession - VP9 decode is specified but videoDecodeVP9 was not enabled");

    ForceDisableFeature(vkt::Feature::videoDecodeVP9);
    RETURN_IF_SKIP(Init());

    VideoConfig config = GetConfigDecodeVP9();
    if (!config) {
        GTEST_SKIP() << "Test requires VP9 encode support";
    }

    VkVideoSessionKHR session;
    VkVideoSessionCreateInfoKHR create_info = *config.SessionCreateInfo();
    create_info.pVideoProfile = config.Profile();
    create_info.pStdHeaderVersion = config.StdVersion();

    m_errorMonitor->SetDesiredError("VUID-VkVideoSessionCreateInfoKHR-pVideoProfile-10793");
    vk::CreateVideoSessionKHR(device(), &create_info, nullptr, &session);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeVideoDecodeVP9, CreateBufferVideoDecodeVP9NotEnabled) {
    TEST_DESCRIPTION("vkCreateBuffer - VP9 decode is specified but videoDecodeVP9 was not enabled");

    ForceDisableFeature(vkt::Feature::videoDecodeVP9);
    RETURN_IF_SKIP(Init());

    VideoConfig config = GetConfigDecodeVP9();
    if (!config) {
        GTEST_SKIP() << "Test requires VP9 encode support";
    }

    VkBuffer buffer = VK_NULL_HANDLE;
    VkBufferCreateInfo buffer_ci = vku::InitStructHelper();
    buffer_ci.usage = VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR;
    buffer_ci.size = 2048;

    VkVideoProfileListInfoKHR video_profiles = vku::InitStructHelper();
    video_profiles.profileCount = 1;
    video_profiles.pProfiles = config.Profile();
    buffer_ci.pNext = &video_profiles;

    m_errorMonitor->SetDesiredError("VUID-VkBufferCreateInfo-pNext-10783");
    vk::CreateBuffer(device(), &buffer_ci, nullptr, &buffer);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeVideoDecodeVP9, CreateImageVideoDecodeVP9NotEnabled) {
    TEST_DESCRIPTION("vkCreateImage - VP9 decode is specified but videoDecodeVP9 was not enabled");

    ForceDisableFeature(vkt::Feature::videoDecodeVP9);
    RETURN_IF_SKIP(Init());

    VideoConfig config = GetConfigDecodeVP9();
    if (!config) {
        GTEST_SKIP() << "Test requires VP9 encode support";
    }

    VkImage image = VK_NULL_HANDLE;
    VkImageCreateInfo image_ci = vku::InitStructHelper();
    image_ci.imageType = config.PictureFormatProps()->imageType;
    image_ci.format = config.PictureFormatProps()->format;
    image_ci.extent = {config.MaxCodedExtent().width, config.MaxCodedExtent().height, 1};
    image_ci.mipLevels = 1;
    image_ci.arrayLayers = 1;
    image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
    image_ci.tiling = config.PictureFormatProps()->imageTiling;
    image_ci.usage = config.PictureFormatProps()->imageUsageFlags;
    image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;

    VkVideoProfileListInfoKHR video_profiles = vku::InitStructHelper();
    video_profiles.profileCount = 1;
    video_profiles.pProfiles = config.Profile();
    image_ci.pNext = &video_profiles;

    m_errorMonitor->SetDesiredError("VUID-VkImageCreateInfo-pNext-10784");
    vk::CreateImage(device(), &image_ci, nullptr, &image);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeVideoDecodeVP9, CreateQueryPoolVideoDecodeVP9NotEnabled) {
    TEST_DESCRIPTION("vkCreateQueryPool - VP9 decode is specified but videoDecodeVP9 was not enabled");

    ForceDisableFeature(vkt::Feature::videoDecodeVP9);
    RETURN_IF_SKIP(Init());

    VideoConfig config = GetConfigDecodeVP9();
    if (!config) {
        GTEST_SKIP() << "Test requires VP9 encode support";
    }
    if (!QueueFamilySupportsResultStatusOnlyQueries(config.QueueFamilyIndex())) {
        GTEST_SKIP() << "Test requires video decode queue to support result status queries";
    }

    VkQueryPool query_pool = VK_NULL_HANDLE;
    auto create_info = vku::InitStruct<VkQueryPoolCreateInfo>(config.Profile());
    create_info.queryType = VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR;
    create_info.queryCount = 1;

    m_errorMonitor->SetDesiredError("VUID-VkQueryPoolCreateInfo-pNext-10779");
    vk::CreateQueryPool(device(), &create_info, nullptr, &query_pool);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeVideoDecodeVP9, CreateVideoSessionParams) {
    TEST_DESCRIPTION("vkCreateVideoSessionParametersKHR - VP9 decode does not support creating session parameters.");

    RETURN_IF_SKIP(Init());

    VideoConfig config = GetConfigDecodeVP9();
    if (!config) {
        GTEST_SKIP() << "Test requires VP9 encode support";
    }

    VideoContext context(DeviceObj(), config);
    context.CreateAndBindSessionMemory();
    context.CreateResources();

    VkVideoSessionParametersKHR params;
    VkVideoSessionParametersCreateInfoKHR create_info = *config.SessionParamsCreateInfo();
    create_info.videoSession = context.Session();

    m_errorMonitor->SetDesiredError("VUID-VkVideoSessionParametersCreateInfoKHR-videoSession-10794");
    vk::CreateVideoSessionParametersKHR(device(), &create_info, nullptr, &params);
    m_errorMonitor->VerifyFound();
}

TEST_F(NegativeVideoDecodeVP9, DecodeInvalidCodecInfo) {
    TEST_DESCRIPTION("vkCmdDecodeVideoKHR - invalid/missing VP9 codec-specific information");

    RETURN_IF_SKIP(Init());

    VideoConfig config = GetConfig(GetConfigsWithDpbSlots(GetConfigsWithReferences(GetConfigsDecodeVP9(), 2), 2));
    if (!config) {
        GTEST_SKIP() << "Test requires VP9 decode support with 2 reference pictures and 2 DPB slots";
    }

    config.SessionCreateInfo()->maxDpbSlots = 2;
    config.SessionCreateInfo()->maxActiveReferencePictures = 2;

    VideoContext context(DeviceObj(), config);
    context.CreateAndBindSessionMemory();
    context.CreateResources();

    vkt::CommandBuffer& cb = context.CmdBuffer();

    VideoDecodeInfo decode_info = context.DecodeFrame(0);

    StdVideoDecodeVP9PictureInfo std_picture_info{};
    auto picture_info = vku::InitStruct<VkVideoDecodeVP9PictureInfoKHR>();
    picture_info.pStdPictureInfo = &std_picture_info;
    for (uint32_t i = 0; i < VK_MAX_VIDEO_VP9_REFERENCES_PER_FRAME_KHR; ++i) {
        picture_info.referenceNameSlotIndices[i] = -1;
    }
    picture_info.uncompressedHeaderOffset = 0;
    picture_info.compressedHeaderOffset = 0;
    picture_info.tilesOffset = 0;

    cb.Begin();
    cb.BeginVideoCoding(context.Begin().AddResource(0, 0).AddResource(-1, 1));

    // Missing VP9 picture info
    {
        decode_info = context.DecodeFrame(0);
        decode_info->pNext = nullptr;

        m_errorMonitor->SetDesiredError("VUID-vkCmdDecodeVideoKHR-pNext-10805");
        cb.DecodeVideo(decode_info);
        m_errorMonitor->VerifyFound();
    }

    // Uncompressed frame header offset must be within buffer range
    {
        decode_info = context.DecodeFrame(0);
        decode_info->pNext = &picture_info;

        m_errorMonitor->SetDesiredError("VUID-vkCmdDecodeVideoKHR-uncompressedHeaderOffset-10806");
        picture_info.uncompressedHeaderOffset = (uint32_t)decode_info->srcBufferRange;
        cb.DecodeVideo(decode_info);
        picture_info.uncompressedHeaderOffset -= 1;
        m_errorMonitor->VerifyFound();
    }

    // Compressed frame header offset must be within buffer range
    {
        decode_info = context.DecodeFrame(0);
        decode_info->pNext = &picture_info;

        m_errorMonitor->SetDesiredError("VUID-vkCmdDecodeVideoKHR-compressedHeaderOffset-10807");
        picture_info.compressedHeaderOffset = (uint32_t)decode_info->srcBufferRange;
        cb.DecodeVideo(decode_info);
        picture_info.compressedHeaderOffset -= 1;
        m_errorMonitor->VerifyFound();
    }

    // Tile offset must be within buffer range
    {
        decode_info = context.DecodeFrame(0);
        decode_info->pNext = &picture_info;

        m_errorMonitor->SetDesiredError("VUID-vkCmdDecodeVideoKHR-tilesOffset-10808");
        picture_info.tilesOffset = (uint32_t)decode_info->srcBufferRange;
        cb.DecodeVideo(decode_info);
        picture_info.tilesOffset -= 1;
        m_errorMonitor->VerifyFound();
    }

    // Missing reference in referenceNameSlotIndices to reference slot
    {
        auto slot = vku::InitStruct<VkVideoReferenceSlotInfoKHR>();
        slot.pNext = nullptr;
        slot.slotIndex = 0;
        slot.pPictureResource = &context.Dpb()->Picture(0);

        decode_info = context.DecodeFrame(1);
        decode_info->pNext = &picture_info;
        decode_info->referenceSlotCount = 1;
        decode_info->pReferenceSlots = &slot;

        m_errorMonitor->SetDesiredError("VUID-vkCmdDecodeVideoKHR-slotIndex-10810");
        cb.DecodeVideo(decode_info);
        m_errorMonitor->VerifyFound();
    }

    // Missing reference slot for DPB slot index referred to by referenceNameSlotIndices
    {
        decode_info = context.DecodeFrame(0);
        decode_info->pNext = &picture_info;

        picture_info.referenceNameSlotIndices[2] = 0;

        m_errorMonitor->SetDesiredError("VUID-vkCmdDecodeVideoKHR-referenceNameSlotIndices-10809");
        cb.DecodeVideo(decode_info);
        m_errorMonitor->VerifyFound();

        picture_info.referenceNameSlotIndices[2] = -1;
    }

    cb.EndVideoCoding(context.End());
    cb.End();
}
