| /* |
| * Copyright (c) 2026 The Khronos Group Inc. |
| * Copyright (c) 2026 RasterGrid Kft. |
| * |
| * 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" |
| #include "generated/enum_flag_bits.h" |
| |
| class NegativeVideoEncodeFeedback2 : public VkVideoLayerTest {}; |
| |
| TEST_F(NegativeVideoEncodeFeedback2, CreateQueryPoolFeedbackFlagsFeatureNotEnabled) { |
| TEST_DESCRIPTION("vkCreateQueryPool - creating query pool with feedback 2 flags requires videoEncodeFeedback2 feature"); |
| |
| AddRequiredExtensions(VK_KHR_VIDEO_ENCODE_FEEDBACK_2_EXTENSION_NAME); |
| ForceDisableFeature(vkt::Feature::videoEncodeFeedback2); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| VideoConfig config = GetConfig(FilterConfigs(GetConfigsEncode(), [](const VideoConfig& config) { |
| return config.EncodeCaps()->supportedEncodeFeedbackFlags & VK_VIDEO_ENCODE_FEEDBACK_AVERAGE_QUANTIZATION_BIT_KHR; |
| })); |
| |
| if (!config) { |
| GTEST_SKIP() << "Test requires a video encode profile that support video encode feedback2 flags"; |
| } |
| |
| auto encode_feedback_info = vku::InitStruct<VkQueryPoolVideoEncodeFeedbackCreateInfoKHR>(config.Profile()); |
| encode_feedback_info.encodeFeedbackFlags = VK_VIDEO_ENCODE_FEEDBACK_AVERAGE_QUANTIZATION_BIT_KHR; |
| |
| auto create_info = vku::InitStruct<VkQueryPoolCreateInfo>(&encode_feedback_info); |
| create_info.queryType = VK_QUERY_TYPE_VIDEO_ENCODE_FEEDBACK_KHR; |
| create_info.queryCount = 1; |
| |
| VkQueryPool query_pool{}; |
| m_errorMonitor->SetDesiredError("VUID-VkQueryPoolCreateInfo-queryType-12437"); |
| vk::CreateQueryPool(device(), &create_info, nullptr, &query_pool); |
| vk::DestroyQueryPool(device(), query_pool, nullptr); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeVideoEncodeFeedback2, CreateQueryPoolPerPartitionFeatureNotEnabled) { |
| TEST_DESCRIPTION( |
| "vkCreateQueryPool - creating query pool with per partition feedback entries requires videoEncodeFeedback2 feature"); |
| |
| AddRequiredExtensions(VK_KHR_VIDEO_ENCODE_FEEDBACK_2_EXTENSION_NAME); |
| ForceDisableFeature(vkt::Feature::videoEncodeFeedback2); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| VideoConfig config = GetConfig(FilterConfigs(GetConfigsEncode(), [](const VideoConfig& config) { |
| return config.EncodeFeedback2Caps()->maxPerPartitionFeedbackEntries != 0; |
| })); |
| |
| if (!config) { |
| GTEST_SKIP() << "Test requires a video encode profile that support non-zero maxPerPartitionFeedbackEntries"; |
| } |
| |
| auto per_partition_feedback_info = vku::InitStruct<VkQueryPoolVideoEncodePerPartitionFeedbackCreateInfoKHR>(config.Profile()); |
| per_partition_feedback_info.maxPerPartitionFeedbackEntries = 4; |
| per_partition_feedback_info.perPartitionEncodeFeedbackFlags = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR; |
| |
| auto encode_feedback_info = vku::InitStruct<VkQueryPoolVideoEncodeFeedbackCreateInfoKHR>(&per_partition_feedback_info); |
| encode_feedback_info.encodeFeedbackFlags = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR; |
| |
| auto create_info = vku::InitStruct<VkQueryPoolCreateInfo>(&encode_feedback_info); |
| create_info.queryType = VK_QUERY_TYPE_VIDEO_ENCODE_FEEDBACK_KHR; |
| create_info.queryCount = 1; |
| |
| VkQueryPool query_pool; |
| m_errorMonitor->SetDesiredError("VUID-VkQueryPoolCreateInfo-queryType-12438"); |
| vk::CreateQueryPool(device(), &create_info, nullptr, &query_pool); |
| vk::DestroyQueryPool(device(), query_pool, nullptr); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeVideoEncodeFeedback2, MissingPerPartitionFeedbackFlags) { |
| TEST_DESCRIPTION("vkCreateQueryPool - creating query pool with invalid per partition feedback entry flags"); |
| |
| AddRequiredExtensions(VK_KHR_VIDEO_ENCODE_FEEDBACK_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::videoEncodeFeedback2); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| VideoConfig config = GetConfig(FilterConfigs(GetConfigsEncode(), [](const VideoConfig& config) { |
| return (config.EncodeFeedback2Caps()->maxPerPartitionFeedbackEntries != 0) && |
| (config.EncodeFeedback2Caps()->supportedPerPartitionEncodeFeedbackFlags != 0); |
| })); |
| |
| if (!config) { |
| GTEST_SKIP() << "Test requires a video encode profile that support non-zero maxPerPartitionFeedbackEntries"; |
| } |
| |
| auto per_partition_feedback_info = vku::InitStruct<VkQueryPoolVideoEncodePerPartitionFeedbackCreateInfoKHR>(config.Profile()); |
| per_partition_feedback_info.maxPerPartitionFeedbackEntries = 4; |
| per_partition_feedback_info.perPartitionEncodeFeedbackFlags = 0; |
| |
| auto encode_feedback_info = vku::InitStruct<VkQueryPoolVideoEncodeFeedbackCreateInfoKHR>(&per_partition_feedback_info); |
| encode_feedback_info.encodeFeedbackFlags = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR; |
| |
| auto create_info = vku::InitStruct<VkQueryPoolCreateInfo>(&encode_feedback_info); |
| create_info.queryType = VK_QUERY_TYPE_VIDEO_ENCODE_FEEDBACK_KHR; |
| create_info.queryCount = 1; |
| |
| VkQueryPool query_pool; |
| m_errorMonitor->SetDesiredError("VUID-VkQueryPoolCreateInfo-queryType-12439"); |
| vk::CreateQueryPool(device(), &create_info, nullptr, &query_pool); |
| vk::DestroyQueryPool(device(), query_pool, nullptr); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeVideoEncodeFeedback2, TooManyPerPartitionFeedbackEntries) { |
| TEST_DESCRIPTION("vkCreateQueryPool - creating query pool with too many per partition feedback entries"); |
| |
| AddRequiredExtensions(VK_KHR_VIDEO_ENCODE_FEEDBACK_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::videoEncodeFeedback2); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| VideoConfig config = GetConfig(FilterConfigs(GetConfigsEncode(), [](const VideoConfig& config) { |
| return (config.EncodeFeedback2Caps()->maxPerPartitionFeedbackEntries != 0) && |
| (config.EncodeFeedback2Caps()->supportedPerPartitionEncodeFeedbackFlags != 0); |
| })); |
| |
| if (!config) { |
| GTEST_SKIP() << "Test requires a video encode profile that support non-zero maxPerPartitionFeedbackEntries"; |
| } |
| |
| auto per_partition_feedback_info = vku::InitStruct<VkQueryPoolVideoEncodePerPartitionFeedbackCreateInfoKHR>(config.Profile()); |
| per_partition_feedback_info.maxPerPartitionFeedbackEntries = config.EncodeFeedback2Caps()->maxPerPartitionFeedbackEntries + 1; |
| per_partition_feedback_info.perPartitionEncodeFeedbackFlags = |
| VK_VIDEO_ENCODE_PER_PARTITION_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR; |
| |
| auto encode_feedback_info = vku::InitStruct<VkQueryPoolVideoEncodeFeedbackCreateInfoKHR>(&per_partition_feedback_info); |
| encode_feedback_info.encodeFeedbackFlags = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR; |
| |
| auto create_info = vku::InitStruct<VkQueryPoolCreateInfo>(&encode_feedback_info); |
| create_info.queryType = VK_QUERY_TYPE_VIDEO_ENCODE_FEEDBACK_KHR; |
| create_info.queryCount = 1; |
| |
| VkQueryPool query_pool; |
| m_errorMonitor->SetDesiredError("VUID-VkQueryPoolCreateInfo-queryType-12440"); |
| vk::CreateQueryPool(device(), &create_info, nullptr, &query_pool); |
| vk::DestroyQueryPool(device(), query_pool, nullptr); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeVideoEncodeFeedback2, UnsupportedPerPartitionFeedbackFlags) { |
| TEST_DESCRIPTION("vkCreateQueryPool - creating query pool with unsupported per partition feedback flags"); |
| |
| AddRequiredExtensions(VK_KHR_VIDEO_ENCODE_FEEDBACK_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::videoEncodeFeedback2); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| VideoConfig config = GetConfig(FilterConfigs(GetConfigsEncode(), [](const VideoConfig& config) { |
| const auto supported_per_partition_encode_feedback_flags = |
| config.EncodeFeedback2Caps()->supportedPerPartitionEncodeFeedbackFlags; |
| return (config.EncodeFeedback2Caps()->maxPerPartitionFeedbackEntries != 0) && |
| (supported_per_partition_encode_feedback_flags != 0) && |
| (supported_per_partition_encode_feedback_flags != AllVkVideoEncodePerPartitionFeedbackFlagBitsKHR); |
| })); |
| |
| if (!config) { |
| GTEST_SKIP() << "Test requires a video encode profile that support non-zero maxPerPartitionFeedbackEntries, but not all " |
| "feedback flags"; |
| } |
| |
| auto per_partition_feedback_info = vku::InitStruct<VkQueryPoolVideoEncodePerPartitionFeedbackCreateInfoKHR>(config.Profile()); |
| per_partition_feedback_info.maxPerPartitionFeedbackEntries = 4; |
| per_partition_feedback_info.perPartitionEncodeFeedbackFlags = AllVkVideoEncodePerPartitionFeedbackFlagBitsKHR; |
| |
| auto encode_feedback_info = vku::InitStruct<VkQueryPoolVideoEncodeFeedbackCreateInfoKHR>(&per_partition_feedback_info); |
| encode_feedback_info.encodeFeedbackFlags = VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR; |
| |
| auto create_info = vku::InitStruct<VkQueryPoolCreateInfo>(&encode_feedback_info); |
| create_info.queryType = VK_QUERY_TYPE_VIDEO_ENCODE_FEEDBACK_KHR; |
| create_info.queryCount = 1; |
| |
| VkQueryPool query_pool; |
| m_errorMonitor->SetDesiredError("VUID-VkQueryPoolCreateInfo-queryType-12441"); |
| vk::CreateQueryPool(device(), &create_info, nullptr, &query_pool); |
| vk::DestroyQueryPool(device(), query_pool, nullptr); |
| m_errorMonitor->VerifyFound(); |
| } |
| |
| TEST_F(NegativeVideoEncodeFeedback2, CreateQueryPoolUnsupportedEncodeFeedback2Flags) { |
| TEST_DESCRIPTION("vkCreateQueryPool - missing VkQueryPoolVideoEncodeFeedbackCreateInfoKHR"); |
| |
| AddRequiredExtensions(VK_KHR_VIDEO_ENCODE_FEEDBACK_2_EXTENSION_NAME); |
| AddRequiredFeature(vkt::Feature::videoEncodeFeedback2); |
| |
| RETURN_IF_SKIP(Init()); |
| |
| const auto kAllVideoEncodeFeedback2Flags = |
| VK_VIDEO_ENCODE_FEEDBACK_AVERAGE_QUANTIZATION_BIT_KHR | VK_VIDEO_ENCODE_FEEDBACK_MIN_QUANTIZATION_BIT_KHR | |
| VK_VIDEO_ENCODE_FEEDBACK_MAX_QUANTIZATION_BIT_KHR | VK_VIDEO_ENCODE_FEEDBACK_INTRA_PIXELS_BIT_KHR | |
| VK_VIDEO_ENCODE_FEEDBACK_INTER_PIXELS_BIT_KHR | VK_VIDEO_ENCODE_FEEDBACK_SKIPPED_PIXELS_BIT_KHR | |
| VK_VIDEO_ENCODE_FEEDBACK_PICTURE_PARTITION_COUNT_BIT_KHR; |
| |
| VideoConfig config = GetConfig(FilterConfigs(GetConfigsEncode(), [](const VideoConfig& config) { |
| return (config.EncodeCaps()->supportedEncodeFeedbackFlags & kAllVideoEncodeFeedback2Flags) != kAllVideoEncodeFeedback2Flags; |
| })); |
| if (!config) { |
| GTEST_SKIP() << "Test requires a video encode profile that does not support all encode feedback 2 flags"; |
| } |
| |
| auto encode_feedback_info = vku::InitStruct<VkQueryPoolVideoEncodeFeedbackCreateInfoKHR>(config.Profile()); |
| encode_feedback_info.encodeFeedbackFlags = kAllVideoEncodeFeedback2Flags; |
| |
| auto create_info = vku::InitStruct<VkQueryPoolCreateInfo>(&encode_feedback_info); |
| create_info.queryType = VK_QUERY_TYPE_VIDEO_ENCODE_FEEDBACK_KHR; |
| create_info.queryCount = 1; |
| |
| VkQueryPool query_pool; |
| m_errorMonitor->SetDesiredError("VUID-VkQueryPoolCreateInfo-queryType-07907"); |
| vk::CreateQueryPool(device(), &create_info, nullptr, &query_pool); |
| m_errorMonitor->VerifyFound(); |
| } |