• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &copyRegion);
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