1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2024 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 /*!
21 * \file
22 * \brief Video Encoding Session tests
23 */
24 /*--------------------------------------------------------------------*/
25
26 #include "vktVideoTestUtils.hpp"
27 #include "vktVideoEncodeTests.hpp"
28 #include "vktVideoTestUtils.hpp"
29 #include "vktTestCase.hpp"
30
31 #ifdef DE_BUILD_VIDEO
32 #include "vktVideoBaseDecodeUtils.hpp"
33 #endif
34
35 #include "tcuTextureUtil.hpp"
36 #include "tcuVectorUtil.hpp"
37 #include "tcuTestLog.hpp"
38 #include "tcuPlatform.hpp"
39 #include "tcuFunctionLibrary.hpp"
40 #include "tcuSurface.hpp"
41
42 #include "tcuTexture.hpp"
43 #include "tcuVector.hpp"
44 #include "tcuPixelFormat.hpp"
45 #include "tcuTextureUtil.hpp"
46 #include "tcuImageCompare.hpp"
47
48 #include "vkDefs.hpp"
49 #include "vkBufferWithMemory.hpp"
50 #include "vkImageWithMemory.hpp"
51 #include "vkImageUtil.hpp"
52 #include "vkBarrierUtil.hpp"
53 #include "vkObjUtil.hpp"
54 #include "vkTypeUtil.hpp"
55
56 #include "vktVideoClipInfo.hpp"
57 #include "ycbcr/vktYCbCrUtil.hpp"
58
59 #include <cstddef>
60 #include <cstdint>
61 #include <fstream>
62 #include <string>
63 #include <algorithm>
64 #include <cmath>
65
66 #ifndef VK_MAX_NUM_IMAGE_PLANES_KHR
67 #define VK_MAX_NUM_IMAGE_PLANES_KHR 4
68 #endif
69
70 #ifndef STREAM_DUMP_DEBUG
71 #define STREAM_DUMP_DEBUG 0
72 #endif
73
74 namespace vkt
75 {
76 namespace video
77 {
78 namespace
79 {
80 using namespace vk;
81 using namespace std;
82
83 using de::MovePtr;
84 using vkt::ycbcr::MultiPlaneImageData;
85
86 template <typename T>
refs(T a,T b)87 std::tuple<T, T> refs(T a, T b)
88 {
89 return std::make_tuple(a, b);
90 }
91
92 typedef de::SharedPtr<vk::Unique<vk::VkSemaphore>> SemaphoreSp;
93
94 enum TestType
95 {
96 TEST_TYPE_H264_ENCODE_I, // Encode one I frame
97 TEST_TYPE_H264_ENCODE_RC_VBR, // Encode one I frame with enabled variable rate control, maximum QP value equal to 42
98 TEST_TYPE_H264_ENCODE_RC_CBR, // Encode one I frame with enabled constant rate control, maximum QP value equal to 42
99 TEST_TYPE_H264_ENCODE_RC_DISABLE, // Encode one I frame with disabled rate control, constant QP value equal to 28
100 TEST_TYPE_H264_ENCODE_QUALITY_LEVEL, // Encode one I frame with quality level set to 0
101 TEST_TYPE_H264_ENCODE_QM_DELTA_RC_VBR, // Encode three I frame with enabled quantization map with enabled variable rate control, maximum QP value equal to 42
102 TEST_TYPE_H264_ENCODE_QM_DELTA_RC_CBR, // Encode three I frame with enabled quantization map with enabled constant rate control, maximum QP value equal to 42
103 TEST_TYPE_H264_ENCODE_QM_DELTA_RC_DISABLE, // Encode three I frame with enabled quantization map with delta values and disabled rate control
104 TEST_TYPE_H264_ENCODE_QM_DELTA, // Encode one I frame with enabled quantization map with delta values
105 TEST_TYPE_H264_ENCODE_QM_EMPHASIS_CBR, // Encode one I frame with enabled quantization map with emphasis values and enabled constant rate control
106 TEST_TYPE_H264_ENCODE_QM_EMPHASIS_VBR, // Encode one I frame with enabled quantization map with emphasis values and enabled variable rate control
107 TEST_TYPE_H264_ENCODE_USAGE, // Encode one I frame with non-default encode usage setup
108 TEST_TYPE_H264_ENCODE_I_P, // Encode one I frame and one P frame, recording and submission order match encode order
109 TEST_TYPE_H264_ENCODE_I_P_NOT_MATCHING_ORDER, // Encode one I frame, one P frame, recording and submission order not matching encoding order
110 TEST_TYPE_H264_I_P_B_13, // Encode two 13-frame GOPs, both I, P, and B frames recording and submission order match encode order
111 TEST_TYPE_H264_ENCODE_QUERY_RESULT_WITH_STATUS, // Encode one I frame, one P frame with status query reported successfully for both frames. Recording and submission order match encode order
112 TEST_TYPE_H264_ENCODE_INLINE_QUERY, // VK_KHR_video_maintenance1 required test: Encode one I frame with inline without vkCmdBegin/EndQuery
113 TEST_TYPE_H264_ENCODE_RESOURCES_WITHOUT_PROFILES, // VK_KHR_video_maintenance1 required test: Encode one I frame with DPB resources defined without passing an encode profile
114 TEST_TYPE_H264_ENCODE_RESOLUTION_CHANGE_DPB, // Encode one I frame and one P frame with session created with a smaller resolution than extracted frame
115
116 TEST_TYPE_H265_ENCODE_I,
117 TEST_TYPE_H265_ENCODE_RC_VBR,
118 TEST_TYPE_H265_ENCODE_RC_CBR,
119 TEST_TYPE_H265_ENCODE_RC_DISABLE,
120 TEST_TYPE_H265_ENCODE_QUALITY_LEVEL,
121 TEST_TYPE_H265_ENCODE_QM_DELTA_RC_VBR,
122 TEST_TYPE_H265_ENCODE_QM_DELTA_RC_CBR,
123 TEST_TYPE_H265_ENCODE_QM_DELTA_RC_DISABLE,
124 TEST_TYPE_H265_ENCODE_QM_DELTA,
125 TEST_TYPE_H265_ENCODE_QM_EMPHASIS_CBR,
126 TEST_TYPE_H265_ENCODE_QM_EMPHASIS_VBR,
127 TEST_TYPE_H265_ENCODE_USAGE,
128 TEST_TYPE_H265_ENCODE_I_P,
129 TEST_TYPE_H265_ENCODE_I_P_NOT_MATCHING_ORDER,
130 TEST_TYPE_H265_I_P_B_13,
131 TEST_TYPE_H265_ENCODE_QUERY_RESULT_WITH_STATUS,
132 TEST_TYPE_H265_ENCODE_INLINE_QUERY,
133 TEST_TYPE_H265_ENCODE_RESOURCES_WITHOUT_PROFILES,
134 TEST_TYPE_H265_ENCODE_RESOLUTION_CHANGE_DPB,
135
136 TEST_TYPE_LAST
137 };
138
139 enum TestCodec
140 {
141 TEST_CODEC_H264,
142 TEST_CODEC_H265,
143
144 TEST_CODEC_LAST
145 };
146
getTestName(const TestType testType)147 const char *getTestName(const TestType testType)
148 {
149 switch (testType)
150 {
151 case TEST_TYPE_H264_ENCODE_I:
152 case TEST_TYPE_H265_ENCODE_I:
153 return "i";
154 case TEST_TYPE_H264_ENCODE_RC_VBR:
155 case TEST_TYPE_H265_ENCODE_RC_VBR:
156 return "rc_vbr";
157 case TEST_TYPE_H264_ENCODE_RC_CBR:
158 case TEST_TYPE_H265_ENCODE_RC_CBR:
159 return "rc_cbr";
160 case TEST_TYPE_H264_ENCODE_RC_DISABLE:
161 case TEST_TYPE_H265_ENCODE_RC_DISABLE:
162 return "rc_disable";
163 case TEST_TYPE_H264_ENCODE_QUALITY_LEVEL:
164 case TEST_TYPE_H265_ENCODE_QUALITY_LEVEL:
165 return "quality_level";
166 case TEST_TYPE_H264_ENCODE_QM_DELTA_RC_VBR:
167 case TEST_TYPE_H265_ENCODE_QM_DELTA_RC_VBR:
168 return "quantization_map_delta_rc_vbr";
169 case TEST_TYPE_H264_ENCODE_QM_DELTA_RC_CBR:
170 case TEST_TYPE_H265_ENCODE_QM_DELTA_RC_CBR:
171 return "quantization_map_delta_rc_cbr";
172 case TEST_TYPE_H264_ENCODE_QM_DELTA_RC_DISABLE:
173 case TEST_TYPE_H265_ENCODE_QM_DELTA_RC_DISABLE:
174 return "quantization_map_delta_rc_disable";
175 case TEST_TYPE_H264_ENCODE_QM_DELTA:
176 case TEST_TYPE_H265_ENCODE_QM_DELTA:
177 return "quantization_map_delta";
178 case TEST_TYPE_H264_ENCODE_QM_EMPHASIS_CBR:
179 case TEST_TYPE_H265_ENCODE_QM_EMPHASIS_CBR:
180 return "quantization_map_emphasis_cbr";
181 case TEST_TYPE_H264_ENCODE_QM_EMPHASIS_VBR:
182 case TEST_TYPE_H265_ENCODE_QM_EMPHASIS_VBR:
183 return "quantization_map_emphasis_vbr";
184 case TEST_TYPE_H264_ENCODE_USAGE:
185 case TEST_TYPE_H265_ENCODE_USAGE:
186 return "usage";
187 case TEST_TYPE_H264_ENCODE_I_P:
188 case TEST_TYPE_H265_ENCODE_I_P:
189 return "i_p";
190 case TEST_TYPE_H264_ENCODE_I_P_NOT_MATCHING_ORDER:
191 case TEST_TYPE_H265_ENCODE_I_P_NOT_MATCHING_ORDER:
192 return "i_p_not_matching_order";
193 case TEST_TYPE_H264_I_P_B_13:
194 case TEST_TYPE_H265_I_P_B_13:
195 return "i_p_b_13";
196 case TEST_TYPE_H264_ENCODE_RESOLUTION_CHANGE_DPB:
197 case TEST_TYPE_H265_ENCODE_RESOLUTION_CHANGE_DPB:
198 return "resolution_change_dpb";
199 case TEST_TYPE_H264_ENCODE_QUERY_RESULT_WITH_STATUS:
200 case TEST_TYPE_H265_ENCODE_QUERY_RESULT_WITH_STATUS:
201 return "query_with_status";
202 case TEST_TYPE_H264_ENCODE_INLINE_QUERY:
203 case TEST_TYPE_H265_ENCODE_INLINE_QUERY:
204 return "inline_query";
205 case TEST_TYPE_H264_ENCODE_RESOURCES_WITHOUT_PROFILES:
206 case TEST_TYPE_H265_ENCODE_RESOURCES_WITHOUT_PROFILES:
207 return "resources_without_profiles";
208 default:
209 TCU_THROW(InternalError, "Unknown TestType");
210 }
211 }
212
getTestCodec(const TestType testType)213 enum TestCodec getTestCodec(const TestType testType)
214 {
215 switch (testType)
216 {
217 case TEST_TYPE_H264_ENCODE_I:
218 case TEST_TYPE_H264_ENCODE_RC_VBR:
219 case TEST_TYPE_H264_ENCODE_RC_CBR:
220 case TEST_TYPE_H264_ENCODE_RC_DISABLE:
221 case TEST_TYPE_H264_ENCODE_QUALITY_LEVEL:
222 case TEST_TYPE_H264_ENCODE_USAGE:
223 case TEST_TYPE_H264_ENCODE_I_P:
224 case TEST_TYPE_H264_ENCODE_I_P_NOT_MATCHING_ORDER:
225 case TEST_TYPE_H264_I_P_B_13:
226 case TEST_TYPE_H264_ENCODE_RESOLUTION_CHANGE_DPB:
227 case TEST_TYPE_H264_ENCODE_QUERY_RESULT_WITH_STATUS:
228 case TEST_TYPE_H264_ENCODE_INLINE_QUERY:
229 case TEST_TYPE_H264_ENCODE_RESOURCES_WITHOUT_PROFILES:
230 case TEST_TYPE_H264_ENCODE_QM_DELTA_RC_VBR:
231 case TEST_TYPE_H264_ENCODE_QM_DELTA_RC_CBR:
232 case TEST_TYPE_H264_ENCODE_QM_DELTA_RC_DISABLE:
233 case TEST_TYPE_H264_ENCODE_QM_DELTA:
234 case TEST_TYPE_H264_ENCODE_QM_EMPHASIS_CBR:
235 case TEST_TYPE_H264_ENCODE_QM_EMPHASIS_VBR:
236 return TEST_CODEC_H264;
237 case TEST_TYPE_H265_ENCODE_I:
238 case TEST_TYPE_H265_ENCODE_RC_VBR:
239 case TEST_TYPE_H265_ENCODE_RC_CBR:
240 case TEST_TYPE_H265_ENCODE_RC_DISABLE:
241 case TEST_TYPE_H265_ENCODE_QUALITY_LEVEL:
242 case TEST_TYPE_H265_ENCODE_USAGE:
243 case TEST_TYPE_H265_ENCODE_I_P:
244 case TEST_TYPE_H265_ENCODE_I_P_NOT_MATCHING_ORDER:
245 case TEST_TYPE_H265_I_P_B_13:
246 case TEST_TYPE_H265_ENCODE_RESOLUTION_CHANGE_DPB:
247 case TEST_TYPE_H265_ENCODE_QUERY_RESULT_WITH_STATUS:
248 case TEST_TYPE_H265_ENCODE_INLINE_QUERY:
249 case TEST_TYPE_H265_ENCODE_RESOURCES_WITHOUT_PROFILES:
250 case TEST_TYPE_H265_ENCODE_QM_DELTA_RC_VBR:
251 case TEST_TYPE_H265_ENCODE_QM_DELTA_RC_CBR:
252 case TEST_TYPE_H265_ENCODE_QM_DELTA_RC_DISABLE:
253 case TEST_TYPE_H265_ENCODE_QM_DELTA:
254 case TEST_TYPE_H265_ENCODE_QM_EMPHASIS_CBR:
255 case TEST_TYPE_H265_ENCODE_QM_EMPHASIS_VBR:
256 return TEST_CODEC_H265;
257 default:
258 TCU_THROW(InternalError, "Unknown TestType");
259 }
260 }
261
262 enum FrameType
263 {
264 IDR_FRAME,
265 I_FRAME,
266 P_FRAME,
267 B_FRAME
268 };
269
270 enum QuantizationMap
271 {
272 QM_DELTA,
273 QM_EMPHASIS
274 };
275
276 enum Option : uint32_t
277 {
278 // The default is to do nothing additional to ordinary encode.
279 Default = 0,
280 UseStatusQueries =
281 1
282 << 0, // All encode operations will have their status checked for success (Q2 2023: not all vendors support these)
283 UseVariableBitrateControl = 1 << 1,
284 UseConstantBitrateControl = 1 << 2,
285 SwapOrder = 1 << 3,
286 DisableRateControl = 1 << 4, // const QP
287 ResolutionChange = 1 << 5,
288 UseQualityLevel = 1 << 6,
289 UseEncodeUsage = 1 << 7,
290 UseInlineQueries = 1 << 8, // Inline queries from the video_mainteance1 extension.
291 ResourcesWithoutProfiles = 1 << 9, // Test profile-less resources from the video_mainteance1 extension.
292 UseDeltaMap = 1 << 10, // VK_KHR_video_encode_quantization_map
293 UseEmphasisMap = 1 << 11, // VK_KHR_video_encode_quantization_map
294 };
295
296 struct EncodeTestParam
297 {
298 TestType type;
299 ClipName clip;
300 uint32_t gops;
301 std::vector<FrameType> encodePattern;
302 std::vector<uint32_t> frameIdx;
303 std::vector<uint32_t> FrameNum;
304 uint8_t spsMaxRefFrames; // Sequence parameter set maximum reference frames.
305 std::tuple<uint8_t, uint8_t> ppsNumActiveRefs; // Picture parameter set number of active references
306 std::vector<std::tuple<uint8_t, uint8_t>> shNumActiveRefs; // Slice header number of active references,
307 std::vector<std::vector<uint8_t>> refSlots; // index of dpbImageVideoReferenceSlots
308 std::vector<int8_t> curSlot; // index of dpbImageVideoReferenceSlots
309 std::vector<std::tuple<std::vector<uint8_t>, std::vector<uint8_t>>>
310 frameReferences; // index of dpbImageVideoReferenceSlots
311 Option encoderOptions;
312 } g_EncodeTests[] = {
313 {TEST_TYPE_H264_ENCODE_I,
314 CLIP_E,
315 1,
316 {IDR_FRAME},
317 /* frameIdx */ {0},
318 /* FrameNum */ {0},
319 /* spsMaxRefFrames */ 1,
320 /* ppsNumActiveRefs */ {0, 0},
321 /* shNumActiveRefs */ {refs(0, 0)},
322 /* refSlots */ {{}},
323 /* curSlot */ {0},
324 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
325 /* encoderOptions */ Option::Default},
326 {TEST_TYPE_H264_ENCODE_RC_VBR,
327 CLIP_E,
328 1,
329 {IDR_FRAME},
330 /* frameIdx */ {0, 1},
331 /* FrameNum */ {0, 1},
332 /* spsMaxRefFrames */ 2,
333 /* ppsNumActiveRefs */ {0, 0},
334 /* shNumActiveRefs */ {refs(0, 0), refs(1, 0)},
335 /* refSlots */ {{}, {0}},
336 /* curSlot */ {0, 1},
337 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {}), refs<std::vector<uint8_t>>({0}, {})},
338 /* encoderOptions */ Option::UseVariableBitrateControl},
339 {TEST_TYPE_H264_ENCODE_RC_CBR,
340 CLIP_E,
341 1,
342 {IDR_FRAME},
343 /* frameIdx */ {0},
344 /* FrameNum */ {0},
345 /* spsMaxRefFrames */ 1,
346 /* ppsNumActiveRefs */ {0, 0},
347 /* shNumActiveRefs */ {refs(0, 0)},
348 /* refSlots */ {{}},
349 /* curSlot */ {0},
350 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
351 /* encoderOptions */ Option::UseConstantBitrateControl},
352 {TEST_TYPE_H264_ENCODE_RC_DISABLE,
353 CLIP_E,
354 1,
355 {IDR_FRAME, P_FRAME},
356 /* frameIdx */ {0, 1},
357 /* FrameNum */ {0, 1},
358 /* spsMaxRefFrames */ 2,
359 /* ppsNumActiveRefs */ {0, 0},
360 /* shNumActiveRefs */ {refs(0, 0), refs(1, 0)},
361 /* refSlots */ {{}, {0}},
362 /* curSlot */ {0, 1},
363 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {}), refs<std::vector<uint8_t>>({0}, {})},
364 /* encoderOptions */ Option::DisableRateControl},
365 {TEST_TYPE_H264_ENCODE_QUALITY_LEVEL,
366 CLIP_E,
367 1,
368 {IDR_FRAME},
369 /* frameIdx */ {0},
370 /* FrameNum */ {0},
371 /* spsMaxRefFrames */ 1,
372 /* ppsNumActiveRefs */ {0, 0},
373 /* shNumActiveRefs */ {refs(0, 0)},
374 /* refSlots */ {{}},
375 /* curSlot */ {0},
376 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
377 /* encoderOptions */ Option::UseQualityLevel},
378 {TEST_TYPE_H264_ENCODE_QM_DELTA_RC_VBR,
379 CLIP_E,
380 3,
381 {IDR_FRAME},
382 /* frameIdx */ {0},
383 /* FrameNum */ {0},
384 /* spsMaxRefFrames */ 1,
385 /* ppsNumActiveRefs */ {0, 0},
386 /* shNumActiveRefs */ {refs(0, 0)},
387 /* refSlots */ {{}},
388 /* curSlot */ {0},
389 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
390 /* encoderOptions */ static_cast<Option>(Option::UseDeltaMap | Option::UseVariableBitrateControl)},
391 {TEST_TYPE_H264_ENCODE_QM_DELTA_RC_CBR,
392 CLIP_E,
393 3,
394 {IDR_FRAME},
395 /* frameIdx */ {0},
396 /* FrameNum */ {0},
397 /* spsMaxRefFrames */ 1,
398 /* ppsNumActiveRefs */ {0, 0},
399 /* shNumActiveRefs */ {refs(0, 0)},
400 /* refSlots */ {{}},
401 /* curSlot */ {0},
402 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
403 /* encoderOptions */ static_cast<Option>(Option::UseDeltaMap | Option::UseConstantBitrateControl)},
404 {TEST_TYPE_H264_ENCODE_QM_DELTA_RC_DISABLE,
405 CLIP_E,
406 3,
407 {IDR_FRAME},
408 /* frameIdx */ {0},
409 /* FrameNum */ {0},
410 /* spsMaxRefFrames */ 1,
411 /* ppsNumActiveRefs */ {0, 0},
412 /* shNumActiveRefs */ {refs(0, 0)},
413 /* refSlots */ {{}},
414 /* curSlot */ {0},
415 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
416 /* encoderOptions */ static_cast<Option>(Option::UseDeltaMap | Option::DisableRateControl)},
417 {TEST_TYPE_H264_ENCODE_QM_DELTA,
418 CLIP_E,
419 3,
420 {IDR_FRAME},
421 /* frameIdx */ {0},
422 /* FrameNum */ {0},
423 /* spsMaxRefFrames */ 1,
424 /* ppsNumActiveRefs */ {0, 0},
425 /* shNumActiveRefs */ {refs(0, 0)},
426 /* refSlots */ {{}},
427 /* curSlot */ {0},
428 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
429 /* encoderOptions */ Option::UseDeltaMap},
430 {TEST_TYPE_H264_ENCODE_QM_EMPHASIS_CBR,
431 CLIP_E,
432 2,
433 {IDR_FRAME},
434 /* frameIdx */ {0},
435 /* FrameNum */ {0},
436 /* spsMaxRefFrames */ 1,
437 /* ppsNumActiveRefs */ {0, 0},
438 /* shNumActiveRefs */ {refs(0, 0)},
439 /* refSlots */ {{}},
440 /* curSlot */ {0},
441 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
442 /* encoderOptions */ static_cast<Option>(Option::UseEmphasisMap | Option::UseConstantBitrateControl)},
443 {TEST_TYPE_H264_ENCODE_QM_EMPHASIS_VBR,
444 CLIP_E,
445 2,
446 {IDR_FRAME},
447 /* frameIdx */ {0},
448 /* FrameNum */ {0},
449 /* spsMaxRefFrames */ 1,
450 /* ppsNumActiveRefs */ {0, 0},
451 /* shNumActiveRefs */ {refs(0, 0)},
452 /* refSlots */ {{}},
453 /* curSlot */ {0},
454 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
455 /* encoderOptions */ static_cast<Option>(Option::UseEmphasisMap | Option::UseVariableBitrateControl)},
456 {TEST_TYPE_H264_ENCODE_USAGE,
457 CLIP_E,
458 1,
459 {IDR_FRAME},
460 /* frameIdx */ {0},
461 /* FrameNum */ {0},
462 /* spsMaxRefFrames */ 1,
463 /* ppsNumActiveRefs */ {0, 0},
464 /* shNumActiveRefs */ {refs(0, 0)},
465 /* refSlots */ {{}},
466 /* curSlot */ {0},
467 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
468 /* encoderOptions */ Option::UseEncodeUsage},
469 {TEST_TYPE_H264_ENCODE_I_P,
470 CLIP_E,
471 1,
472 {IDR_FRAME, P_FRAME},
473 /* frameIdx */ {0, 1},
474 /* FrameNum */ {0, 1},
475 /* spsMaxRefFrames */ 2,
476 /* ppsNumActiveRefs */ {0, 0},
477 /* shNumActiveRefs */ {refs(0, 0), refs(1, 0)},
478 /* refSlots */ {{}, {0}},
479 /* curSlot */ {0, 1},
480 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {}), refs<std::vector<uint8_t>>({0}, {})},
481 /* encoderOptions */ Option::Default},
482 {TEST_TYPE_H264_ENCODE_I_P_NOT_MATCHING_ORDER,
483 CLIP_E,
484 1,
485 {IDR_FRAME, P_FRAME},
486 /* frameIdx */ {0, 1},
487 /* FrameNum */ {0, 1},
488 /* spsMaxRefFrames */ 2,
489 /* ppsNumActiveRefs */ {0, 0},
490 /* shNumActiveRefs */ {refs(0, 0), refs(1, 0)},
491 /* refSlots */ {{}, {0}},
492 /* curSlot */ {0, 1},
493 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {}), refs<std::vector<uint8_t>>({0}, {})},
494 /* encoderOptions */ Option::SwapOrder},
495 {TEST_TYPE_H264_ENCODE_QUERY_RESULT_WITH_STATUS,
496 CLIP_E,
497 1,
498 {IDR_FRAME, P_FRAME},
499 /* frameIdx */ {0, 1},
500 /* FrameNum */ {0, 1},
501 /* spsMaxRefFrames */ 2,
502 /* ppsNumActiveRefs */ {0, 0},
503 /* shNumActiveRefs */ {refs(0, 0), refs(1, 0)},
504 /* refSlots */ {{}, {0}},
505 /* curSlot */ {0, 1},
506 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {}), refs<std::vector<uint8_t>>({0}, {})},
507 /* encoderOptions */ Option::UseStatusQueries},
508 {TEST_TYPE_H264_ENCODE_INLINE_QUERY,
509 CLIP_E,
510 1,
511 {IDR_FRAME},
512 /* frameIdx */ {0},
513 /* FrameNum */ {0},
514 /* spsMaxRefFrames */ 1,
515 /* ppsNumActiveRefs */ {0, 0},
516 /* shNumActiveRefs */ {refs(0, 0)},
517 /* refSlots */ {{}},
518 /* curSlot */ {0},
519 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
520 /* encoderOptions */ Option::UseInlineQueries},
521 {TEST_TYPE_H264_ENCODE_RESOURCES_WITHOUT_PROFILES,
522 CLIP_E,
523 1,
524 {IDR_FRAME, P_FRAME},
525 /* frameIdx */ {0, 1},
526 /* FrameNum */ {0, 1},
527 /* spsMaxRefFrames */ 2,
528 /* ppsNumActiveRefs */ {0, 0},
529 /* shNumActiveRefs */ {refs(0, 0), refs(1, 0)},
530 /* refSlots */ {{}, {0}},
531 /* curSlot */ {0, 1},
532 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {}), refs<std::vector<uint8_t>>({0}, {})},
533 /* encoderOptions */ Option::ResourcesWithoutProfiles},
534 {TEST_TYPE_H264_ENCODE_RESOLUTION_CHANGE_DPB,
535 CLIP_G,
536 2,
537 {IDR_FRAME, P_FRAME},
538 /* frameIdx */ {0, 1},
539 /* FrameNum */ {0, 1},
540 /* spsMaxRefFrames */ 2,
541 /* ppsNumActiveRefs */ {0, 0},
542 /* shNumActiveRefs */ {refs(0, 0), refs(1, 0)},
543 /* refSlots */ {{}, {0}},
544 /* curSlot */ {0, 1},
545 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {}), refs<std::vector<uint8_t>>({0}, {})},
546 /* encoderOptions */ Option::ResolutionChange},
547 {TEST_TYPE_H264_I_P_B_13,
548 CLIP_E,
549 2,
550 {IDR_FRAME, P_FRAME, B_FRAME, B_FRAME, P_FRAME, B_FRAME, B_FRAME, P_FRAME, B_FRAME, B_FRAME, P_FRAME, B_FRAME,
551 B_FRAME, P_FRAME},
552 /* frameIdx */ {0, 3, 1, 2, 6, 4, 5, 9, 7, 8, 12, 10, 11, 13},
553 /* frameNum */ {0, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5},
554 /* spsMaxRefFrames */ 4,
555 /* ppsNumActiveRefs */ {2, 2},
556 /* shNumActiveRefs */
557 {refs(0, 0), refs(1, 0), refs(2, 2), refs(2, 2), refs(2, 0), refs(2, 2), refs(2, 2), refs(2, 0), refs(2, 2),
558 refs(2, 2), refs(2, 0), refs(2, 2), refs(2, 2), refs(2, 0)},
559 /* refSlots */
560 {{},
561 {0},
562 {0, 1},
563 {0, 1},
564 {0, 1},
565 {0, 1, 2},
566 {0, 1, 2},
567 {0, 1, 2},
568 {0, 1, 2, 3},
569 {0, 1, 2, 3},
570 {0, 1, 2, 3},
571 {1, 2, 3, 4},
572 {1, 2, 3, 4},
573 {1, 2, 3, 4}},
574 /* curSlot */ {0, 1, -1, -1, 2, -1, -1, 3, -1, -1, 4, -1, -1, 5},
575 /* frameReferences */
576 {refs<std::vector<uint8_t>>({}, {}), refs<std::vector<uint8_t>>({0}, {}),
577 refs<std::vector<uint8_t>>({0, 1}, {1, 0}), refs<std::vector<uint8_t>>({0, 1}, {1, 0}),
578 refs<std::vector<uint8_t>>({1, 0}, {}), refs<std::vector<uint8_t>>({1, 0}, {2, 1}),
579 refs<std::vector<uint8_t>>({1, 0}, {2, 1}), refs<std::vector<uint8_t>>({2, 1}, {}),
580 refs<std::vector<uint8_t>>({2, 1}, {3, 2}), refs<std::vector<uint8_t>>({2, 1}, {3, 2}),
581 refs<std::vector<uint8_t>>({3, 2}, {}), refs<std::vector<uint8_t>>({3, 2}, {4, 3}),
582 refs<std::vector<uint8_t>>({3, 2}, {4, 3}), refs<std::vector<uint8_t>>({4, 3}, {})},
583 /* encoderOptions */ Option::Default},
584 {TEST_TYPE_H265_ENCODE_I,
585 CLIP_F,
586 1,
587 {IDR_FRAME},
588 /* frameIdx */ {0},
589 /* FrameNum */ {0},
590 /* spsMaxRefFrames */ 1,
591 /* ppsNumActiveRefs */ {0, 0},
592 /* shNumActiveRefs */ {refs(0, 0)},
593 /* refSlots */ {{}},
594 /* curSlot */ {0},
595 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
596 /* encoderOptions */ Option::Default},
597 {TEST_TYPE_H265_ENCODE_RC_VBR,
598 CLIP_F,
599 1,
600 {IDR_FRAME},
601 /* frameIdx */ {0, 1},
602 /* FrameNum */ {0, 1},
603 /* spsMaxRefFrames */ 2,
604 /* ppsNumActiveRefs */ {0, 0},
605 /* shNumActiveRefs */ {refs(0, 0), refs(1, 0)},
606 /* refSlots */ {{}, {0}},
607 /* curSlot */ {0, 1},
608 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {}), refs<std::vector<uint8_t>>({0}, {})},
609 /* encoderOptions */ Option::UseVariableBitrateControl},
610 {TEST_TYPE_H265_ENCODE_RC_CBR,
611 CLIP_F,
612 1,
613 {IDR_FRAME},
614 /* frameIdx */ {0},
615 /* FrameNum */ {0},
616 /* spsMaxRefFrames */ 1,
617 /* ppsNumActiveRefs */ {0, 0},
618 /* shNumActiveRefs */ {refs(0, 0)},
619 /* refSlots */ {{}},
620 /* curSlot */ {0},
621 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
622 /* encoderOptions */ Option::UseConstantBitrateControl},
623 {TEST_TYPE_H265_ENCODE_RC_DISABLE,
624 CLIP_F,
625 1,
626 {IDR_FRAME, P_FRAME},
627 /* frameIdx */ {0, 1},
628 /* FrameNum */ {0, 1},
629 /* spsMaxRefFrames */ 2,
630 /* ppsNumActiveRefs */ {0, 0},
631 /* shNumActiveRefs */ {refs(0, 0), refs(1, 0)},
632 /* refSlots */ {{}, {0}},
633 /* curSlot */ {0, 1},
634 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {}), refs<std::vector<uint8_t>>({0}, {})},
635 /* encoderOptions */ Option::DisableRateControl},
636 {TEST_TYPE_H265_ENCODE_QUALITY_LEVEL,
637 CLIP_F,
638 1,
639 {IDR_FRAME},
640 /* frameIdx */ {0},
641 /* FrameNum */ {0},
642 /* spsMaxRefFrames */ 1,
643 /* ppsNumActiveRefs */ {0, 0},
644 /* shNumActiveRefs */ {refs(0, 0)},
645 /* refSlots */ {{}},
646 /* curSlot */ {0},
647 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
648 /* encoderOptions */ Option::UseQualityLevel},
649 {TEST_TYPE_H265_ENCODE_QM_DELTA_RC_VBR,
650 CLIP_F,
651 3,
652 {IDR_FRAME},
653 /* frameIdx */ {0},
654 /* FrameNum */ {0},
655 /* spsMaxRefFrames */ 1,
656 /* ppsNumActiveRefs */ {0, 0},
657 /* shNumActiveRefs */ {refs(0, 0)},
658 /* refSlots */ {{}},
659 /* curSlot */ {0},
660 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
661 /* encoderOptions */ static_cast<Option>(Option::UseDeltaMap | Option::UseVariableBitrateControl)},
662 {TEST_TYPE_H265_ENCODE_QM_DELTA_RC_CBR,
663 CLIP_F,
664 3,
665 {IDR_FRAME},
666 /* frameIdx */ {0},
667 /* FrameNum */ {0},
668 /* spsMaxRefFrames */ 1,
669 /* ppsNumActiveRefs */ {0, 0},
670 /* shNumActiveRefs */ {refs(0, 0)},
671 /* refSlots */ {{}},
672 /* curSlot */ {0},
673 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
674 /* encoderOptions */ static_cast<Option>(Option::UseDeltaMap | Option::UseConstantBitrateControl)},
675 {TEST_TYPE_H265_ENCODE_QM_DELTA_RC_DISABLE,
676 CLIP_F,
677 3,
678 {IDR_FRAME},
679 /* frameIdx */ {0},
680 /* FrameNum */ {0},
681 /* spsMaxRefFrames */ 1,
682 /* ppsNumActiveRefs */ {0, 0},
683 /* shNumActiveRefs */ {refs(0, 0)},
684 /* refSlots */ {{}},
685 /* curSlot */ {0},
686 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
687 /* encoderOptions */ static_cast<Option>(Option::UseDeltaMap | Option::DisableRateControl)},
688 {TEST_TYPE_H265_ENCODE_QM_DELTA,
689 CLIP_F,
690 3,
691 {IDR_FRAME},
692 /* frameIdx */ {0},
693 /* FrameNum */ {0},
694 /* spsMaxRefFrames */ 1,
695 /* ppsNumActiveRefs */ {0, 0},
696 /* shNumActiveRefs */ {refs(0, 0)},
697 /* refSlots */ {{}},
698 /* curSlot */ {0},
699 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
700 /* encoderOptions */ Option::UseDeltaMap},
701 {TEST_TYPE_H265_ENCODE_QM_EMPHASIS_CBR,
702 CLIP_F,
703 2,
704 {IDR_FRAME},
705 /* frameIdx */ {0},
706 /* FrameNum */ {0},
707 /* spsMaxRefFrames */ 1,
708 /* ppsNumActiveRefs */ {0, 0},
709 /* shNumActiveRefs */ {refs(0, 0)},
710 /* refSlots */ {{}},
711 /* curSlot */ {0},
712 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
713 /* encoderOptions */ static_cast<Option>(Option::UseEmphasisMap | Option::UseConstantBitrateControl)},
714 {TEST_TYPE_H265_ENCODE_QM_EMPHASIS_VBR,
715 CLIP_F,
716 2,
717 {IDR_FRAME},
718 /* frameIdx */ {0},
719 /* FrameNum */ {0},
720 /* spsMaxRefFrames */ 1,
721 /* ppsNumActiveRefs */ {0, 0},
722 /* shNumActiveRefs */ {refs(0, 0)},
723 /* refSlots */ {{}},
724 /* curSlot */ {0},
725 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
726 /* encoderOptions */ static_cast<Option>(Option::UseEmphasisMap | Option::UseVariableBitrateControl)},
727 {TEST_TYPE_H265_ENCODE_USAGE,
728 CLIP_F,
729 1,
730 {IDR_FRAME},
731 /* frameIdx */ {0},
732 /* FrameNum */ {0},
733 /* spsMaxRefFrames */ 1,
734 /* ppsNumActiveRefs */ {0, 0},
735 /* shNumActiveRefs */ {refs(0, 0)},
736 /* refSlots */ {{}},
737 /* curSlot */ {0},
738 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
739 /* encoderOptions */ Option::UseEncodeUsage},
740 {TEST_TYPE_H265_ENCODE_I_P,
741 CLIP_F,
742 1,
743 {IDR_FRAME, P_FRAME},
744 /* frameIdx */ {0, 1},
745 /* FrameNum */ {0, 1},
746 /* spsMaxRefFrames */ 2,
747 /* ppsNumActiveRefs */ {0, 0},
748 /* shNumActiveRefs */ {refs(0, 0), refs(1, 0)},
749 /* refSlots */ {{}, {0}},
750 /* curSlot */ {0, 1},
751 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {}), refs<std::vector<uint8_t>>({0}, {})},
752 /* encoderOptions */ Option::Default},
753 {TEST_TYPE_H265_ENCODE_I_P_NOT_MATCHING_ORDER,
754 CLIP_F,
755 1,
756 {IDR_FRAME, P_FRAME},
757 /* frameIdx */ {0, 1},
758 /* FrameNum */ {0, 1},
759 /* spsMaxRefFrames */ 2,
760 /* ppsNumActiveRefs */ {0, 0},
761 /* shNumActiveRefs */ {refs(0, 0), refs(1, 0)},
762 /* refSlots */ {{}, {0}},
763 /* curSlot */ {0, 1},
764 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {}), refs<std::vector<uint8_t>>({0}, {})},
765 /* encoderOptions */ Option::SwapOrder},
766 {TEST_TYPE_H265_ENCODE_QUERY_RESULT_WITH_STATUS,
767 CLIP_F,
768 1,
769 {IDR_FRAME, P_FRAME},
770 /* frameIdx */ {0, 1},
771 /* FrameNum */ {0, 1},
772 /* spsMaxRefFrames */ 2,
773 /* ppsNumActiveRefs */ {0, 0},
774 /* shNumActiveRefs */ {refs(0, 0), refs(1, 0)},
775 /* refSlots */ {{}, {0}},
776 /* curSlot */ {0, 1},
777 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {}), refs<std::vector<uint8_t>>({0}, {})},
778 /* encoderOptions */ Option::UseStatusQueries},
779 {TEST_TYPE_H265_ENCODE_INLINE_QUERY,
780 CLIP_F,
781 1,
782 {IDR_FRAME},
783 /* frameIdx */ {0},
784 /* FrameNum */ {0},
785 /* spsMaxRefFrames */ 1,
786 /* ppsNumActiveRefs */ {0, 0},
787 /* shNumActiveRefs */ {refs(0, 0)},
788 /* refSlots */ {{}},
789 /* curSlot */ {0},
790 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {})},
791 /* encoderOptions */ Option::UseInlineQueries},
792 {TEST_TYPE_H265_ENCODE_RESOURCES_WITHOUT_PROFILES,
793 CLIP_F,
794 1,
795 {IDR_FRAME, P_FRAME},
796 /* frameIdx */ {0, 1},
797 /* FrameNum */ {0, 1},
798 /* spsMaxRefFrames */ 2,
799 /* ppsNumActiveRefs */ {0, 0},
800 /* shNumActiveRefs */ {refs(0, 0), refs(1, 0)},
801 /* refSlots */ {{}, {0}},
802 /* curSlot */ {0, 1},
803 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {}), refs<std::vector<uint8_t>>({0}, {})},
804 /* encoderOptions */ Option::ResourcesWithoutProfiles},
805 {TEST_TYPE_H265_ENCODE_RESOLUTION_CHANGE_DPB,
806 CLIP_H,
807 2,
808 {IDR_FRAME, P_FRAME},
809 /* frameIdx */ {0, 1},
810 /* FrameNum */ {0, 1},
811 /* spsMaxRefFrames */ 2,
812 /* ppsNumActiveRefs */ {0, 0},
813 /* shNumActiveRefs */ {refs(0, 0), refs(1, 0)},
814 /* refSlots */ {{}, {0}},
815 /* curSlot */ {0, 1},
816 /* frameReferences */ {refs<std::vector<uint8_t>>({}, {}), refs<std::vector<uint8_t>>({0}, {})},
817 /* encoderOptions */ Option::ResolutionChange},
818 {TEST_TYPE_H265_I_P_B_13,
819 CLIP_F,
820 2,
821 {IDR_FRAME, P_FRAME, B_FRAME, B_FRAME, P_FRAME, B_FRAME, B_FRAME, P_FRAME, B_FRAME, B_FRAME, P_FRAME, B_FRAME,
822 B_FRAME, P_FRAME},
823 /* frameIdx */ {0, 3, 1, 2, 6, 4, 5, 9, 7, 8, 12, 10, 11, 13},
824 /* frameNum */ {0, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5},
825 /* spsMaxRefFrames */ 2,
826 /* ppsNumActiveRefs */ {1, 1},
827 /* shNumActiveRefs */
828 {refs(0, 0), refs(1, 0), refs(1, 1), refs(1, 1), refs(1, 0), refs(1, 1), refs(1, 1), refs(1, 0), refs(1, 1),
829 refs(1, 1), refs(1, 0), refs(1, 1), refs(1, 1), refs(1, 0)},
830 /* refSlots */
831 {{},
832 {0},
833 {0, 1},
834 {0, 1},
835 {0, 1},
836 {0, 1, 2},
837 {0, 1, 2},
838 {0, 1, 2},
839 {0, 1, 2, 3},
840 {0, 1, 2, 3},
841 {0, 1, 2, 3},
842 {1, 2, 3, 4},
843 {1, 2, 3, 4},
844 {1, 2, 3, 4}},
845 /* curSlot */ {0, 1, -1, -1, 2, -1, -1, 3, -1, -1, 4, -1, -1, 5},
846 /* frameReferences */
847 {refs<std::vector<uint8_t>>({}, {}), refs<std::vector<uint8_t>>({0}, {}),
848 refs<std::vector<uint8_t>>({0, 1}, {1, 0}), refs<std::vector<uint8_t>>({0, 1}, {1, 0}),
849 refs<std::vector<uint8_t>>({1, 0}, {}), refs<std::vector<uint8_t>>({1, 0}, {2, 1}),
850 refs<std::vector<uint8_t>>({1, 0}, {2, 1}), refs<std::vector<uint8_t>>({2, 1}, {}),
851 refs<std::vector<uint8_t>>({2, 1}, {3, 2}), refs<std::vector<uint8_t>>({2, 1}, {3, 2}),
852 refs<std::vector<uint8_t>>({3, 2}, {}), refs<std::vector<uint8_t>>({3, 2}, {4, 3}),
853 refs<std::vector<uint8_t>>({3, 2}, {4, 3}), refs<std::vector<uint8_t>>({4, 3}, {})},
854 /* encoderOptions */ Option::Default},
855 };
856
857 class TestDefinition
858 {
859 public:
create(EncodeTestParam params)860 static MovePtr<TestDefinition> create(EncodeTestParam params)
861 {
862 return MovePtr<TestDefinition>(new TestDefinition(params));
863 }
864
TestDefinition(EncodeTestParam params)865 TestDefinition(EncodeTestParam params) : m_params(params), m_info(clipInfo(params.clip))
866 {
867 VideoProfileInfo profile = m_info->sessionProfiles[0];
868 m_profile = VkVideoCoreProfile(profile.codecOperation, profile.subsamplingFlags, profile.lumaBitDepth,
869 profile.chromaBitDepth, profile.profileIDC);
870 }
871
getTestType() const872 TestType getTestType() const
873 {
874 return m_params.type;
875 }
876
getClipFilename() const877 const char *getClipFilename() const
878 {
879 return m_info->filename;
880 }
881
getClipWidth() const882 uint32_t getClipWidth() const
883 {
884 return m_info->frameWidth;
885 }
886
getClipHeight() const887 uint32_t getClipHeight() const
888 {
889 return m_info->frameHeight;
890 }
891
getClipFrameRate() const892 uint32_t getClipFrameRate() const
893 {
894 return m_info->frameRate;
895 }
896
getCodecOperation() const897 VkVideoCodecOperationFlagBitsKHR getCodecOperation() const
898 {
899 return m_profile.GetCodecType();
900 }
901
getDecodeProfileExtension() const902 void *getDecodeProfileExtension() const
903 {
904 if (m_profile.IsH264())
905 {
906 const VkVideoDecodeH264ProfileInfoKHR *videoProfileExtention = m_profile.GetDecodeH264Profile();
907 return reinterpret_cast<void *>(const_cast<VkVideoDecodeH264ProfileInfoKHR *>(videoProfileExtention));
908 }
909 if (m_profile.IsH265())
910 {
911 const VkVideoDecodeH265ProfileInfoKHR *videoProfileExtention = m_profile.GetDecodeH265Profile();
912 return reinterpret_cast<void *>(const_cast<VkVideoDecodeH265ProfileInfoKHR *>(videoProfileExtention));
913 }
914 TCU_THROW(InternalError, "Unsupported codec");
915 }
916
getEncodeProfileExtension() const917 void *getEncodeProfileExtension() const
918 {
919 if (m_profile.IsH264())
920 {
921 const VkVideoEncodeH264ProfileInfoKHR *videoProfileExtention = m_profile.GetEncodeH264Profile();
922 return reinterpret_cast<void *>(const_cast<VkVideoEncodeH264ProfileInfoKHR *>(videoProfileExtention));
923 }
924 if (m_profile.IsH265())
925 {
926 const VkVideoEncodeH265ProfileInfoKHR *videoProfileExtention = m_profile.GetEncodeH265Profile();
927 return reinterpret_cast<void *>(const_cast<VkVideoEncodeH265ProfileInfoKHR *>(videoProfileExtention));
928 }
929 TCU_THROW(InternalError, "Unsupported codec");
930 }
931
getProfile() const932 const VkVideoCoreProfile *getProfile() const
933 {
934 return &m_profile;
935 }
936
gopCount() const937 uint32_t gopCount() const
938 {
939 return m_params.gops;
940 }
941
gopFrameCount() const942 uint32_t gopFrameCount() const
943 {
944 return static_cast<uint32_t>(m_params.encodePattern.size());
945 }
946
gopReferenceFrameCount() const947 int gopReferenceFrameCount() const
948 {
949 int count = 0;
950 for (const auto &frame : m_params.encodePattern)
951 {
952 if (frame != B_FRAME)
953 {
954 count++;
955 }
956 }
957 return count;
958 }
959
gopCycles() const960 int gopCycles() const
961 {
962 int gopNum = 0;
963
964 for (auto &frame : m_params.encodePattern)
965 if (frame == IDR_FRAME || frame == I_FRAME)
966 gopNum++;
967
968 DE_ASSERT(gopNum);
969
970 return gopNum;
971 }
972
patternContain(FrameType type) const973 bool patternContain(FrameType type) const
974 {
975 return std::find(m_params.encodePattern.begin(), m_params.encodePattern.end(), type) !=
976 m_params.encodePattern.end();
977 }
978
frameIdx(uint32_t Idx) const979 uint32_t frameIdx(uint32_t Idx) const
980 {
981 return m_params.frameIdx[Idx];
982 }
983
frameType(uint32_t Idx) const984 FrameType frameType(uint32_t Idx) const
985 {
986 return m_params.encodePattern[Idx];
987 }
988
maxNumRefs() const989 uint8_t maxNumRefs() const
990 {
991 return m_params.spsMaxRefFrames;
992 }
993
ppsActiveRefs0() const994 uint8_t ppsActiveRefs0() const
995 {
996 return std::get<0>(m_params.ppsNumActiveRefs);
997 }
998
ppsActiveRefs1() const999 uint8_t ppsActiveRefs1() const
1000 {
1001 return std::get<1>(m_params.ppsNumActiveRefs);
1002 }
1003
shActiveRefs0(uint32_t Idx) const1004 uint8_t shActiveRefs0(uint32_t Idx) const
1005 {
1006 return std::get<0>(m_params.shNumActiveRefs[Idx]);
1007 }
1008
shActiveRefs1(uint32_t Idx) const1009 uint8_t shActiveRefs1(uint32_t Idx) const
1010 {
1011 return std::get<1>(m_params.shNumActiveRefs[Idx]);
1012 }
1013
ref0(uint32_t Idx) const1014 std::vector<uint8_t> ref0(uint32_t Idx) const
1015 {
1016 std::tuple<std::vector<uint8_t>, std::vector<uint8_t>> ref = m_params.frameReferences[Idx];
1017 return std::get<0>(ref);
1018 }
1019
ref1(uint32_t Idx) const1020 std::vector<uint8_t> ref1(uint32_t Idx) const
1021 {
1022 std::tuple<std::vector<uint8_t>, std::vector<uint8_t>> ref = m_params.frameReferences[Idx];
1023 return std::get<1>(ref);
1024 }
1025
refSlots(uint32_t Idx) const1026 std::vector<uint8_t> refSlots(uint32_t Idx) const
1027 {
1028 std::vector<uint8_t> refs = m_params.refSlots[Idx];
1029 return refs;
1030 }
1031
refsCount(uint32_t Idx) const1032 uint8_t refsCount(uint32_t Idx) const
1033 {
1034 return static_cast<uint8_t>(m_params.refSlots[Idx].size());
1035 }
1036
curSlot(uint32_t Idx) const1037 int8_t curSlot(uint32_t Idx) const
1038 {
1039 return m_params.curSlot[Idx];
1040 }
1041
frameNumber(uint32_t Idx) const1042 uint32_t frameNumber(uint32_t Idx) const
1043 {
1044 return m_params.FrameNum[Idx];
1045 }
1046
getConsecutiveBFrameCount(void) const1047 uint32_t getConsecutiveBFrameCount(void) const
1048 {
1049 uint32_t maxConsecutiveBFrameCount = 0;
1050 uint32_t currentConsecutiveBFrameCount = 0;
1051
1052 for (const auto &frame : m_params.encodePattern)
1053 {
1054 if (frame == B_FRAME)
1055 {
1056 currentConsecutiveBFrameCount++;
1057 }
1058 else
1059 {
1060 if (currentConsecutiveBFrameCount > maxConsecutiveBFrameCount)
1061 {
1062 maxConsecutiveBFrameCount = currentConsecutiveBFrameCount;
1063 }
1064 currentConsecutiveBFrameCount = 0;
1065 }
1066 }
1067
1068 return maxConsecutiveBFrameCount;
1069 }
1070
framesToCheck() const1071 size_t framesToCheck() const
1072 {
1073 return m_params.encodePattern.size() * m_params.gops;
1074 }
1075
hasOption(Option o) const1076 bool hasOption(Option o) const
1077 {
1078 return (m_params.encoderOptions & o) != 0;
1079 }
1080
requiredDeviceFlags() const1081 VideoDevice::VideoDeviceFlags requiredDeviceFlags() const
1082 {
1083 switch (m_profile.GetCodecType())
1084 {
1085 case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR:
1086 case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR:
1087 case VK_VIDEO_CODEC_OPERATION_ENCODE_AV1_BIT_KHR:
1088 {
1089 VideoDevice::VideoDeviceFlags flags = VideoDevice::VIDEO_DEVICE_FLAG_REQUIRE_SYNC2_OR_NOT_SUPPORTED;
1090
1091 if (hasOption(Option::UseStatusQueries))
1092 flags |= VideoDevice::VIDEO_DEVICE_FLAG_QUERY_WITH_STATUS_FOR_ENCODE_SUPPORT;
1093
1094 if (hasOption(Option::UseInlineQueries) || hasOption(Option::ResourcesWithoutProfiles))
1095 flags |= VideoDevice::VIDEO_DEVICE_FLAG_REQUIRE_MAINTENANCE_1;
1096
1097 if (hasOption(Option::UseDeltaMap) || hasOption(Option::UseEmphasisMap))
1098 flags |= VideoDevice::VIDEO_DEVICE_FLAG_REQUIRE_QUANTIZATION_MAP;
1099
1100 return flags;
1101 }
1102 default:
1103 tcu::die("Unsupported video codec %s\n", util::codecToName(m_profile.GetCodecType()));
1104 break;
1105 }
1106
1107 TCU_THROW(InternalError, "Unsupported codec");
1108 }
1109
extensionProperties() const1110 const VkExtensionProperties *extensionProperties() const
1111 {
1112 static const VkExtensionProperties h264StdExtensionVersion = {
1113 VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_EXTENSION_NAME, VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_SPEC_VERSION};
1114 static const VkExtensionProperties h265StdExtensionVersion = {
1115 VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_EXTENSION_NAME, VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_SPEC_VERSION};
1116
1117 switch (m_profile.GetCodecType())
1118 {
1119 case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR:
1120 return &h264StdExtensionVersion;
1121 case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR:
1122 return &h265StdExtensionVersion;
1123 default:
1124 tcu::die("Unsupported video codec %s\n", util::codecToName(m_profile.GetCodecType()));
1125 break;
1126 }
1127
1128 TCU_THROW(InternalError, "Unsupported codec");
1129 };
1130
1131 private:
1132 EncodeTestParam m_params;
1133 const ClipInfo *m_info{};
1134 VkVideoCoreProfile m_profile;
1135 };
1136
1137 struct bytestreamWriteWithStatus
1138 {
1139 uint32_t bitstreamOffset;
1140 uint32_t bitstreamWrite;
1141 VkQueryResultStatusKHR status;
1142 };
1143
processQueryPoolResults(const DeviceInterface & vk,const VkDevice device,VkQueryPool encodeQueryPool,uint32_t firstQueryId,uint32_t queryCount,VkDeviceSize & bitstreamBufferOffset,VkDeviceSize & minBitstreamBufferOffsetAlignment,const bool queryStatus)1144 bool processQueryPoolResults(const DeviceInterface &vk, const VkDevice device, VkQueryPool encodeQueryPool,
1145 uint32_t firstQueryId, uint32_t queryCount, VkDeviceSize &bitstreamBufferOffset,
1146 VkDeviceSize &minBitstreamBufferOffsetAlignment, const bool queryStatus)
1147 {
1148 bytestreamWriteWithStatus queryResultWithStatus;
1149 deMemset(&queryResultWithStatus, 0xFF, sizeof(queryResultWithStatus));
1150
1151 if (vk.getQueryPoolResults(device, encodeQueryPool, firstQueryId, queryCount, sizeof(queryResultWithStatus),
1152 &queryResultWithStatus, sizeof(queryResultWithStatus),
1153 VK_QUERY_RESULT_WITH_STATUS_BIT_KHR | VK_QUERY_RESULT_WAIT_BIT) == VK_SUCCESS)
1154 {
1155 bitstreamBufferOffset += queryResultWithStatus.bitstreamWrite;
1156
1157 // Align buffer offset after adding written data
1158 bitstreamBufferOffset = deAlign64(bitstreamBufferOffset, minBitstreamBufferOffsetAlignment);
1159
1160 if (queryStatus && queryResultWithStatus.status != VK_QUERY_RESULT_STATUS_COMPLETE_KHR)
1161 {
1162 return false;
1163 }
1164 }
1165 return true;
1166 }
1167
getH264PictureType(const FrameType frameType)1168 StdVideoH264PictureType getH264PictureType(const FrameType frameType)
1169 {
1170 switch (frameType)
1171 {
1172 case IDR_FRAME:
1173 return STD_VIDEO_H264_PICTURE_TYPE_IDR;
1174 case I_FRAME:
1175 return STD_VIDEO_H264_PICTURE_TYPE_I;
1176 case P_FRAME:
1177 return STD_VIDEO_H264_PICTURE_TYPE_P;
1178 case B_FRAME:
1179 return STD_VIDEO_H264_PICTURE_TYPE_B;
1180 default:
1181 return {};
1182 }
1183 }
1184
getH264SliceType(const FrameType frameType)1185 StdVideoH264SliceType getH264SliceType(const FrameType frameType)
1186 {
1187 switch (frameType)
1188 {
1189 case IDR_FRAME:
1190 case I_FRAME:
1191 return STD_VIDEO_H264_SLICE_TYPE_I;
1192 case P_FRAME:
1193 return STD_VIDEO_H264_SLICE_TYPE_P;
1194 case B_FRAME:
1195 return STD_VIDEO_H264_SLICE_TYPE_B;
1196 default:
1197 return {};
1198 }
1199 }
1200
getH265PictureType(const FrameType frameType)1201 StdVideoH265PictureType getH265PictureType(const FrameType frameType)
1202 {
1203 switch (frameType)
1204 {
1205 case IDR_FRAME:
1206 return STD_VIDEO_H265_PICTURE_TYPE_IDR;
1207 case I_FRAME:
1208 return STD_VIDEO_H265_PICTURE_TYPE_I;
1209 case P_FRAME:
1210 return STD_VIDEO_H265_PICTURE_TYPE_P;
1211 case B_FRAME:
1212 return STD_VIDEO_H265_PICTURE_TYPE_B;
1213 default:
1214 return {};
1215 }
1216 }
1217
getH265SliceType(const FrameType frameType)1218 StdVideoH265SliceType getH265SliceType(const FrameType frameType)
1219 {
1220 switch (frameType)
1221 {
1222 case IDR_FRAME:
1223 case I_FRAME:
1224 return STD_VIDEO_H265_SLICE_TYPE_I;
1225 case P_FRAME:
1226 return STD_VIDEO_H265_SLICE_TYPE_P;
1227 case B_FRAME:
1228 return STD_VIDEO_H265_SLICE_TYPE_B;
1229 default:
1230 return {};
1231 }
1232 }
1233
getCodecDecodeOperationFromEncode(VkVideoCodecOperationFlagBitsKHR encodeOperation)1234 VkVideoCodecOperationFlagBitsKHR getCodecDecodeOperationFromEncode(VkVideoCodecOperationFlagBitsKHR encodeOperation)
1235 {
1236 switch (encodeOperation)
1237 {
1238 case VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR:
1239 return VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR;
1240 case VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR:
1241 return VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR;
1242 default:
1243 return VK_VIDEO_CODEC_OPERATION_NONE_KHR;
1244 }
1245 }
1246
1247 template <typename T>
fillBuffer(const DeviceInterface & vk,const VkDevice device,Allocation & bufferAlloc,const std::vector<T> & data,VkDeviceSize nonCoherentAtomSize,VkDeviceSize mappedSize,VkDeviceSize dataOffset=0)1248 void fillBuffer(const DeviceInterface &vk, const VkDevice device, Allocation &bufferAlloc, const std::vector<T> &data,
1249 VkDeviceSize nonCoherentAtomSize, VkDeviceSize mappedSize, VkDeviceSize dataOffset = 0)
1250 {
1251 VkDeviceSize dataSize = data.size() * sizeof(T);
1252 VkDeviceSize roundedSize = ((dataSize + nonCoherentAtomSize - 1) / nonCoherentAtomSize) * nonCoherentAtomSize;
1253
1254 VkDeviceSize flushSize;
1255 if (dataOffset + roundedSize > mappedSize)
1256 {
1257 flushSize = VK_WHOLE_SIZE;
1258 }
1259 else
1260 {
1261 flushSize = roundedSize;
1262 }
1263
1264 const VkMappedMemoryRange memRange = {
1265 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
1266 nullptr, // const void* pNext;
1267 bufferAlloc.getMemory(), // VkDeviceMemory memory;
1268 bufferAlloc.getOffset() + dataOffset, // VkDeviceSize offset;
1269 flushSize // VkDeviceSize size;
1270 };
1271
1272 T *hostPtr = static_cast<T *>(bufferAlloc.getHostPtr());
1273 memcpy(hostPtr + dataOffset, data.data(), data.size() * sizeof(T));
1274
1275 VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &memRange));
1276 }
1277
1278 template <typename T>
createQuantizationPatternImage(VkExtent2D quantizationMapExtent,T leftSideQp,T rightSideQp)1279 vector<T> createQuantizationPatternImage(VkExtent2D quantizationMapExtent, T leftSideQp, T rightSideQp)
1280 {
1281 size_t totalPixels = quantizationMapExtent.width * quantizationMapExtent.height;
1282 vector<T> quantizationMap(totalPixels);
1283
1284 uint32_t midPoint = quantizationMapExtent.width / 2;
1285
1286 for (uint32_t y = 0; y < quantizationMapExtent.height; ++y)
1287 {
1288 for (uint32_t x = 0; x < quantizationMapExtent.width; ++x)
1289 {
1290 if (x < midPoint)
1291 {
1292 quantizationMap[y * quantizationMapExtent.width + x] = leftSideQp;
1293 }
1294 else
1295 {
1296 quantizationMap[y * quantizationMapExtent.width + x] = rightSideQp;
1297 }
1298 }
1299 }
1300
1301 return quantizationMap;
1302 }
1303
copyBufferToImage(const DeviceInterface & vk,VkDevice device,VkQueue queue,uint32_t queueFamilyIndex,const VkBuffer & buffer,VkDeviceSize bufferSize,const VkExtent2D & imageSize,uint32_t arrayLayers,VkImage destImage)1304 void copyBufferToImage(const DeviceInterface &vk, VkDevice device, VkQueue queue, uint32_t queueFamilyIndex,
1305 const VkBuffer &buffer, VkDeviceSize bufferSize, const VkExtent2D &imageSize,
1306 uint32_t arrayLayers, VkImage destImage)
1307 {
1308 Move<VkCommandPool> cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1309 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1310 Move<VkFence> fence = createFence(vk, device);
1311 VkImageLayout destImageLayout = VK_IMAGE_LAYOUT_VIDEO_ENCODE_QUANTIZATION_MAP_KHR;
1312 VkPipelineStageFlags destImageDstStageFlags = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
1313 VkAccessFlags finalAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT;
1314
1315 const VkCommandBufferBeginInfo cmdBufferBeginInfo = {
1316 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1317 DE_NULL, // const void* pNext;
1318 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
1319 (const VkCommandBufferInheritanceInfo *)DE_NULL,
1320 };
1321
1322 const VkBufferImageCopy copyRegion = {
1323 0, // VkDeviceSize bufferOffset
1324 0, // uint32_t bufferRowLength
1325 0, // uint32_t bufferImageHeight
1326 {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, arrayLayers}, // VkImageSubresourceLayers imageSubresource
1327 {0, 0, 0}, // VkOffset3D imageOffset
1328 {imageSize.width, imageSize.height, 1} // VkExtent3D imageExtent
1329 };
1330
1331 // Barriers for copying buffer to image
1332 const VkBufferMemoryBarrier preBufferBarrier =
1333 makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
1334 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1335 buffer, // VkBuffer buffer;
1336 0u, // VkDeviceSize offset;
1337 bufferSize // VkDeviceSize size;
1338 );
1339
1340 const VkImageSubresourceRange subresourceRange{
1341 // VkImageSubresourceRange subresourceRange;
1342 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
1343 0u, // uint32_t baseMipLevel;
1344 1u, // uint32_t mipLevels;
1345 0u, // uint32_t baseArraySlice;
1346 arrayLayers // uint32_t arraySize;
1347 };
1348
1349 const VkImageMemoryBarrier preImageBarrier =
1350 makeImageMemoryBarrier(0u, // VkAccessFlags srcAccessMask;
1351 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1352 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1353 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
1354 destImage, // VkImage image;
1355 subresourceRange // VkImageSubresourceRange subresourceRange;
1356 );
1357
1358 const VkImageMemoryBarrier postImageBarrier =
1359 makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1360 finalAccessMask, // VkAccessFlags dstAccessMask;
1361 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1362 destImageLayout, // VkImageLayout newLayout;
1363 destImage, // VkImage image;
1364 subresourceRange // VkImageSubresourceRange subresourceRange;
1365 );
1366
1367 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
1368 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
1369 0, (const VkMemoryBarrier *)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
1370 vk.cmdCopyBufferToImage(*cmdBuffer, buffer, destImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
1371 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, destImageDstStageFlags, (VkDependencyFlags)0, 0,
1372 (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL, 1,
1373 &postImageBarrier);
1374 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
1375
1376 const VkPipelineStageFlags pipelineStageFlags = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
1377
1378 const VkSubmitInfo submitInfo = {
1379 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
1380 DE_NULL, // const void* pNext;
1381 0u, // uint32_t waitSemaphoreCount;
1382 DE_NULL, // const VkSemaphore* pWaitSemaphores;
1383 &pipelineStageFlags, // const VkPipelineStageFlags* pWaitDstStageMask;
1384 1u, // uint32_t commandBufferCount;
1385 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
1386 0u, // uint32_t signalSemaphoreCount;
1387 DE_NULL // const VkSemaphore* pSignalSemaphores;
1388 };
1389
1390 try
1391 {
1392 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1393 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull)));
1394 }
1395 catch (...)
1396 {
1397 VK_CHECK(vk.deviceWaitIdle(device));
1398 throw;
1399 }
1400 }
1401
makeVideoPictureResource(const VkExtent2D & codedExtent,uint32_t baseArrayLayer,const VkImageView imageView,const void * pNext=nullptr)1402 VkVideoPictureResourceInfoKHR makeVideoPictureResource(const VkExtent2D &codedExtent, uint32_t baseArrayLayer,
1403 const VkImageView imageView, const void *pNext = nullptr)
1404 {
1405 const VkVideoPictureResourceInfoKHR videoPictureResource = {
1406 VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR, // VkStructureType sType;
1407 pNext, // const void* pNext;
1408 {0, 0}, // VkOffset2D codedOffset;
1409 codedExtent, // VkExtent2D codedExtent;
1410 baseArrayLayer, // uint32_t baseArrayLayer;
1411 imageView, // VkImageView imageViewBinding;
1412 };
1413
1414 return videoPictureResource;
1415 }
1416
makeVideoReferenceSlot(int32_t slotIndex,const VkVideoPictureResourceInfoKHR * pPictureResource,const void * pNext=nullptr)1417 VkVideoReferenceSlotInfoKHR makeVideoReferenceSlot(int32_t slotIndex,
1418 const VkVideoPictureResourceInfoKHR *pPictureResource,
1419 const void *pNext = nullptr)
1420 {
1421 const VkVideoReferenceSlotInfoKHR videoReferenceSlotKHR = {
1422 VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR, // VkStructureType sType;
1423 pNext, // const void* pNext;
1424 slotIndex, // int32_t slotIndex;
1425 pPictureResource, // const VkVideoPictureResourceInfoKHR* pPictureResource;
1426 };
1427
1428 return videoReferenceSlotKHR;
1429 }
1430
1431 // Vulkan video is not supported on android platform
1432 // all external libraries, helper functions and test instances has been excluded
1433 #ifdef DE_BUILD_VIDEO
1434
1435 #endif // DE_BUILD_VIDEO
1436
1437 class VideoEncodeTestInstance : public VideoBaseTestInstance
1438 {
1439 public:
1440 VideoEncodeTestInstance(Context &context, const TestDefinition *testDefinition);
1441 ~VideoEncodeTestInstance(void);
1442
1443 tcu::TestStatus iterate(void);
1444
1445 protected:
1446 Move<VkQueryPool> createEncodeVideoQueries(const DeviceInterface &videoDeviceDriver, VkDevice device,
1447 uint32_t numQueries, const VkVideoProfileInfoKHR *pVideoProfile);
1448
1449 VkFormat checkImageFormat(VkImageUsageFlags flags, const VkVideoProfileListInfoKHR *videoProfileList,
1450 const VkFormat requiredFormat);
1451
1452 bool checkQueryResultSupport(void);
1453
1454 void printBuffer(const DeviceInterface &videoDeviceDriver, VkDevice device, const BufferWithMemory &buffer,
1455 VkDeviceSize bufferSize);
1456
1457 VkFormat getResultImageFormat(void);
1458
1459 const TestDefinition *m_testDefinition;
1460 };
1461
VideoEncodeTestInstance(Context & context,const TestDefinition * testDefinition)1462 VideoEncodeTestInstance::VideoEncodeTestInstance(Context &context, const TestDefinition *testDefinition)
1463 : VideoBaseTestInstance(context)
1464 , m_testDefinition(testDefinition)
1465 {
1466 }
1467
~VideoEncodeTestInstance(void)1468 VideoEncodeTestInstance::~VideoEncodeTestInstance(void)
1469 {
1470 }
1471
createEncodeVideoQueries(const DeviceInterface & videoDeviceDriver,VkDevice device,uint32_t numQueries,const VkVideoProfileInfoKHR * pVideoProfile)1472 Move<VkQueryPool> VideoEncodeTestInstance::createEncodeVideoQueries(const DeviceInterface &videoDeviceDriver,
1473 VkDevice device, uint32_t numQueries,
1474 const VkVideoProfileInfoKHR *pVideoProfile)
1475 {
1476
1477 VkQueryPoolVideoEncodeFeedbackCreateInfoKHR encodeFeedbackQueryType = {
1478 VK_STRUCTURE_TYPE_QUERY_POOL_VIDEO_ENCODE_FEEDBACK_CREATE_INFO_KHR, // VkStructureType sType;
1479 pVideoProfile, // const void* pNext;
1480 VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR |
1481 VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR, // VkVideoEncodeFeedbackFlagsKHR encodeFeedbackFlags;
1482 };
1483
1484 const VkQueryPoolCreateInfo queryPoolCreateInfo = {
1485 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // VkStructureType sType;
1486 static_cast<const void *>(&encodeFeedbackQueryType), // const void* pNext;
1487 0, // VkQueryPoolCreateFlags flags;
1488 VK_QUERY_TYPE_VIDEO_ENCODE_FEEDBACK_KHR, // VkQueryType queryType;
1489 numQueries, // uint32_t queryCount;
1490 0, // VkQueryPipelineStatisticFlags pipelineStatistics;
1491 };
1492
1493 return createQueryPool(videoDeviceDriver, device, &queryPoolCreateInfo);
1494 }
1495
checkImageFormat(VkImageUsageFlags flags,const VkVideoProfileListInfoKHR * videoProfileList,const VkFormat requiredFormat)1496 VkFormat VideoEncodeTestInstance::checkImageFormat(VkImageUsageFlags flags,
1497 const VkVideoProfileListInfoKHR *videoProfileList,
1498 const VkFormat requiredFormat)
1499 {
1500 const InstanceInterface &vki = m_context.getInstanceInterface();
1501 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
1502 MovePtr<vector<VkFormat>> supportedFormats = getSupportedFormats(vki, physicalDevice, flags, videoProfileList);
1503
1504 if (!supportedFormats || supportedFormats->empty())
1505 TCU_THROW(NotSupportedError, "No supported picture formats");
1506
1507 for (const auto &supportedFormat : *supportedFormats)
1508 if (supportedFormat == requiredFormat)
1509 return requiredFormat;
1510
1511 TCU_THROW(NotSupportedError, "Failed to find required picture format");
1512 }
1513
checkQueryResultSupport(void)1514 bool VideoEncodeTestInstance::checkQueryResultSupport(void)
1515 {
1516 uint32_t count = 0;
1517 auto &vkif = m_context.getInstanceInterface();
1518 vkif.getPhysicalDeviceQueueFamilyProperties2(m_context.getPhysicalDevice(), &count, nullptr);
1519 std::vector<VkQueueFamilyProperties2> queues(count);
1520 std::vector<VkQueueFamilyVideoPropertiesKHR> videoQueues(count);
1521 std::vector<VkQueueFamilyQueryResultStatusPropertiesKHR> queryResultStatus(count);
1522
1523 for (std::vector<VkQueueFamilyProperties2>::size_type i = 0; i < queues.size(); i++)
1524 {
1525 queues[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
1526 videoQueues[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR;
1527 queues[i].pNext = &videoQueues[i];
1528 queryResultStatus[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_QUERY_RESULT_STATUS_PROPERTIES_KHR;
1529 videoQueues[i].pNext = &queryResultStatus[i];
1530 }
1531 vkif.getPhysicalDeviceQueueFamilyProperties2(m_context.getPhysicalDevice(), &count, queues.data());
1532
1533 for (auto &property : queryResultStatus)
1534 {
1535 if (property.queryResultStatusSupport)
1536 return true;
1537 }
1538
1539 return false;
1540 }
1541
1542 #if STREAM_DUMP_DEBUG
saveBufferAsFile(const BufferWithMemory & buffer,VkDeviceSize bufferSize,const string & outputFileName)1543 bool saveBufferAsFile(const BufferWithMemory &buffer, VkDeviceSize bufferSize, const string &outputFileName)
1544 {
1545 auto &bufferAlloc = buffer.getAllocation();
1546 const auto dataPtr = reinterpret_cast<uint8_t *>(bufferAlloc.getHostPtr());
1547 ofstream outFile(outputFileName, ios::binary | ios::out);
1548
1549 if (!outFile.is_open())
1550 {
1551 cerr << "Error: Unable to open output file '" << outputFileName << "'." << endl;
1552 return false;
1553 }
1554
1555 outFile.write(reinterpret_cast<char *>(dataPtr), static_cast<std::streamsize>(bufferSize));
1556 outFile.close();
1557
1558 return true;
1559 }
1560
1561 #endif
1562
iterate(void)1563 tcu::TestStatus VideoEncodeTestInstance::iterate(void)
1564 {
1565 const VkVideoCodecOperationFlagBitsKHR videoCodecEncodeOperation = m_testDefinition->getCodecOperation();
1566 const VkVideoCodecOperationFlagBitsKHR videoCodecDecodeOperation =
1567 getCodecDecodeOperationFromEncode(videoCodecEncodeOperation);
1568
1569 const uint32_t gopCount = m_testDefinition->gopCount();
1570 const uint32_t gopFrameCount = m_testDefinition->gopFrameCount();
1571 const uint32_t dpbSlots = m_testDefinition->gopReferenceFrameCount();
1572
1573 const bool queryStatus = m_testDefinition->hasOption(Option::UseStatusQueries);
1574 const bool useInlineQueries = m_testDefinition->hasOption(Option::UseInlineQueries);
1575 const bool resourcesWithoutProfiles = m_testDefinition->hasOption(Option::ResourcesWithoutProfiles);
1576 const bool resolutionChange = m_testDefinition->hasOption(Option::ResolutionChange);
1577 const bool swapOrder = m_testDefinition->hasOption(Option::SwapOrder);
1578 const bool useVariableBitrate = m_testDefinition->hasOption(Option::UseVariableBitrateControl);
1579 const bool useConstantBitrate = m_testDefinition->hasOption(Option::UseConstantBitrateControl);
1580 const bool customEncodeUsage = m_testDefinition->hasOption(Option::UseEncodeUsage);
1581 const bool useQualityLevel = m_testDefinition->hasOption(Option::UseQualityLevel);
1582 const bool useDeltaMap = m_testDefinition->hasOption(Option::UseDeltaMap);
1583 const bool useEmphasisMap = m_testDefinition->hasOption(Option::UseEmphasisMap);
1584 const bool disableRateControl = m_testDefinition->hasOption(Option::DisableRateControl);
1585
1586 const bool activeRateControl = useVariableBitrate || useConstantBitrate;
1587
1588 const int32_t constQp = 28;
1589 const int32_t maxQpValue = disableRateControl || activeRateControl ? 42 : 51;
1590 const int32_t minQpValue = 0;
1591 const float minEmphasisQpValue = 0.0f;
1592 const float maxEmphasisQpValue = 1.0f;
1593 int32_t minQpDelta = 0;
1594 int32_t maxQpDelta = 0;
1595
1596 const VkExtent2D codedExtent = {m_testDefinition->getClipWidth(), m_testDefinition->getClipHeight()};
1597
1598 const MovePtr<VkVideoEncodeUsageInfoKHR> encodeUsageInfo = getEncodeUsageInfo(
1599 m_testDefinition->getEncodeProfileExtension(),
1600 customEncodeUsage ? VK_VIDEO_ENCODE_USAGE_STREAMING_BIT_KHR : VK_VIDEO_ENCODE_USAGE_DEFAULT_KHR,
1601 customEncodeUsage ? VK_VIDEO_ENCODE_CONTENT_DESKTOP_BIT_KHR : VK_VIDEO_ENCODE_CONTENT_DEFAULT_KHR,
1602 customEncodeUsage ? VK_VIDEO_ENCODE_TUNING_MODE_HIGH_QUALITY_KHR : VK_VIDEO_ENCODE_TUNING_MODE_DEFAULT_KHR);
1603
1604 const MovePtr<VkVideoProfileInfoKHR> videoEncodeProfile =
1605 getVideoProfile(videoCodecEncodeOperation, encodeUsageInfo.get());
1606 const MovePtr<VkVideoProfileInfoKHR> videoDecodeProfile =
1607 getVideoProfile(videoCodecDecodeOperation, m_testDefinition->getDecodeProfileExtension());
1608
1609 const MovePtr<VkVideoProfileListInfoKHR> videoEncodeProfileList = getVideoProfileList(videoEncodeProfile.get(), 1);
1610
1611 const VkFormat imageFormat = checkImageFormat(VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR, videoEncodeProfileList.get(),
1612 VK_FORMAT_G8_B8R8_2PLANE_420_UNORM);
1613 const VkFormat dpbImageFormat = checkImageFormat(VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR,
1614 videoEncodeProfileList.get(), VK_FORMAT_G8_B8R8_2PLANE_420_UNORM);
1615
1616 const VideoDevice::VideoDeviceFlags videoDeviceFlags = m_testDefinition->requiredDeviceFlags();
1617
1618 if (queryStatus && !checkQueryResultSupport())
1619 TCU_THROW(NotSupportedError, "Implementation does not support query status");
1620
1621 const InstanceInterface &vki = m_context.getInstanceInterface();
1622 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
1623 const VkDevice videoDevice =
1624 getDeviceSupportingQueue(VK_QUEUE_VIDEO_ENCODE_BIT_KHR | VK_QUEUE_VIDEO_DECODE_BIT_KHR | VK_QUEUE_TRANSFER_BIT,
1625 videoCodecEncodeOperation | videoCodecDecodeOperation, videoDeviceFlags);
1626 const DeviceInterface &videoDeviceDriver = getDeviceDriver();
1627
1628 const uint32_t encodeQueueFamilyIndex = getQueueFamilyIndexEncode();
1629 const uint32_t decodeQueueFamilyIndex = getQueueFamilyIndexDecode();
1630 const uint32_t transferQueueFamilyIndex = getQueueFamilyIndexTransfer();
1631
1632 const VkQueue encodeQueue = getDeviceQueue(videoDeviceDriver, videoDevice, encodeQueueFamilyIndex, 0u);
1633 const VkQueue decodeQueue = getDeviceQueue(videoDeviceDriver, videoDevice, decodeQueueFamilyIndex, 0u);
1634 const VkQueue transferQueue = getDeviceQueue(videoDeviceDriver, videoDevice, transferQueueFamilyIndex, 0u);
1635
1636 const MovePtr<VkVideoEncodeH264QuantizationMapCapabilitiesKHR> H264QuantizationMapCapabilities =
1637 getVideoEncodeH264QuantizationMapCapabilities();
1638 const MovePtr<VkVideoEncodeH265QuantizationMapCapabilitiesKHR> H265QuantizationMapCapabilities =
1639 getVideoEncodeH265QuantizationMapCapabilities();
1640
1641 const MovePtr<VkVideoEncodeH264CapabilitiesKHR> videoH264CapabilitiesExtension =
1642 getVideoCapabilitiesExtensionH264E(H264QuantizationMapCapabilities.get());
1643 const MovePtr<VkVideoEncodeH265CapabilitiesKHR> videoH265CapabilitiesExtension =
1644 getVideoCapabilitiesExtensionH265E(H265QuantizationMapCapabilities.get());
1645
1646 void *videoCapabilitiesExtensionPtr = NULL;
1647
1648 if (m_testDefinition->getProfile()->IsH264())
1649 {
1650 videoCapabilitiesExtensionPtr = static_cast<void *>(videoH264CapabilitiesExtension.get());
1651 }
1652 else if (m_testDefinition->getProfile()->IsH265())
1653 {
1654 videoCapabilitiesExtensionPtr = static_cast<void *>(videoH265CapabilitiesExtension.get());
1655 }
1656 DE_ASSERT(videoCapabilitiesExtensionPtr);
1657
1658 const MovePtr<VkVideoEncodeCapabilitiesKHR> videoEncodeCapabilities =
1659 getVideoEncodeCapabilities(videoCapabilitiesExtensionPtr);
1660 const MovePtr<VkVideoCapabilitiesKHR> videoCapabilities =
1661 getVideoCapabilities(vki, physicalDevice, videoEncodeProfile.get(), videoEncodeCapabilities.get());
1662
1663 DE_ASSERT(videoEncodeCapabilities->supportedEncodeFeedbackFlags &
1664 VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR);
1665
1666 if (useDeltaMap)
1667 {
1668 if (!(videoEncodeCapabilities->flags & VK_VIDEO_ENCODE_CAPABILITY_QUANTIZATION_DELTA_MAP_BIT_KHR))
1669 {
1670 TCU_THROW(NotSupportedError, "Implementation does not support quantization delta map");
1671 }
1672 }
1673 if (useEmphasisMap)
1674 {
1675 if (!(videoEncodeCapabilities->flags & VK_VIDEO_ENCODE_CAPABILITY_EMPHASIS_MAP_BIT_KHR))
1676 {
1677 TCU_THROW(NotSupportedError, "Implementation does not support emphasis map");
1678 }
1679 }
1680
1681 if (m_testDefinition->getProfile()->IsH264())
1682 {
1683 minQpDelta = H264QuantizationMapCapabilities->minQpDelta;
1684 maxQpDelta = H264QuantizationMapCapabilities->maxQpDelta;
1685 }
1686 else if (m_testDefinition->getProfile()->IsH265())
1687 {
1688 minQpDelta = H265QuantizationMapCapabilities->minQpDelta;
1689 maxQpDelta = H265QuantizationMapCapabilities->maxQpDelta;
1690 }
1691
1692 // Check support for P and B frames
1693 if (m_testDefinition->getProfile()->IsH264())
1694 {
1695 bool minPReferenceCount = videoH264CapabilitiesExtension->maxPPictureL0ReferenceCount > 0;
1696 bool minBReferenceCount = videoH264CapabilitiesExtension->maxBPictureL0ReferenceCount > 0;
1697 bool minL1ReferenceCount = videoH264CapabilitiesExtension->maxL1ReferenceCount > 0;
1698
1699 if (m_testDefinition->patternContain(P_FRAME) && !minPReferenceCount)
1700 {
1701 TCU_THROW(NotSupportedError, "Implementation does not support H264 P frames encoding");
1702 }
1703 else if (m_testDefinition->patternContain(B_FRAME) && !minBReferenceCount && !minL1ReferenceCount)
1704 {
1705 TCU_THROW(NotSupportedError, "Implementation does not support H264 B frames encoding");
1706 }
1707 }
1708 else if (m_testDefinition->getProfile()->IsH265())
1709 {
1710 bool minPReferenceCount = videoH265CapabilitiesExtension->maxPPictureL0ReferenceCount > 0;
1711 bool minBReferenceCount = videoH265CapabilitiesExtension->maxBPictureL0ReferenceCount > 0;
1712 bool minL1ReferenceCount = videoH265CapabilitiesExtension->maxL1ReferenceCount > 0;
1713
1714 if (m_testDefinition->patternContain(P_FRAME) && !minPReferenceCount)
1715 {
1716 TCU_THROW(NotSupportedError, "Implementation does not support H265 P frames encoding");
1717 }
1718 else if (m_testDefinition->patternContain(B_FRAME) && !minBReferenceCount && !minL1ReferenceCount)
1719 {
1720 TCU_THROW(NotSupportedError, "Implementation does not support H265 B frames encoding");
1721 }
1722 }
1723
1724 // Check support for bitrate control
1725 if (m_testDefinition->hasOption(Option::UseVariableBitrateControl))
1726 {
1727 if ((videoEncodeCapabilities->rateControlModes & VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR) == 0)
1728 TCU_THROW(NotSupportedError, "Implementation does not support variable bitrate control");
1729
1730 DE_ASSERT(videoEncodeCapabilities->maxBitrate > 0);
1731 }
1732 else if (m_testDefinition->hasOption(Option::UseConstantBitrateControl))
1733 {
1734 if ((videoEncodeCapabilities->rateControlModes & VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR) == 0)
1735 TCU_THROW(NotSupportedError, "Implementation does not support constant bitrate control");
1736
1737 DE_ASSERT(videoEncodeCapabilities->maxBitrate > 0);
1738 }
1739
1740 VkDeviceSize bitstreamBufferOffset = 0u;
1741 VkDeviceSize minBitstreamBufferOffsetAlignment = videoCapabilities->minBitstreamBufferOffsetAlignment;
1742 VkDeviceSize nonCoherentAtomSize = m_context.getDeviceProperties().limits.nonCoherentAtomSize;
1743
1744 Allocator &allocator = getAllocator();
1745
1746 DE_ASSERT(videoCapabilities->maxDpbSlots >= dpbSlots);
1747
1748 VkVideoSessionCreateFlagsKHR videoSessionFlags = 0;
1749
1750 if (useInlineQueries)
1751 videoSessionFlags |= VK_VIDEO_SESSION_CREATE_INLINE_QUERIES_BIT_KHR;
1752 if (useDeltaMap)
1753 videoSessionFlags |= VK_VIDEO_SESSION_CREATE_ALLOW_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR;
1754 if (useEmphasisMap)
1755 videoSessionFlags |= VK_VIDEO_SESSION_CREATE_ALLOW_ENCODE_EMPHASIS_MAP_BIT_KHR;
1756
1757 const MovePtr<VkVideoSessionCreateInfoKHR> videoEncodeSessionCreateInfo =
1758 getVideoSessionCreateInfo(encodeQueueFamilyIndex, videoSessionFlags, videoEncodeProfile.get(), codedExtent,
1759 imageFormat, dpbImageFormat, dpbSlots, videoCapabilities->maxActiveReferencePictures);
1760
1761 const Move<VkVideoSessionKHR> videoEncodeSession =
1762 createVideoSessionKHR(videoDeviceDriver, videoDevice, videoEncodeSessionCreateInfo.get());
1763 const vector<AllocationPtr> encodeAllocation =
1764 getAndBindVideoSessionMemory(videoDeviceDriver, videoDevice, *videoEncodeSession, allocator);
1765
1766 uint8_t quantizationMapCount = useDeltaMap ? 3 : 2;
1767 VkFormat quantizationImageFormat = VK_FORMAT_R8_SNORM;
1768 VkImageTiling quantizationImageTiling = VK_IMAGE_TILING_OPTIMAL;
1769 VkExtent2D quantizationMapExtent = {0, 0};
1770 VkExtent2D quantizationMapTexelSize = {0, 0};
1771
1772 std::vector<std::unique_ptr<const ImageWithMemory>> quantizationMapImages;
1773 std::vector<std::unique_ptr<const Move<VkImageView>>> quantizationMapImageViews;
1774
1775 if (useDeltaMap || useEmphasisMap)
1776 {
1777 // Query quantization map capabilities
1778 uint32_t videoFormatPropertiesCount = 0u;
1779
1780 VkImageUsageFlags quantizationImageUsageFlags =
1781 (useDeltaMap ? VK_IMAGE_USAGE_VIDEO_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR :
1782 VK_IMAGE_USAGE_VIDEO_ENCODE_EMPHASIS_MAP_BIT_KHR) |
1783 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1784
1785 const VkPhysicalDeviceVideoFormatInfoKHR videoFormatInfo = {
1786 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR, // VkStructureType sType;
1787 videoEncodeProfileList.get(), // const void* pNext;
1788 quantizationImageUsageFlags, // VkImageUsageFlags imageUsage;
1789 };
1790
1791 VkVideoFormatPropertiesKHR videoFormatPropertiesKHR = {};
1792 videoFormatPropertiesKHR.sType = VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR;
1793 videoFormatPropertiesKHR.pNext = DE_NULL;
1794
1795 VkVideoFormatQuantizationMapPropertiesKHR quantizationMapPropertiesKHR = {};
1796 quantizationMapPropertiesKHR.sType = VK_STRUCTURE_TYPE_VIDEO_FORMAT_QUANTIZATION_MAP_PROPERTIES_KHR;
1797 quantizationMapPropertiesKHR.pNext = DE_NULL;
1798
1799 VkVideoFormatH265QuantizationMapPropertiesKHR H265QuantizationMapFormatProperty = {};
1800 H265QuantizationMapFormatProperty.sType = VK_STRUCTURE_TYPE_VIDEO_FORMAT_H265_QUANTIZATION_MAP_PROPERTIES_KHR;
1801 H265QuantizationMapFormatProperty.pNext = DE_NULL;
1802
1803 vector<VkVideoFormatPropertiesKHR> videoFormatProperties;
1804 vector<VkVideoFormatQuantizationMapPropertiesKHR> quantizationMapProperties;
1805 vector<VkVideoFormatH265QuantizationMapPropertiesKHR> H265quantizationMapFormatProperties;
1806 de::MovePtr<vector<VkFormat>> result;
1807
1808 VK_CHECK(vki.getPhysicalDeviceVideoFormatPropertiesKHR(physicalDevice, &videoFormatInfo,
1809 &videoFormatPropertiesCount, DE_NULL));
1810
1811 videoFormatProperties.resize(videoFormatPropertiesCount, videoFormatPropertiesKHR);
1812 quantizationMapProperties.resize(videoFormatPropertiesCount, quantizationMapPropertiesKHR);
1813 H265quantizationMapFormatProperties.resize(videoFormatPropertiesCount, H265QuantizationMapFormatProperty);
1814
1815 for (uint32_t i = 0; i < videoFormatPropertiesCount; ++i)
1816 {
1817 videoFormatProperties[i].pNext = &quantizationMapProperties[i];
1818 if (m_testDefinition->getProfile()->IsH265())
1819 {
1820 quantizationMapProperties[i].pNext = &H265quantizationMapFormatProperties[i];
1821 }
1822 }
1823
1824 VK_CHECK(vki.getPhysicalDeviceVideoFormatPropertiesKHR(
1825 physicalDevice, &videoFormatInfo, &videoFormatPropertiesCount, videoFormatProperties.data()));
1826
1827 // Pick first available quantization map format and properties
1828 quantizationImageFormat = videoFormatProperties[0].format;
1829 quantizationImageTiling = videoFormatProperties[0].imageTiling;
1830 quantizationMapTexelSize = quantizationMapProperties[0].quantizationMapTexelSize;
1831
1832 DE_ASSERT(quantizationMapTexelSize.width > 0 && quantizationMapTexelSize.height > 0);
1833
1834 quantizationMapExtent = {static_cast<uint32_t>(std::ceil(static_cast<float>(codedExtent.width) /
1835 static_cast<float>(quantizationMapTexelSize.width))),
1836 static_cast<uint32_t>(std::ceil(static_cast<float>(codedExtent.height) /
1837 static_cast<float>(quantizationMapTexelSize.height)))};
1838
1839 const VkImageUsageFlags quantizationMapImageUsage =
1840 (useDeltaMap ? VK_IMAGE_USAGE_VIDEO_ENCODE_QUANTIZATION_DELTA_MAP_BIT_KHR :
1841 VK_IMAGE_USAGE_VIDEO_ENCODE_EMPHASIS_MAP_BIT_KHR) |
1842 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1843 const VkImageCreateInfo quantizationMapImageCreateInfo = makeImageCreateInfo(
1844 quantizationImageFormat, quantizationMapExtent, 0, &encodeQueueFamilyIndex, quantizationMapImageUsage,
1845 videoEncodeProfileList.get(), 1U, VK_IMAGE_LAYOUT_UNDEFINED, quantizationImageTiling);
1846
1847 const vector<uint32_t> transaferQueueFamilyIndices(1u, transferQueueFamilyIndex);
1848
1849 const VkBufferUsageFlags quantizationMapBufferUsageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
1850 const VkDeviceSize quantizationMapBufferSize =
1851 getBufferSize(quantizationImageFormat, quantizationMapExtent.width, quantizationMapExtent.height);
1852
1853 const VkBufferCreateInfo quantizationMapBufferCreateInfo = makeBufferCreateInfo(
1854 quantizationMapBufferSize, quantizationMapBufferUsageFlags, transaferQueueFamilyIndices, 0, DE_NULL);
1855
1856 BufferWithMemory quantizationMapBuffer(videoDeviceDriver, videoDevice, getAllocator(),
1857 quantizationMapBufferCreateInfo,
1858 MemoryRequirement::Local | MemoryRequirement::HostVisible);
1859
1860 Allocation &quantizationMapBufferAlloc = quantizationMapBuffer.getAllocation();
1861 void *quantizationMapBufferHostPtr = quantizationMapBufferAlloc.getHostPtr();
1862
1863 // Calculate QP values for each image sides, the type of values is based on the quantization map format and adnotated by the index
1864 auto calculateMapValues = [minQpValue, constQp, minQpDelta, maxQpValue, maxQpDelta, minEmphasisQpValue,
1865 maxEmphasisQpValue](auto idx, QuantizationMap mapType) -> auto
1866 {
1867 using T = decltype(idx);
1868 T leftSideValue = T{0};
1869 T rightSideValue = T{0};
1870
1871 if (mapType == QM_DELTA)
1872 {
1873 // Quantization map provided, constant Qp set to 26
1874 if (idx == 0)
1875 {
1876 leftSideValue = rightSideValue = static_cast<T>(std::max(minQpValue - constQp, minQpDelta));
1877 }
1878 // Quantization map provided, constant Qp set to 26
1879 else if (idx == 1)
1880 {
1881 leftSideValue = rightSideValue = static_cast<T>(std::min(maxQpValue - constQp, maxQpDelta));
1882 }
1883 // Only third frame will receive different quantization values for both sides
1884 else if (idx == 2)
1885 {
1886 leftSideValue = static_cast<T>(std::max(minQpValue - constQp, minQpDelta));
1887 rightSideValue = static_cast<T>(std::min(maxQpValue - constQp, maxQpDelta));
1888 }
1889 }
1890 else if (mapType == QM_EMPHASIS)
1891 {
1892 // Only second frame will receive different quantization values for both sides
1893 if (idx == 1)
1894 {
1895 if constexpr (std::is_same_v<T, uint8_t>)
1896 {
1897 leftSideValue = static_cast<T>(minEmphasisQpValue * 255.0f);
1898 rightSideValue = static_cast<T>(maxEmphasisQpValue * 255.0f);
1899 }
1900 else
1901 {
1902 leftSideValue = static_cast<T>(minEmphasisQpValue);
1903 rightSideValue = static_cast<T>(maxEmphasisQpValue);
1904 }
1905 }
1906 }
1907
1908 return std::make_tuple(leftSideValue, rightSideValue);
1909 };
1910
1911 // Create quantization map image
1912 auto processQuantizationMapImage = [&](auto leftSideQp, auto rightSideQp)
1913 {
1914 using T = decltype(leftSideQp);
1915
1916 auto quantizationMapImageData =
1917 createQuantizationPatternImage<T>(quantizationMapExtent, leftSideQp, rightSideQp);
1918
1919 std::unique_ptr<const ImageWithMemory> quantizationMapImage(
1920 new ImageWithMemory(videoDeviceDriver, videoDevice, getAllocator(), quantizationMapImageCreateInfo,
1921 MemoryRequirement::Any));
1922 std::unique_ptr<const Move<VkImageView>> quantizationMapImageView(new Move<VkImageView>(makeImageView(
1923 videoDeviceDriver, videoDevice, quantizationMapImage->get(), VK_IMAGE_VIEW_TYPE_2D,
1924 quantizationImageFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1))));
1925
1926 deMemset(quantizationMapBufferHostPtr, 0x00, static_cast<size_t>(quantizationMapBufferSize));
1927 flushAlloc(videoDeviceDriver, videoDevice, quantizationMapBufferAlloc);
1928
1929 fillBuffer(videoDeviceDriver, videoDevice, quantizationMapBufferAlloc, quantizationMapImageData,
1930 nonCoherentAtomSize, quantizationMapBufferSize);
1931
1932 copyBufferToImage(videoDeviceDriver, videoDevice, transferQueue, transferQueueFamilyIndex,
1933 *quantizationMapBuffer, quantizationMapBufferSize, quantizationMapExtent, 1,
1934 quantizationMapImage->get());
1935
1936 quantizationMapImages.push_back(std::move(quantizationMapImage));
1937 quantizationMapImageViews.push_back(std::move(quantizationMapImageView));
1938 };
1939
1940 for (uint32_t qmIdx = 0; qmIdx < quantizationMapCount; ++qmIdx)
1941 {
1942 switch (quantizationImageFormat)
1943 {
1944 case VK_FORMAT_R8_UNORM:
1945 {
1946 auto [leftSideQp, rightSideQp] = calculateMapValues(uint8_t(qmIdx), QM_EMPHASIS);
1947 processQuantizationMapImage(leftSideQp, rightSideQp);
1948 break;
1949 }
1950 case VK_FORMAT_R8_SINT:
1951 {
1952 auto [leftSideQp, rightSideQp] = calculateMapValues(int8_t(qmIdx), QM_DELTA);
1953 processQuantizationMapImage(leftSideQp, rightSideQp);
1954 break;
1955 }
1956 case VK_FORMAT_R32_SINT:
1957 {
1958 auto [leftSideQp, rightSideQp] = calculateMapValues(int32_t(qmIdx), QM_DELTA);
1959 processQuantizationMapImage(leftSideQp, rightSideQp);
1960 break;
1961 }
1962 default:
1963 TCU_THROW(NotSupportedError, "Unsupported quantization map format");
1964 }
1965 }
1966 } // if (useDeltaMap || useEmphasisMap)
1967
1968 // Must be smaller than the maxQualityLevels capabilities limit supported by the specified video profile
1969 uint32_t qualityLevel = 0;
1970 DE_ASSERT(qualityLevel < videoEncodeCapabilities->maxQualityLevels);
1971
1972 const MovePtr<VkVideoEncodeQualityLevelInfoKHR> videoEncodeQualityLevelInfo =
1973 getVideoEncodeQualityLevelInfo(qualityLevel, nullptr);
1974
1975 const MovePtr<VkVideoEncodeQuantizationMapSessionParametersCreateInfoKHR> quantizationMapSessionParametersInfo =
1976 getVideoEncodeH264QuantizationMapParameters(quantizationMapTexelSize);
1977
1978 std::vector<MovePtr<StdVideoH264SequenceParameterSet>> stdVideoH264SequenceParameterSets;
1979 std::vector<MovePtr<StdVideoH264PictureParameterSet>> stdVideoH264PictureParameterSets;
1980 std::vector<MovePtr<VkVideoEncodeH264SessionParametersAddInfoKHR>> encodeH264SessionParametersAddInfoKHRs;
1981 std::vector<MovePtr<VkVideoEncodeH264SessionParametersCreateInfoKHR>> H264sessionParametersCreateInfos;
1982
1983 std::vector<MovePtr<StdVideoH265ProfileTierLevel>> stdVideoH265ProfileTierLevels;
1984 std::vector<MovePtr<StdVideoH265DecPicBufMgr>> stdVideoH265DecPicBufMgrs;
1985 std::vector<MovePtr<StdVideoH265VideoParameterSet>> stdVideoH265VideoParameterSets;
1986 std::vector<MovePtr<StdVideoH265SequenceParameterSetVui>> stdVideoH265SequenceParameterSetVuis;
1987 std::vector<MovePtr<StdVideoH265SequenceParameterSet>> stdVideoH265SequenceParameterSets;
1988 std::vector<MovePtr<StdVideoH265PictureParameterSet>> stdVideoH265PictureParameterSets;
1989 std::vector<MovePtr<VkVideoEncodeH265SessionParametersAddInfoKHR>> encodeH265SessionParametersAddInfoKHRs;
1990 std::vector<MovePtr<VkVideoEncodeH265SessionParametersCreateInfoKHR>> H265sessionParametersCreateInfos;
1991
1992 std::vector<MovePtr<VkVideoSessionParametersCreateInfoKHR>> videoEncodeSessionParametersCreateInfos;
1993 std::vector<Move<VkVideoSessionParametersKHR>> videoEncodeSessionParameters;
1994
1995 for (int i = 0; i < (resolutionChange ? 2 : 1); ++i)
1996 {
1997 // Second videoEncodeSessionParameters is being created with half the size
1998 uint32_t extentWidth = i == 0 ? codedExtent.width : codedExtent.width / 2;
1999 uint32_t extentHeight = i == 0 ? codedExtent.height : codedExtent.height / 2;
2000
2001 stdVideoH264SequenceParameterSets.push_back(getStdVideoH264EncodeSequenceParameterSet(
2002 extentWidth, extentHeight, m_testDefinition->maxNumRefs(), nullptr));
2003 stdVideoH264PictureParameterSets.push_back(getStdVideoH264EncodePictureParameterSet(
2004 m_testDefinition->ppsActiveRefs0(), m_testDefinition->ppsActiveRefs1()));
2005 encodeH264SessionParametersAddInfoKHRs.push_back(createVideoEncodeH264SessionParametersAddInfoKHR(
2006 1u, stdVideoH264SequenceParameterSets.back().get(), 1u, stdVideoH264PictureParameterSets.back().get()));
2007
2008 H264sessionParametersCreateInfos.push_back(createVideoEncodeH264SessionParametersCreateInfoKHR(
2009 static_cast<const void *>(useQualityLevel ?
2010 videoEncodeQualityLevelInfo.get() :
2011 ((useDeltaMap || useEmphasisMap) ?
2012 static_cast<const void *>(quantizationMapSessionParametersInfo.get()) :
2013 nullptr)),
2014 1u, 1u, encodeH264SessionParametersAddInfoKHRs.back().get()));
2015
2016 stdVideoH265ProfileTierLevels.push_back(
2017 getStdVideoH265ProfileTierLevel(STD_VIDEO_H265_PROFILE_IDC_MAIN, STD_VIDEO_H265_LEVEL_IDC_6_2));
2018 stdVideoH265DecPicBufMgrs.push_back(getStdVideoH265DecPicBufMgr());
2019 stdVideoH265VideoParameterSets.push_back(getStdVideoH265VideoParameterSet(
2020 stdVideoH265DecPicBufMgrs.back().get(), stdVideoH265ProfileTierLevels.back().get()));
2021 stdVideoH265SequenceParameterSetVuis.push_back(
2022 getStdVideoH265SequenceParameterSetVui(m_testDefinition->getClipFrameRate()));
2023 stdVideoH265SequenceParameterSets.push_back(getStdVideoH265SequenceParameterSet(
2024 extentWidth, extentHeight, videoH265CapabilitiesExtension->ctbSizes,
2025 videoH265CapabilitiesExtension->transformBlockSizes, stdVideoH265DecPicBufMgrs.back().get(),
2026 stdVideoH265ProfileTierLevels.back().get(), stdVideoH265SequenceParameterSetVuis.back().get()));
2027 stdVideoH265PictureParameterSets.push_back(
2028 getStdVideoH265PictureParameterSet(videoH265CapabilitiesExtension.get()));
2029 encodeH265SessionParametersAddInfoKHRs.push_back(getVideoEncodeH265SessionParametersAddInfoKHR(
2030 1u, stdVideoH265VideoParameterSets.back().get(), 1u, stdVideoH265SequenceParameterSets.back().get(), 1u,
2031 stdVideoH265PictureParameterSets.back().get()));
2032 H265sessionParametersCreateInfos.push_back(getVideoEncodeH265SessionParametersCreateInfoKHR(
2033 static_cast<const void *>(useQualityLevel ?
2034 videoEncodeQualityLevelInfo.get() :
2035 ((useDeltaMap || useEmphasisMap) ?
2036 static_cast<const void *>(quantizationMapSessionParametersInfo.get()) :
2037 nullptr)),
2038 1u, 1u, 1u, encodeH265SessionParametersAddInfoKHRs.back().get()));
2039
2040 const void *sessionParametersCreateInfoPtr = nullptr;
2041
2042 if (m_testDefinition->getProfile()->IsH264())
2043 {
2044 sessionParametersCreateInfoPtr = static_cast<const void *>(H264sessionParametersCreateInfos.back().get());
2045 }
2046 else if (m_testDefinition->getProfile()->IsH265())
2047 {
2048 sessionParametersCreateInfoPtr = static_cast<const void *>(H265sessionParametersCreateInfos.back().get());
2049 }
2050 DE_ASSERT(sessionParametersCreateInfoPtr);
2051
2052 const VkVideoSessionParametersCreateFlagsKHR videoSessionParametersFlags =
2053 (useDeltaMap || useEmphasisMap) ?
2054 static_cast<VkVideoSessionParametersCreateFlagsKHR>(
2055 VK_VIDEO_SESSION_PARAMETERS_CREATE_QUANTIZATION_MAP_COMPATIBLE_BIT_KHR) :
2056 static_cast<VkVideoSessionParametersCreateFlagsKHR>(0);
2057
2058 videoEncodeSessionParametersCreateInfos.push_back(getVideoSessionParametersCreateInfoKHR(
2059 sessionParametersCreateInfoPtr, videoSessionParametersFlags, *videoEncodeSession));
2060 videoEncodeSessionParameters.push_back(createVideoSessionParametersKHR(
2061 videoDeviceDriver, videoDevice, videoEncodeSessionParametersCreateInfos.back().get()));
2062 }
2063
2064 const VkImageUsageFlags dpbImageUsage = VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR;
2065 // If the implementation does not support individual images for DPB and so must use arrays
2066 const bool separateReferenceImages =
2067 videoCapabilities.get()->flags & VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR;
2068 const VkImageCreateInfo dpbImageCreateInfo =
2069 makeImageCreateInfo(imageFormat, codedExtent, 0, &encodeQueueFamilyIndex, dpbImageUsage,
2070 videoEncodeProfileList.get(), separateReferenceImages ? 1 : dpbSlots);
2071 const VkImageViewType dpbImageViewType =
2072 separateReferenceImages ? VK_IMAGE_VIEW_TYPE_2D : VK_IMAGE_VIEW_TYPE_2D_ARRAY;
2073
2074 std::vector<std::unique_ptr<const ImageWithMemory>> dpbImages;
2075
2076 for (uint8_t i = 0; i < (separateReferenceImages ? dpbSlots : 1); ++i)
2077 {
2078 std::unique_ptr<ImageWithMemory> dpbImage(new ImageWithMemory(videoDeviceDriver, videoDevice, getAllocator(),
2079 dpbImageCreateInfo, MemoryRequirement::Any));
2080 dpbImages.push_back(std::move(dpbImage));
2081 }
2082
2083 std::vector<MovePtr<StdVideoEncodeH264ReferenceInfo>> H264refInfos;
2084 std::vector<MovePtr<StdVideoEncodeH265ReferenceInfo>> H265refInfos;
2085
2086 std::vector<MovePtr<VkVideoEncodeH264DpbSlotInfoKHR>> H264dpbSlotInfos;
2087 std::vector<MovePtr<VkVideoEncodeH265DpbSlotInfoKHR>> H265dpbSlotInfos;
2088
2089 for (uint8_t i = 0, j = 0; i < gopFrameCount; ++i)
2090 {
2091 if (m_testDefinition->frameType(i) == B_FRAME)
2092 continue;
2093
2094 H264refInfos.push_back(getStdVideoEncodeH264ReferenceInfo(getH264PictureType(m_testDefinition->frameType(i)),
2095 m_testDefinition->frameNumber(i),
2096 m_testDefinition->frameIdx(i) * 2));
2097 H265refInfos.push_back(getStdVideoEncodeH265ReferenceInfo(getH265PictureType(m_testDefinition->frameType(i)),
2098 m_testDefinition->frameIdx(i)));
2099
2100 H264dpbSlotInfos.push_back(getVideoEncodeH264DpbSlotInfo(H264refInfos[j].get()));
2101 H265dpbSlotInfos.push_back(getVideoEncodeH265DpbSlotInfo(H265refInfos[j].get()));
2102
2103 j++;
2104 }
2105
2106 std::vector<std::unique_ptr<const Move<VkImageView>>> dpbImageViews;
2107 std::vector<std::unique_ptr<const VkVideoPictureResourceInfoKHR>> dpbPictureResources;
2108 std::vector<VkVideoReferenceSlotInfoKHR> dpbImageVideoReferenceSlots;
2109
2110 for (uint8_t i = 0, j = 0; i < gopFrameCount; ++i)
2111 {
2112 if (m_testDefinition->frameType(i) == B_FRAME)
2113 continue;
2114
2115 const VkImageSubresourceRange dpbImageSubresourceRange = {
2116 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2117 0, // uint32_t baseMipLevel;
2118 1, // uint32_t levelCount;
2119 separateReferenceImages ? static_cast<uint32_t>(0) : static_cast<uint32_t>(j), // uint32_t baseArrayLayer;
2120 1, // uint32_t layerCount;
2121 };
2122
2123 std::unique_ptr<Move<VkImageView>> dpbImageView(new Move<VkImageView>(
2124 makeImageView(videoDeviceDriver, videoDevice, dpbImages[separateReferenceImages ? j : 0]->get(),
2125 dpbImageViewType, imageFormat, dpbImageSubresourceRange)));
2126 std::unique_ptr<VkVideoPictureResourceInfoKHR> dpbPictureResource(
2127 new VkVideoPictureResourceInfoKHR(makeVideoPictureResource(codedExtent, 0, dpbImageView->get())));
2128
2129 dpbImageViews.push_back(std::move(dpbImageView));
2130 dpbPictureResources.push_back(std::move(dpbPictureResource));
2131
2132 const void *dpbSlotInfoPtr = nullptr;
2133
2134 if (m_testDefinition->getProfile()->IsH264())
2135 {
2136 dpbSlotInfoPtr = static_cast<const void *>(H264dpbSlotInfos[j].get());
2137 }
2138 else if (m_testDefinition->getProfile()->IsH265())
2139 {
2140 dpbSlotInfoPtr = static_cast<const void *>(H265dpbSlotInfos[j].get());
2141 }
2142 DE_ASSERT(dpbSlotInfoPtr);
2143
2144 dpbImageVideoReferenceSlots.push_back(
2145 makeVideoReferenceSlot(swapOrder ? j : -1, dpbPictureResources[j].get(), dpbSlotInfoPtr));
2146
2147 j++;
2148 }
2149
2150 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
2151
2152 std::vector<std::unique_ptr<const ImageWithMemory>> imageVector;
2153 std::vector<std::unique_ptr<const Move<VkImageView>>> imageViewVector;
2154 std::vector<std::unique_ptr<const VkVideoPictureResourceInfoKHR>> imagePictureResourceVector;
2155
2156 for (uint32_t i = 0; i < gopCount; ++i)
2157 {
2158 for (uint32_t j = 0; j < gopFrameCount; ++j)
2159 {
2160 VkExtent2D currentCodedExtent = codedExtent;
2161 if (resolutionChange && i == 1)
2162 {
2163 currentCodedExtent.width /= 2;
2164 currentCodedExtent.height /= 2;
2165 }
2166
2167 const VkImageCreateInfo imageCreateInfo =
2168 makeImageCreateInfo(imageFormat, currentCodedExtent,
2169 resourcesWithoutProfiles ? VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR : 0,
2170 &transferQueueFamilyIndex, imageUsage,
2171 resourcesWithoutProfiles ? nullptr : videoEncodeProfileList.get());
2172
2173 std::unique_ptr<const ImageWithMemory> image(new ImageWithMemory(
2174 videoDeviceDriver, videoDevice, getAllocator(), imageCreateInfo, MemoryRequirement::Any));
2175 std::unique_ptr<const Move<VkImageView>> imageView(new Move<VkImageView>(
2176 makeImageView(videoDeviceDriver, videoDevice, image->get(), VK_IMAGE_VIEW_TYPE_2D, imageFormat,
2177 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1))));
2178 std::unique_ptr<const VkVideoPictureResourceInfoKHR> imagePictureResource(
2179 new VkVideoPictureResourceInfoKHR(makeVideoPictureResource(currentCodedExtent, 0, **imageView)));
2180
2181 imageVector.push_back(std::move(image));
2182 imageViewVector.push_back(std::move(imageView));
2183 imagePictureResourceVector.push_back(std::move(imagePictureResource));
2184 }
2185 }
2186
2187 const vector<uint32_t> encodeQueueFamilyIndices(1u, encodeQueueFamilyIndex);
2188
2189 const VkBufferUsageFlags encodeBufferUsageFlags =
2190 VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR | VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
2191 const VkDeviceSize encodeFrameBufferSize = getBufferSize(imageFormat, codedExtent.width, codedExtent.height);
2192 const VkDeviceSize encodeFrameBufferSizeAligned =
2193 deAlign64(encodeFrameBufferSize, videoCapabilities->minBitstreamBufferSizeAlignment);
2194 const VkDeviceSize encodeBufferSize = encodeFrameBufferSizeAligned * gopFrameCount * gopCount;
2195
2196 const VkBufferCreateInfo encodeBufferCreateInfo = makeBufferCreateInfo(
2197 encodeBufferSize, encodeBufferUsageFlags, encodeQueueFamilyIndices, 0, videoEncodeProfileList.get());
2198
2199 BufferWithMemory encodeBuffer(videoDeviceDriver, videoDevice, getAllocator(), encodeBufferCreateInfo,
2200 MemoryRequirement::Local | MemoryRequirement::HostVisible);
2201
2202 Allocation &encodeBufferAlloc = encodeBuffer.getAllocation();
2203 void *encodeBufferHostPtr = encodeBufferAlloc.getHostPtr();
2204
2205 Move<VkQueryPool> encodeQueryPool =
2206 createEncodeVideoQueries(videoDeviceDriver, videoDevice, 2, videoEncodeProfile.get());
2207
2208 deMemset(encodeBufferHostPtr, 0x00, static_cast<size_t>(encodeBufferSize));
2209 flushAlloc(videoDeviceDriver, videoDevice, encodeBufferAlloc);
2210
2211 de::MovePtr<vector<uint8_t>> clip = loadVideoData(m_testDefinition->getClipFilename());
2212
2213 std::vector<de::MovePtr<std::vector<uint8_t>>> inVector;
2214
2215 for (uint32_t i = 0; i < gopCount; ++i)
2216 {
2217 for (uint32_t j = 0; j < gopFrameCount; ++j)
2218 {
2219 uint32_t index = i * gopFrameCount + j;
2220
2221 uint32_t extentWidth = codedExtent.width;
2222 uint32_t extentHeight = codedExtent.height;
2223
2224 bool half_size = false;
2225
2226 if (resolutionChange && i == 1)
2227 {
2228 extentWidth /= 2;
2229 extentHeight /= 2;
2230 half_size = true;
2231 }
2232
2233 MovePtr<MultiPlaneImageData> multiPlaneImageData(
2234 new MultiPlaneImageData(imageFormat, tcu::UVec2(extentWidth, extentHeight)));
2235 vkt::ycbcr::extractI420Frame(*clip, index, codedExtent.width, codedExtent.height, multiPlaneImageData.get(),
2236 half_size);
2237
2238 // Save NV12 Multiplanar frame to YUV 420p 8 bits
2239 de::MovePtr<std::vector<uint8_t>> in =
2240 vkt::ycbcr::YCbCrConvUtil<uint8_t>::MultiPlanarNV12toI420(multiPlaneImageData.get());
2241
2242 #if STREAM_DUMP_DEBUG
2243 std::string filename = "in_" + std::to_string(index) + ".yuv";
2244 vkt::ycbcr::YCbCrContent<uint8_t>::save(*in, filename);
2245 #endif
2246
2247 vkt::ycbcr::uploadImage(videoDeviceDriver, videoDevice, transferQueueFamilyIndex, allocator,
2248 *(*imageVector[index]), *multiPlaneImageData, 0, VK_IMAGE_LAYOUT_GENERAL);
2249
2250 inVector.push_back(std::move(in));
2251 }
2252 }
2253
2254 VkVideoEncodeSessionParametersFeedbackInfoKHR videoEncodeSessionParametersFeedbackInfo = {
2255 VK_STRUCTURE_TYPE_VIDEO_ENCODE_SESSION_PARAMETERS_FEEDBACK_INFO_KHR, // VkStructureType sType;
2256 nullptr, // void* pNext;
2257 false, // VkBool32 hasOverrides;
2258 };
2259
2260 const VkVideoEncodeH264SessionParametersGetInfoKHR videoEncodeH264SessionParametersGetInfo = {
2261 VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_GET_INFO_KHR, // VkStructureType sType;
2262 nullptr, // const void* pNext;
2263 true, // VkBool32 writeStdSPS;
2264 true, // VkBool32 writeStdPPS;
2265 0, // uint32_t stdSPSId;
2266 0, // uint32_t stdPPSId;
2267 };
2268
2269 const VkVideoEncodeH265SessionParametersGetInfoKHR videoEncodeH265SessionParametersGetInfo = {
2270 VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_GET_INFO_KHR, // VkStructureType sType;
2271 nullptr, // const void* pNext;
2272 true, // VkBool32 writeStdVPS;
2273 true, // VkBool32 writeStdSPS;
2274 true, // VkBool32 writeStdPPS;
2275 0, // uint32_t stdVPSId;
2276 0, // uint32_t stdSPSId;
2277 0, // uint32_t stdPPSId;
2278 };
2279
2280 const void *videoEncodeSessionParametersGetInfoPtr = nullptr;
2281
2282 if (m_testDefinition->getProfile()->IsH264())
2283 {
2284 videoEncodeSessionParametersGetInfoPtr = static_cast<const void *>(&videoEncodeH264SessionParametersGetInfo);
2285 }
2286 else if (m_testDefinition->getProfile()->IsH265())
2287 {
2288 videoEncodeSessionParametersGetInfoPtr = static_cast<const void *>(&videoEncodeH265SessionParametersGetInfo);
2289 }
2290 DE_ASSERT(videoEncodeSessionParametersGetInfoPtr);
2291
2292 std::vector<std::vector<uint8_t>> headersData;
2293
2294 for (int i = 0; i < (resolutionChange ? 2 : 1); ++i)
2295 {
2296 const VkVideoEncodeSessionParametersGetInfoKHR videoEncodeSessionParametersGetInfo = {
2297 VK_STRUCTURE_TYPE_VIDEO_ENCODE_SESSION_PARAMETERS_GET_INFO_KHR, // VkStructureType sType;
2298 videoEncodeSessionParametersGetInfoPtr, // const void* pNext;
2299 videoEncodeSessionParameters[i].get(), // VkVideoSessionParametersKHR videoSessionParameters;
2300 };
2301
2302 std::vector<uint8_t> headerData;
2303
2304 size_t requiredHeaderSize = 0;
2305 VK_CHECK(videoDeviceDriver.getEncodedVideoSessionParametersKHR(
2306 videoDevice, &videoEncodeSessionParametersGetInfo, &videoEncodeSessionParametersFeedbackInfo,
2307 &requiredHeaderSize, nullptr));
2308
2309 DE_ASSERT(requiredHeaderSize != 0);
2310
2311 headerData.resize(requiredHeaderSize);
2312 VK_CHECK(videoDeviceDriver.getEncodedVideoSessionParametersKHR(
2313 videoDevice, &videoEncodeSessionParametersGetInfo, &videoEncodeSessionParametersFeedbackInfo,
2314 &requiredHeaderSize, headerData.data()));
2315
2316 headersData.push_back(std::move(headerData));
2317 }
2318
2319 // Pre fill buffer with SPS and PPS header
2320 fillBuffer(videoDeviceDriver, videoDevice, encodeBufferAlloc, headersData[0], nonCoherentAtomSize, encodeBufferSize,
2321 bitstreamBufferOffset);
2322
2323 // Move offset to accommodate header data
2324 bitstreamBufferOffset =
2325 deAlign64(bitstreamBufferOffset + headersData[0].size(), videoCapabilities->minBitstreamBufferOffsetAlignment);
2326
2327 const Unique<VkCommandPool> encodeCmdPool(makeCommandPool(videoDeviceDriver, videoDevice, encodeQueueFamilyIndex));
2328 const Unique<VkCommandBuffer> firstEncodeCmdBuffer(
2329 allocateCommandBuffer(videoDeviceDriver, videoDevice, *encodeCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2330 const Unique<VkCommandBuffer> secondEncodeCmdBuffer(
2331 allocateCommandBuffer(videoDeviceDriver, videoDevice, *encodeCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2332
2333 // Rate control
2334 const de::MovePtr<VkVideoEncodeH264RateControlLayerInfoKHR> videoEncodeH264RateControlLayerInfo =
2335 getVideoEncodeH264RateControlLayerInfo(true, 0, 0, 0, true, maxQpValue, maxQpValue, maxQpValue);
2336 const de::MovePtr<VkVideoEncodeH265RateControlLayerInfoKHR> videoEncodeH265RateControlLayerInfo =
2337 getVideoEncodeH265RateControlLayerInfo(true, 0, 0, 0, true, maxQpValue, maxQpValue, maxQpValue);
2338
2339 const void *videoEncodeRateControlLayerInfoPtr = nullptr;
2340
2341 if (m_testDefinition->getProfile()->IsH264())
2342 {
2343 videoEncodeRateControlLayerInfoPtr = static_cast<const void *>(videoEncodeH264RateControlLayerInfo.get());
2344 }
2345 else if (m_testDefinition->getProfile()->IsH265())
2346 {
2347 videoEncodeRateControlLayerInfoPtr = static_cast<const void *>(videoEncodeH265RateControlLayerInfo.get());
2348 }
2349 DE_ASSERT(videoEncodeRateControlLayerInfoPtr);
2350
2351 const VkVideoEncodeRateControlModeFlagBitsKHR rateControlMode =
2352 disableRateControl ? VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR :
2353 (activeRateControl ? (useVariableBitrate ? VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR :
2354 VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR) :
2355 VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR);
2356
2357 const de::MovePtr<VkVideoEncodeRateControlLayerInfoKHR> videoEncodeRateControlLayerInfo =
2358 getVideoEncodeRateControlLayerInfo(videoEncodeRateControlLayerInfoPtr, rateControlMode,
2359 m_testDefinition->getClipFrameRate());
2360
2361 const VkVideoEncodeH264RateControlInfoKHR videoEncodeH264RateControlInfo = {
2362 VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_RATE_CONTROL_INFO_KHR, // VkStructureType sType;
2363 nullptr, // const void* pNext;
2364 VK_VIDEO_ENCODE_H264_RATE_CONTROL_REGULAR_GOP_BIT_KHR, // VkVideoEncodeH264RateControlFlagsKHR flags;
2365 m_testDefinition->gopFrameCount(), // uint32_t gopFrameCount;
2366 m_testDefinition->gopFrameCount(), // uint32_t idrPeriod;
2367 m_testDefinition->getConsecutiveBFrameCount(), // uint32_t consecutiveBFrameCount;
2368 1, // uint32_t temporalLayerCount;
2369 };
2370
2371 const VkVideoEncodeH265RateControlInfoKHR videoEncodeH265RateControlInfo = {
2372 VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_INFO_KHR, // VkStructureType sType;
2373 nullptr, // const void* pNext;
2374 VK_VIDEO_ENCODE_H265_RATE_CONTROL_REGULAR_GOP_BIT_KHR, // VkVideoEncodeH265RateControlFlagsKHR flags;
2375 m_testDefinition->gopFrameCount(), // uint32_t gopFrameCount;
2376 m_testDefinition->gopFrameCount(), // uint32_t idrPeriod;
2377 m_testDefinition->getConsecutiveBFrameCount(), // uint32_t consecutiveBFrameCount;
2378 (useConstantBitrate || useVariableBitrate) ? 1U : 0, // uint32_t subLayerCount;
2379 };
2380
2381 const void *videoEncodeRateControlInfoPtr = nullptr;
2382
2383 if (m_testDefinition->getProfile()->IsH264())
2384 {
2385 videoEncodeRateControlInfoPtr = static_cast<const void *>(&videoEncodeH264RateControlInfo);
2386 }
2387 else if (m_testDefinition->getProfile()->IsH265())
2388 {
2389 videoEncodeRateControlInfoPtr = static_cast<const void *>(&videoEncodeH265RateControlInfo);
2390 }
2391 DE_ASSERT(videoEncodeRateControlInfoPtr);
2392
2393 const de::MovePtr<VkVideoEncodeRateControlInfoKHR> videoEncodeRateControlInfo = getVideoEncodeRateControlInfo(
2394 disableRateControl ? DE_NULL : videoEncodeRateControlInfoPtr, rateControlMode,
2395 (useConstantBitrate || useVariableBitrate) ? videoEncodeRateControlLayerInfo.get() : DE_NULL);
2396 // End coding
2397 const VkVideoEndCodingInfoKHR videoEndCodingInfo = {
2398 VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR, // VkStructureType sType;
2399 nullptr, // const void* pNext;
2400 0u, // VkVideoEndCodingFlagsKHR flags;
2401 };
2402
2403 std::vector<de::MovePtr<StdVideoEncodeH264SliceHeader>> stdVideoEncodeH264SliceHeaders;
2404 std::vector<de::MovePtr<VkVideoEncodeH264NaluSliceInfoKHR>> videoEncodeH264NaluSlices;
2405 std::vector<de::MovePtr<StdVideoEncodeH264ReferenceListsInfo>> videoEncodeH264ReferenceListInfos;
2406 std::vector<de::MovePtr<StdVideoEncodeH264PictureInfo>> H264pictureInfos;
2407 std::vector<de::MovePtr<VkVideoEncodeH264PictureInfoKHR>> videoEncodeH264PictureInfo;
2408
2409 std::vector<de::MovePtr<StdVideoEncodeH265SliceSegmentHeader>> stdVideoEncodeH265SliceSegmentHeaders;
2410 std::vector<de::MovePtr<StdVideoH265ShortTermRefPicSet>> stdVideoH265ShortTermRefPicSets;
2411 std::vector<de::MovePtr<VkVideoEncodeH265NaluSliceSegmentInfoKHR>> videoEncodeH265NaluSliceSegments;
2412 std::vector<de::MovePtr<StdVideoEncodeH265ReferenceListsInfo>> videoEncodeH265ReferenceListInfos;
2413 std::vector<de::MovePtr<StdVideoEncodeH265PictureInfo>> H265pictureInfos;
2414 std::vector<de::MovePtr<VkVideoEncodeH265PictureInfoKHR>> videoEncodeH265PictureInfos;
2415
2416 std::vector<de::MovePtr<VkVideoEncodeInfoKHR>> videoEncodeFrameInfos;
2417 uint32_t queryId = 0;
2418
2419 for (uint16_t GOPIdx = 0; GOPIdx < gopCount; ++GOPIdx)
2420 {
2421 uint32_t emptyRefSlotIdx = swapOrder ? 1 : 0;
2422
2423 if (resolutionChange && GOPIdx == 1)
2424 {
2425 // Pre fill buffer with new SPS/PPS/VPS header
2426 fillBuffer(videoDeviceDriver, videoDevice, encodeBufferAlloc, headersData[1], nonCoherentAtomSize,
2427 encodeBufferSize, bitstreamBufferOffset);
2428 bitstreamBufferOffset =
2429 deAlign64(bitstreamBufferOffset + headersData[1].size(), minBitstreamBufferOffsetAlignment);
2430 }
2431
2432 for (uint32_t NALIdx = emptyRefSlotIdx; NALIdx < gopFrameCount; (swapOrder ? --NALIdx : ++NALIdx))
2433 {
2434 VkCommandBuffer encodeCmdBuffer =
2435 (NALIdx == 1 && swapOrder) ? *secondEncodeCmdBuffer : *firstEncodeCmdBuffer;
2436
2437 beginCommandBuffer(videoDeviceDriver, encodeCmdBuffer, 0u);
2438
2439 videoDeviceDriver.cmdResetQueryPool(encodeCmdBuffer, encodeQueryPool.get(), 0, 2);
2440
2441 de::MovePtr<VkVideoBeginCodingInfoKHR> videoBeginCodingFrameInfoKHR = getVideoBeginCodingInfo(
2442 *videoEncodeSession,
2443 resolutionChange ? videoEncodeSessionParameters[GOPIdx].get() : videoEncodeSessionParameters[0].get(),
2444 dpbSlots, &dpbImageVideoReferenceSlots[0],
2445 (activeRateControl && NALIdx > 0) ? videoEncodeRateControlInfo.get() : DE_NULL);
2446
2447 videoDeviceDriver.cmdBeginVideoCodingKHR(encodeCmdBuffer, videoBeginCodingFrameInfoKHR.get());
2448
2449 de::MovePtr<VkVideoCodingControlInfoKHR> resetVideoEncodingControl =
2450 getVideoCodingControlInfo(VK_VIDEO_CODING_CONTROL_RESET_BIT_KHR);
2451
2452 if (NALIdx == 0)
2453 {
2454 videoDeviceDriver.cmdControlVideoCodingKHR(encodeCmdBuffer, resetVideoEncodingControl.get());
2455
2456 if (disableRateControl || activeRateControl)
2457 {
2458 de::MovePtr<VkVideoCodingControlInfoKHR> videoRateConstrolInfo = getVideoCodingControlInfo(
2459 VK_VIDEO_CODING_CONTROL_ENCODE_RATE_CONTROL_BIT_KHR, videoEncodeRateControlInfo.get());
2460 videoDeviceDriver.cmdControlVideoCodingKHR(encodeCmdBuffer, videoRateConstrolInfo.get());
2461 }
2462 if (useQualityLevel)
2463 {
2464 de::MovePtr<VkVideoCodingControlInfoKHR> videoQualityControlInfo = getVideoCodingControlInfo(
2465 VK_VIDEO_CODING_CONTROL_ENCODE_QUALITY_LEVEL_BIT_KHR, videoEncodeQualityLevelInfo.get());
2466 videoDeviceDriver.cmdControlVideoCodingKHR(encodeCmdBuffer, videoQualityControlInfo.get());
2467 }
2468 }
2469
2470 StdVideoH264PictureType stdVideoH264PictureType = getH264PictureType(m_testDefinition->frameType(NALIdx));
2471 StdVideoH265PictureType stdVideoH265PictureType = getH265PictureType(m_testDefinition->frameType(NALIdx));
2472
2473 StdVideoH264SliceType stdVideoH264SliceType = getH264SliceType(m_testDefinition->frameType(NALIdx));
2474 StdVideoH265SliceType stdVideoH265SliceType = getH265SliceType(m_testDefinition->frameType(NALIdx));
2475
2476 uint32_t refsPool = 0;
2477
2478 uint8_t H264RefPicList0[STD_VIDEO_H264_MAX_NUM_LIST_REF];
2479 uint8_t H265RefPicList0[STD_VIDEO_H265_MAX_NUM_LIST_REF];
2480
2481 std::fill(H264RefPicList0, H264RefPicList0 + STD_VIDEO_H264_MAX_NUM_LIST_REF,
2482 STD_VIDEO_H264_NO_REFERENCE_PICTURE);
2483 std::fill(H265RefPicList0, H265RefPicList0 + STD_VIDEO_H265_MAX_NUM_LIST_REF,
2484 STD_VIDEO_H265_NO_REFERENCE_PICTURE);
2485
2486 uint8_t numL0 = 0;
2487 uint8_t numL1 = 0;
2488
2489 bool pType = stdVideoH264PictureType == STD_VIDEO_H264_PICTURE_TYPE_P ||
2490 stdVideoH265PictureType == STD_VIDEO_H265_PICTURE_TYPE_P;
2491 bool bType = stdVideoH264PictureType == STD_VIDEO_H264_PICTURE_TYPE_B ||
2492 stdVideoH265PictureType == STD_VIDEO_H265_PICTURE_TYPE_B;
2493
2494 if (pType)
2495 {
2496 refsPool = 1;
2497
2498 std::vector<uint8_t> list0 = m_testDefinition->ref0(NALIdx);
2499 for (auto idx : list0)
2500 {
2501 H264RefPicList0[numL0] = idx;
2502 H265RefPicList0[numL0++] = idx;
2503 }
2504 }
2505
2506 uint8_t H264RefPicList1[STD_VIDEO_H264_MAX_NUM_LIST_REF];
2507 uint8_t H265RefPicList1[STD_VIDEO_H265_MAX_NUM_LIST_REF];
2508
2509 std::fill(H264RefPicList1, H264RefPicList1 + STD_VIDEO_H264_MAX_NUM_LIST_REF,
2510 STD_VIDEO_H264_NO_REFERENCE_PICTURE);
2511 std::fill(H265RefPicList1, H265RefPicList1 + STD_VIDEO_H265_MAX_NUM_LIST_REF,
2512 STD_VIDEO_H265_NO_REFERENCE_PICTURE);
2513
2514 if (bType)
2515 {
2516 refsPool = 2;
2517
2518 std::vector<uint8_t> list0 = m_testDefinition->ref0(NALIdx);
2519 for (auto idx : list0)
2520 {
2521 H264RefPicList0[numL0] = idx;
2522 H265RefPicList0[numL0++] = idx;
2523 }
2524
2525 std::vector<uint8_t> list1 = m_testDefinition->ref1(NALIdx);
2526 for (auto idx : list1)
2527 {
2528 H264RefPicList1[numL1] = idx;
2529 H265RefPicList1[numL1++] = idx;
2530 }
2531 }
2532
2533 bool h264ActiveOverrideFlag =
2534 (stdVideoH264SliceType != STD_VIDEO_H264_SLICE_TYPE_I) &&
2535 ((m_testDefinition->ppsActiveRefs0() != m_testDefinition->shActiveRefs0(NALIdx)) ||
2536 (m_testDefinition->ppsActiveRefs1() != m_testDefinition->shActiveRefs1(NALIdx)));
2537
2538 stdVideoEncodeH264SliceHeaders.push_back(
2539 getStdVideoEncodeH264SliceHeader(stdVideoH264SliceType, h264ActiveOverrideFlag));
2540 videoEncodeH264NaluSlices.push_back(getVideoEncodeH264NaluSlice(
2541 stdVideoEncodeH264SliceHeaders.back().get(),
2542 (rateControlMode == VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR) ? constQp : 0));
2543 videoEncodeH264ReferenceListInfos.push_back(
2544 getVideoEncodeH264ReferenceListsInfo(H264RefPicList0, H264RefPicList1, numL0, numL1));
2545 H264pictureInfos.push_back(getStdVideoEncodeH264PictureInfo(
2546 getH264PictureType(m_testDefinition->frameType(NALIdx)), m_testDefinition->frameNumber(NALIdx),
2547 m_testDefinition->frameIdx(NALIdx) * 2, GOPIdx,
2548 NALIdx > 0 ? videoEncodeH264ReferenceListInfos.back().get() : nullptr));
2549 videoEncodeH264PictureInfo.push_back(
2550 getVideoEncodeH264PictureInfo(H264pictureInfos.back().get(), videoEncodeH264NaluSlices.back().get()));
2551
2552 stdVideoEncodeH265SliceSegmentHeaders.push_back(
2553 getStdVideoEncodeH265SliceSegmentHeader(stdVideoH265SliceType));
2554 videoEncodeH265NaluSliceSegments.push_back(getVideoEncodeH265NaluSliceSegment(
2555 stdVideoEncodeH265SliceSegmentHeaders.back().get(),
2556 (rateControlMode == VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR) ? constQp : 0));
2557 videoEncodeH265ReferenceListInfos.push_back(
2558 getVideoEncodeH265ReferenceListsInfo(H265RefPicList0, H265RefPicList1));
2559 stdVideoH265ShortTermRefPicSets.push_back(getStdVideoH265ShortTermRefPicSet(
2560 getH265PictureType(m_testDefinition->frameType(NALIdx)), m_testDefinition->frameIdx(NALIdx),
2561 m_testDefinition->getConsecutiveBFrameCount()));
2562 H265pictureInfos.push_back(getStdVideoEncodeH265PictureInfo(
2563 getH265PictureType(m_testDefinition->frameType(NALIdx)), m_testDefinition->frameIdx(NALIdx),
2564 NALIdx > 0 ? videoEncodeH265ReferenceListInfos.back().get() : nullptr,
2565 stdVideoH265ShortTermRefPicSets.back().get()));
2566 videoEncodeH265PictureInfos.push_back(getVideoEncodeH265PictureInfo(
2567 H265pictureInfos.back().get(), videoEncodeH265NaluSliceSegments.back().get()));
2568
2569 const void *videoEncodePictureInfoPtr = nullptr;
2570
2571 if (m_testDefinition->getProfile()->IsH264())
2572 {
2573 videoEncodePictureInfoPtr = static_cast<const void *>(videoEncodeH264PictureInfo.back().get());
2574 }
2575 else if (m_testDefinition->getProfile()->IsH265())
2576 {
2577 videoEncodePictureInfoPtr = static_cast<const void *>(videoEncodeH265PictureInfos.back().get());
2578 }
2579 DE_ASSERT(videoEncodePictureInfoPtr);
2580
2581 VkVideoReferenceSlotInfoKHR *setupReferenceSlotPtr = nullptr;
2582
2583 int8_t curSlotIdx = m_testDefinition->curSlot(NALIdx);
2584 if (!bType)
2585 {
2586 setupReferenceSlotPtr = &dpbImageVideoReferenceSlots[curSlotIdx];
2587 setupReferenceSlotPtr->slotIndex = curSlotIdx;
2588 }
2589
2590 int32_t startRefSlot = refsPool == 0 ? -1 : m_testDefinition->refSlots(NALIdx)[0];
2591 VkVideoReferenceSlotInfoKHR *referenceSlots =
2592 &dpbImageVideoReferenceSlots[separateReferenceImages && startRefSlot > -1 ? startRefSlot : 0];
2593 uint8_t refsCount = m_testDefinition->refsCount(NALIdx);
2594 uint32_t srcPictureResourceIdx = (GOPIdx * gopFrameCount) + m_testDefinition->frameIdx(NALIdx);
2595
2596 VkDeviceSize dstBufferOffset;
2597
2598 // Due to the invert command order dstBufferOffset for P frame is unknown during the recording, set offset to a "safe" values
2599 if (swapOrder)
2600 {
2601 if (NALIdx == 0)
2602 {
2603 dstBufferOffset = deAlign64(256, minBitstreamBufferOffsetAlignment);
2604 }
2605 else
2606 {
2607 dstBufferOffset = deAlign64(encodeFrameBufferSizeAligned + 256, minBitstreamBufferOffsetAlignment);
2608 }
2609 }
2610 else
2611 {
2612 dstBufferOffset = bitstreamBufferOffset;
2613 }
2614
2615 de::MovePtr<VkVideoInlineQueryInfoKHR> inlineQueryInfo =
2616 getVideoInlineQueryInfo(encodeQueryPool.get(), queryId, 1, nullptr);
2617
2618 de::MovePtr<VkVideoEncodeQuantizationMapInfoKHR> quantizationMapInfo;
2619
2620 if (useInlineQueries)
2621 {
2622 VkBaseInStructure *pStruct = (VkBaseInStructure *)videoEncodePictureInfoPtr;
2623 while (pStruct->pNext)
2624 pStruct = (VkBaseInStructure *)pStruct->pNext;
2625 pStruct->pNext = (VkBaseInStructure *)inlineQueryInfo.get();
2626 }
2627 else if (useDeltaMap || useEmphasisMap)
2628 {
2629 VkBaseInStructure *pStruct = (VkBaseInStructure *)videoEncodePictureInfoPtr;
2630 quantizationMapInfo = getQuantizationMapInfo(
2631 quantizationMapImageViews[GOPIdx % quantizationMapCount]->get(), quantizationMapExtent);
2632 while (pStruct->pNext)
2633 pStruct = (VkBaseInStructure *)pStruct->pNext;
2634 pStruct->pNext = (VkBaseInStructure *)quantizationMapInfo.get();
2635 }
2636
2637 const VkVideoEncodeFlagsKHR encodeFlags =
2638 (useDeltaMap || useEmphasisMap) ?
2639 (useDeltaMap ?
2640 static_cast<VkVideoEncodeFlagsKHR>(VK_VIDEO_ENCODE_WITH_QUANTIZATION_DELTA_MAP_BIT_KHR) :
2641 static_cast<VkVideoEncodeFlagsKHR>(VK_VIDEO_ENCODE_WITH_EMPHASIS_MAP_BIT_KHR)) :
2642 static_cast<VkVideoEncodeFlagsKHR>(0);
2643
2644 videoEncodeFrameInfos.push_back(
2645 getVideoEncodeInfo(videoEncodePictureInfoPtr, encodeFlags, *encodeBuffer, dstBufferOffset,
2646 (*imagePictureResourceVector[srcPictureResourceIdx]), setupReferenceSlotPtr,
2647 refsCount, (refsPool == 0) ? DE_NULL : referenceSlots));
2648
2649 if (!useInlineQueries)
2650 videoDeviceDriver.cmdBeginQuery(encodeCmdBuffer, encodeQueryPool.get(), queryId, 0);
2651
2652 videoDeviceDriver.cmdEncodeVideoKHR(encodeCmdBuffer, videoEncodeFrameInfos.back().get());
2653
2654 if (!useInlineQueries)
2655 videoDeviceDriver.cmdEndQuery(encodeCmdBuffer, encodeQueryPool.get(), queryId);
2656 videoDeviceDriver.cmdEndVideoCodingKHR(encodeCmdBuffer, &videoEndCodingInfo);
2657
2658 endCommandBuffer(videoDeviceDriver, encodeCmdBuffer);
2659
2660 if (!swapOrder)
2661 {
2662 submitCommandsAndWait(videoDeviceDriver, videoDevice, encodeQueue, encodeCmdBuffer);
2663
2664 if (!processQueryPoolResults(videoDeviceDriver, videoDevice, encodeQueryPool.get(), queryId, 1,
2665 bitstreamBufferOffset, minBitstreamBufferOffsetAlignment, queryStatus))
2666 return tcu::TestStatus::fail("Unexpected query result status");
2667 }
2668
2669 if (!bType)
2670 {
2671 if (swapOrder)
2672 emptyRefSlotIdx--;
2673 else
2674 emptyRefSlotIdx++;
2675 }
2676 }
2677 }
2678
2679 if (swapOrder)
2680 {
2681 Move<VkSemaphore> frameEncodedSemaphore = createSemaphore(videoDeviceDriver, videoDevice);
2682 const VkPipelineStageFlags waitDstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
2683
2684 const auto firstCommandFence =
2685 submitCommands(videoDeviceDriver, videoDevice, encodeQueue, *firstEncodeCmdBuffer, false, 1U, 0, nullptr,
2686 nullptr, 1, &frameEncodedSemaphore.get());
2687 waitForFence(videoDeviceDriver, videoDevice, *firstCommandFence);
2688
2689 if (!processQueryPoolResults(videoDeviceDriver, videoDevice, encodeQueryPool.get(), queryId, 1,
2690 bitstreamBufferOffset, minBitstreamBufferOffsetAlignment, queryStatus))
2691 return tcu::TestStatus::fail("Unexpected query result status");
2692
2693 const auto secondCommandFence =
2694 submitCommands(videoDeviceDriver, videoDevice, encodeQueue, *secondEncodeCmdBuffer, false, 1U, 1,
2695 &frameEncodedSemaphore.get(), &waitDstStageMask);
2696 waitForFence(videoDeviceDriver, videoDevice, *secondCommandFence);
2697
2698 if (!processQueryPoolResults(videoDeviceDriver, videoDevice, encodeQueryPool.get(), queryId, 1,
2699 bitstreamBufferOffset, minBitstreamBufferOffsetAlignment, queryStatus))
2700 return tcu::TestStatus::fail("Unexpected query result status");
2701 }
2702
2703 #if STREAM_DUMP_DEBUG
2704 if (m_testDefinition->getProfile()->IsH264())
2705 {
2706 saveBufferAsFile(encodeBuffer, encodeBufferSize, "out.h264");
2707 }
2708 else if (m_testDefinition->getProfile()->IsH265())
2709 {
2710 saveBufferAsFile(encodeBuffer, encodeBufferSize, "out.h265");
2711 }
2712 #endif
2713
2714 // Vulkan video is not supported on android platform
2715 // all external libraries, helper functions and test instances has been excluded
2716 #ifdef DE_BUILD_VIDEO
2717 DeviceContext deviceContext(&m_context, &m_videoDevice, physicalDevice, videoDevice, decodeQueue, encodeQueue,
2718 transferQueue);
2719
2720 const Unique<VkCommandPool> decodeCmdPool(makeCommandPool(videoDeviceDriver, videoDevice, decodeQueueFamilyIndex));
2721 const Unique<VkCommandBuffer> decodeCmdBuffer(
2722 allocateCommandBuffer(videoDeviceDriver, videoDevice, *decodeCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2723
2724 uint32_t H264profileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN;
2725 uint32_t H265profileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN;
2726
2727 uint32_t profileIdc = 0;
2728
2729 if (m_testDefinition->getProfile()->IsH264())
2730 {
2731 profileIdc = H264profileIdc;
2732 }
2733 else if (m_testDefinition->getProfile()->IsH265())
2734 {
2735 profileIdc = H265profileIdc;
2736 }
2737 DE_ASSERT(profileIdc);
2738
2739 auto decodeProfile =
2740 VkVideoCoreProfile(videoCodecDecodeOperation, VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR,
2741 VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR, VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR, profileIdc);
2742 auto basicDecoder =
2743 createBasicDecoder(&deviceContext, &decodeProfile, m_testDefinition->framesToCheck(), resolutionChange);
2744
2745 Demuxer::Params demuxParams = {};
2746 demuxParams.data = std::make_unique<BufferedReader>(
2747 static_cast<const char *>(encodeBuffer.getAllocation().getHostPtr()), encodeBufferSize);
2748 demuxParams.codecOperation = videoCodecDecodeOperation;
2749 demuxParams.framing = ElementaryStreamFraming::H26X_BYTE_STREAM;
2750 auto demuxer = Demuxer::create(std::move(demuxParams));
2751 VkVideoParser parser;
2752 // TODO: Check for decoder extension support before attempting validation!
2753 createParser(demuxer->codecOperation(), basicDecoder, parser, demuxer->framing());
2754
2755 FrameProcessor processor(std::move(demuxer), basicDecoder);
2756 std::vector<int> incorrectFrames;
2757 std::vector<int> correctFrames;
2758 std::vector<double> psnrDiff;
2759
2760 for (int NALIdx = 0; NALIdx < m_testDefinition->framesToCheck(); NALIdx++)
2761 {
2762 DecodedFrame frame;
2763 TCU_CHECK_AND_THROW(
2764 InternalError, processor.getNextFrame(&frame) > 0,
2765 "Expected more frames from the bitstream. Most likely an internal CTS bug, or maybe an invalid bitstream");
2766
2767 auto resultImage =
2768 getDecodedImageFromContext(deviceContext,
2769 basicDecoder->dpbAndOutputCoincide() ? VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR :
2770 VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR,
2771 &frame);
2772 de::MovePtr<std::vector<uint8_t>> out =
2773 vkt::ycbcr::YCbCrConvUtil<uint8_t>::MultiPlanarNV12toI420(resultImage.get());
2774
2775 #if STREAM_DUMP_DEBUG
2776 const string outputFileName = "out_" + std::to_string(NALIdx) + ".yuv";
2777 vkt::ycbcr::YCbCrContent<uint8_t>::save(*out, outputFileName);
2778 #endif
2779 // Quantization maps verification
2780 if (useDeltaMap || useEmphasisMap)
2781 {
2782 double d = util::calculatePSNRdifference(*inVector[NALIdx], *out, codedExtent, quantizationMapExtent,
2783 quantizationMapTexelSize);
2784
2785 psnrDiff.push_back(d);
2786
2787 if (useEmphasisMap && NALIdx == 1)
2788 {
2789 if (psnrDiff[1] <= psnrDiff[0])
2790 return tcu::TestStatus::fail(
2791 "PSNR difference for the second frame is not greater than for the first frame");
2792 }
2793 else if (useDeltaMap && NALIdx == 2)
2794 {
2795 if (psnrDiff[2] > 0)
2796 return tcu::TestStatus::fail(
2797 "PSNR value for left half of the frame is lower than for the right half");
2798 }
2799 }
2800
2801 double higherPsnrThreshold = 30.0;
2802 double lowerPsnrThreshold = 20.0;
2803 double criticalPsnrThreshold = 10;
2804 double psnrThresholdLowerLimit = disableRateControl ? lowerPsnrThreshold : higherPsnrThreshold;
2805 string failMessage;
2806
2807 double psnr = util::PSNR(*inVector[NALIdx], *out);
2808
2809 // Quality checks
2810 if (psnr < psnrThresholdLowerLimit)
2811 {
2812 double difference = psnrThresholdLowerLimit - psnr;
2813
2814 if ((useDeltaMap || useEmphasisMap) && NALIdx == 1)
2815 {
2816 // When testing quantization map, the PSNR of the secont image is expected to be low
2817 break;
2818 }
2819 if (psnr > criticalPsnrThreshold)
2820 {
2821 failMessage = "Frame " + std::to_string(NALIdx) + " with PSNR " + std::to_string(psnr) + " is " +
2822 std::to_string(difference) + " points below the lower threshold";
2823 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, failMessage);
2824 }
2825 else
2826 {
2827 failMessage = "Frame " + std::to_string(NALIdx) + " with PSNR " + std::to_string(psnr) + " is " +
2828 std::to_string(difference) + " points below the critical threshold";
2829 return tcu::TestStatus::fail(failMessage);
2830 }
2831 }
2832 }
2833 const string passMessage = std::to_string(m_testDefinition->framesToCheck()) + " correctly encoded frames";
2834 return tcu::TestStatus::pass(passMessage);
2835
2836 #else
2837 DE_UNREF(transferQueue);
2838 DE_UNREF(decodeQueue);
2839 TCU_THROW(NotSupportedError, "Vulkan video is not supported on android platform");
2840 #endif
2841 }
2842
2843 class VideoEncodeTestCase : public TestCase
2844 {
2845 public:
2846 VideoEncodeTestCase(tcu::TestContext &context, const char *name, MovePtr<TestDefinition> testDefinition);
2847 ~VideoEncodeTestCase(void);
2848
2849 virtual TestInstance *createInstance(Context &context) const;
2850 virtual void checkSupport(Context &context) const;
2851
2852 private:
2853 MovePtr<TestDefinition> m_testDefinition;
2854 };
2855
VideoEncodeTestCase(tcu::TestContext & context,const char * name,MovePtr<TestDefinition> testDefinition)2856 VideoEncodeTestCase::VideoEncodeTestCase(tcu::TestContext &context, const char *name,
2857 MovePtr<TestDefinition> testDefinition)
2858 : vkt::TestCase(context, name)
2859 , m_testDefinition(testDefinition)
2860 {
2861 }
2862
~VideoEncodeTestCase(void)2863 VideoEncodeTestCase::~VideoEncodeTestCase(void)
2864 {
2865 }
2866
checkSupport(Context & context) const2867 void VideoEncodeTestCase::checkSupport(Context &context) const
2868 {
2869 context.requireDeviceFunctionality("VK_KHR_video_queue");
2870 context.requireDeviceFunctionality("VK_KHR_synchronization2");
2871 context.requireDeviceFunctionality("VK_KHR_video_encode_queue");
2872
2873 switch (m_testDefinition->getTestType())
2874 {
2875 case TEST_TYPE_H264_ENCODE_I:
2876 case TEST_TYPE_H264_ENCODE_RC_VBR:
2877 case TEST_TYPE_H264_ENCODE_RC_CBR:
2878 case TEST_TYPE_H264_ENCODE_RC_DISABLE:
2879 case TEST_TYPE_H264_ENCODE_QUALITY_LEVEL:
2880 case TEST_TYPE_H264_ENCODE_USAGE:
2881 case TEST_TYPE_H264_ENCODE_I_P:
2882 case TEST_TYPE_H264_ENCODE_I_P_NOT_MATCHING_ORDER:
2883 case TEST_TYPE_H264_I_P_B_13:
2884 case TEST_TYPE_H264_ENCODE_RESOLUTION_CHANGE_DPB:
2885 case TEST_TYPE_H264_ENCODE_QUERY_RESULT_WITH_STATUS:
2886 context.requireDeviceFunctionality("VK_KHR_video_encode_h264");
2887 break;
2888 case TEST_TYPE_H264_ENCODE_INLINE_QUERY:
2889 case TEST_TYPE_H264_ENCODE_RESOURCES_WITHOUT_PROFILES:
2890 context.requireDeviceFunctionality("VK_KHR_video_encode_h264");
2891 context.requireDeviceFunctionality("VK_KHR_video_maintenance1");
2892 break;
2893 case TEST_TYPE_H264_ENCODE_QM_DELTA_RC_DISABLE:
2894 case TEST_TYPE_H264_ENCODE_QM_DELTA_RC_VBR:
2895 case TEST_TYPE_H264_ENCODE_QM_DELTA_RC_CBR:
2896 case TEST_TYPE_H264_ENCODE_QM_DELTA:
2897 case TEST_TYPE_H264_ENCODE_QM_EMPHASIS_CBR:
2898 case TEST_TYPE_H264_ENCODE_QM_EMPHASIS_VBR:
2899 context.requireDeviceFunctionality("VK_KHR_video_encode_h264");
2900 context.requireDeviceFunctionality("VK_KHR_video_encode_quantization_map");
2901 break;
2902 case TEST_TYPE_H265_ENCODE_I:
2903 case TEST_TYPE_H265_ENCODE_RC_VBR:
2904 case TEST_TYPE_H265_ENCODE_RC_CBR:
2905 case TEST_TYPE_H265_ENCODE_RC_DISABLE:
2906 case TEST_TYPE_H265_ENCODE_QUALITY_LEVEL:
2907 case TEST_TYPE_H265_ENCODE_USAGE:
2908 case TEST_TYPE_H265_ENCODE_I_P:
2909 case TEST_TYPE_H265_ENCODE_I_P_NOT_MATCHING_ORDER:
2910 case TEST_TYPE_H265_I_P_B_13:
2911 case TEST_TYPE_H265_ENCODE_RESOLUTION_CHANGE_DPB:
2912 case TEST_TYPE_H265_ENCODE_QUERY_RESULT_WITH_STATUS:
2913 context.requireDeviceFunctionality("VK_KHR_video_encode_h265");
2914 break;
2915 case TEST_TYPE_H265_ENCODE_INLINE_QUERY:
2916 case TEST_TYPE_H265_ENCODE_RESOURCES_WITHOUT_PROFILES:
2917 context.requireDeviceFunctionality("VK_KHR_video_encode_h265");
2918 context.requireDeviceFunctionality("VK_KHR_video_maintenance1");
2919 break;
2920 case TEST_TYPE_H265_ENCODE_QM_DELTA_RC_DISABLE:
2921 case TEST_TYPE_H265_ENCODE_QM_DELTA_RC_VBR:
2922 case TEST_TYPE_H265_ENCODE_QM_DELTA_RC_CBR:
2923 case TEST_TYPE_H265_ENCODE_QM_DELTA:
2924 case TEST_TYPE_H265_ENCODE_QM_EMPHASIS_CBR:
2925 case TEST_TYPE_H265_ENCODE_QM_EMPHASIS_VBR:
2926 context.requireDeviceFunctionality("VK_KHR_video_encode_h265");
2927 context.requireDeviceFunctionality("VK_KHR_video_encode_quantization_map");
2928 break;
2929 default:
2930 TCU_THROW(InternalError, "Unknown TestType");
2931 }
2932 }
2933
createInstance(Context & context) const2934 TestInstance *VideoEncodeTestCase::createInstance(Context &context) const
2935 {
2936 #ifdef DE_BUILD_VIDEO
2937 return new VideoEncodeTestInstance(context, m_testDefinition.get());
2938 #else
2939 DE_UNREF(context);
2940 return nullptr;
2941 #endif
2942 }
2943
2944 } // namespace
2945
createVideoEncodeTests(tcu::TestContext & testCtx)2946 tcu::TestCaseGroup *createVideoEncodeTests(tcu::TestContext &testCtx)
2947 {
2948 MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "encode", "Video encoding session tests"));
2949
2950 MovePtr<tcu::TestCaseGroup> h264Group(new tcu::TestCaseGroup(testCtx, "h264", "H.264 video codec"));
2951 MovePtr<tcu::TestCaseGroup> h265Group(new tcu::TestCaseGroup(testCtx, "h265", "H.265 video codec"));
2952
2953 for (const auto &encodeTest : g_EncodeTests)
2954 {
2955 auto defn = TestDefinition::create(encodeTest);
2956
2957 const char *testName = getTestName(defn->getTestType());
2958 auto testCodec = getTestCodec(defn->getTestType());
2959
2960 if (testCodec == TEST_CODEC_H264)
2961 h264Group->addChild(new VideoEncodeTestCase(testCtx, testName, defn));
2962 else if (testCodec == TEST_CODEC_H265)
2963 h265Group->addChild(new VideoEncodeTestCase(testCtx, testName, defn));
2964 else
2965 {
2966 TCU_THROW(InternalError, "Unknown Video Codec");
2967 }
2968 }
2969
2970 group->addChild(h264Group.release());
2971 group->addChild(h265Group.release());
2972 group->addChild(createVideoEncodeTestsAV1(testCtx));
2973
2974 return group.release();
2975 }
2976 } // namespace video
2977 } // namespace vkt
2978