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