1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------ 2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests 3e5c31af7Sopenharmony_ci * ------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2021 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief Video Encoding and Decoding Utility Functions 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "vktVideoTestUtils.hpp" 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "vkDefs.hpp" 27e5c31af7Sopenharmony_ci#include "vkMemUtil.hpp" 28e5c31af7Sopenharmony_ci#include "vkRefUtil.hpp" 29e5c31af7Sopenharmony_ci#include "vkTypeUtil.hpp" 30e5c31af7Sopenharmony_ci#include "vkQueryUtil.hpp" 31e5c31af7Sopenharmony_ci#include "vkDeviceUtil.hpp" 32e5c31af7Sopenharmony_ci#include "tcuCommandLine.hpp" 33e5c31af7Sopenharmony_ci#include "tcuResource.hpp" 34e5c31af7Sopenharmony_ci 35e5c31af7Sopenharmony_ci#include "vktCustomInstancesDevices.hpp" 36e5c31af7Sopenharmony_ci#include "vktTestCase.hpp" 37e5c31af7Sopenharmony_ci 38e5c31af7Sopenharmony_ci#include "vktVideoDecodeTests.hpp" 39e5c31af7Sopenharmony_ci 40e5c31af7Sopenharmony_ci#include "vkMd5Sum.hpp" 41e5c31af7Sopenharmony_ci 42e5c31af7Sopenharmony_ciusing namespace vk; 43e5c31af7Sopenharmony_ciusing namespace std; 44e5c31af7Sopenharmony_ci 45e5c31af7Sopenharmony_cinamespace vkt 46e5c31af7Sopenharmony_ci{ 47e5c31af7Sopenharmony_cinamespace video 48e5c31af7Sopenharmony_ci{ 49e5c31af7Sopenharmony_ci 50e5c31af7Sopenharmony_ciusing namespace vk; 51e5c31af7Sopenharmony_ciusing namespace std; 52e5c31af7Sopenharmony_ci 53e5c31af7Sopenharmony_ci 54e5c31af7Sopenharmony_cibool videoLoggingEnabled() 55e5c31af7Sopenharmony_ci{ 56e5c31af7Sopenharmony_ci static int debuggingEnabled = -1; // -1 means it hasn't been checked yet 57e5c31af7Sopenharmony_ci if (debuggingEnabled == -1) { 58e5c31af7Sopenharmony_ci const char* s = getenv("CTS_DEBUG_VIDEO"); 59e5c31af7Sopenharmony_ci debuggingEnabled = s != nullptr; 60e5c31af7Sopenharmony_ci } 61e5c31af7Sopenharmony_ci 62e5c31af7Sopenharmony_ci return debuggingEnabled > 0; 63e5c31af7Sopenharmony_ci} 64e5c31af7Sopenharmony_ci 65e5c31af7Sopenharmony_civoid cmdPipelineImageMemoryBarrier2 (const DeviceInterface& vk, 66e5c31af7Sopenharmony_ci const VkCommandBuffer commandBuffer, 67e5c31af7Sopenharmony_ci const VkImageMemoryBarrier2KHR* pImageMemoryBarriers, 68e5c31af7Sopenharmony_ci const size_t imageMemoryBarrierCount, 69e5c31af7Sopenharmony_ci const VkDependencyFlags dependencyFlags) 70e5c31af7Sopenharmony_ci{ 71e5c31af7Sopenharmony_ci const deUint32 imageMemoryBarrierCount32 = static_cast<deUint32>(imageMemoryBarrierCount); 72e5c31af7Sopenharmony_ci const VkDependencyInfo dependencyInfoKHR = 73e5c31af7Sopenharmony_ci { 74e5c31af7Sopenharmony_ci vk::VK_STRUCTURE_TYPE_DEPENDENCY_INFO, // VkStructureType sType; 75e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 76e5c31af7Sopenharmony_ci dependencyFlags, // VkDependencyFlags dependencyFlags; 77e5c31af7Sopenharmony_ci 0u, // deUint32 memoryBarrierCount; 78e5c31af7Sopenharmony_ci DE_NULL, // const VkMemoryBarrier2KHR* pMemoryBarriers; 79e5c31af7Sopenharmony_ci 0u, // deUint32 bufferMemoryBarrierCount; 80e5c31af7Sopenharmony_ci DE_NULL, // const VkBufferMemoryBarrier2KHR* pBufferMemoryBarriers; 81e5c31af7Sopenharmony_ci imageMemoryBarrierCount32, // deUint32 imageMemoryBarrierCount; 82e5c31af7Sopenharmony_ci pImageMemoryBarriers, // const VkImageMemoryBarrier2KHR* pImageMemoryBarriers; 83e5c31af7Sopenharmony_ci }; 84e5c31af7Sopenharmony_ci 85e5c31af7Sopenharmony_ci DE_ASSERT(imageMemoryBarrierCount == imageMemoryBarrierCount32); 86e5c31af7Sopenharmony_ci 87e5c31af7Sopenharmony_ci vk.cmdPipelineBarrier2(commandBuffer, &dependencyInfoKHR); 88e5c31af7Sopenharmony_ci} 89e5c31af7Sopenharmony_ci 90e5c31af7Sopenharmony_cistatic VkExtensionProperties makeExtensionProperties(const char* extensionName, deUint32 specVersion) 91e5c31af7Sopenharmony_ci{ 92e5c31af7Sopenharmony_ci const deUint32 extensionNameLen = static_cast<deUint32>(deStrnlen(extensionName, VK_MAX_EXTENSION_NAME_SIZE)); 93e5c31af7Sopenharmony_ci VkExtensionProperties result; 94e5c31af7Sopenharmony_ci 95e5c31af7Sopenharmony_ci deMemset(&result, 0, sizeof(result)); 96e5c31af7Sopenharmony_ci 97e5c31af7Sopenharmony_ci deMemcpy(&result.extensionName, extensionName, extensionNameLen); 98e5c31af7Sopenharmony_ci 99e5c31af7Sopenharmony_ci result.specVersion = specVersion; 100e5c31af7Sopenharmony_ci 101e5c31af7Sopenharmony_ci return result; 102e5c31af7Sopenharmony_ci} 103e5c31af7Sopenharmony_ci 104e5c31af7Sopenharmony_cistatic const VkExtensionProperties EXTENSION_PROPERTIES_H264_DECODE = makeExtensionProperties(VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_EXTENSION_NAME, VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_SPEC_VERSION); 105e5c31af7Sopenharmony_cistatic const VkExtensionProperties EXTENSION_PROPERTIES_H264_ENCODE = makeExtensionProperties(VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_EXTENSION_NAME, VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_SPEC_VERSION); 106e5c31af7Sopenharmony_cistatic const VkExtensionProperties EXTENSION_PROPERTIES_H265_DECODE = makeExtensionProperties(VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_EXTENSION_NAME, VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_SPEC_VERSION); 107e5c31af7Sopenharmony_cistatic const VkExtensionProperties EXTENSION_PROPERTIES_H265_ENCODE = makeExtensionProperties(VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_EXTENSION_NAME, VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_SPEC_VERSION); 108e5c31af7Sopenharmony_ci 109e5c31af7Sopenharmony_cibool VideoBaseTestInstance::createDeviceSupportingQueue (const VkQueueFlags queueFlagsRequired, const VkVideoCodecOperationFlagsKHR videoCodecOperationFlags, const VideoDevice::VideoDeviceFlags videoDeviceFlags) 110e5c31af7Sopenharmony_ci{ 111e5c31af7Sopenharmony_ci return m_videoDevice.createDeviceSupportingQueue(queueFlagsRequired, videoCodecOperationFlags, videoDeviceFlags); 112e5c31af7Sopenharmony_ci} 113e5c31af7Sopenharmony_ci 114e5c31af7Sopenharmony_ciVkDevice VideoBaseTestInstance::getDeviceSupportingQueue (const VkQueueFlags queueFlagsRequired, const VkVideoCodecOperationFlagsKHR videoCodecOperationFlags, const VideoDevice::VideoDeviceFlags videoDeviceFlags) 115e5c31af7Sopenharmony_ci{ 116e5c31af7Sopenharmony_ci return m_videoDevice.getDeviceSupportingQueue(queueFlagsRequired, videoCodecOperationFlags, videoDeviceFlags); 117e5c31af7Sopenharmony_ci} 118e5c31af7Sopenharmony_ci 119e5c31af7Sopenharmony_ciconst DeviceDriver& VideoBaseTestInstance::getDeviceDriver (void) 120e5c31af7Sopenharmony_ci{ 121e5c31af7Sopenharmony_ci return m_videoDevice.getDeviceDriver(); 122e5c31af7Sopenharmony_ci} 123e5c31af7Sopenharmony_ci 124e5c31af7Sopenharmony_cideUint32 VideoBaseTestInstance::getQueueFamilyIndexTransfer (void) 125e5c31af7Sopenharmony_ci{ 126e5c31af7Sopenharmony_ci return m_videoDevice.getQueueFamilyIndexTransfer(); 127e5c31af7Sopenharmony_ci} 128e5c31af7Sopenharmony_ci 129e5c31af7Sopenharmony_cideUint32 VideoBaseTestInstance::getQueueFamilyIndexDecode (void) 130e5c31af7Sopenharmony_ci{ 131e5c31af7Sopenharmony_ci return m_videoDevice.getQueueFamilyIndexDecode(); 132e5c31af7Sopenharmony_ci} 133e5c31af7Sopenharmony_ci 134e5c31af7Sopenharmony_cideUint32 VideoBaseTestInstance::getQueueFamilyIndexEncode (void) 135e5c31af7Sopenharmony_ci{ 136e5c31af7Sopenharmony_ci return m_videoDevice.getQueueFamilyIndexEncode(); 137e5c31af7Sopenharmony_ci} 138e5c31af7Sopenharmony_ci 139e5c31af7Sopenharmony_ciAllocator& VideoBaseTestInstance::getAllocator (void) 140e5c31af7Sopenharmony_ci{ 141e5c31af7Sopenharmony_ci return m_videoDevice.getAllocator(); 142e5c31af7Sopenharmony_ci} 143e5c31af7Sopenharmony_ci 144e5c31af7Sopenharmony_cide::MovePtr<vector<deUint8>> VideoBaseTestInstance::loadVideoData (const string& filename) 145e5c31af7Sopenharmony_ci{ 146e5c31af7Sopenharmony_ci tcu::Archive& archive = m_context.getTestContext().getArchive(); 147e5c31af7Sopenharmony_ci de::UniquePtr<tcu::Resource> resource (archive.getResource(filename.c_str())); 148e5c31af7Sopenharmony_ci const int resourceSize = resource->getSize(); 149e5c31af7Sopenharmony_ci de::MovePtr<vector<deUint8>> result (new vector<deUint8>(resourceSize)); 150e5c31af7Sopenharmony_ci 151e5c31af7Sopenharmony_ci resource->read(result->data(), resource->getSize()); 152e5c31af7Sopenharmony_ci 153e5c31af7Sopenharmony_ci return result; 154e5c31af7Sopenharmony_ci} 155e5c31af7Sopenharmony_ci 156e5c31af7Sopenharmony_cistd::string VideoBaseTestInstance::getVideoDataClipA (void) 157e5c31af7Sopenharmony_ci{ 158e5c31af7Sopenharmony_ci return std::string("vulkan/video/clip-a.h264"); 159e5c31af7Sopenharmony_ci} 160e5c31af7Sopenharmony_ci 161e5c31af7Sopenharmony_cistd::string VideoBaseTestInstance::getVideoDataClipB (void) 162e5c31af7Sopenharmony_ci{ 163e5c31af7Sopenharmony_ci return std::string("vulkan/video/clip-b.h264"); 164e5c31af7Sopenharmony_ci} 165e5c31af7Sopenharmony_ci 166e5c31af7Sopenharmony_cistd::string VideoBaseTestInstance::getVideoDataClipC (void) 167e5c31af7Sopenharmony_ci{ 168e5c31af7Sopenharmony_ci return std::string("vulkan/video/clip-c.h264"); 169e5c31af7Sopenharmony_ci} 170e5c31af7Sopenharmony_ci 171e5c31af7Sopenharmony_cistd::string VideoBaseTestInstance::getVideoDataClipD (void) 172e5c31af7Sopenharmony_ci{ 173e5c31af7Sopenharmony_ci return std::string("vulkan/video/clip-d.h265"); 174e5c31af7Sopenharmony_ci} 175e5c31af7Sopenharmony_ci 176e5c31af7Sopenharmony_cistd::string VideoBaseTestInstance::getVideoDataClipH264G13 (void) 177e5c31af7Sopenharmony_ci{ 178e5c31af7Sopenharmony_ci return std::string("vulkan/video/jellyfish-250-mbps-4k-uhd-GOB-IPB13.h264"); 179e5c31af7Sopenharmony_ci} 180e5c31af7Sopenharmony_ci 181e5c31af7Sopenharmony_cistd::string VideoBaseTestInstance::getVideoDataClipH265G13 (void) 182e5c31af7Sopenharmony_ci{ 183e5c31af7Sopenharmony_ci return std::string("vulkan/video/jellyfish-250-mbps-4k-uhd-GOB-IPB13.h265"); 184e5c31af7Sopenharmony_ci} 185e5c31af7Sopenharmony_ci 186e5c31af7Sopenharmony_ciconst VkExtensionProperties* getVideoExtensionProperties (const VkVideoCodecOperationFlagBitsKHR codecOperation) 187e5c31af7Sopenharmony_ci{ 188e5c31af7Sopenharmony_ci switch (codecOperation) 189e5c31af7Sopenharmony_ci { 190e5c31af7Sopenharmony_ci case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT: return &EXTENSION_PROPERTIES_H264_ENCODE; 191e5c31af7Sopenharmony_ci case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT: return &EXTENSION_PROPERTIES_H265_ENCODE; 192e5c31af7Sopenharmony_ci case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR: return &EXTENSION_PROPERTIES_H264_DECODE; 193e5c31af7Sopenharmony_ci case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR: return &EXTENSION_PROPERTIES_H265_DECODE; 194e5c31af7Sopenharmony_ci default: TCU_THROW(InternalError, "Unkown codec operation"); 195e5c31af7Sopenharmony_ci } 196e5c31af7Sopenharmony_ci} 197e5c31af7Sopenharmony_ci 198e5c31af7Sopenharmony_cide::MovePtr<vector<VkFormat>> getSupportedFormats (const InstanceInterface& vk, 199e5c31af7Sopenharmony_ci const VkPhysicalDevice physicalDevice, 200e5c31af7Sopenharmony_ci const VkImageUsageFlags imageUsageFlags, 201e5c31af7Sopenharmony_ci const VkVideoProfileListInfoKHR* videoProfileList) 202e5c31af7Sopenharmony_ci 203e5c31af7Sopenharmony_ci{ 204e5c31af7Sopenharmony_ci deUint32 videoFormatPropertiesCount = 0u; 205e5c31af7Sopenharmony_ci 206e5c31af7Sopenharmony_ci const VkPhysicalDeviceVideoFormatInfoKHR videoFormatInfo = 207e5c31af7Sopenharmony_ci { 208e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR, // VkStructureType sType; 209e5c31af7Sopenharmony_ci videoProfileList, // const void* pNext; 210e5c31af7Sopenharmony_ci imageUsageFlags, // VkImageUsageFlags imageUsage; 211e5c31af7Sopenharmony_ci }; 212e5c31af7Sopenharmony_ci 213e5c31af7Sopenharmony_ci VkVideoFormatPropertiesKHR videoFormatPropertiesKHR = {}; 214e5c31af7Sopenharmony_ci videoFormatPropertiesKHR.sType = VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR; 215e5c31af7Sopenharmony_ci videoFormatPropertiesKHR.pNext = DE_NULL; 216e5c31af7Sopenharmony_ci 217e5c31af7Sopenharmony_ci 218e5c31af7Sopenharmony_ci vector<VkVideoFormatPropertiesKHR> videoFormatProperties; 219e5c31af7Sopenharmony_ci de::MovePtr<vector<VkFormat>> result; 220e5c31af7Sopenharmony_ci 221e5c31af7Sopenharmony_ci const VkResult res = vk.getPhysicalDeviceVideoFormatPropertiesKHR(physicalDevice, &videoFormatInfo, &videoFormatPropertiesCount, DE_NULL); 222e5c31af7Sopenharmony_ci 223e5c31af7Sopenharmony_ci if (res == VK_ERROR_FORMAT_NOT_SUPPORTED) 224e5c31af7Sopenharmony_ci return de::MovePtr<vector<VkFormat>>(DE_NULL); 225e5c31af7Sopenharmony_ci else 226e5c31af7Sopenharmony_ci VK_CHECK(res); 227e5c31af7Sopenharmony_ci 228e5c31af7Sopenharmony_ci videoFormatProperties.resize(videoFormatPropertiesCount, videoFormatPropertiesKHR); 229e5c31af7Sopenharmony_ci 230e5c31af7Sopenharmony_ci VK_CHECK(vk.getPhysicalDeviceVideoFormatPropertiesKHR(physicalDevice, &videoFormatInfo, &videoFormatPropertiesCount, videoFormatProperties.data())); 231e5c31af7Sopenharmony_ci 232e5c31af7Sopenharmony_ci DE_ASSERT(videoFormatPropertiesCount == videoFormatProperties.size()); 233e5c31af7Sopenharmony_ci 234e5c31af7Sopenharmony_ci result = de::MovePtr<vector<VkFormat>>(new vector<VkFormat>); 235e5c31af7Sopenharmony_ci 236e5c31af7Sopenharmony_ci result->reserve(videoFormatProperties.size()); 237e5c31af7Sopenharmony_ci 238e5c31af7Sopenharmony_ci for (const auto& videoFormatProperty : videoFormatProperties) 239e5c31af7Sopenharmony_ci result->push_back(videoFormatProperty.format); 240e5c31af7Sopenharmony_ci 241e5c31af7Sopenharmony_ci return result; 242e5c31af7Sopenharmony_ci} 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_ciVkVideoFormatPropertiesKHR getSupportedFormatProperties (const InstanceInterface& vk, 245e5c31af7Sopenharmony_ci const VkPhysicalDevice physicalDevice, 246e5c31af7Sopenharmony_ci const VkImageUsageFlags imageUsageFlags, 247e5c31af7Sopenharmony_ci void* pNext, 248e5c31af7Sopenharmony_ci const VkFormat format) 249e5c31af7Sopenharmony_ci 250e5c31af7Sopenharmony_ci{ 251e5c31af7Sopenharmony_ci if (format == VK_FORMAT_UNDEFINED) 252e5c31af7Sopenharmony_ci return VkVideoFormatPropertiesKHR(); 253e5c31af7Sopenharmony_ci 254e5c31af7Sopenharmony_ci deUint32 videoFormatPropertiesCount = 0u; 255e5c31af7Sopenharmony_ci 256e5c31af7Sopenharmony_ci const VkPhysicalDeviceVideoFormatInfoKHR videoFormatInfo = 257e5c31af7Sopenharmony_ci { 258e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR, // VkStructureType sType; 259e5c31af7Sopenharmony_ci pNext, // const void* pNext; 260e5c31af7Sopenharmony_ci imageUsageFlags, // VkImageUsageFlags imageUsage; 261e5c31af7Sopenharmony_ci }; 262e5c31af7Sopenharmony_ci 263e5c31af7Sopenharmony_ci VkVideoFormatPropertiesKHR videoFormatPropertiesKHR = {}; 264e5c31af7Sopenharmony_ci videoFormatPropertiesKHR.sType = VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR; 265e5c31af7Sopenharmony_ci videoFormatPropertiesKHR.pNext = DE_NULL; 266e5c31af7Sopenharmony_ci 267e5c31af7Sopenharmony_ci vector<VkVideoFormatPropertiesKHR> videoFormatProperties; 268e5c31af7Sopenharmony_ci 269e5c31af7Sopenharmony_ci const VkResult res = vk.getPhysicalDeviceVideoFormatPropertiesKHR(physicalDevice, &videoFormatInfo, &videoFormatPropertiesCount, DE_NULL); 270e5c31af7Sopenharmony_ci 271e5c31af7Sopenharmony_ci if (res == VK_ERROR_FORMAT_NOT_SUPPORTED) 272e5c31af7Sopenharmony_ci return VkVideoFormatPropertiesKHR(); 273e5c31af7Sopenharmony_ci else 274e5c31af7Sopenharmony_ci VK_CHECK(res); 275e5c31af7Sopenharmony_ci 276e5c31af7Sopenharmony_ci videoFormatProperties.resize(videoFormatPropertiesCount, videoFormatPropertiesKHR); 277e5c31af7Sopenharmony_ci 278e5c31af7Sopenharmony_ci VK_CHECK(vk.getPhysicalDeviceVideoFormatPropertiesKHR(physicalDevice, &videoFormatInfo, &videoFormatPropertiesCount, videoFormatProperties.data())); 279e5c31af7Sopenharmony_ci 280e5c31af7Sopenharmony_ci DE_ASSERT(videoFormatPropertiesCount == videoFormatProperties.size()); 281e5c31af7Sopenharmony_ci 282e5c31af7Sopenharmony_ci for (const auto& videoFormatProperty : videoFormatProperties) 283e5c31af7Sopenharmony_ci { 284e5c31af7Sopenharmony_ci if (videoFormatProperty.format == format) 285e5c31af7Sopenharmony_ci return videoFormatProperty; 286e5c31af7Sopenharmony_ci }; 287e5c31af7Sopenharmony_ci 288e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Video format not found in properties list"); 289e5c31af7Sopenharmony_ci} 290e5c31af7Sopenharmony_ci 291e5c31af7Sopenharmony_ci 292e5c31af7Sopenharmony_cibool validateVideoExtent (const VkExtent2D& codedExtent, const VkVideoCapabilitiesKHR& videoCapabilities) 293e5c31af7Sopenharmony_ci{ 294e5c31af7Sopenharmony_ci if (!de::inRange(codedExtent.width, videoCapabilities.minCodedExtent.width, videoCapabilities.maxCodedExtent.width)) 295e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Video width does not fit capabilities"); 296e5c31af7Sopenharmony_ci 297e5c31af7Sopenharmony_ci if (!de::inRange(codedExtent.height, videoCapabilities.minCodedExtent.height, videoCapabilities.maxCodedExtent.height)) 298e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Video height does not fit capabilities"); 299e5c31af7Sopenharmony_ci 300e5c31af7Sopenharmony_ci return true; 301e5c31af7Sopenharmony_ci} 302e5c31af7Sopenharmony_ci 303e5c31af7Sopenharmony_cibool validateFormatSupport (const InstanceInterface& vk, 304e5c31af7Sopenharmony_ci VkPhysicalDevice physicalDevice, 305e5c31af7Sopenharmony_ci const VkImageUsageFlags imageUsageFlags, 306e5c31af7Sopenharmony_ci const VkVideoProfileListInfoKHR* videoProfileList, 307e5c31af7Sopenharmony_ci const VkFormat format, 308e5c31af7Sopenharmony_ci bool throwException) 309e5c31af7Sopenharmony_ci{ 310e5c31af7Sopenharmony_ci de::MovePtr<vector<VkFormat>> supportedVideoFormats = getSupportedFormats(vk, physicalDevice, imageUsageFlags, videoProfileList); 311e5c31af7Sopenharmony_ci 312e5c31af7Sopenharmony_ci if (supportedVideoFormats != DE_NULL) 313e5c31af7Sopenharmony_ci { 314e5c31af7Sopenharmony_ci if (supportedVideoFormats->size() == 0) 315e5c31af7Sopenharmony_ci if (throwException) 316e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Supported video formats count is 0"); 317e5c31af7Sopenharmony_ci 318e5c31af7Sopenharmony_ci for (const auto& supportedVideoFormat : *supportedVideoFormats) 319e5c31af7Sopenharmony_ci { 320e5c31af7Sopenharmony_ci if (supportedVideoFormat == format) 321e5c31af7Sopenharmony_ci return true; 322e5c31af7Sopenharmony_ci } 323e5c31af7Sopenharmony_ci 324e5c31af7Sopenharmony_ci if (throwException) 325e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Required format is not supported for video"); 326e5c31af7Sopenharmony_ci } 327e5c31af7Sopenharmony_ci else 328e5c31af7Sopenharmony_ci { 329e5c31af7Sopenharmony_ci if (throwException) 330e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Separate DPB and DST buffers expected"); 331e5c31af7Sopenharmony_ci } 332e5c31af7Sopenharmony_ci 333e5c31af7Sopenharmony_ci return false; 334e5c31af7Sopenharmony_ci} 335e5c31af7Sopenharmony_ci 336e5c31af7Sopenharmony_civoid validateVideoProfileList (const InstanceInterface& vk, 337e5c31af7Sopenharmony_ci VkPhysicalDevice physicalDevice, 338e5c31af7Sopenharmony_ci const VkVideoProfileListInfoKHR* videoProfileList, 339e5c31af7Sopenharmony_ci const VkFormat format, 340e5c31af7Sopenharmony_ci const VkImageUsageFlags usage) 341e5c31af7Sopenharmony_ci{ 342e5c31af7Sopenharmony_ci VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = {}; 343e5c31af7Sopenharmony_ci imageFormatInfo.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2; 344e5c31af7Sopenharmony_ci imageFormatInfo.pNext = videoProfileList; 345e5c31af7Sopenharmony_ci imageFormatInfo.format = format; 346e5c31af7Sopenharmony_ci imageFormatInfo.usage = usage; 347e5c31af7Sopenharmony_ci 348e5c31af7Sopenharmony_ci 349e5c31af7Sopenharmony_ci VkImageFormatProperties2 imageFormatProperties = {}; 350e5c31af7Sopenharmony_ci imageFormatProperties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2; 351e5c31af7Sopenharmony_ci imageFormatProperties.pNext = DE_NULL; 352e5c31af7Sopenharmony_ci 353e5c31af7Sopenharmony_ci VK_CHECK(vk.getPhysicalDeviceImageFormatProperties2(physicalDevice, &imageFormatInfo, &imageFormatProperties)); 354e5c31af7Sopenharmony_ci} 355e5c31af7Sopenharmony_ci 356e5c31af7Sopenharmony_ciVkVideoDecodeH264ProfileInfoKHR getProfileOperationH264Decode (StdVideoH264ProfileIdc stdProfileIdc, VkVideoDecodeH264PictureLayoutFlagBitsKHR pictureLayout) 357e5c31af7Sopenharmony_ci{ 358e5c31af7Sopenharmony_ci const VkVideoDecodeH264ProfileInfoKHR videoProfileOperation = 359e5c31af7Sopenharmony_ci { 360e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR, // VkStructureType sType; 361e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 362e5c31af7Sopenharmony_ci stdProfileIdc, // StdVideoH264ProfileIdc stdProfileIdc; 363e5c31af7Sopenharmony_ci pictureLayout, // VkVideoDecodeH264PictureLayoutFlagBitsKHR pictureLayout; 364e5c31af7Sopenharmony_ci }; 365e5c31af7Sopenharmony_ci 366e5c31af7Sopenharmony_ci return videoProfileOperation; 367e5c31af7Sopenharmony_ci} 368e5c31af7Sopenharmony_ci 369e5c31af7Sopenharmony_ciVkVideoEncodeH264ProfileInfoEXT getProfileOperationH264Encode (StdVideoH264ProfileIdc stdProfileIdc) 370e5c31af7Sopenharmony_ci{ 371e5c31af7Sopenharmony_ci const VkVideoEncodeH264ProfileInfoEXT videoProfileOperation = 372e5c31af7Sopenharmony_ci { 373e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_EXT, // VkStructureType sType; 374e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 375e5c31af7Sopenharmony_ci stdProfileIdc, // StdVideoH264ProfileIdc stdProfileIdc; 376e5c31af7Sopenharmony_ci }; 377e5c31af7Sopenharmony_ci 378e5c31af7Sopenharmony_ci return videoProfileOperation; 379e5c31af7Sopenharmony_ci} 380e5c31af7Sopenharmony_ci 381e5c31af7Sopenharmony_ciVkVideoDecodeH265ProfileInfoKHR getProfileOperationH265Decode (StdVideoH265ProfileIdc stdProfileIdc) 382e5c31af7Sopenharmony_ci{ 383e5c31af7Sopenharmony_ci const VkVideoDecodeH265ProfileInfoKHR videoProfileOperation = 384e5c31af7Sopenharmony_ci { 385e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR, // VkStructureType sType; 386e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 387e5c31af7Sopenharmony_ci stdProfileIdc, // StdVideoH265ProfileIdc stdProfileIdc; 388e5c31af7Sopenharmony_ci }; 389e5c31af7Sopenharmony_ci 390e5c31af7Sopenharmony_ci return videoProfileOperation; 391e5c31af7Sopenharmony_ci} 392e5c31af7Sopenharmony_ci 393e5c31af7Sopenharmony_ciVkVideoEncodeH265ProfileInfoEXT getProfileOperationH265Encode (StdVideoH265ProfileIdc stdProfileIdc) 394e5c31af7Sopenharmony_ci{ 395e5c31af7Sopenharmony_ci const VkVideoEncodeH265ProfileInfoEXT videoProfileOperation = 396e5c31af7Sopenharmony_ci { 397e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_EXT, // VkStructureType sType; 398e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 399e5c31af7Sopenharmony_ci stdProfileIdc, // StdVideoH265ProfileIdc stdProfileIdc; 400e5c31af7Sopenharmony_ci }; 401e5c31af7Sopenharmony_ci 402e5c31af7Sopenharmony_ci return videoProfileOperation; 403e5c31af7Sopenharmony_ci} 404e5c31af7Sopenharmony_ci 405e5c31af7Sopenharmony_ciVkImageCreateInfo makeImageCreateInfo (VkFormat format, 406e5c31af7Sopenharmony_ci const VkExtent2D& extent, 407e5c31af7Sopenharmony_ci const deUint32* queueFamilyIndex, 408e5c31af7Sopenharmony_ci const VkImageUsageFlags usage, 409e5c31af7Sopenharmony_ci void* pNext, 410e5c31af7Sopenharmony_ci const deUint32 arrayLayers) 411e5c31af7Sopenharmony_ci{ 412e5c31af7Sopenharmony_ci 413e5c31af7Sopenharmony_ci 414e5c31af7Sopenharmony_ci const VkExtent3D extent3D = makeExtent3D(extent.width, extent.height, 1u); 415e5c31af7Sopenharmony_ci 416e5c31af7Sopenharmony_ci 417e5c31af7Sopenharmony_ci const VkImageCreateInfo imageCreateInfo = 418e5c31af7Sopenharmony_ci { 419e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 420e5c31af7Sopenharmony_ci pNext, // const void* pNext; 421e5c31af7Sopenharmony_ci (VkImageCreateFlags)0u, // VkImageCreateFlags flags; 422e5c31af7Sopenharmony_ci VK_IMAGE_TYPE_2D, // VkImageType imageType; 423e5c31af7Sopenharmony_ci format, // VkFormat format; 424e5c31af7Sopenharmony_ci extent3D, // VkExtent3D extent; 425e5c31af7Sopenharmony_ci 1, // deUint32 mipLevels; 426e5c31af7Sopenharmony_ci arrayLayers, // deUint32 arrayLayers; 427e5c31af7Sopenharmony_ci VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 428e5c31af7Sopenharmony_ci VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 429e5c31af7Sopenharmony_ci usage, // VkImageUsageFlags usage; 430e5c31af7Sopenharmony_ci VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 431e5c31af7Sopenharmony_ci 1u, // deUint32 queueFamilyIndexCount; 432e5c31af7Sopenharmony_ci queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 433e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 434e5c31af7Sopenharmony_ci }; 435e5c31af7Sopenharmony_ci 436e5c31af7Sopenharmony_ci return imageCreateInfo; 437e5c31af7Sopenharmony_ci} 438e5c31af7Sopenharmony_ci 439e5c31af7Sopenharmony_cide::MovePtr<StdVideoH264SequenceParameterSet> getStdVideoH264SequenceParameterSet (deUint32 width, 440e5c31af7Sopenharmony_ci deUint32 height, 441e5c31af7Sopenharmony_ci StdVideoH264SequenceParameterSetVui* stdVideoH264SequenceParameterSetVui) 442e5c31af7Sopenharmony_ci{ 443e5c31af7Sopenharmony_ci const StdVideoH264SpsFlags stdVideoH264SpsFlags = 444e5c31af7Sopenharmony_ci { 445e5c31af7Sopenharmony_ci 0u, // deUint32 constraint_set0_flag:1; 446e5c31af7Sopenharmony_ci 0u, // deUint32 constraint_set1_flag:1; 447e5c31af7Sopenharmony_ci 0u, // deUint32 constraint_set2_flag:1; 448e5c31af7Sopenharmony_ci 0u, // deUint32 constraint_set3_flag:1; 449e5c31af7Sopenharmony_ci 0u, // deUint32 constraint_set4_flag:1; 450e5c31af7Sopenharmony_ci 0u, // deUint32 constraint_set5_flag:1; 451e5c31af7Sopenharmony_ci 1u, // deUint32 direct_8x8_inference_flag:1; 452e5c31af7Sopenharmony_ci 0u, // deUint32 mb_adaptive_frame_field_flag:1; 453e5c31af7Sopenharmony_ci 1u, // deUint32 frame_mbs_only_flag:1; 454e5c31af7Sopenharmony_ci 0u, // deUint32 delta_pic_order_always_zero_flag:1; 455e5c31af7Sopenharmony_ci 0u, // deUint32 separate_colour_plane_flag:1; 456e5c31af7Sopenharmony_ci 0u, // deUint32 gaps_in_frame_num_value_allowed_flag:1; 457e5c31af7Sopenharmony_ci 0u, // deUint32 qpprime_y_zero_transform_bypass_flag:1; 458e5c31af7Sopenharmony_ci 0u, // deUint32 frame_cropping_flag:1; 459e5c31af7Sopenharmony_ci 0u, // deUint32 seq_scaling_matrix_present_flag:1; 460e5c31af7Sopenharmony_ci 0u, // deUint32 vui_parameters_present_flag:1; 461e5c31af7Sopenharmony_ci }; 462e5c31af7Sopenharmony_ci 463e5c31af7Sopenharmony_ci const StdVideoH264SequenceParameterSet stdVideoH264SequenceParameterSet = 464e5c31af7Sopenharmony_ci { 465e5c31af7Sopenharmony_ci stdVideoH264SpsFlags, // StdVideoH264SpsFlags flags; 466e5c31af7Sopenharmony_ci STD_VIDEO_H264_PROFILE_IDC_BASELINE, // StdVideoH264ProfileIdc profile_idc; 467e5c31af7Sopenharmony_ci STD_VIDEO_H264_LEVEL_IDC_4_1, // StdVideoH264Level level_idc; 468e5c31af7Sopenharmony_ci STD_VIDEO_H264_CHROMA_FORMAT_IDC_420, // StdVideoH264ChromaFormatIdc chroma_format_idc; 469e5c31af7Sopenharmony_ci 0u, // deUint8 seq_parameter_set_id; 470e5c31af7Sopenharmony_ci 0u, // deUint8 bit_depth_luma_minus8; 471e5c31af7Sopenharmony_ci 0u, // deUint8 bit_depth_chroma_minus8; 472e5c31af7Sopenharmony_ci 0u, // deUint8 log2_max_frame_num_minus4; 473e5c31af7Sopenharmony_ci STD_VIDEO_H264_POC_TYPE_2, // StdVideoH264PocType pic_order_cnt_type; 474e5c31af7Sopenharmony_ci 0, // int32_t offset_for_non_ref_pic; 475e5c31af7Sopenharmony_ci 0, // int32_t offset_for_top_to_bottom_field; 476e5c31af7Sopenharmony_ci 0u, // deUint8 log2_max_pic_order_cnt_lsb_minus4; 477e5c31af7Sopenharmony_ci 0u, // deUint8 num_ref_frames_in_pic_order_cnt_cycle; 478e5c31af7Sopenharmony_ci 3u, // deUint8 max_num_ref_frames; 479e5c31af7Sopenharmony_ci 0u, // deUint8 reserved1; 480e5c31af7Sopenharmony_ci (width + 15) / 16 - 1, // deUint32 pic_width_in_mbs_minus1; 481e5c31af7Sopenharmony_ci (height + 15) / 16 - 1, // deUint32 pic_height_in_map_units_minus1; 482e5c31af7Sopenharmony_ci 0u, // deUint32 frame_crop_left_offset; 483e5c31af7Sopenharmony_ci 0u, // deUint32 frame_crop_right_offset; 484e5c31af7Sopenharmony_ci 0u, // deUint32 frame_crop_top_offset; 485e5c31af7Sopenharmony_ci 0u, // deUint32 frame_crop_bottom_offset; 486e5c31af7Sopenharmony_ci 0u, // deUint32 reserved2; 487e5c31af7Sopenharmony_ci DE_NULL, // const int32_t* pOffsetForRefFrame; 488e5c31af7Sopenharmony_ci DE_NULL, // const StdVideoH264ScalingLists* pScalingLists; 489e5c31af7Sopenharmony_ci stdVideoH264SequenceParameterSetVui, // const StdVideoH264SequenceParameterSetVui* pSequenceParameterSetVui; 490e5c31af7Sopenharmony_ci }; 491e5c31af7Sopenharmony_ci 492e5c31af7Sopenharmony_ci return de::MovePtr<StdVideoH264SequenceParameterSet>(new StdVideoH264SequenceParameterSet(stdVideoH264SequenceParameterSet)); 493e5c31af7Sopenharmony_ci} 494e5c31af7Sopenharmony_ci 495e5c31af7Sopenharmony_cide::MovePtr<StdVideoH264PictureParameterSet> getStdVideoH264PictureParameterSet (void) 496e5c31af7Sopenharmony_ci{ 497e5c31af7Sopenharmony_ci const StdVideoH264PpsFlags stdVideoH264PpsFlags = 498e5c31af7Sopenharmony_ci { 499e5c31af7Sopenharmony_ci 1u, // deUint32 transform_8x8_mode_flag:1; 500e5c31af7Sopenharmony_ci 0u, // deUint32 redundant_pic_cnt_present_flag:1; 501e5c31af7Sopenharmony_ci 0u, // deUint32 constrained_intra_pred_flag:1; 502e5c31af7Sopenharmony_ci 1u, // deUint32 deblocking_filter_control_present_flag:1; 503e5c31af7Sopenharmony_ci 0u, // deUint32 weighted_pred_flag:1; 504e5c31af7Sopenharmony_ci 0u, // uint32_4 bottom_field_pic_order_in_frame_present_flag:1; 505e5c31af7Sopenharmony_ci 1u, // deUint32 entropy_coding_mode_flag:1; 506e5c31af7Sopenharmony_ci 0u, // deUint32 pic_scaling_matrix_present_flag; 507e5c31af7Sopenharmony_ci }; 508e5c31af7Sopenharmony_ci 509e5c31af7Sopenharmony_ci const StdVideoH264PictureParameterSet stdVideoH264PictureParameterSet = 510e5c31af7Sopenharmony_ci { 511e5c31af7Sopenharmony_ci stdVideoH264PpsFlags, // StdVideoH264PpsFlags flags; 512e5c31af7Sopenharmony_ci 0u, // deUint8 seq_parameter_set_id; 513e5c31af7Sopenharmony_ci 0u, // deUint8 pic_parameter_set_id; 514e5c31af7Sopenharmony_ci 2u, // deUint8 num_ref_idx_l0_default_active_minus1; 515e5c31af7Sopenharmony_ci 0u, // deUint8 num_ref_idx_l1_default_active_minus1; 516e5c31af7Sopenharmony_ci STD_VIDEO_H264_WEIGHTED_BIPRED_IDC_DEFAULT, // StdVideoH264WeightedBipredIdc weighted_bipred_idc; 517e5c31af7Sopenharmony_ci -16, // int8_t pic_init_qp_minus26; 518e5c31af7Sopenharmony_ci 0, // int8_t pic_init_qs_minus26; 519e5c31af7Sopenharmony_ci -2, // int8_t chroma_qp_index_offset; 520e5c31af7Sopenharmony_ci -2, // int8_t second_chroma_qp_index_offset; 521e5c31af7Sopenharmony_ci DE_NULL, // const StdVideoH264ScalingLists* pScalingLists; 522e5c31af7Sopenharmony_ci }; 523e5c31af7Sopenharmony_ci 524e5c31af7Sopenharmony_ci return de::MovePtr<StdVideoH264PictureParameterSet>(new StdVideoH264PictureParameterSet(stdVideoH264PictureParameterSet)); 525e5c31af7Sopenharmony_ci} 526e5c31af7Sopenharmony_ci 527e5c31af7Sopenharmony_cistd::vector<deUint8> semiplanarToYV12(const ycbcr::MultiPlaneImageData& multiPlaneImageData) 528e5c31af7Sopenharmony_ci{ 529e5c31af7Sopenharmony_ci DE_ASSERT(multiPlaneImageData.getFormat() == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM); 530e5c31af7Sopenharmony_ci 531e5c31af7Sopenharmony_ci std::vector<deUint8> YV12Buffer; 532e5c31af7Sopenharmony_ci size_t plane0Size = multiPlaneImageData.getPlaneSize(0); 533e5c31af7Sopenharmony_ci size_t plane1Size = multiPlaneImageData.getPlaneSize(1); 534e5c31af7Sopenharmony_ci 535e5c31af7Sopenharmony_ci YV12Buffer.resize(plane0Size + plane1Size); 536e5c31af7Sopenharmony_ci 537e5c31af7Sopenharmony_ci // Copy the luma plane. 538e5c31af7Sopenharmony_ci deMemcpy(YV12Buffer.data(), multiPlaneImageData.getPlanePtr(0), plane0Size); 539e5c31af7Sopenharmony_ci 540e5c31af7Sopenharmony_ci // Deinterleave the Cr and Cb plane. 541e5c31af7Sopenharmony_ci deUint16 *plane2 = (deUint16*)multiPlaneImageData.getPlanePtr(1); 542e5c31af7Sopenharmony_ci std::vector<deUint8>::size_type idx = plane0Size; 543e5c31af7Sopenharmony_ci for (unsigned i = 0 ; i < plane1Size / 2; i ++) 544e5c31af7Sopenharmony_ci YV12Buffer[idx++] = static_cast<deUint8>(plane2[i] & 0xFF); 545e5c31af7Sopenharmony_ci for (unsigned i = 0 ; i < plane1Size / 2; i ++) 546e5c31af7Sopenharmony_ci YV12Buffer[idx++] = static_cast<deUint8>((plane2[i] >> 8) & 0xFF); 547e5c31af7Sopenharmony_ci 548e5c31af7Sopenharmony_ci return YV12Buffer; 549e5c31af7Sopenharmony_ci} 550e5c31af7Sopenharmony_ci 551e5c31af7Sopenharmony_cibool imageMatchesReferenceChecksum(const ycbcr::MultiPlaneImageData& multiPlaneImageData, const std::string& referenceChecksum) 552e5c31af7Sopenharmony_ci{ 553e5c31af7Sopenharmony_ci std::vector<deUint8> yv12 = semiplanarToYV12(multiPlaneImageData); 554e5c31af7Sopenharmony_ci std::string checksum = MD5SumBase16(yv12.data(), yv12.size()); 555e5c31af7Sopenharmony_ci return checksum == referenceChecksum; 556e5c31af7Sopenharmony_ci} 557e5c31af7Sopenharmony_ci 558e5c31af7Sopenharmony_ci 559e5c31af7Sopenharmony_cinamespace util { 560e5c31af7Sopenharmony_ciconst char* getVideoCodecString(VkVideoCodecOperationFlagBitsKHR codec) 561e5c31af7Sopenharmony_ci{ 562e5c31af7Sopenharmony_ci static struct { 563e5c31af7Sopenharmony_ci VkVideoCodecOperationFlagBitsKHR eCodec; 564e5c31af7Sopenharmony_ci const char* name; 565e5c31af7Sopenharmony_ci } aCodecName[] = { 566e5c31af7Sopenharmony_ci { VK_VIDEO_CODEC_OPERATION_NONE_KHR, "None" }, 567e5c31af7Sopenharmony_ci { VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR, "AVC/H.264" }, 568e5c31af7Sopenharmony_ci { VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR, "H.265/HEVC" }, 569e5c31af7Sopenharmony_ci }; 570e5c31af7Sopenharmony_ci 571e5c31af7Sopenharmony_ci for (auto& i : aCodecName) { 572e5c31af7Sopenharmony_ci if (codec == i.eCodec) 573e5c31af7Sopenharmony_ci return aCodecName[codec].name; 574e5c31af7Sopenharmony_ci } 575e5c31af7Sopenharmony_ci 576e5c31af7Sopenharmony_ci return "Unknown"; 577e5c31af7Sopenharmony_ci} 578e5c31af7Sopenharmony_ci 579e5c31af7Sopenharmony_ciconst char* getVideoChromaFormatString(VkVideoChromaSubsamplingFlagBitsKHR chromaFormat) 580e5c31af7Sopenharmony_ci{ 581e5c31af7Sopenharmony_ci switch (chromaFormat) { 582e5c31af7Sopenharmony_ci case VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR: 583e5c31af7Sopenharmony_ci return "YCbCr 400 (Monochrome)"; 584e5c31af7Sopenharmony_ci case VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR: 585e5c31af7Sopenharmony_ci return "YCbCr 420"; 586e5c31af7Sopenharmony_ci case VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR: 587e5c31af7Sopenharmony_ci return "YCbCr 422"; 588e5c31af7Sopenharmony_ci case VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR: 589e5c31af7Sopenharmony_ci return "YCbCr 444"; 590e5c31af7Sopenharmony_ci default: 591e5c31af7Sopenharmony_ci DE_ASSERT(false && "Unknown Chroma sub-sampled format"); 592e5c31af7Sopenharmony_ci }; 593e5c31af7Sopenharmony_ci 594e5c31af7Sopenharmony_ci return "Unknown"; 595e5c31af7Sopenharmony_ci} 596e5c31af7Sopenharmony_ci 597e5c31af7Sopenharmony_ciVkVideoCodecOperationFlagsKHR getSupportedCodecs(DeviceContext& devCtx, 598e5c31af7Sopenharmony_ci deUint32 selectedVideoQueueFamily, 599e5c31af7Sopenharmony_ci VkQueueFlags queueFlagsRequired , 600e5c31af7Sopenharmony_ci VkVideoCodecOperationFlagsKHR videoCodeOperations) 601e5c31af7Sopenharmony_ci{ 602e5c31af7Sopenharmony_ci deUint32 count = 0; 603e5c31af7Sopenharmony_ci auto& vkif = devCtx.context->getInstanceInterface(); 604e5c31af7Sopenharmony_ci vkif.getPhysicalDeviceQueueFamilyProperties2(devCtx.phys, &count, nullptr); 605e5c31af7Sopenharmony_ci std::vector<VkQueueFamilyProperties2> queues(count); 606e5c31af7Sopenharmony_ci std::vector<VkQueueFamilyVideoPropertiesKHR> videoQueues(count); 607e5c31af7Sopenharmony_ci std::vector<VkQueueFamilyQueryResultStatusPropertiesKHR> queryResultStatus(count); 608e5c31af7Sopenharmony_ci for (std::vector<VkQueueFamilyProperties2>::size_type i = 0; i < queues.size(); i++) 609e5c31af7Sopenharmony_ci { 610e5c31af7Sopenharmony_ci queues[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2; 611e5c31af7Sopenharmony_ci videoQueues[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR; 612e5c31af7Sopenharmony_ci queues[i].pNext = &videoQueues[i]; 613e5c31af7Sopenharmony_ci queryResultStatus[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_QUERY_RESULT_STATUS_PROPERTIES_KHR; 614e5c31af7Sopenharmony_ci videoQueues[i].pNext = &queryResultStatus[i]; 615e5c31af7Sopenharmony_ci } 616e5c31af7Sopenharmony_ci vkif.getPhysicalDeviceQueueFamilyProperties2(devCtx.phys, &count, queues.data()); 617e5c31af7Sopenharmony_ci 618e5c31af7Sopenharmony_ci 619e5c31af7Sopenharmony_ci TCU_CHECK(selectedVideoQueueFamily < queues.size()); 620e5c31af7Sopenharmony_ci 621e5c31af7Sopenharmony_ci const VkQueueFamilyProperties2 &q = queues[selectedVideoQueueFamily]; 622e5c31af7Sopenharmony_ci const VkQueueFamilyVideoPropertiesKHR &videoQueue = videoQueues[selectedVideoQueueFamily]; 623e5c31af7Sopenharmony_ci 624e5c31af7Sopenharmony_ci if (q.queueFamilyProperties.queueFlags & queueFlagsRequired && videoQueue.videoCodecOperations & videoCodeOperations) { 625e5c31af7Sopenharmony_ci // The video queues may or may not support queryResultStatus 626e5c31af7Sopenharmony_ci // DE_ASSERT(queryResultStatus[queueIndx].queryResultStatusSupport); 627e5c31af7Sopenharmony_ci return videoQueue.videoCodecOperations; 628e5c31af7Sopenharmony_ci } 629e5c31af7Sopenharmony_ci 630e5c31af7Sopenharmony_ci return VK_VIDEO_CODEC_OPERATION_NONE_KHR; 631e5c31af7Sopenharmony_ci} 632e5c31af7Sopenharmony_ci 633e5c31af7Sopenharmony_ciVkResult getVideoFormats(DeviceContext& devCtx, 634e5c31af7Sopenharmony_ci const VkVideoCoreProfile& videoProfile, VkImageUsageFlags imageUsage, 635e5c31af7Sopenharmony_ci deUint32& formatCount, VkFormat* formats, 636e5c31af7Sopenharmony_ci bool dumpData) 637e5c31af7Sopenharmony_ci{ 638e5c31af7Sopenharmony_ci auto& vkif = devCtx.context->getInstanceInterface(); 639e5c31af7Sopenharmony_ci 640e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < formatCount; i++) { 641e5c31af7Sopenharmony_ci formats[i] = VK_FORMAT_UNDEFINED; 642e5c31af7Sopenharmony_ci } 643e5c31af7Sopenharmony_ci 644e5c31af7Sopenharmony_ci const VkVideoProfileListInfoKHR videoProfiles = { VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR, nullptr, 1, videoProfile.GetProfile() }; 645e5c31af7Sopenharmony_ci const VkPhysicalDeviceVideoFormatInfoKHR videoFormatInfo = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR, const_cast<VkVideoProfileListInfoKHR *>(&videoProfiles), 646e5c31af7Sopenharmony_ci imageUsage }; 647e5c31af7Sopenharmony_ci 648e5c31af7Sopenharmony_ci deUint32 supportedFormatCount = 0; 649e5c31af7Sopenharmony_ci VkResult result = vkif.getPhysicalDeviceVideoFormatPropertiesKHR(devCtx.phys, &videoFormatInfo, &supportedFormatCount, nullptr); 650e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_SUCCESS); 651e5c31af7Sopenharmony_ci DE_ASSERT(supportedFormatCount); 652e5c31af7Sopenharmony_ci 653e5c31af7Sopenharmony_ci VkVideoFormatPropertiesKHR* pSupportedFormats = new VkVideoFormatPropertiesKHR[supportedFormatCount]; 654e5c31af7Sopenharmony_ci memset(pSupportedFormats, 0x00, supportedFormatCount * sizeof(VkVideoFormatPropertiesKHR)); 655e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < supportedFormatCount; i++) { 656e5c31af7Sopenharmony_ci pSupportedFormats[i].sType = VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR; 657e5c31af7Sopenharmony_ci } 658e5c31af7Sopenharmony_ci 659e5c31af7Sopenharmony_ci result = vkif.getPhysicalDeviceVideoFormatPropertiesKHR(devCtx.phys, &videoFormatInfo, &supportedFormatCount, pSupportedFormats); 660e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_SUCCESS); 661e5c31af7Sopenharmony_ci if (dumpData) { 662e5c31af7Sopenharmony_ci std::cout << "\t\t\t" << ((videoProfile.GetCodecType() == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) ? "h264" : "h265") << "decode formats: " << std::endl; 663e5c31af7Sopenharmony_ci for (deUint32 fmt = 0; fmt < supportedFormatCount; fmt++) { 664e5c31af7Sopenharmony_ci std::cout << "\t\t\t " << fmt << ": " << std::hex << pSupportedFormats[fmt].format << std::dec << std::endl; 665e5c31af7Sopenharmony_ci } 666e5c31af7Sopenharmony_ci } 667e5c31af7Sopenharmony_ci 668e5c31af7Sopenharmony_ci formatCount = std::min(supportedFormatCount, formatCount); 669e5c31af7Sopenharmony_ci 670e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < formatCount; i++) { 671e5c31af7Sopenharmony_ci formats[i] = pSupportedFormats[i].format; 672e5c31af7Sopenharmony_ci } 673e5c31af7Sopenharmony_ci 674e5c31af7Sopenharmony_ci delete[] pSupportedFormats; 675e5c31af7Sopenharmony_ci 676e5c31af7Sopenharmony_ci return result; 677e5c31af7Sopenharmony_ci} 678e5c31af7Sopenharmony_ci 679e5c31af7Sopenharmony_ciVkResult getSupportedVideoFormats(DeviceContext& devCtx, 680e5c31af7Sopenharmony_ci const VkVideoCoreProfile& videoProfile, 681e5c31af7Sopenharmony_ci VkVideoDecodeCapabilityFlagsKHR capabilityFlags, 682e5c31af7Sopenharmony_ci VkFormat& pictureFormat, 683e5c31af7Sopenharmony_ci VkFormat& referencePicturesFormat) 684e5c31af7Sopenharmony_ci{ 685e5c31af7Sopenharmony_ci VkResult result = VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR; 686e5c31af7Sopenharmony_ci if ((capabilityFlags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR) != 0) { 687e5c31af7Sopenharmony_ci // NV, Intel 688e5c31af7Sopenharmony_ci VkFormat supportedDpbFormats[8]; 689e5c31af7Sopenharmony_ci deUint32 formatCount = sizeof(supportedDpbFormats) / sizeof(supportedDpbFormats[0]); 690e5c31af7Sopenharmony_ci result = util::getVideoFormats(devCtx, videoProfile, 691e5c31af7Sopenharmony_ci (VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR | VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR | VK_IMAGE_USAGE_TRANSFER_SRC_BIT), 692e5c31af7Sopenharmony_ci formatCount, supportedDpbFormats); 693e5c31af7Sopenharmony_ci 694e5c31af7Sopenharmony_ci referencePicturesFormat = supportedDpbFormats[0]; 695e5c31af7Sopenharmony_ci pictureFormat = supportedDpbFormats[0]; 696e5c31af7Sopenharmony_ci 697e5c31af7Sopenharmony_ci } else if ((capabilityFlags & VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR) != 0) { 698e5c31af7Sopenharmony_ci // AMD 699e5c31af7Sopenharmony_ci VkFormat supportedDpbFormats[8]; 700e5c31af7Sopenharmony_ci VkFormat supportedOutFormats[8]; 701e5c31af7Sopenharmony_ci deUint32 formatCount = sizeof(supportedDpbFormats) / sizeof(supportedDpbFormats[0]); 702e5c31af7Sopenharmony_ci result = util::getVideoFormats(devCtx, videoProfile, 703e5c31af7Sopenharmony_ci VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR, 704e5c31af7Sopenharmony_ci formatCount, supportedDpbFormats); 705e5c31af7Sopenharmony_ci 706e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_SUCCESS); 707e5c31af7Sopenharmony_ci 708e5c31af7Sopenharmony_ci result = util::getVideoFormats(devCtx, videoProfile, 709e5c31af7Sopenharmony_ci VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 710e5c31af7Sopenharmony_ci formatCount, supportedOutFormats); 711e5c31af7Sopenharmony_ci 712e5c31af7Sopenharmony_ci referencePicturesFormat = supportedDpbFormats[0]; 713e5c31af7Sopenharmony_ci pictureFormat = supportedOutFormats[0]; 714e5c31af7Sopenharmony_ci 715e5c31af7Sopenharmony_ci } else { 716e5c31af7Sopenharmony_ci fprintf(stderr, "\nERROR: Unsupported decode capability flags."); 717e5c31af7Sopenharmony_ci return VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR; 718e5c31af7Sopenharmony_ci } 719e5c31af7Sopenharmony_ci 720e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_SUCCESS); 721e5c31af7Sopenharmony_ci if (result != VK_SUCCESS) { 722e5c31af7Sopenharmony_ci fprintf(stderr, "\nERROR: GetVideoFormats() result: 0x%x\n", result); 723e5c31af7Sopenharmony_ci } 724e5c31af7Sopenharmony_ci 725e5c31af7Sopenharmony_ci DE_ASSERT((referencePicturesFormat != VK_FORMAT_UNDEFINED) && (pictureFormat != VK_FORMAT_UNDEFINED)); 726e5c31af7Sopenharmony_ci DE_ASSERT(referencePicturesFormat == pictureFormat); 727e5c31af7Sopenharmony_ci 728e5c31af7Sopenharmony_ci return result; 729e5c31af7Sopenharmony_ci} 730e5c31af7Sopenharmony_ci 731e5c31af7Sopenharmony_ciconst char* codecToName(VkVideoCodecOperationFlagBitsKHR codec) 732e5c31af7Sopenharmony_ci{ 733e5c31af7Sopenharmony_ci switch ((int32_t)codec) { 734e5c31af7Sopenharmony_ci case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR: 735e5c31af7Sopenharmony_ci return "decode h.264"; 736e5c31af7Sopenharmony_ci case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR: 737e5c31af7Sopenharmony_ci return "decode h.265"; 738e5c31af7Sopenharmony_ci case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT: 739e5c31af7Sopenharmony_ci return "encode h.264"; 740e5c31af7Sopenharmony_ci case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT: 741e5c31af7Sopenharmony_ci return "encode h.265"; 742e5c31af7Sopenharmony_ci default: 743e5c31af7Sopenharmony_ci tcu::die("Unknown video codec"); 744e5c31af7Sopenharmony_ci } 745e5c31af7Sopenharmony_ci 746e5c31af7Sopenharmony_ci return ""; 747e5c31af7Sopenharmony_ci} 748e5c31af7Sopenharmony_ci 749e5c31af7Sopenharmony_ciVkResult getVideoCapabilities(DeviceContext& devCtx, 750e5c31af7Sopenharmony_ci const VkVideoCoreProfile& videoProfile, 751e5c31af7Sopenharmony_ci VkVideoCapabilitiesKHR* pVideoCapabilities) 752e5c31af7Sopenharmony_ci{ 753e5c31af7Sopenharmony_ci auto& vkif = devCtx.context->getInstanceInterface(); 754e5c31af7Sopenharmony_ci DE_ASSERT(pVideoCapabilities->sType == VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR); 755e5c31af7Sopenharmony_ci VkVideoDecodeCapabilitiesKHR* pVideoDecodeCapabilities = (VkVideoDecodeCapabilitiesKHR*)pVideoCapabilities->pNext; 756e5c31af7Sopenharmony_ci DE_ASSERT(pVideoDecodeCapabilities->sType == VK_STRUCTURE_TYPE_VIDEO_DECODE_CAPABILITIES_KHR); 757e5c31af7Sopenharmony_ci VkVideoDecodeH264CapabilitiesKHR* pH264Capabilities = nullptr; 758e5c31af7Sopenharmony_ci VkVideoDecodeH265CapabilitiesKHR* pH265Capabilities = nullptr; 759e5c31af7Sopenharmony_ci 760e5c31af7Sopenharmony_ci if (videoProfile.GetCodecType() == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) { 761e5c31af7Sopenharmony_ci DE_ASSERT(pVideoDecodeCapabilities->pNext); 762e5c31af7Sopenharmony_ci pH264Capabilities = (VkVideoDecodeH264CapabilitiesKHR*)pVideoDecodeCapabilities->pNext; 763e5c31af7Sopenharmony_ci DE_ASSERT(pH264Capabilities->sType == VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_KHR); 764e5c31af7Sopenharmony_ci } else if (videoProfile.GetCodecType() == VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) { 765e5c31af7Sopenharmony_ci DE_ASSERT(pVideoDecodeCapabilities->pNext); 766e5c31af7Sopenharmony_ci pH265Capabilities = (VkVideoDecodeH265CapabilitiesKHR*)pVideoDecodeCapabilities->pNext; 767e5c31af7Sopenharmony_ci DE_ASSERT(pH265Capabilities->sType == VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_CAPABILITIES_KHR); 768e5c31af7Sopenharmony_ci } else { 769e5c31af7Sopenharmony_ci DE_ASSERT(false && "Unsupported codec"); 770e5c31af7Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 771e5c31af7Sopenharmony_ci } 772e5c31af7Sopenharmony_ci VkResult result = vkif.getPhysicalDeviceVideoCapabilitiesKHR(devCtx.phys, 773e5c31af7Sopenharmony_ci videoProfile.GetProfile(), 774e5c31af7Sopenharmony_ci pVideoCapabilities); 775e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_SUCCESS); 776e5c31af7Sopenharmony_ci if (result != VK_SUCCESS) { 777e5c31af7Sopenharmony_ci return result; 778e5c31af7Sopenharmony_ci } 779e5c31af7Sopenharmony_ci 780e5c31af7Sopenharmony_ci if (videoLoggingEnabled()) { 781e5c31af7Sopenharmony_ci std::cout << "\t\t\t" << ((videoProfile.GetCodecType() == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) ? "h264" : "h265") << " decode capabilities: " << std::endl; 782e5c31af7Sopenharmony_ci 783e5c31af7Sopenharmony_ci if (pVideoCapabilities->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR) { 784e5c31af7Sopenharmony_ci std::cout << "\t\t\t" << "Use separate reference images" << std::endl; 785e5c31af7Sopenharmony_ci } 786e5c31af7Sopenharmony_ci 787e5c31af7Sopenharmony_ci std::cout << "\t\t\t" << "minBitstreamBufferOffsetAlignment: " << pVideoCapabilities->minBitstreamBufferOffsetAlignment << std::endl; 788e5c31af7Sopenharmony_ci std::cout << "\t\t\t" << "minBitstreamBufferSizeAlignment: " << pVideoCapabilities->minBitstreamBufferSizeAlignment << std::endl; 789e5c31af7Sopenharmony_ci std::cout << "\t\t\t" << "pictureAccessGranularity: " << pVideoCapabilities->pictureAccessGranularity.width << " x " << pVideoCapabilities->pictureAccessGranularity.height << std::endl; 790e5c31af7Sopenharmony_ci std::cout << "\t\t\t" << "minCodedExtent: " << pVideoCapabilities->minCodedExtent.width << " x " << pVideoCapabilities->minCodedExtent.height << std::endl; 791e5c31af7Sopenharmony_ci std::cout << "\t\t\t" << "maxCodedExtent: " << pVideoCapabilities->maxCodedExtent.width << " x " << pVideoCapabilities->maxCodedExtent.height << std::endl; 792e5c31af7Sopenharmony_ci std::cout << "\t\t\t" << "maxDpbSlots: " << pVideoCapabilities->maxDpbSlots << std::endl; 793e5c31af7Sopenharmony_ci std::cout << "\t\t\t" << "maxActiveReferencePictures: " << pVideoCapabilities->maxActiveReferencePictures << std::endl; 794e5c31af7Sopenharmony_ci 795e5c31af7Sopenharmony_ci if (videoProfile.GetCodecType() == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) { 796e5c31af7Sopenharmony_ci std::cout << "\t\t\t" << "maxLevelIdc: " << pH264Capabilities->maxLevelIdc << std::endl; 797e5c31af7Sopenharmony_ci std::cout << "\t\t\t" << "fieldOffsetGranularity: " << pH264Capabilities->fieldOffsetGranularity.x << " x " << pH264Capabilities->fieldOffsetGranularity.y << std::endl;; 798e5c31af7Sopenharmony_ci 799e5c31af7Sopenharmony_ci if (strncmp(pVideoCapabilities->stdHeaderVersion.extensionName, 800e5c31af7Sopenharmony_ci VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_EXTENSION_NAME, 801e5c31af7Sopenharmony_ci sizeof (pVideoCapabilities->stdHeaderVersion.extensionName) - 1U) || 802e5c31af7Sopenharmony_ci (pVideoCapabilities->stdHeaderVersion.specVersion != VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_SPEC_VERSION)) { 803e5c31af7Sopenharmony_ci DE_ASSERT(false && "Unsupported h.264 STD version"); 804e5c31af7Sopenharmony_ci return VK_ERROR_INCOMPATIBLE_DRIVER; 805e5c31af7Sopenharmony_ci } 806e5c31af7Sopenharmony_ci } else if (videoProfile.GetCodecType() == VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) { 807e5c31af7Sopenharmony_ci std::cout << "\t\t\t" << "maxLevelIdc: " << pH265Capabilities->maxLevelIdc << std::endl; 808e5c31af7Sopenharmony_ci if (strncmp(pVideoCapabilities->stdHeaderVersion.extensionName, 809e5c31af7Sopenharmony_ci VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_EXTENSION_NAME, 810e5c31af7Sopenharmony_ci sizeof (pVideoCapabilities->stdHeaderVersion.extensionName) - 1U) || 811e5c31af7Sopenharmony_ci (pVideoCapabilities->stdHeaderVersion.specVersion != VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_SPEC_VERSION)) { 812e5c31af7Sopenharmony_ci DE_ASSERT(false && "Unsupported h.265 STD version"); 813e5c31af7Sopenharmony_ci return VK_ERROR_INCOMPATIBLE_DRIVER; 814e5c31af7Sopenharmony_ci } 815e5c31af7Sopenharmony_ci } else { 816e5c31af7Sopenharmony_ci DE_ASSERT(false && "Unsupported codec"); 817e5c31af7Sopenharmony_ci } 818e5c31af7Sopenharmony_ci } 819e5c31af7Sopenharmony_ci 820e5c31af7Sopenharmony_ci return result; 821e5c31af7Sopenharmony_ci} 822e5c31af7Sopenharmony_ci 823e5c31af7Sopenharmony_ciVkResult getVideoDecodeCapabilities(DeviceContext& devCtx, 824e5c31af7Sopenharmony_ci const VkVideoCoreProfile& videoProfile, 825e5c31af7Sopenharmony_ci VkVideoCapabilitiesKHR& videoCapabilities, 826e5c31af7Sopenharmony_ci VkVideoDecodeCapabilitiesKHR& videoDecodeCapabilities) { 827e5c31af7Sopenharmony_ci 828e5c31af7Sopenharmony_ci VkVideoCodecOperationFlagsKHR videoCodec = videoProfile.GetProfile()->videoCodecOperation; 829e5c31af7Sopenharmony_ci 830e5c31af7Sopenharmony_ci videoDecodeCapabilities = VkVideoDecodeCapabilitiesKHR { VK_STRUCTURE_TYPE_VIDEO_DECODE_CAPABILITIES_KHR, nullptr, 0 }; 831e5c31af7Sopenharmony_ci 832e5c31af7Sopenharmony_ci deMemset(&videoCapabilities, 0, sizeof(VkVideoCapabilitiesKHR)); 833e5c31af7Sopenharmony_ci videoCapabilities.sType = VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR; 834e5c31af7Sopenharmony_ci videoCapabilities.pNext = &videoDecodeCapabilities; 835e5c31af7Sopenharmony_ci 836e5c31af7Sopenharmony_ci VkVideoDecodeH264CapabilitiesKHR h264Capabilities{}; 837e5c31af7Sopenharmony_ci h264Capabilities.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_KHR; 838e5c31af7Sopenharmony_ci 839e5c31af7Sopenharmony_ci VkVideoDecodeH265CapabilitiesKHR h265Capabilities{}; 840e5c31af7Sopenharmony_ci h265Capabilities.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_CAPABILITIES_KHR; 841e5c31af7Sopenharmony_ci 842e5c31af7Sopenharmony_ci if (videoCodec == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) { 843e5c31af7Sopenharmony_ci videoDecodeCapabilities.pNext = &h264Capabilities; 844e5c31af7Sopenharmony_ci } else if (videoCodec == VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) { 845e5c31af7Sopenharmony_ci videoDecodeCapabilities.pNext = &h265Capabilities; 846e5c31af7Sopenharmony_ci } else { 847e5c31af7Sopenharmony_ci DE_ASSERT(false && "Unsupported codec"); 848e5c31af7Sopenharmony_ci return VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR; 849e5c31af7Sopenharmony_ci } 850e5c31af7Sopenharmony_ci VkResult result = util::getVideoCapabilities(devCtx, videoProfile, &videoCapabilities); 851e5c31af7Sopenharmony_ci DE_ASSERT(result == VK_SUCCESS); 852e5c31af7Sopenharmony_ci if (result != VK_SUCCESS) { 853e5c31af7Sopenharmony_ci fprintf(stderr, "\nERROR: Input is not supported. GetVideoCapabilities() result: 0x%x\n", result); 854e5c31af7Sopenharmony_ci } 855e5c31af7Sopenharmony_ci return result; 856e5c31af7Sopenharmony_ci} 857e5c31af7Sopenharmony_ci} //util 858e5c31af7Sopenharmony_ci 859e5c31af7Sopenharmony_ci} // video 860e5c31af7Sopenharmony_ci} // vkt 861