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