1 #ifndef _VKTVIDEOTESTUTILS_HPP 2 #define _VKTVIDEOTESTUTILS_HPP 3 /*------------------------------------------------------------------------ 4 * Vulkan Conformance Tests 5 * ------------------------ 6 * 7 * Copyright (c) 2021 The Khronos Group Inc. 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 *//*! 22 * \file 23 * \brief Video Encoding and Decoding Utility Functions 24 *//*--------------------------------------------------------------------*/ 25 26 #include "vktVideoTestUtils.hpp" 27 28 #include "vkDefs.hpp" 29 #include "vkRefUtil.hpp" 30 #include "vkMemUtil.hpp" 31 #include "vkPlatform.hpp" 32 #include "vktTestCase.hpp" 33 #include "vktCustomInstancesDevices.hpp" 34 35 #include "ycbcr/vktYCbCrUtil.hpp" 36 #include "vkMd5Sum.hpp" 37 38 namespace vkt 39 { 40 namespace video 41 { 42 43 using namespace vk; 44 using namespace std; 45 46 typedef de::MovePtr<Allocation> AllocationPtr; 47 48 bool videoLoggingEnabled(); 49 50 bool imageMatchesReferenceChecksum(const ycbcr::MultiPlaneImageData& multiPlaneImageData, const std::string& referenceChecksums); 51 52 VkVideoDecodeH264ProfileInfoKHR getProfileOperationH264Decode (StdVideoH264ProfileIdc stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN, 53 VkVideoDecodeH264PictureLayoutFlagBitsKHR pictureLayout = VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR); 54 VkVideoEncodeH264ProfileInfoEXT getProfileOperationH264Encode (StdVideoH264ProfileIdc stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN); 55 VkVideoDecodeH265ProfileInfoKHR getProfileOperationH265Decode (StdVideoH265ProfileIdc stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN); 56 VkVideoEncodeH265ProfileInfoEXT getProfileOperationH265Encode (StdVideoH265ProfileIdc stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN); 57 58 const VkExtensionProperties* getVideoExtensionProperties (const VkVideoCodecOperationFlagBitsKHR codecOperation); 59 60 de::MovePtr<vector<VkFormat>> getSupportedFormats (const InstanceInterface& vk, 61 const VkPhysicalDevice physicalDevice, 62 const VkImageUsageFlags imageUsageFlags, 63 const VkVideoProfileListInfoKHR* videoProfileList); 64 65 66 VkImageCreateInfo makeImageCreateInfo (VkFormat format, 67 const VkExtent2D& extent, 68 const deUint32* queueFamilyIndex, 69 const VkImageUsageFlags usage, 70 void* pNext, 71 const deUint32 arrayLayers = 1); 72 73 74 void cmdPipelineImageMemoryBarrier2 (const DeviceInterface& vk, 75 const VkCommandBuffer commandBuffer, 76 const VkImageMemoryBarrier2KHR* pImageMemoryBarriers, 77 const size_t imageMemoryBarrierCount = 1u, 78 const VkDependencyFlags dependencyFlags = 0); 79 80 void validateVideoProfileList (const InstanceInterface& vk, 81 VkPhysicalDevice physicalDevice, 82 const VkVideoProfileListInfoKHR* videoProfileList, 83 const VkFormat format, 84 const VkImageUsageFlags usage); 85 86 struct DeviceContext 87 { 88 Context* context{}; 89 VideoDevice* vd{}; 90 VkPhysicalDevice phys{VK_NULL_HANDLE}; 91 VkDevice device{VK_NULL_HANDLE}; 92 VkQueue decodeQueue{VK_NULL_HANDLE}; 93 VkQueue transferQueue{VK_NULL_HANDLE}; 94 getInstanceInterfacevkt::video::DeviceContext95 const InstanceInterface& getInstanceInterface() const 96 { 97 return context->getInstanceInterface(); 98 } getDeviceDrivervkt::video::DeviceContext99 const DeviceDriver& getDeviceDriver() const 100 { 101 return vd->getDeviceDriver(); 102 } decodeQueueFamilyIdxvkt::video::DeviceContext103 deUint32 decodeQueueFamilyIdx() const 104 { 105 return vd->getQueueFamilyIndexDecode(); 106 } transferQueueFamilyIdxvkt::video::DeviceContext107 deUint32 transferQueueFamilyIdx() const 108 { 109 return vd->getQueueFamilyIndexTransfer(); 110 } allocatorvkt::video::DeviceContext111 Allocator& allocator() const 112 { 113 return vd->getAllocator(); 114 } waitDecodeQueuevkt::video::DeviceContext115 void waitDecodeQueue() const 116 { 117 VK_CHECK(getDeviceDriver().queueWaitIdle(decodeQueue)); 118 } deviceWaitIdlevkt::video::DeviceContext119 void deviceWaitIdle() const 120 { 121 VK_CHECK(getDeviceDriver().deviceWaitIdle(device)); 122 } 123 }; 124 125 class VideoBaseTestInstance : public TestInstance 126 { 127 public: VideoBaseTestInstance(Context& context)128 explicit VideoBaseTestInstance(Context& context) 129 : TestInstance(context) 130 , m_videoDevice(context) 131 { 132 } 133 134 ~VideoBaseTestInstance() override = default; 135 136 VkDevice getDeviceSupportingQueue(VkQueueFlags queueFlagsRequired = 0, 137 VkVideoCodecOperationFlagsKHR videoCodecOperationFlags = 0, 138 VideoDevice::VideoDeviceFlags videoDeviceFlags = VideoDevice::VIDEO_DEVICE_FLAG_NONE); 139 bool createDeviceSupportingQueue(VkQueueFlags queueFlagsRequired, 140 VkVideoCodecOperationFlagsKHR videoCodecOperationFlags, 141 VideoDevice::VideoDeviceFlags videoDeviceFlags = VideoDevice::VIDEO_DEVICE_FLAG_NONE); 142 const DeviceDriver& getDeviceDriver(); 143 deUint32 getQueueFamilyIndexTransfer(); 144 deUint32 getQueueFamilyIndexDecode(); 145 deUint32 getQueueFamilyIndexEncode(); 146 Allocator& getAllocator(); 147 148 std::string getVideoDataClipA(); 149 std::string getVideoDataClipB(); 150 std::string getVideoDataClipC(); 151 std::string getVideoDataClipD(); 152 std::string getVideoDataClipH264G13(); 153 std::string getVideoDataClipH265G13(); 154 155 protected: 156 de::MovePtr<vector<deUint8>> loadVideoData(const string& filename); 157 VideoDevice m_videoDevice; 158 }; 159 160 typedef enum StdChromaFormatIdc 161 { 162 chroma_format_idc_monochrome = STD_VIDEO_H264_CHROMA_FORMAT_IDC_MONOCHROME, 163 chroma_format_idc_420 = STD_VIDEO_H264_CHROMA_FORMAT_IDC_420, 164 chroma_format_idc_422 = STD_VIDEO_H264_CHROMA_FORMAT_IDC_422, 165 chroma_format_idc_444 = STD_VIDEO_H264_CHROMA_FORMAT_IDC_444, 166 } StdChromaFormatIdc; 167 168 class VkVideoCoreProfile 169 { 170 public: isValidCodec(VkVideoCodecOperationFlagsKHR videoCodecOperations)171 static bool isValidCodec(VkVideoCodecOperationFlagsKHR videoCodecOperations) 172 { 173 return (videoCodecOperations & (VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR | 174 VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR | 175 VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT | 176 VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT)); 177 } 178 PopulateProfileExt(VkBaseInStructure const* pVideoProfileExt)179 bool PopulateProfileExt(VkBaseInStructure const* pVideoProfileExt) 180 { 181 if (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) 182 { 183 VkVideoDecodeH264ProfileInfoKHR const* pProfileExt = (VkVideoDecodeH264ProfileInfoKHR const*)pVideoProfileExt; 184 if (pProfileExt && (pProfileExt->sType != VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR)) 185 { 186 m_profile.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; 187 return false; 188 } 189 if (pProfileExt) 190 { 191 m_h264DecodeProfile = *pProfileExt; 192 } 193 else 194 { 195 // Use default ext profile parameters 196 m_h264DecodeProfile.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR; 197 m_h264DecodeProfile.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN; 198 m_h264DecodeProfile.pictureLayout = VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR; 199 } 200 m_profile.pNext = &m_h264DecodeProfile; 201 m_h264DecodeProfile.pNext = NULL; 202 } 203 else if (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) 204 { 205 VkVideoDecodeH265ProfileInfoKHR const* pProfileExt = (VkVideoDecodeH265ProfileInfoKHR const*)pVideoProfileExt; 206 if (pProfileExt && (pProfileExt->sType != VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR)) 207 { 208 m_profile.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; 209 return false; 210 } 211 if (pProfileExt) 212 { 213 m_h265DecodeProfile = *pProfileExt; 214 } 215 else 216 { 217 // Use default ext profile parameters 218 m_h265DecodeProfile.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR; 219 m_h265DecodeProfile.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN; 220 } 221 m_profile.pNext = &m_h265DecodeProfile; 222 m_h265DecodeProfile.pNext = NULL; 223 } 224 else if (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT) 225 { 226 VkVideoEncodeH264ProfileInfoEXT const* pProfileExt = (VkVideoEncodeH264ProfileInfoEXT const*)pVideoProfileExt; 227 if (pProfileExt && (pProfileExt->sType != VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_EXT)) 228 { 229 m_profile.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; 230 return false; 231 } 232 if (pProfileExt) 233 { 234 m_h264EncodeProfile = *pProfileExt; 235 } 236 else 237 { 238 // Use default ext profile parameters 239 m_h264DecodeProfile.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_EXT; 240 m_h264DecodeProfile.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN; 241 } 242 m_profile.pNext = &m_h264EncodeProfile; 243 m_h264EncodeProfile.pNext = NULL; 244 } 245 else if (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT) 246 { 247 VkVideoEncodeH265ProfileInfoEXT const* pProfileExt = (VkVideoEncodeH265ProfileInfoEXT const*)pVideoProfileExt; 248 if (pProfileExt && (pProfileExt->sType != VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_EXT)) 249 { 250 m_profile.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; 251 return false; 252 } 253 if (pProfileExt) 254 { 255 m_h265EncodeProfile = *pProfileExt; 256 } 257 else 258 { 259 // Use default ext profile parameters 260 m_h265EncodeProfile.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_EXT; 261 m_h265EncodeProfile.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN; 262 } 263 m_profile.pNext = &m_h265EncodeProfile; 264 m_h265EncodeProfile.pNext = NULL; 265 } 266 else 267 { 268 DE_ASSERT(false && "Unknown codec!"); 269 return false; 270 } 271 272 return true; 273 } 274 InitFromProfile(const VkVideoProfileInfoKHR* pVideoProfile)275 bool InitFromProfile(const VkVideoProfileInfoKHR* pVideoProfile) 276 { 277 m_profile = *pVideoProfile; 278 m_profile.pNext = NULL; 279 return PopulateProfileExt((VkBaseInStructure const*)pVideoProfile->pNext); 280 } 281 VkVideoCoreProfile(const VkVideoProfileInfoKHR* pVideoProfile)282 VkVideoCoreProfile(const VkVideoProfileInfoKHR* pVideoProfile) 283 : m_profile(*pVideoProfile) 284 { 285 286 PopulateProfileExt((VkBaseInStructure const*)pVideoProfile->pNext); 287 } 288 VkVideoCoreProfile(VkVideoCodecOperationFlagBitsKHR videoCodecOperation = VK_VIDEO_CODEC_OPERATION_NONE_KHR, VkVideoChromaSubsamplingFlagsKHR chromaSubsampling = VK_VIDEO_CHROMA_SUBSAMPLING_INVALID_KHR, VkVideoComponentBitDepthFlagsKHR lumaBitDepth = VK_VIDEO_COMPONENT_BIT_DEPTH_INVALID_KHR, VkVideoComponentBitDepthFlagsKHR chromaBitDepth = VK_VIDEO_COMPONENT_BIT_DEPTH_INVALID_KHR, deUint32 videoH26xProfileIdc = 0)289 VkVideoCoreProfile(VkVideoCodecOperationFlagBitsKHR videoCodecOperation = VK_VIDEO_CODEC_OPERATION_NONE_KHR, 290 VkVideoChromaSubsamplingFlagsKHR chromaSubsampling = VK_VIDEO_CHROMA_SUBSAMPLING_INVALID_KHR, 291 VkVideoComponentBitDepthFlagsKHR lumaBitDepth = VK_VIDEO_COMPONENT_BIT_DEPTH_INVALID_KHR, 292 VkVideoComponentBitDepthFlagsKHR chromaBitDepth = VK_VIDEO_COMPONENT_BIT_DEPTH_INVALID_KHR, 293 deUint32 videoH26xProfileIdc = 0) 294 : m_profile({VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR, NULL, videoCodecOperation, chromaSubsampling, lumaBitDepth, chromaBitDepth}), m_profileList({VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR, NULL, 1, &m_profile}) 295 { 296 if (!isValidCodec(videoCodecOperation)) 297 { 298 return; 299 } 300 301 VkVideoDecodeH264ProfileInfoKHR decodeH264ProfilesRequest; 302 VkVideoDecodeH265ProfileInfoKHR decodeH265ProfilesRequest; 303 VkVideoEncodeH264ProfileInfoEXT encodeH264ProfilesRequest; 304 VkVideoEncodeH265ProfileInfoEXT encodeH265ProfilesRequest; 305 VkBaseInStructure* pVideoProfileExt = NULL; 306 307 if (videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) 308 { 309 decodeH264ProfilesRequest.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR; 310 decodeH264ProfilesRequest.pNext = NULL; 311 decodeH264ProfilesRequest.stdProfileIdc = (videoH26xProfileIdc == 0) ? 312 STD_VIDEO_H264_PROFILE_IDC_INVALID : 313 (StdVideoH264ProfileIdc)videoH26xProfileIdc; 314 decodeH264ProfilesRequest.pictureLayout = VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR; 315 pVideoProfileExt = (VkBaseInStructure*)&decodeH264ProfilesRequest; 316 } 317 else if (videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) 318 { 319 decodeH265ProfilesRequest.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR; 320 decodeH265ProfilesRequest.pNext = NULL; 321 decodeH265ProfilesRequest.stdProfileIdc = (videoH26xProfileIdc == 0) ? 322 STD_VIDEO_H265_PROFILE_IDC_INVALID : 323 (StdVideoH265ProfileIdc)videoH26xProfileIdc; 324 pVideoProfileExt = (VkBaseInStructure*)&decodeH265ProfilesRequest; 325 } 326 else if (videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT) 327 { 328 encodeH264ProfilesRequest.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_EXT; 329 encodeH264ProfilesRequest.pNext = NULL; 330 encodeH264ProfilesRequest.stdProfileIdc = (videoH26xProfileIdc == 0) ? 331 STD_VIDEO_H264_PROFILE_IDC_INVALID : 332 (StdVideoH264ProfileIdc)videoH26xProfileIdc; 333 pVideoProfileExt = (VkBaseInStructure*)&encodeH264ProfilesRequest; 334 } 335 else if (videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT) 336 { 337 encodeH265ProfilesRequest.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_EXT; 338 encodeH265ProfilesRequest.pNext = NULL; 339 encodeH265ProfilesRequest.stdProfileIdc = (videoH26xProfileIdc == 0) ? 340 STD_VIDEO_H265_PROFILE_IDC_INVALID : 341 (StdVideoH265ProfileIdc)videoH26xProfileIdc; 342 pVideoProfileExt = (VkBaseInStructure*)&encodeH265ProfilesRequest; 343 } 344 else 345 { 346 DE_ASSERT(false && "Unknown codec!"); 347 return; 348 } 349 350 PopulateProfileExt(pVideoProfileExt); 351 } 352 GetCodecType() const353 VkVideoCodecOperationFlagBitsKHR GetCodecType() const 354 { 355 return m_profile.videoCodecOperation; 356 } 357 IsEncodeCodecType() const358 bool IsEncodeCodecType() const 359 { 360 return ((m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT) || 361 (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT)); 362 } 363 IsDecodeCodecType() const364 bool IsDecodeCodecType() const 365 { 366 return ((m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) || 367 (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR)); 368 } 369 operator bool() const370 operator bool() const 371 { 372 return (m_profile.sType == VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR); 373 } 374 GetProfile() const375 const VkVideoProfileInfoKHR* GetProfile() const 376 { 377 if (m_profile.sType == VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR) 378 { 379 return &m_profile; 380 } 381 else 382 { 383 return NULL; 384 } 385 } 386 GetProfileListInfo() const387 const VkVideoProfileListInfoKHR* GetProfileListInfo() const 388 { 389 if (m_profileList.sType == VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR) 390 { 391 return &m_profileList; 392 } 393 else 394 { 395 return NULL; 396 } 397 } 398 GetDecodeH264Profile() const399 const VkVideoDecodeH264ProfileInfoKHR* GetDecodeH264Profile() const 400 { 401 if (m_h264DecodeProfile.sType == VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR) 402 { 403 return &m_h264DecodeProfile; 404 } 405 else 406 { 407 return NULL; 408 } 409 } 410 GetDecodeH265Profile() const411 const VkVideoDecodeH265ProfileInfoKHR* GetDecodeH265Profile() const 412 { 413 if (m_h265DecodeProfile.sType == VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR) 414 { 415 return &m_h265DecodeProfile; 416 } 417 else 418 { 419 return NULL; 420 } 421 } 422 GetEncodeH264Profile() const423 const VkVideoEncodeH264ProfileInfoEXT* GetEncodeH264Profile() const 424 { 425 if (m_h264DecodeProfile.sType == VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_EXT) 426 { 427 return &m_h264EncodeProfile; 428 } 429 else 430 { 431 return NULL; 432 } 433 } 434 GetEncodeH265Profile() const435 const VkVideoEncodeH265ProfileInfoEXT* GetEncodeH265Profile() const 436 { 437 if (m_h265DecodeProfile.sType == VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_EXT) 438 { 439 return &m_h265EncodeProfile; 440 } 441 else 442 { 443 return NULL; 444 } 445 } 446 copyProfile(const VkVideoCoreProfile& src)447 bool copyProfile(const VkVideoCoreProfile& src) 448 { 449 if (!src) 450 { 451 return false; 452 } 453 454 m_profile = src.m_profile; 455 m_profile.pNext = nullptr; 456 457 m_profileList = src.m_profileList; 458 m_profileList.pNext = nullptr; 459 460 m_profileList.pProfiles = &m_profile; 461 462 PopulateProfileExt((VkBaseInStructure const*)src.m_profile.pNext); 463 464 return true; 465 } 466 VkVideoCoreProfile(const VkVideoCoreProfile& other)467 VkVideoCoreProfile(const VkVideoCoreProfile& other) 468 { 469 copyProfile(other); 470 } 471 operator =(const VkVideoCoreProfile& other)472 VkVideoCoreProfile& operator=(const VkVideoCoreProfile& other) 473 { 474 copyProfile(other); 475 return *this; 476 } 477 operator ==(const VkVideoCoreProfile& other) const478 bool operator==(const VkVideoCoreProfile& other) const 479 { 480 if (m_profile.videoCodecOperation != other.m_profile.videoCodecOperation) 481 { 482 return false; 483 } 484 485 if (m_profile.chromaSubsampling != other.m_profile.chromaSubsampling) 486 { 487 return false; 488 } 489 490 if (m_profile.lumaBitDepth != other.m_profile.lumaBitDepth) 491 { 492 return false; 493 } 494 495 if (m_profile.chromaBitDepth != other.m_profile.chromaBitDepth) 496 { 497 return false; 498 } 499 500 if (m_profile.pNext != nullptr) 501 { 502 switch (m_profile.videoCodecOperation) { 503 case vk::VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR: 504 { 505 auto* ours = (VkVideoDecodeH264ProfileInfoKHR*)m_profile.pNext; 506 auto* theirs = (VkVideoDecodeH264ProfileInfoKHR*)other.m_profile.pNext; 507 if (ours->sType != theirs->sType) 508 return false; 509 if (ours->stdProfileIdc != theirs->stdProfileIdc) 510 return false; 511 if (ours->pictureLayout != theirs->pictureLayout) 512 return false; 513 break; 514 } 515 case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR: 516 { 517 auto* ours = (VkVideoDecodeH265ProfileInfoKHR*)m_profile.pNext; 518 auto* theirs = (VkVideoDecodeH265ProfileInfoKHR*)other.m_profile.pNext; 519 if (ours->sType != theirs->sType) 520 return false; 521 if (ours->stdProfileIdc != theirs->stdProfileIdc) 522 return false; 523 break; 524 } 525 default: 526 tcu::die("Unknown codec"); 527 } 528 } 529 530 531 return true; 532 } 533 operator !=(const VkVideoCoreProfile& other) const534 bool operator!=(const VkVideoCoreProfile& other) const 535 { 536 return !(*this == other); 537 } 538 GetColorSubsampling() const539 VkVideoChromaSubsamplingFlagsKHR GetColorSubsampling() const 540 { 541 return m_profile.chromaSubsampling; 542 } 543 GetNvColorSubsampling() const544 StdChromaFormatIdc GetNvColorSubsampling() const 545 { 546 if (m_profile.chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR) 547 { 548 return chroma_format_idc_monochrome; 549 } 550 else if (m_profile.chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR) 551 { 552 return chroma_format_idc_420; 553 } 554 else if (m_profile.chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR) 555 { 556 return chroma_format_idc_422; 557 } 558 else if (m_profile.chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR) 559 { 560 return chroma_format_idc_444; 561 } 562 563 return chroma_format_idc_monochrome; 564 } 565 GetLumaBitDepthMinus8() const566 deUint32 GetLumaBitDepthMinus8() const 567 { 568 if (m_profile.lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR) 569 { 570 return 8 - 8; 571 } 572 else if (m_profile.lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR) 573 { 574 return 10 - 8; 575 } 576 else if (m_profile.lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR) 577 { 578 return 12 - 8; 579 } 580 return 0; 581 } 582 GetChromaBitDepthMinus8() const583 deUint32 GetChromaBitDepthMinus8() const 584 { 585 if (m_profile.chromaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR) 586 { 587 return 8 - 8; 588 } 589 else if (m_profile.chromaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR) 590 { 591 return 10 - 8; 592 } 593 else if (m_profile.chromaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR) 594 { 595 return 12 - 8; 596 } 597 return 0; 598 } 599 is16BitFormat() const600 bool is16BitFormat() const 601 { 602 return !!GetLumaBitDepthMinus8() || !!GetChromaBitDepthMinus8(); 603 } 604 CodecGetVkFormat(VkVideoChromaSubsamplingFlagBitsKHR chromaFormatIdc, VkVideoComponentBitDepthFlagBitsKHR lumaBitDepth, bool isSemiPlanar)605 static VkFormat CodecGetVkFormat(VkVideoChromaSubsamplingFlagBitsKHR chromaFormatIdc, 606 VkVideoComponentBitDepthFlagBitsKHR lumaBitDepth, 607 bool isSemiPlanar) 608 { 609 VkFormat vkFormat = VK_FORMAT_UNDEFINED; 610 switch (chromaFormatIdc) 611 { 612 case VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR: 613 switch (lumaBitDepth) 614 { 615 case VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR: 616 vkFormat = VK_FORMAT_R8_UNORM; 617 break; 618 case VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR: 619 vkFormat = VK_FORMAT_R10X6_UNORM_PACK16; 620 break; 621 case VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR: 622 vkFormat = VK_FORMAT_R12X4_UNORM_PACK16; 623 break; 624 default: 625 DE_ASSERT(false); 626 } 627 break; 628 case VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR: 629 switch (lumaBitDepth) 630 { 631 case VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR: 632 vkFormat = isSemiPlanar ? VK_FORMAT_G8_B8R8_2PLANE_420_UNORM : VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM; 633 break; 634 case VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR: 635 vkFormat = isSemiPlanar ? VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 : VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16; 636 break; 637 case VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR: 638 vkFormat = isSemiPlanar ? VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 : VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16; 639 break; 640 default: 641 DE_ASSERT(false); 642 } 643 break; 644 case VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR: 645 switch (lumaBitDepth) 646 { 647 case VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR: 648 vkFormat = isSemiPlanar ? VK_FORMAT_G8_B8R8_2PLANE_422_UNORM : VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM; 649 break; 650 case VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR: 651 vkFormat = isSemiPlanar ? VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 : VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16; 652 break; 653 case VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR: 654 vkFormat = isSemiPlanar ? VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 : VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16; 655 break; 656 default: 657 DE_ASSERT(false); 658 } 659 break; 660 case VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR: 661 switch (lumaBitDepth) 662 { 663 case VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR: 664 vkFormat = isSemiPlanar ? VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT : VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM; 665 break; 666 case VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR: 667 vkFormat = isSemiPlanar ? VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT : VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16; 668 break; 669 case VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR: 670 vkFormat = isSemiPlanar ? VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT : VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16; 671 break; 672 default: 673 DE_ASSERT(false); 674 } 675 break; 676 default: 677 DE_ASSERT(false); 678 } 679 680 return vkFormat; 681 } 682 GetVideoChromaFormatFromVkFormat(VkFormat format)683 static StdChromaFormatIdc GetVideoChromaFormatFromVkFormat(VkFormat format) 684 { 685 StdChromaFormatIdc videoChromaFormat = chroma_format_idc_420; 686 switch ((deUint32)format) 687 { 688 case VK_FORMAT_R8_UNORM: 689 case VK_FORMAT_R10X6_UNORM_PACK16: 690 case VK_FORMAT_R12X4_UNORM_PACK16: 691 videoChromaFormat = chroma_format_idc_monochrome; 692 break; 693 694 case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: 695 case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: 696 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: 697 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: 698 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: 699 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: 700 videoChromaFormat = chroma_format_idc_420; 701 break; 702 703 case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: 704 case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: 705 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: 706 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: 707 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: 708 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: 709 videoChromaFormat = chroma_format_idc_422; 710 break; 711 712 case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: 713 case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: 714 case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: 715 case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT: 716 case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT: 717 case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT: 718 case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT: 719 videoChromaFormat = chroma_format_idc_444; 720 break; 721 default: 722 DE_ASSERT(false); 723 } 724 725 return videoChromaFormat; 726 } 727 CodecToName(VkVideoCodecOperationFlagBitsKHR codec)728 static const char* CodecToName(VkVideoCodecOperationFlagBitsKHR codec) 729 { 730 switch ((int32_t)codec) 731 { 732 case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR: 733 return "decode h.264"; 734 case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR: 735 return "decode h.265"; 736 case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT: 737 return "encode h.264"; 738 case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT: 739 return "encode h.265"; 740 default:; 741 } 742 DE_ASSERT(false && "Unknown codec"); 743 return "UNKNON"; 744 } 745 DumpFormatProfiles(VkVideoProfileInfoKHR* pVideoProfile)746 static void DumpFormatProfiles(VkVideoProfileInfoKHR* pVideoProfile) 747 { 748 // formatProfile info based on supported chroma_format_idc 749 if (pVideoProfile->chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR) 750 { 751 std::cout << "MONO, "; 752 } 753 if (pVideoProfile->chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR) 754 { 755 std::cout << " 420, "; 756 } 757 if (pVideoProfile->chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR) 758 { 759 std::cout << " 422, "; 760 } 761 if (pVideoProfile->chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR) 762 { 763 std::cout << " 444, "; 764 } 765 766 // Profile info based on max bit_depth_luma_minus8 767 if (pVideoProfile->lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR) 768 { 769 std::cout << "LUMA: 8-bit, "; 770 } 771 if (pVideoProfile->lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR) 772 { 773 std::cout << "LUMA: 10-bit, "; 774 } 775 if (pVideoProfile->lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR) 776 { 777 std::cout << "LUMA: 12-bit, "; 778 } 779 780 // Profile info based on max bit_depth_chroma_minus8 781 if (pVideoProfile->chromaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR) 782 { 783 std::cout << "CHROMA: 8-bit, "; 784 } 785 if (pVideoProfile->chromaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR) 786 { 787 std::cout << "CHROMA:10-bit, "; 788 } 789 if (pVideoProfile->chromaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR) 790 { 791 std::cout << "CHROMA:12-bit,"; 792 } 793 } 794 DumpH264Profiles(VkVideoDecodeH264ProfileInfoKHR* pH264Profiles)795 static void DumpH264Profiles(VkVideoDecodeH264ProfileInfoKHR* pH264Profiles) 796 { 797 switch (pH264Profiles->stdProfileIdc) 798 { 799 case STD_VIDEO_H264_PROFILE_IDC_BASELINE: 800 std::cout << "BASELINE, "; 801 break; 802 case STD_VIDEO_H264_PROFILE_IDC_MAIN: 803 std::cout << "MAIN, "; 804 break; 805 case STD_VIDEO_H264_PROFILE_IDC_HIGH: 806 std::cout << "HIGH, "; 807 break; 808 case STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE: 809 std::cout << "HIGH_444_PREDICTIVE, "; 810 break; 811 default: 812 std::cout << "UNKNOWN PROFILE, "; 813 break; 814 } 815 } 816 DumpH265Profiles(VkVideoDecodeH265ProfileInfoKHR* pH265Profiles)817 static void DumpH265Profiles(VkVideoDecodeH265ProfileInfoKHR* pH265Profiles) 818 { 819 switch (pH265Profiles->stdProfileIdc) 820 { 821 case STD_VIDEO_H265_PROFILE_IDC_MAIN: 822 std::cout << "MAIN, "; 823 break; 824 case STD_VIDEO_H265_PROFILE_IDC_MAIN_10: 825 std::cout << "MAIN_10, "; 826 break; 827 case STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE: 828 std::cout << "MAIN_STILL_PICTURE, "; 829 break; 830 case STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS: 831 std::cout << "FORMAT_RANGE_EXTENSIONS, "; 832 break; 833 case STD_VIDEO_H265_PROFILE_IDC_SCC_EXTENSIONS: 834 std::cout << "SCC_EXTENSIONS, "; 835 break; 836 default: 837 std::cout << "UNKNOWN PROFILE, "; 838 break; 839 } 840 } 841 842 private: 843 VkVideoProfileInfoKHR m_profile; 844 VkVideoProfileListInfoKHR m_profileList; 845 union 846 { 847 VkVideoDecodeH264ProfileInfoKHR m_h264DecodeProfile; 848 VkVideoDecodeH265ProfileInfoKHR m_h265DecodeProfile; 849 VkVideoEncodeH264ProfileInfoEXT m_h264EncodeProfile; 850 VkVideoEncodeH265ProfileInfoEXT m_h265EncodeProfile; 851 }; 852 }; 853 854 namespace util 855 { 856 const char* getVideoCodecString(VkVideoCodecOperationFlagBitsKHR codec); 857 858 const char* getVideoChromaFormatString(VkVideoChromaSubsamplingFlagBitsKHR chromaFormat); 859 860 VkVideoCodecOperationFlagsKHR getSupportedCodecs(DeviceContext& devCtx, 861 deUint32 selectedVideoQueueFamily, 862 VkQueueFlags queueFlagsRequired = (VK_QUEUE_VIDEO_DECODE_BIT_KHR | VK_QUEUE_VIDEO_ENCODE_BIT_KHR), 863 VkVideoCodecOperationFlagsKHR videoCodeOperations = 864 (VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR | VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR | 865 VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT | VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_EXT)); 866 867 VkResult getVideoFormats(DeviceContext& devCtx, 868 const VkVideoCoreProfile& videoProfile, 869 VkImageUsageFlags imageUsage, 870 deUint32& formatCount, 871 VkFormat* formats, 872 bool dumpData = false); 873 874 VkResult getSupportedVideoFormats(DeviceContext& devCtx, 875 const VkVideoCoreProfile& videoProfile, 876 VkVideoDecodeCapabilityFlagsKHR capabilityFlags, 877 VkFormat& pictureFormat, 878 VkFormat& referencePicturesFormat); 879 880 const char* codecToName(VkVideoCodecOperationFlagBitsKHR codec); 881 882 VkResult getVideoCapabilities(DeviceContext& devCtx, 883 const VkVideoCoreProfile& videoProfile, 884 VkVideoCapabilitiesKHR* pVideoCapabilities); 885 886 VkResult getVideoDecodeCapabilities(DeviceContext& devCtx, 887 const VkVideoCoreProfile& videoProfile, 888 VkVideoCapabilitiesKHR& videoCapabilities, 889 VkVideoDecodeCapabilitiesKHR& videoDecodeCapabilities); 890 } // namespace util 891 892 std::vector<deUint8> semiplanarToYV12(const ycbcr::MultiPlaneImageData& multiPlaneImageData); 893 894 } // video 895 } // vkt 896 897 #endif // _VKTVIDEOTESTUTILS_HPP 898