• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "vkCmdUtil.hpp"
32 #include "vkBarrierUtil.hpp"
33 #include "vkPlatform.hpp"
34 #include "vktTestCase.hpp"
35 #include "vktCustomInstancesDevices.hpp"
36 
37 #include "ycbcr/vktYCbCrUtil.hpp"
38 #include "vkMd5Sum.hpp"
39 
40 namespace vkt
41 {
42 namespace video
43 {
44 
45 using namespace vk;
46 using namespace std;
47 
48 typedef de::MovePtr<Allocation> AllocationPtr;
49 
50 struct DeviceContext
51 {
52 
53     Context *context{};
54     VideoDevice *vd{};
55     VkPhysicalDevice phys{VK_NULL_HANDLE};
56     VkDevice device{VK_NULL_HANDLE};
57     VkQueue decodeQueue{VK_NULL_HANDLE};
58     VkQueue encodeQueue{VK_NULL_HANDLE};
59     VkQueue transferQueue{VK_NULL_HANDLE};
60 
DeviceContextvkt::video::DeviceContext61     DeviceContext(Context *c, VideoDevice *v, VkPhysicalDevice p = VK_NULL_HANDLE, VkDevice d = VK_NULL_HANDLE,
62                   VkQueue decodeQ = VK_NULL_HANDLE, VkQueue encodeQ = VK_NULL_HANDLE,
63                   VkQueue transferQ = VK_NULL_HANDLE)
64         : context(c)
65         , vd(v)
66         , phys(p)
67         , device(d)
68         , decodeQueue(decodeQ)
69         , encodeQueue(encodeQ)
70         , transferQueue(transferQ)
71     {
72     }
73 
updateDevicevkt::video::DeviceContext74     void updateDevice(VkPhysicalDevice p, VkDevice d, VkQueue decodeQ, VkQueue encodeQ, VkQueue transferQ)
75     {
76         phys          = p;
77         device        = d;
78         decodeQueue   = decodeQ;
79         encodeQueue   = encodeQ;
80         transferQueue = transferQ;
81     }
82 
getInstanceInterfacevkt::video::DeviceContext83     const InstanceInterface &getInstanceInterface() const
84     {
85         return context->getInstanceInterface();
86     }
getDeviceDrivervkt::video::DeviceContext87     const DeviceDriver &getDeviceDriver() const
88     {
89         return vd->getDeviceDriver();
90     }
decodeQueueFamilyIdxvkt::video::DeviceContext91     uint32_t decodeQueueFamilyIdx() const
92     {
93         return vd->getQueueFamilyIndexDecode();
94     }
encodeQueueFamilyIdxvkt::video::DeviceContext95     uint32_t encodeQueueFamilyIdx() const
96     {
97         return vd->getQueueFamilyIndexEncode();
98     }
transferQueueFamilyIdxvkt::video::DeviceContext99     uint32_t transferQueueFamilyIdx() const
100     {
101         return vd->getQueueFamilyIndexTransfer();
102     }
allocatorvkt::video::DeviceContext103     Allocator &allocator() const
104     {
105         return vd->getAllocator();
106     }
waitDecodeQueuevkt::video::DeviceContext107     void waitDecodeQueue() const
108     {
109         VK_CHECK(getDeviceDriver().queueWaitIdle(decodeQueue));
110     }
waitEncodeQueuevkt::video::DeviceContext111     void waitEncodeQueue() const
112     {
113         VK_CHECK(getDeviceDriver().queueWaitIdle(encodeQueue));
114     }
deviceWaitIdlevkt::video::DeviceContext115     void deviceWaitIdle() const
116     {
117         VK_CHECK(getDeviceDriver().deviceWaitIdle(device));
118     }
119 };
120 
121 typedef de::MovePtr<Allocation> AllocationPtr;
122 
123 bool videoLoggingEnabled();
124 
125 bool videoLoggingEnabled();
126 
127 VkVideoDecodeH264ProfileInfoKHR getProfileOperationH264Decode(
128     StdVideoH264ProfileIdc stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN,
129     VkVideoDecodeH264PictureLayoutFlagBitsKHR pictureLayout =
130         VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR);
131 VkVideoEncodeH264ProfileInfoKHR getProfileOperationH264Encode(
132     StdVideoH264ProfileIdc stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN);
133 VkVideoDecodeH265ProfileInfoKHR getProfileOperationH265Decode(
134     StdVideoH265ProfileIdc stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN);
135 VkVideoEncodeH265ProfileInfoKHR getProfileOperationH265Encode(
136     StdVideoH265ProfileIdc stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN);
137 VkVideoDecodeAV1ProfileInfoKHR getProfileOperationAV1Decode(StdVideoAV1Profile stdProfile = STD_VIDEO_AV1_PROFILE_MAIN,
138                                                             bool filmgrainSupport         = true);
139 VkVideoEncodeAV1ProfileInfoKHR getProfileOperationAV1Encode(StdVideoAV1Profile stdProfile = STD_VIDEO_AV1_PROFILE_MAIN);
140 const VkExtensionProperties *getVideoExtensionProperties(const VkVideoCodecOperationFlagBitsKHR codecOperation);
141 
142 de::MovePtr<vector<VkFormat>> getSupportedFormats(const InstanceInterface &vk, const VkPhysicalDevice physicalDevice,
143                                                   const VkImageUsageFlags imageUsageFlags,
144                                                   const VkVideoProfileListInfoKHR *videoProfileList);
145 
146 void cmdPipelineImageMemoryBarrier2(const DeviceInterface &vk, const VkCommandBuffer commandBuffer,
147                                     const VkImageMemoryBarrier2KHR *pImageMemoryBarriers,
148                                     const size_t imageMemoryBarrierCount    = 1u,
149                                     const VkDependencyFlags dependencyFlags = 0);
150 
151 void validateVideoProfileList(const InstanceInterface &vk, VkPhysicalDevice physicalDevice,
152                               const VkVideoProfileListInfoKHR *videoProfileList, const VkFormat format,
153                               const VkImageUsageFlags usage);
154 
155 de::MovePtr<VkVideoDecodeCapabilitiesKHR> getVideoDecodeCapabilities(void *pNext);
156 de::MovePtr<VkVideoDecodeH264CapabilitiesKHR> getVideoCapabilitiesExtensionH264D(void);
157 de::MovePtr<VkVideoEncodeH264CapabilitiesKHR> getVideoCapabilitiesExtensionH264E(void *pNext);
158 de::MovePtr<VkVideoEncodeH264QuantizationMapCapabilitiesKHR> getVideoEncodeH264QuantizationMapCapabilities(void);
159 de::MovePtr<VkVideoDecodeH265CapabilitiesKHR> getVideoCapabilitiesExtensionH265D(void);
160 de::MovePtr<VkVideoEncodeH265CapabilitiesKHR> getVideoCapabilitiesExtensionH265E(void *pNext);
161 de::MovePtr<VkVideoEncodeH265QuantizationMapCapabilitiesKHR> getVideoEncodeH265QuantizationMapCapabilities(void);
162 de::MovePtr<VkVideoEncodeAV1CapabilitiesKHR> getVideoCapabilitiesExtensionAV1E(void);
163 de::MovePtr<VkVideoEncodeCapabilitiesKHR> getVideoEncodeCapabilities(void *pNext);
164 de::MovePtr<VkVideoCapabilitiesKHR> getVideoCapabilities(const InstanceInterface &vk, VkPhysicalDevice physicalDevice,
165                                                          const VkVideoProfileInfoKHR *videoProfile, void *pNext);
166 
167 de::MovePtr<VkVideoDecodeH264ProfileInfoKHR> getVideoProfileExtensionH264D(
168     StdVideoH264ProfileIdc stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN,
169     VkVideoDecodeH264PictureLayoutFlagBitsKHR pictureLayout =
170         VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR);
171 de::MovePtr<VkVideoEncodeH264ProfileInfoKHR> getVideoProfileExtensionH264E(
172     StdVideoH264ProfileIdc stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN);
173 de::MovePtr<VkVideoDecodeH265ProfileInfoKHR> getVideoProfileExtensionH265D(
174     StdVideoH265ProfileIdc stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN);
175 de::MovePtr<VkVideoEncodeH265ProfileInfoKHR> getVideoProfileExtensionH265E(
176     StdVideoH265ProfileIdc stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN);
177 
178 de::MovePtr<VkVideoEncodeUsageInfoKHR> getEncodeUsageInfo(void *pNext, VkVideoEncodeUsageFlagsKHR videoUsageHints,
179                                                           VkVideoEncodeContentFlagsKHR videoContentHints,
180                                                           VkVideoEncodeTuningModeKHR tuningMode);
181 de::MovePtr<VkVideoProfileInfoKHR> getVideoProfile(
182     VkVideoCodecOperationFlagBitsKHR videoCodecOperation, void *pNext,
183     VkVideoChromaSubsamplingFlagsKHR chromaSubsampling = VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR,
184     VkVideoComponentBitDepthFlagsKHR lumaBitDepth      = VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR,
185     VkVideoComponentBitDepthFlagsKHR chromaBitDepth    = VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR);
186 de::MovePtr<VkVideoProfileListInfoKHR> getVideoProfileList(const VkVideoProfileInfoKHR *videoProfile,
187                                                            const uint32_t profileCount);
188 
189 de::MovePtr<VkVideoSessionCreateInfoKHR> getVideoSessionCreateInfo(
190     uint32_t queueFamilyIndex, VkVideoSessionCreateFlagsKHR flags, const VkVideoProfileInfoKHR *videoProfile,
191     const VkExtent2D &codedExtent = {1920, 1080}, VkFormat pictureFormat = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
192     VkFormat referencePicturesFormat = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, uint32_t maxReferencePicturesSlotsCount = 2u,
193     uint32_t maxReferencePicturesActiveCount = 2u);
194 
195 vector<AllocationPtr> getAndBindVideoSessionMemory(const DeviceInterface &vkd, const VkDevice device,
196                                                    VkVideoSessionKHR videoSession, Allocator &allocator);
197 
198 bool validateFormatSupport(const InstanceInterface &vk, VkPhysicalDevice physicalDevice,
199                            const VkImageUsageFlags imageUsageFlags, const VkVideoProfileListInfoKHR *videoProfileList,
200                            const VkFormat format, const bool throwException = true);
201 
202 VkImageCreateInfo makeImageCreateInfo(VkFormat format, const VkExtent2D &extent, const VkImageCreateFlags flags,
203                                       const uint32_t *queueFamilyIndex, const VkImageUsageFlags usage, void *pNext,
204                                       const uint32_t arrayLayers        = 1,
205                                       const VkImageLayout initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
206                                       const VkImageTiling tiling        = VK_IMAGE_TILING_OPTIMAL);
207 
208 de::MovePtr<StdVideoH264SequenceParameterSet> getStdVideoH264DecodeSequenceParameterSet(
209     uint32_t width, uint32_t height, StdVideoH264SequenceParameterSetVui *stdVideoH264SequenceParameterSetVui);
210 de::MovePtr<StdVideoH264SequenceParameterSet> getStdVideoH264EncodeSequenceParameterSet(
211     uint32_t width, uint32_t height, uint8_t maxNumRefs,
212     StdVideoH264SequenceParameterSetVui *stdVideoH264SequenceParameterSetVui);
213 
214 de::MovePtr<StdVideoH264PictureParameterSet> getStdVideoH264DecodePictureParameterSet(void);
215 de::MovePtr<StdVideoH264PictureParameterSet> getStdVideoH264EncodePictureParameterSet(uint8_t numL0, uint8_t numL1);
216 
217 de::MovePtr<VkVideoEncodeH264SessionParametersAddInfoKHR> createVideoEncodeH264SessionParametersAddInfoKHR(
218     uint32_t stdSPSCount, const StdVideoH264SequenceParameterSet *pStdSPSs, uint32_t stdPPSCount,
219     const StdVideoH264PictureParameterSet *pStdPPSs);
220 
221 de::MovePtr<VkVideoEncodeH264SessionParametersCreateInfoKHR> createVideoEncodeH264SessionParametersCreateInfoKHR(
222     const void *pNext, uint32_t maxStdSPSCount, uint32_t maxStdPPSCount,
223     const VkVideoEncodeH264SessionParametersAddInfoKHR *pParametersAddInfo);
224 
225 de::MovePtr<StdVideoH265ProfileTierLevel> getStdVideoH265ProfileTierLevel(StdVideoH265ProfileIdc general_profile_idc,
226                                                                           StdVideoH265LevelIdc general_level_idc);
227 de::MovePtr<StdVideoH265DecPicBufMgr> getStdVideoH265DecPicBufMgr(void);
228 de::MovePtr<StdVideoH265VideoParameterSet> getStdVideoH265VideoParameterSet(
229     const StdVideoH265DecPicBufMgr *pDecPicBufMgr, const StdVideoH265ProfileTierLevel *pProfileTierLevel);
230 
231 de::MovePtr<StdVideoH265SequenceParameterSetVui> getStdVideoH265SequenceParameterSetVui(uint32_t vui_time_scale);
232 de::MovePtr<StdVideoH265ShortTermRefPicSet> getStdVideoH265ShortTermRefPicSet(StdVideoH265PictureType pictureType,
233                                                                               uint32_t frameIdx,
234                                                                               uint32_t consecutiveBFrameCount);
235 de::MovePtr<StdVideoH265SequenceParameterSet> getStdVideoH265SequenceParameterSet(
236     uint32_t width, uint32_t height, VkVideoEncodeH265CtbSizeFlagsKHR ctbSizesFlag,
237     VkVideoEncodeH265TransformBlockSizeFlagsKHR transformBlockSizesFlag, const StdVideoH265DecPicBufMgr *pDecPicBufMgr,
238     const StdVideoH265ProfileTierLevel *pProfileTierLevel,
239     const StdVideoH265SequenceParameterSetVui *pSequenceParameterSetVui);
240 
241 de::MovePtr<StdVideoH265PictureParameterSet> getStdVideoH265PictureParameterSet(
242     const VkVideoEncodeH265CapabilitiesKHR *videoH265CapabilitiesExtension);
243 
244 de::MovePtr<VkVideoEncodeH265SessionParametersAddInfoKHR> getVideoEncodeH265SessionParametersAddInfoKHR(
245     uint32_t stdVPSCount, const StdVideoH265VideoParameterSet *pStdVPSs, uint32_t stdSPSCount,
246     const StdVideoH265SequenceParameterSet *pStdSPSs, uint32_t stdPPSCount,
247     const StdVideoH265PictureParameterSet *pStdPPSs);
248 
249 de::MovePtr<VkVideoEncodeH265SessionParametersCreateInfoKHR> getVideoEncodeH265SessionParametersCreateInfoKHR(
250     const void *pNext, uint32_t maxStdVPSCount, uint32_t maxStdSPSCount, uint32_t maxStdPPSCount,
251     const VkVideoEncodeH265SessionParametersAddInfoKHR *pParametersAddInfo);
252 
253 de::MovePtr<VkVideoSessionParametersCreateInfoKHR> getVideoSessionParametersCreateInfoKHR(
254     const void *pNext, const VkVideoSessionParametersCreateFlagsKHR flags, VkVideoSessionKHR videoSession);
255 
256 de::MovePtr<StdVideoEncodeH264ReferenceInfo> getStdVideoEncodeH264ReferenceInfo(
257     StdVideoH264PictureType primary_pic_type, uint32_t FrameNum, int32_t PicOrderCnt);
258 de::MovePtr<VkVideoEncodeH264DpbSlotInfoKHR> getVideoEncodeH264DpbSlotInfo(
259     const StdVideoEncodeH264ReferenceInfo *pStdReferenceInfo);
260 de::MovePtr<StdVideoEncodeH265ReferenceInfo> getStdVideoEncodeH265ReferenceInfo(StdVideoH265PictureType pic_type,
261                                                                                 int32_t PicOrderCntVal);
262 de::MovePtr<VkVideoEncodeH265DpbSlotInfoKHR> getVideoEncodeH265DpbSlotInfo(
263     const StdVideoEncodeH265ReferenceInfo *pStdReferenceInfo);
264 
265 de::MovePtr<StdVideoEncodeH264SliceHeader> getStdVideoEncodeH264SliceHeader(StdVideoH264SliceType sliceType,
266                                                                             bool activeOverrideFlag);
267 de::MovePtr<StdVideoEncodeH265SliceSegmentHeader> getStdVideoEncodeH265SliceSegmentHeader(
268     StdVideoH265SliceType sliceType);
269 
270 de::MovePtr<VkVideoEncodeH264NaluSliceInfoKHR> getVideoEncodeH264NaluSlice(
271     StdVideoEncodeH264SliceHeader *stdVideoEncodeH264SliceHeader, const int32_t qpValue = 0);
272 de::MovePtr<VkVideoEncodeH265NaluSliceSegmentInfoKHR> getVideoEncodeH265NaluSliceSegment(
273     StdVideoEncodeH265SliceSegmentHeader *stdVideoEncodeH265SliceSegmentHeader, const int32_t qpValue = 0);
274 
275 de::MovePtr<StdVideoEncodeH264ReferenceListsInfo> getVideoEncodeH264ReferenceListsInfo(
276     uint8_t RefPicList0[STD_VIDEO_H264_MAX_NUM_LIST_REF], uint8_t RefPicList1[STD_VIDEO_H264_MAX_NUM_LIST_REF],
277     uint8_t numL0, uint8_t numL1);
278 de::MovePtr<StdVideoEncodeH265ReferenceListsInfo> getVideoEncodeH265ReferenceListsInfo(
279     uint8_t RefPicList0[STD_VIDEO_H265_MAX_NUM_LIST_REF], uint8_t RefPicList1[STD_VIDEO_H265_MAX_NUM_LIST_REF]);
280 
281 de::MovePtr<StdVideoEncodeH264PictureInfo> getStdVideoEncodeH264PictureInfo(
282     StdVideoH264PictureType pictureType, uint32_t frameNum, int32_t PicOrderCnt, uint16_t idr_pic_id,
283     const StdVideoEncodeH264ReferenceListsInfo *pRefLists);
284 
285 de::MovePtr<VkVideoEncodeH264PictureInfoKHR> getVideoEncodeH264PictureInfo(
286     const StdVideoEncodeH264PictureInfo *pictureInfo,
287     const VkVideoEncodeH264NaluSliceInfoKHR *pNaluSliceEntries = nullptr);
288 
289 de::MovePtr<StdVideoEncodeH265PictureInfo> getStdVideoEncodeH265PictureInfo(
290     StdVideoH265PictureType pictureType, int32_t PicOrderCntVal, const StdVideoEncodeH265ReferenceListsInfo *pRefLists,
291     StdVideoH265ShortTermRefPicSet *pShortTermRefPicSet);
292 
293 de::MovePtr<VkVideoEncodeH265PictureInfoKHR> getVideoEncodeH265PictureInfo(
294     const StdVideoEncodeH265PictureInfo *pictureInfo,
295     const VkVideoEncodeH265NaluSliceSegmentInfoKHR *pNaluSliceSegmentInfo);
296 
297 de::MovePtr<VkVideoBeginCodingInfoKHR> getVideoBeginCodingInfo(
298     VkVideoSessionKHR videoEncodeSession, VkVideoSessionParametersKHR videoEncodeSessionParameters,
299     uint32_t referenceSlotCount = 0, const VkVideoReferenceSlotInfoKHR *pReferenceSlots = nullptr,
300     const void *pNext = nullptr);
301 
302 de::MovePtr<VkVideoInlineQueryInfoKHR> getVideoInlineQueryInfo(VkQueryPool queryPool, uint32_t firstQuery,
303                                                                uint32_t queryCount, const void *pNext = nullptr);
304 
305 de::MovePtr<VkVideoEncodeQuantizationMapSessionParametersCreateInfoKHR> getVideoEncodeH264QuantizationMapParameters(
306     VkExtent2D quantizationMapTexelSize);
307 de::MovePtr<VkVideoEncodeQuantizationMapInfoKHR> getQuantizationMapInfo(VkImageView quantizationMap,
308                                                                         VkExtent2D quantizationMapExtent,
309                                                                         const void *pNext = DE_NULL);
310 de::MovePtr<StdVideoDecodeH264PictureInfo> getStdVideoDecodeH264PictureInfo(void);
311 
312 de::SharedPtr<VkVideoDecodeH264PictureInfoKHR> getVideoDecodeH264PictureInfo(
313     StdVideoDecodeH264PictureInfo *stdPictureInfo, uint32_t *sliceOffset);
314 
315 de::MovePtr<VkVideoEncodeH264RateControlLayerInfoKHR> getVideoEncodeH264RateControlLayerInfo(
316     VkBool32 useMinQp, int32_t minQpI, int32_t minQpP, int32_t minQpB, VkBool32 useMaxQp, int32_t maxQpI,
317     int32_t maxQpP, int32_t maxQpB);
318 de::MovePtr<VkVideoEncodeH265RateControlLayerInfoKHR> getVideoEncodeH265RateControlLayerInfo(
319     VkBool32 useMinQp, int32_t minQpI, int32_t minQpP, int32_t minQpB, VkBool32 useMaxQp, int32_t maxQpI,
320     int32_t maxQpP, int32_t maxQpB);
321 
322 de::MovePtr<VkVideoEncodeRateControlLayerInfoKHR> getVideoEncodeRateControlLayerInfo(
323     const void *pNext, VkVideoEncodeRateControlModeFlagBitsKHR rateControlMode, const uint32_t frameRateNumerator);
324 de::MovePtr<VkVideoEncodeRateControlInfoKHR> getVideoEncodeRateControlInfo(
325     const void *pNext, VkVideoEncodeRateControlModeFlagBitsKHR rateControlMode,
326     VkVideoEncodeRateControlLayerInfoKHR *videoEncodeRateControlLayerInfo);
327 
328 de::MovePtr<VkVideoEncodeH264QualityLevelPropertiesKHR> getvideoEncodeH264QualityLevelProperties(int32_t qpI,
329                                                                                                  int32_t qpP,
330                                                                                                  int32_t qpB);
331 de::MovePtr<VkVideoEncodeH265QualityLevelPropertiesKHR> getvideoEncodeH265QualityLevelProperties(int32_t qpI,
332                                                                                                  int32_t qpP,
333                                                                                                  int32_t qpB);
334 
335 de::MovePtr<VkVideoEncodeQualityLevelPropertiesKHR> getVideoEncodeQualityLevelProperties(
336     void *pNext, VkVideoEncodeRateControlModeFlagBitsKHR preferredRateControlMode);
337 de::MovePtr<VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR> getPhysicalDeviceVideoEncodeQualityLevelInfo(
338     const VkVideoProfileInfoKHR *pVideoProfile, uint32_t qualityLevel);
339 
340 de::MovePtr<VkVideoEncodeQualityLevelInfoKHR> getVideoEncodeQualityLevelInfo(
341     uint32_t qualityLevel, VkVideoEncodeQualityLevelPropertiesKHR *videoEncodeQualityLevelProperties = nullptr);
342 
343 de::MovePtr<VkVideoCodingControlInfoKHR> getVideoCodingControlInfo(VkVideoCodingControlFlagsKHR flags,
344                                                                    const void *pNext = nullptr);
345 
346 de::MovePtr<VkVideoEncodeInfoKHR> getVideoEncodeInfo(const void *pNext, const VkVideoEncodeFlagsKHR encodeFlags,
347                                                      const VkBuffer &dstBuffer, const VkDeviceSize &dstBufferOffset,
348                                                      const VkVideoPictureResourceInfoKHR &srcPictureResource,
349                                                      const VkVideoReferenceSlotInfoKHR *pSetupReferenceSlot,
350                                                      const uint32_t &referenceSlotCount,
351                                                      const VkVideoReferenceSlotInfoKHR *pReferenceSlots);
352 
353 void transferImageOwnership(const DeviceInterface &vkd, VkDevice device, VkImage image,
354                             uint32_t transferQueueFamilyIndex, uint32_t encodeQueueFamilyIndex,
355                             VkImageLayout newLayout);
356 
357 VkDeviceSize getBufferSize(VkFormat format, uint32_t width, uint32_t height);
358 
359 de::MovePtr<vkt::ycbcr::MultiPlaneImageData> getDecodedImage(const DeviceInterface &vkd, VkDevice device,
360                                                              Allocator &allocator, VkImage image, VkImageLayout layout,
361                                                              VkFormat format, VkExtent2D codedExtent,
362                                                              uint32_t queueFamilyIndexTransfer,
363                                                              uint32_t queueFamilyIndexDecode);
364 
365 const VkImageFormatProperties getImageFormatProperties(const InstanceInterface &vk, VkPhysicalDevice physicalDevice,
366                                                        const VkVideoProfileListInfoKHR *videoProfileList,
367                                                        const VkFormat format, const VkImageUsageFlags usage);
368 
369 class VideoBaseTestInstance : public TestInstance
370 {
371 public:
VideoBaseTestInstance(Context & context)372     explicit VideoBaseTestInstance(Context &context) : TestInstance(context), m_videoDevice(context)
373     {
374     }
375 
VideoBaseTestInstance(Context & context,const VkVideoCodecOperationFlagsKHR videoCodecOperation,const uint32_t videoDeviceFlags)376     explicit VideoBaseTestInstance(Context &context, const VkVideoCodecOperationFlagsKHR videoCodecOperation,
377                                    const uint32_t videoDeviceFlags)
378         : TestInstance(context)
379         , m_videoDevice(context, videoCodecOperation, videoDeviceFlags)
380     {
381     }
382 
383     ~VideoBaseTestInstance() override = default;
384 
385     VkDevice getDeviceSupportingQueue(
386         VkQueueFlags queueFlagsRequired = 0, VkVideoCodecOperationFlagsKHR videoCodecOperationFlags = 0,
387         VideoDevice::VideoDeviceFlags videoDeviceFlags = VideoDevice::VIDEO_DEVICE_FLAG_NONE);
388     bool createDeviceSupportingQueue(
389         VkQueueFlags queueFlagsRequired, VkVideoCodecOperationFlagsKHR videoCodecOperationFlags,
390         VideoDevice::VideoDeviceFlags videoDeviceFlags = VideoDevice::VIDEO_DEVICE_FLAG_NONE);
391     const DeviceDriver &getDeviceDriver();
392     uint32_t getQueueFamilyIndexTransfer();
393     uint32_t getQueueFamilyIndexDecode();
394     uint32_t getQueueFamilyIndexEncode();
395     Allocator &getAllocator();
396     tcu::TestStatus validateEncodedContent(VkVideoCodecOperationFlagBitsKHR videoCodecEncodeOperation,
397                                            StdVideoAV1Profile profile, const char *encodedFileName,
398                                            const char *yuvFileName, int32_t numberOfFrames, int32_t inputWidth,
399                                            int32_t inputHeight, const VkExtent2D expectedOutputExtent,
400                                            VkVideoChromaSubsamplingFlagsKHR chromaSubsampling,
401                                            VkVideoComponentBitDepthFlagsKHR lumaBitDepth,
402                                            VkVideoComponentBitDepthFlagsKHR chromaBitDepth,
403                                            double psnrThresholdLowerLimit);
404 
405 protected:
406     de::MovePtr<vector<uint8_t>> loadVideoData(const string &filename);
407     VideoDevice m_videoDevice;
408 };
409 
410 typedef enum StdChromaFormatIdc
411 {
412     chroma_format_idc_monochrome = STD_VIDEO_H264_CHROMA_FORMAT_IDC_MONOCHROME,
413     chroma_format_idc_420        = STD_VIDEO_H264_CHROMA_FORMAT_IDC_420,
414     chroma_format_idc_422        = STD_VIDEO_H264_CHROMA_FORMAT_IDC_422,
415     chroma_format_idc_444        = STD_VIDEO_H264_CHROMA_FORMAT_IDC_444,
416 } StdChromaFormatIdc;
417 
418 class VkVideoCoreProfile
419 {
420 public:
isValidCodec(VkVideoCodecOperationFlagsKHR videoCodecOperations)421     static bool isValidCodec(VkVideoCodecOperationFlagsKHR videoCodecOperations)
422     {
423         return (videoCodecOperations &
424                 (VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR | VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR |
425                  VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR | VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR |
426                  VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR));
427     }
428 
PopulateProfileExt(VkBaseInStructure const * pVideoProfileExt)429     bool PopulateProfileExt(VkBaseInStructure const *pVideoProfileExt)
430     {
431         if (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR)
432         {
433             VkVideoDecodeH264ProfileInfoKHR const *pProfileExt =
434                 (VkVideoDecodeH264ProfileInfoKHR const *)pVideoProfileExt;
435             if (pProfileExt && (pProfileExt->sType != VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR))
436             {
437                 m_profile.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
438                 return false;
439             }
440             if (pProfileExt)
441             {
442                 m_h264DecodeProfile = *pProfileExt;
443             }
444             else
445             {
446                 //  Use default ext profile parameters
447                 m_h264DecodeProfile.sType         = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR;
448                 m_h264DecodeProfile.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN;
449                 m_h264DecodeProfile.pictureLayout =
450                     VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR;
451             }
452             m_profile.pNext           = &m_h264DecodeProfile;
453             m_h264DecodeProfile.pNext = NULL;
454         }
455         else if (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR)
456         {
457             VkVideoDecodeH265ProfileInfoKHR const *pProfileExt =
458                 (VkVideoDecodeH265ProfileInfoKHR const *)pVideoProfileExt;
459             if (pProfileExt && (pProfileExt->sType != VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR))
460             {
461                 m_profile.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
462                 return false;
463             }
464             if (pProfileExt)
465             {
466                 m_h265DecodeProfile = *pProfileExt;
467             }
468             else
469             {
470                 //  Use default ext profile parameters
471                 m_h265DecodeProfile.sType         = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR;
472                 m_h265DecodeProfile.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN;
473             }
474             m_profile.pNext           = &m_h265DecodeProfile;
475             m_h265DecodeProfile.pNext = NULL;
476         }
477         else if (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR)
478         {
479             VkVideoDecodeAV1ProfileInfoKHR const *pProfileExt =
480                 (VkVideoDecodeAV1ProfileInfoKHR const *)pVideoProfileExt;
481             if (pProfileExt && (pProfileExt->sType != VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PROFILE_INFO_KHR))
482             {
483                 m_profile.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
484                 return false;
485             }
486             if (pProfileExt)
487             {
488                 m_av1DecodeProfile = *pProfileExt;
489             }
490             else
491             {
492                 //  Use default ext profile parameters
493                 m_av1DecodeProfile.sType      = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PROFILE_INFO_KHR;
494                 m_av1DecodeProfile.stdProfile = STD_VIDEO_AV1_PROFILE_MAIN;
495             }
496             m_profile.pNext          = &m_av1DecodeProfile;
497             m_av1DecodeProfile.pNext = NULL;
498         }
499         else if (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR)
500         {
501             VkVideoEncodeH264ProfileInfoKHR const *pProfileExt =
502                 (VkVideoEncodeH264ProfileInfoKHR const *)pVideoProfileExt;
503             if (pProfileExt && (pProfileExt->sType != VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_KHR))
504             {
505                 m_profile.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
506                 return false;
507             }
508             if (pProfileExt)
509             {
510                 m_h264EncodeProfile = *pProfileExt;
511             }
512             else
513             {
514                 //  Use default ext profile parameters
515                 m_h264DecodeProfile.sType         = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_KHR;
516                 m_h264DecodeProfile.stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN;
517             }
518             m_profile.pNext           = &m_h264EncodeProfile;
519             m_h264EncodeProfile.pNext = NULL;
520         }
521         else if (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR)
522         {
523             VkVideoEncodeH265ProfileInfoKHR const *pProfileExt =
524                 (VkVideoEncodeH265ProfileInfoKHR const *)pVideoProfileExt;
525             if (pProfileExt && (pProfileExt->sType != VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_KHR))
526             {
527                 m_profile.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
528                 return false;
529             }
530             if (pProfileExt)
531             {
532                 m_h265EncodeProfile = *pProfileExt;
533             }
534             else
535             {
536                 //  Use default ext profile parameters
537                 m_h265EncodeProfile.sType         = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_KHR;
538                 m_h265EncodeProfile.stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN;
539             }
540             m_profile.pNext           = &m_h265EncodeProfile;
541             m_h265EncodeProfile.pNext = NULL;
542         }
543         else if (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR)
544         {
545             VkVideoEncodeAV1ProfileInfoKHR const *pProfileExt =
546                 (VkVideoEncodeAV1ProfileInfoKHR const *)pVideoProfileExt;
547             if (pProfileExt && (pProfileExt->sType != VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_PROFILE_INFO_KHR))
548             {
549                 m_profile.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
550                 return false;
551             }
552             if (pProfileExt)
553             {
554                 m_av1EncodeProfile = *pProfileExt;
555             }
556             else
557             {
558                 //  Use default ext profile parameters
559                 m_av1EncodeProfile.sType      = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_PROFILE_INFO_KHR;
560                 m_av1EncodeProfile.stdProfile = STD_VIDEO_AV1_PROFILE_MAIN;
561             }
562             m_profile.pNext          = &m_av1EncodeProfile;
563             m_av1EncodeProfile.pNext = NULL;
564         }
565         else
566         {
567             DE_ASSERT(false && "Unknown codec!");
568             return false;
569         }
570 
571         return true;
572     }
573 
InitFromProfile(const VkVideoProfileInfoKHR * pVideoProfile)574     bool InitFromProfile(const VkVideoProfileInfoKHR *pVideoProfile)
575     {
576         m_profile       = *pVideoProfile;
577         m_profile.pNext = NULL;
578         return PopulateProfileExt((VkBaseInStructure const *)pVideoProfile->pNext);
579     }
580 
VkVideoCoreProfile(const VkVideoProfileInfoKHR * pVideoProfile)581     VkVideoCoreProfile(const VkVideoProfileInfoKHR *pVideoProfile) : m_profile(*pVideoProfile)
582     {
583         PopulateProfileExt((VkBaseInStructure const *)pVideoProfile->pNext);
584     }
585 
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,uint32_t videoProfileIdc=0,bool filmGrainPresent=false)586     VkVideoCoreProfile(VkVideoCodecOperationFlagBitsKHR videoCodecOperation = VK_VIDEO_CODEC_OPERATION_NONE_KHR,
587                        VkVideoChromaSubsamplingFlagsKHR chromaSubsampling   = VK_VIDEO_CHROMA_SUBSAMPLING_INVALID_KHR,
588                        VkVideoComponentBitDepthFlagsKHR lumaBitDepth        = VK_VIDEO_COMPONENT_BIT_DEPTH_INVALID_KHR,
589                        VkVideoComponentBitDepthFlagsKHR chromaBitDepth      = VK_VIDEO_COMPONENT_BIT_DEPTH_INVALID_KHR,
590                        uint32_t videoProfileIdc = 0, bool filmGrainPresent = false)
591         : m_profile({VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR, NULL, videoCodecOperation, chromaSubsampling,
592                      lumaBitDepth, chromaBitDepth})
593         , m_profileList({VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR, NULL, 1, &m_profile})
594     {
595         if (!isValidCodec(videoCodecOperation))
596         {
597             return;
598         }
599 
600         VkVideoDecodeH264ProfileInfoKHR decodeH264ProfilesRequest;
601         VkVideoDecodeH265ProfileInfoKHR decodeH265ProfilesRequest;
602         VkVideoDecodeAV1ProfileInfoKHR decodeAV1ProfilesRequest;
603         VkVideoEncodeH264ProfileInfoKHR encodeH264ProfilesRequest;
604         VkVideoEncodeH265ProfileInfoKHR encodeH265ProfilesRequest;
605         VkVideoEncodeAV1ProfileInfoKHR encodeAV1ProfilesRequest;
606         VkBaseInStructure *pVideoProfileExt = NULL;
607 
608         if (videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR)
609         {
610             decodeH264ProfilesRequest.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR;
611             decodeH264ProfilesRequest.pNext = NULL;
612             decodeH264ProfilesRequest.stdProfileIdc =
613                 (videoProfileIdc == 0) ? STD_VIDEO_H264_PROFILE_IDC_INVALID : (StdVideoH264ProfileIdc)videoProfileIdc;
614             decodeH264ProfilesRequest.pictureLayout =
615                 VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR;
616             pVideoProfileExt = (VkBaseInStructure *)&decodeH264ProfilesRequest;
617         }
618         else if (videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR)
619         {
620             decodeH265ProfilesRequest.sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR;
621             decodeH265ProfilesRequest.pNext = NULL;
622             decodeH265ProfilesRequest.stdProfileIdc =
623                 (videoProfileIdc == 0) ? STD_VIDEO_H265_PROFILE_IDC_INVALID : (StdVideoH265ProfileIdc)videoProfileIdc;
624             pVideoProfileExt = (VkBaseInStructure *)&decodeH265ProfilesRequest;
625         }
626         else if (videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR)
627         {
628             decodeAV1ProfilesRequest.sType            = VK_STRUCTURE_TYPE_VIDEO_DECODE_AV1_PROFILE_INFO_KHR;
629             decodeAV1ProfilesRequest.pNext            = NULL;
630             decodeAV1ProfilesRequest.stdProfile       = (StdVideoAV1Profile)videoProfileIdc;
631             decodeAV1ProfilesRequest.filmGrainSupport = filmGrainPresent;
632             pVideoProfileExt                          = (VkBaseInStructure *)&decodeAV1ProfilesRequest;
633         }
634         else if (videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR)
635         {
636             encodeH264ProfilesRequest.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_KHR;
637             encodeH264ProfilesRequest.pNext = NULL;
638             encodeH264ProfilesRequest.stdProfileIdc =
639                 (videoProfileIdc == 0) ? STD_VIDEO_H264_PROFILE_IDC_INVALID : (StdVideoH264ProfileIdc)videoProfileIdc;
640             pVideoProfileExt = (VkBaseInStructure *)&encodeH264ProfilesRequest;
641         }
642         else if (videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR)
643         {
644             encodeH265ProfilesRequest.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_KHR;
645             encodeH265ProfilesRequest.pNext = NULL;
646             encodeH265ProfilesRequest.stdProfileIdc =
647                 (videoProfileIdc == 0) ? STD_VIDEO_H265_PROFILE_IDC_INVALID : (StdVideoH265ProfileIdc)videoProfileIdc;
648             pVideoProfileExt = (VkBaseInStructure *)&encodeH265ProfilesRequest;
649         }
650         else if (videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR)
651         {
652             encodeAV1ProfilesRequest.sType = VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_PROFILE_INFO_KHR;
653             encodeAV1ProfilesRequest.pNext = NULL;
654             encodeAV1ProfilesRequest.stdProfile =
655                 (videoProfileIdc == 0) ? STD_VIDEO_AV1_PROFILE_INVALID : (StdVideoAV1Profile)videoProfileIdc;
656             pVideoProfileExt = (VkBaseInStructure *)&encodeAV1ProfilesRequest;
657         }
658         else
659         {
660             DE_ASSERT(false && "Unknown codec!");
661             return;
662         }
663 
664         PopulateProfileExt(pVideoProfileExt);
665     }
666 
GetCodecType() const667     VkVideoCodecOperationFlagBitsKHR GetCodecType() const
668     {
669         return m_profile.videoCodecOperation;
670     }
671 
IsEncodeCodecType() const672     bool IsEncodeCodecType() const
673     {
674         return ((m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR) ||
675                 (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR) ||
676                 (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR));
677     }
678 
IsDecodeCodecType() const679     bool IsDecodeCodecType() const
680     {
681         return ((m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) ||
682                 (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) ||
683                 (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR));
684     }
685 
IsH264() const686     bool IsH264() const
687     {
688         return ((m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) ||
689                 (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR));
690     }
691 
IsH265() const692     bool IsH265() const
693     {
694         return ((m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) ||
695                 (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR));
696     }
IsAV1() const697     bool IsAV1() const
698     {
699         return ((m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR) ||
700                 (m_profile.videoCodecOperation == VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR));
701     }
702 
operator bool() const703     operator bool() const
704     {
705         return (m_profile.sType == VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR);
706     }
707 
GetProfile() const708     const VkVideoProfileInfoKHR *GetProfile() const
709     {
710         if (m_profile.sType == VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR)
711         {
712             return &m_profile;
713         }
714         else
715         {
716             return NULL;
717         }
718     }
719 
GetProfileListInfo() const720     const VkVideoProfileListInfoKHR *GetProfileListInfo() const
721     {
722         if (m_profileList.sType == VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR)
723         {
724             return &m_profileList;
725         }
726         else
727         {
728             return NULL;
729         }
730     }
731 
GetDecodeH264Profile() const732     const VkVideoDecodeH264ProfileInfoKHR *GetDecodeH264Profile() const
733     {
734         if (m_h264DecodeProfile.sType == VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR)
735         {
736             return &m_h264DecodeProfile;
737         }
738         else
739         {
740             return NULL;
741         }
742     }
743 
GetDecodeH265Profile() const744     const VkVideoDecodeH265ProfileInfoKHR *GetDecodeH265Profile() const
745     {
746         if (m_h265DecodeProfile.sType == VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR)
747         {
748             return &m_h265DecodeProfile;
749         }
750         else
751         {
752             return NULL;
753         }
754     }
755 
GetEncodeH264Profile() const756     const VkVideoEncodeH264ProfileInfoKHR *GetEncodeH264Profile() const
757     {
758         if (m_h264EncodeProfile.sType == VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_KHR)
759         {
760             return &m_h264EncodeProfile;
761         }
762         else
763         {
764             return NULL;
765         }
766     }
767 
GetEncodeH265Profile() const768     const VkVideoEncodeH265ProfileInfoKHR *GetEncodeH265Profile() const
769     {
770         if (m_h265EncodeProfile.sType == VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_KHR)
771         {
772             return &m_h265EncodeProfile;
773         }
774         else
775         {
776             return NULL;
777         }
778     }
779 
GetEncodeAV1Profile() const780     const VkVideoEncodeAV1ProfileInfoKHR *GetEncodeAV1Profile() const
781     {
782         if (m_av1EncodeProfile.sType == VK_STRUCTURE_TYPE_VIDEO_ENCODE_AV1_PROFILE_INFO_KHR)
783         {
784             return &m_av1EncodeProfile;
785         }
786         else
787         {
788             return NULL;
789         }
790     }
791 
copyProfile(const VkVideoCoreProfile & src)792     bool copyProfile(const VkVideoCoreProfile &src)
793     {
794         if (!src)
795         {
796             return false;
797         }
798 
799         m_profile       = src.m_profile;
800         m_profile.pNext = nullptr;
801 
802         m_profileList       = src.m_profileList;
803         m_profileList.pNext = nullptr;
804 
805         m_profileList.pProfiles = &m_profile;
806 
807         PopulateProfileExt((VkBaseInStructure const *)src.m_profile.pNext);
808 
809         return true;
810     }
811 
VkVideoCoreProfile(const VkVideoCoreProfile & other)812     VkVideoCoreProfile(const VkVideoCoreProfile &other)
813     {
814         copyProfile(other);
815     }
816 
operator =(const VkVideoCoreProfile & other)817     VkVideoCoreProfile &operator=(const VkVideoCoreProfile &other)
818     {
819         copyProfile(other);
820         return *this;
821     }
822 
operator ==(const VkVideoCoreProfile & other) const823     bool operator==(const VkVideoCoreProfile &other) const
824     {
825         if (m_profile.videoCodecOperation != other.m_profile.videoCodecOperation)
826         {
827             return false;
828         }
829 
830         if (m_profile.chromaSubsampling != other.m_profile.chromaSubsampling)
831         {
832             return false;
833         }
834 
835         if (m_profile.lumaBitDepth != other.m_profile.lumaBitDepth)
836         {
837             return false;
838         }
839 
840         if (m_profile.chromaBitDepth != other.m_profile.chromaBitDepth)
841         {
842             return false;
843         }
844 
845         if (m_profile.pNext != nullptr)
846         {
847             switch (m_profile.videoCodecOperation)
848             {
849             case vk::VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR:
850             {
851                 auto *ours   = (VkVideoDecodeH264ProfileInfoKHR *)m_profile.pNext;
852                 auto *theirs = (VkVideoDecodeH264ProfileInfoKHR *)other.m_profile.pNext;
853                 if (ours->sType != theirs->sType)
854                     return false;
855                 if (ours->stdProfileIdc != theirs->stdProfileIdc)
856                     return false;
857                 if (ours->pictureLayout != theirs->pictureLayout)
858                     return false;
859                 break;
860             }
861             case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR:
862             {
863                 auto *ours   = (VkVideoDecodeH265ProfileInfoKHR *)m_profile.pNext;
864                 auto *theirs = (VkVideoDecodeH265ProfileInfoKHR *)other.m_profile.pNext;
865                 if (ours->sType != theirs->sType)
866                     return false;
867                 if (ours->stdProfileIdc != theirs->stdProfileIdc)
868                     return false;
869                 break;
870             }
871             case VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR:
872             {
873                 auto *ours   = (VkVideoDecodeAV1ProfileInfoKHR *)m_profile.pNext;
874                 auto *theirs = (VkVideoDecodeAV1ProfileInfoKHR *)other.m_profile.pNext;
875                 if (ours->sType != theirs->sType)
876                     return false;
877                 if (ours->stdProfile != theirs->stdProfile)
878                     return false;
879                 break;
880             }
881             default:
882                 tcu::die("Unknown codec");
883             }
884         }
885 
886         return true;
887     }
888 
operator !=(const VkVideoCoreProfile & other) const889     bool operator!=(const VkVideoCoreProfile &other) const
890     {
891         return !(*this == other);
892     }
893 
GetColorSubsampling() const894     VkVideoChromaSubsamplingFlagsKHR GetColorSubsampling() const
895     {
896         return m_profile.chromaSubsampling;
897     }
898 
GetNvColorSubsampling() const899     StdChromaFormatIdc GetNvColorSubsampling() const
900     {
901         if (m_profile.chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR)
902         {
903             return chroma_format_idc_monochrome;
904         }
905         else if (m_profile.chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR)
906         {
907             return chroma_format_idc_420;
908         }
909         else if (m_profile.chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR)
910         {
911             return chroma_format_idc_422;
912         }
913         else if (m_profile.chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR)
914         {
915             return chroma_format_idc_444;
916         }
917 
918         return chroma_format_idc_monochrome;
919     }
920 
GetLumaBitDepthMinus8() const921     uint32_t GetLumaBitDepthMinus8() const
922     {
923         if (m_profile.lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR)
924         {
925             return 8 - 8;
926         }
927         else if (m_profile.lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR)
928         {
929             return 10 - 8;
930         }
931         else if (m_profile.lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR)
932         {
933             return 12 - 8;
934         }
935         return 0;
936     }
937 
GetChromaBitDepthMinus8() const938     uint32_t GetChromaBitDepthMinus8() const
939     {
940         if (m_profile.chromaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR)
941         {
942             return 8 - 8;
943         }
944         else if (m_profile.chromaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR)
945         {
946             return 10 - 8;
947         }
948         else if (m_profile.chromaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR)
949         {
950             return 12 - 8;
951         }
952         return 0;
953     }
954 
is16BitFormat() const955     bool is16BitFormat() const
956     {
957         return !!GetLumaBitDepthMinus8() || !!GetChromaBitDepthMinus8();
958     }
959 
CodecGetVkFormat(VkVideoChromaSubsamplingFlagBitsKHR chromaFormatIdc,VkVideoComponentBitDepthFlagBitsKHR lumaBitDepth,bool isSemiPlanar)960     static VkFormat CodecGetVkFormat(VkVideoChromaSubsamplingFlagBitsKHR chromaFormatIdc,
961                                      VkVideoComponentBitDepthFlagBitsKHR lumaBitDepth, bool isSemiPlanar)
962     {
963         VkFormat vkFormat = VK_FORMAT_UNDEFINED;
964         switch (chromaFormatIdc)
965         {
966         case VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR:
967             switch (lumaBitDepth)
968             {
969             case VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR:
970                 vkFormat = VK_FORMAT_R8_UNORM;
971                 break;
972             case VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR:
973                 vkFormat = VK_FORMAT_R10X6_UNORM_PACK16;
974                 break;
975             case VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR:
976                 vkFormat = VK_FORMAT_R12X4_UNORM_PACK16;
977                 break;
978             default:
979                 DE_ASSERT(false);
980             }
981             break;
982         case VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR:
983             switch (lumaBitDepth)
984             {
985             case VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR:
986                 vkFormat = isSemiPlanar ? VK_FORMAT_G8_B8R8_2PLANE_420_UNORM : VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
987                 break;
988             case VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR:
989                 vkFormat = isSemiPlanar ? VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 :
990                                           VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16;
991                 break;
992             case VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR:
993                 vkFormat = isSemiPlanar ? VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 :
994                                           VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16;
995                 break;
996             default:
997                 DE_ASSERT(false);
998             }
999             break;
1000         case VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR:
1001             switch (lumaBitDepth)
1002             {
1003             case VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR:
1004                 vkFormat = isSemiPlanar ? VK_FORMAT_G8_B8R8_2PLANE_422_UNORM : VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM;
1005                 break;
1006             case VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR:
1007                 vkFormat = isSemiPlanar ? VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 :
1008                                           VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16;
1009                 break;
1010             case VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR:
1011                 vkFormat = isSemiPlanar ? VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 :
1012                                           VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16;
1013                 break;
1014             default:
1015                 DE_ASSERT(false);
1016             }
1017             break;
1018         case VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR:
1019             switch (lumaBitDepth)
1020             {
1021             case VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR:
1022                 vkFormat = isSemiPlanar ? VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT : VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM;
1023                 break;
1024             case VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR:
1025                 vkFormat = isSemiPlanar ? VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT :
1026                                           VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16;
1027                 break;
1028             case VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR:
1029                 vkFormat = isSemiPlanar ? VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT :
1030                                           VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16;
1031                 break;
1032             default:
1033                 DE_ASSERT(false);
1034             }
1035             break;
1036         default:
1037             DE_ASSERT(false);
1038         }
1039 
1040         return vkFormat;
1041     }
1042 
GetVideoChromaFormatFromVkFormat(VkFormat format)1043     static StdChromaFormatIdc GetVideoChromaFormatFromVkFormat(VkFormat format)
1044     {
1045         StdChromaFormatIdc videoChromaFormat = chroma_format_idc_420;
1046         switch ((uint32_t)format)
1047         {
1048         case VK_FORMAT_R8_UNORM:
1049         case VK_FORMAT_R10X6_UNORM_PACK16:
1050         case VK_FORMAT_R12X4_UNORM_PACK16:
1051             videoChromaFormat = chroma_format_idc_monochrome;
1052             break;
1053 
1054         case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
1055         case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
1056         case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16:
1057         case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16:
1058         case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
1059         case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16:
1060             videoChromaFormat = chroma_format_idc_420;
1061             break;
1062 
1063         case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM:
1064         case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
1065         case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16:
1066         case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16:
1067         case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
1068         case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
1069             videoChromaFormat = chroma_format_idc_422;
1070             break;
1071 
1072         case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
1073         case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16:
1074         case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
1075         case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT:
1076         case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT:
1077         case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT:
1078         case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT:
1079             videoChromaFormat = chroma_format_idc_444;
1080             break;
1081         default:
1082             DE_ASSERT(false);
1083         }
1084 
1085         return videoChromaFormat;
1086     }
1087 
CodecToName(VkVideoCodecOperationFlagBitsKHR codec)1088     static const char *CodecToName(VkVideoCodecOperationFlagBitsKHR codec)
1089     {
1090         switch ((int32_t)codec)
1091         {
1092         case VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR:
1093             return "decode h.264";
1094         case VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR:
1095             return "decode h.265";
1096         case VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR:
1097             return "decode av1";
1098         case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR:
1099             return "encode h.264";
1100         case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR:
1101             return "encode h.265";
1102         default:;
1103         }
1104         DE_ASSERT(false && "Unknown codec");
1105         return "UNKNON";
1106     }
1107 
DumpFormatProfiles(VkVideoProfileInfoKHR * pVideoProfile)1108     static void DumpFormatProfiles(VkVideoProfileInfoKHR *pVideoProfile)
1109     {
1110         // formatProfile info based on supported chroma_format_idc
1111         if (pVideoProfile->chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR)
1112         {
1113             std::cout << "MONO, ";
1114         }
1115         if (pVideoProfile->chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR)
1116         {
1117             std::cout << " 420, ";
1118         }
1119         if (pVideoProfile->chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR)
1120         {
1121             std::cout << " 422, ";
1122         }
1123         if (pVideoProfile->chromaSubsampling & VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR)
1124         {
1125             std::cout << " 444, ";
1126         }
1127 
1128         // Profile info based on max bit_depth_luma_minus8
1129         if (pVideoProfile->lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR)
1130         {
1131             std::cout << "LUMA:   8-bit, ";
1132         }
1133         if (pVideoProfile->lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR)
1134         {
1135             std::cout << "LUMA:  10-bit, ";
1136         }
1137         if (pVideoProfile->lumaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR)
1138         {
1139             std::cout << "LUMA:  12-bit, ";
1140         }
1141 
1142         // Profile info based on max bit_depth_chroma_minus8
1143         if (pVideoProfile->chromaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR)
1144         {
1145             std::cout << "CHROMA: 8-bit, ";
1146         }
1147         if (pVideoProfile->chromaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR)
1148         {
1149             std::cout << "CHROMA:10-bit, ";
1150         }
1151         if (pVideoProfile->chromaBitDepth & VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR)
1152         {
1153             std::cout << "CHROMA:12-bit,";
1154         }
1155     }
1156 
DumpH264Profiles(VkVideoDecodeH264ProfileInfoKHR * pH264Profiles)1157     static void DumpH264Profiles(VkVideoDecodeH264ProfileInfoKHR *pH264Profiles)
1158     {
1159         switch (pH264Profiles->stdProfileIdc)
1160         {
1161         case STD_VIDEO_H264_PROFILE_IDC_BASELINE:
1162             std::cout << "BASELINE, ";
1163             break;
1164         case STD_VIDEO_H264_PROFILE_IDC_MAIN:
1165             std::cout << "MAIN, ";
1166             break;
1167         case STD_VIDEO_H264_PROFILE_IDC_HIGH:
1168             std::cout << "HIGH, ";
1169             break;
1170         case STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE:
1171             std::cout << "HIGH_444_PREDICTIVE, ";
1172             break;
1173         default:
1174             std::cout << "UNKNOWN PROFILE, ";
1175             break;
1176         }
1177     }
1178 
DumpH265Profiles(VkVideoDecodeH265ProfileInfoKHR * pH265Profiles)1179     static void DumpH265Profiles(VkVideoDecodeH265ProfileInfoKHR *pH265Profiles)
1180     {
1181         switch (pH265Profiles->stdProfileIdc)
1182         {
1183         case STD_VIDEO_H265_PROFILE_IDC_MAIN:
1184             std::cout << "MAIN, ";
1185             break;
1186         case STD_VIDEO_H265_PROFILE_IDC_MAIN_10:
1187             std::cout << "MAIN_10, ";
1188             break;
1189         case STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE:
1190             std::cout << "MAIN_STILL_PICTURE, ";
1191             break;
1192         case STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS:
1193             std::cout << "FORMAT_RANGE_EXTENSIONS, ";
1194             break;
1195         case STD_VIDEO_H265_PROFILE_IDC_SCC_EXTENSIONS:
1196             std::cout << "SCC_EXTENSIONS, ";
1197             break;
1198         default:
1199             std::cout << "UNKNOWN PROFILE, ";
1200             break;
1201         }
1202     }
1203 
DumpAV1Profiles(VkVideoDecodeAV1ProfileInfoKHR * pAV1Profiles)1204     static void DumpAV1Profiles(VkVideoDecodeAV1ProfileInfoKHR *pAV1Profiles)
1205     {
1206         switch (pAV1Profiles->stdProfile)
1207         {
1208         case STD_VIDEO_AV1_PROFILE_MAIN:
1209             std::cout << "MAIN, ";
1210             break;
1211         case STD_VIDEO_AV1_PROFILE_HIGH:
1212             std::cout << "HIGH, ";
1213             break;
1214         case STD_VIDEO_AV1_PROFILE_PROFESSIONAL:
1215             std::cout << "PROFESSIONAL,  ";
1216             break;
1217         default:
1218             std::cout << "UNKNOWN PROFILE, ";
1219             break;
1220         }
1221     }
1222 
1223 private:
1224     VkVideoProfileInfoKHR m_profile;
1225     VkVideoProfileListInfoKHR m_profileList;
1226     union
1227     {
1228         VkVideoDecodeH264ProfileInfoKHR m_h264DecodeProfile;
1229         VkVideoDecodeH265ProfileInfoKHR m_h265DecodeProfile;
1230         VkVideoDecodeAV1ProfileInfoKHR m_av1DecodeProfile;
1231         VkVideoEncodeH264ProfileInfoKHR m_h264EncodeProfile;
1232         VkVideoEncodeH265ProfileInfoKHR m_h265EncodeProfile;
1233         VkVideoEncodeAV1ProfileInfoKHR m_av1EncodeProfile;
1234     };
1235 };
1236 
1237 namespace util
1238 {
1239 const char *getVideoCodecString(VkVideoCodecOperationFlagBitsKHR codec);
1240 
1241 const char *getVideoChromaFormatString(VkVideoChromaSubsamplingFlagBitsKHR chromaFormat);
1242 
1243 VkVideoCodecOperationFlagsKHR getSupportedCodecs(
1244     DeviceContext &devCtx, uint32_t selectedVideoQueueFamily,
1245     VkQueueFlags queueFlagsRequired = (VK_QUEUE_VIDEO_DECODE_BIT_KHR | VK_QUEUE_VIDEO_ENCODE_BIT_KHR),
1246     VkVideoCodecOperationFlagsKHR videoCodeOperations =
1247         (VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR | VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR |
1248          VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR | VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR |
1249          VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR | VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR));
1250 
1251 VkResult getVideoFormats(DeviceContext &devCtx, const VkVideoCoreProfile &videoProfile, VkImageUsageFlags imageUsage,
1252                          uint32_t &formatCount, VkFormat *formats, bool dumpData = false);
1253 
1254 VkResult getSupportedVideoFormats(DeviceContext &devCtx, const VkVideoCoreProfile &videoProfile,
1255                                   VkVideoDecodeCapabilityFlagsKHR capabilityFlags, VkFormat &pictureFormat,
1256                                   VkFormat &referencePicturesFormat);
1257 
1258 const char *codecToName(VkVideoCodecOperationFlagBitsKHR codec);
1259 
1260 VkResult getVideoCapabilities(DeviceContext &devCtx, const VkVideoCoreProfile &videoProfile,
1261                               VkVideoCapabilitiesKHR *pVideoCapabilities);
1262 
1263 VkResult getVideoDecodeCapabilities(DeviceContext &devCtx, const VkVideoCoreProfile &videoProfile,
1264                                     VkVideoCapabilitiesKHR &videoCapabilities,
1265                                     VkVideoDecodeCapabilitiesKHR &videoDecodeCapabilities);
1266 double PSNR(const std::vector<uint8_t> &img1, const std::vector<uint8_t> &img2);
1267 double calculatePSNRdifference(const std::vector<uint8_t> &inVector, const std::vector<uint8_t> &out,
1268                                const VkExtent2D &codedExtent, const VkExtent2D &quantizationMapExtent,
1269                                const VkExtent2D &quantizationMapTexelSize);
1270 std::vector<uint8_t> cropImage(const std::vector<uint8_t> &imageData, int imageWidth, int imageHeight, int roiX,
1271                                int roiY, int roiWidth, int roiHeight);
1272 
1273 void generateYCbCrFile(std::string fileName, uint32_t n_frames, uint32_t width, uint32_t height, uint32_t format,
1274                        uint8_t bitdepth);
1275 template <typename planeType>
PSNR(const std::vector<planeType> & img1,const std::vector<planeType> & img2)1276 double PSNR(const std::vector<planeType> &img1, const std::vector<planeType> &img2)
1277 {
1278     TCU_CHECK_AND_THROW(InternalError, (img1.size() > 0) && (img1.size() == img2.size()),
1279                         "Input and output YUVs have different sizes " + de::toString(img1.size()) + " vs " +
1280                             de::toString(img2.size()));
1281 
1282     size_t sz           = img1.size();
1283     double squaredError = 0.0;
1284 
1285     for (size_t i = 0; i < sz; i++)
1286     {
1287         int diff = img1[i] - img2[i];
1288         if (diff > 100)
1289             squaredError += std::abs(diff);
1290     }
1291 
1292     double mse = squaredError / static_cast<double>(sz);
1293     if (mse == 0)
1294     {
1295         return std::numeric_limits<double>::infinity();
1296     }
1297     double type_max = (double)std::numeric_limits<planeType>::max();
1298     return 10 * std::log10((type_max * type_max) / mse);
1299 }
1300 
1301 template <typename planeType>
PSNRImplicitCrop(const std::vector<planeType> & img1,const uint32_t width1,const uint32_t height1,const std::vector<planeType> & img2,const uint32_t width2,const uint32_t height2)1302 double PSNRImplicitCrop(const std::vector<planeType> &img1, const uint32_t width1, const uint32_t height1,
1303                         const std::vector<planeType> &img2, const uint32_t width2, const uint32_t height2)
1304 {
1305     size_t sz           = img1.size();
1306     double squaredError = 0.0;
1307 
1308     DE_ASSERT(width1 <= width2);
1309     DE_ASSERT(height1 <= height2);
1310 
1311     auto yOffset1 = 0U;
1312     auto yStride1 = width1;
1313     auto uOffset1 = width1 * height1;
1314     auto uStride1 = width1 / 4;
1315     auto vOffset1 = uOffset1 + (uOffset1 / 4);
1316     auto vStride1 = width1 / 4;
1317 
1318     auto yOffset2 = 0U;
1319     auto yStride2 = width2;
1320     auto uOffset2 = width2 * height2;
1321     auto uStride2 = width2 / 4;
1322     auto vOffset2 = uOffset2 + (uOffset2 / 4);
1323     auto vStride2 = width2 / 4;
1324 
1325     for (auto row = 0U; row < height1; row++)
1326         for (auto col = 0U; col < width1; col++)
1327         {
1328             auto accumulateDiff = [&squaredError, &img1, &img2](auto offset1, auto stride1, auto offset2, auto stride2,
1329                                                                 auto _row, auto _col)
1330             {
1331                 auto index1 = offset1 + _row * stride1 + _col;
1332                 auto index2 = offset2 + _row * stride2 + _col;
1333                 int diff    = img1[index1] - img2[index2];
1334                 if (diff > 100)
1335                     squaredError += std::abs(diff);
1336             };
1337 
1338             accumulateDiff(yOffset1, yStride1, yOffset2, yStride2, row, col);
1339             if (row % 2 == 0 && col % 2 == 0)
1340             {
1341                 accumulateDiff(uOffset1, uStride1, uOffset2, uStride2, row, col / 2);
1342                 accumulateDiff(vOffset1, vStride1, vOffset2, vStride2, row, col / 2);
1343             }
1344         }
1345 
1346     double mse = squaredError / static_cast<double>(sz);
1347     if (mse == 0)
1348     {
1349         return std::numeric_limits<double>::infinity();
1350     }
1351     double type_max = (double)std::numeric_limits<planeType>::max();
1352     return 10 * std::log10((type_max * type_max) / mse);
1353 }
1354 
1355 } // namespace util
1356 
1357 } // namespace video
1358 } // namespace vkt
1359 
1360 #endif // _VKTVIDEOTESTUTILS_HPP
1361