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