blob: 62188264719bf4cd0c8d2a8d83d91df615d21246 [file] [log] [blame]
/*
* Copyright (c) 2022-2025 The Khronos Group Inc.
* Copyright (c) 2022-2025 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 "../framework/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();
}