tests/amdgpu/vcn: fix drm test failure
[platform/upstream/libdrm.git] / tests / amdgpu / vcn_tests.c
1 /*
2  * Copyright 2017 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22 */
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <inttypes.h>
27 #include <unistd.h>
28
29 #include "CUnit/Basic.h"
30
31 #include <unistd.h>
32 #include "util_math.h"
33
34 #include "amdgpu_test.h"
35 #include "amdgpu_drm.h"
36 #include "amdgpu_internal.h"
37 #include "decode_messages.h"
38 #include "frame.h"
39
40 #define IB_SIZE         4096
41 #define MAX_RESOURCES   16
42
43 #define DECODE_CMD_MSG_BUFFER                              0x00000000
44 #define DECODE_CMD_DPB_BUFFER                              0x00000001
45 #define DECODE_CMD_DECODING_TARGET_BUFFER                  0x00000002
46 #define DECODE_CMD_FEEDBACK_BUFFER                         0x00000003
47 #define DECODE_CMD_PROB_TBL_BUFFER                         0x00000004
48 #define DECODE_CMD_SESSION_CONTEXT_BUFFER                  0x00000005
49 #define DECODE_CMD_BITSTREAM_BUFFER                        0x00000100
50 #define DECODE_CMD_IT_SCALING_TABLE_BUFFER                 0x00000204
51 #define DECODE_CMD_CONTEXT_BUFFER                          0x00000206
52
53 #define DECODE_IB_PARAM_DECODE_BUFFER                      (0x00000001)
54
55 #define DECODE_CMDBUF_FLAGS_MSG_BUFFER                     (0x00000001)
56 #define DECODE_CMDBUF_FLAGS_DPB_BUFFER                     (0x00000002)
57 #define DECODE_CMDBUF_FLAGS_BITSTREAM_BUFFER               (0x00000004)
58 #define DECODE_CMDBUF_FLAGS_DECODING_TARGET_BUFFER         (0x00000008)
59 #define DECODE_CMDBUF_FLAGS_FEEDBACK_BUFFER                (0x00000010)
60 #define DECODE_CMDBUF_FLAGS_IT_SCALING_BUFFER              (0x00000200)
61 #define DECODE_CMDBUF_FLAGS_CONTEXT_BUFFER                 (0x00000800)
62 #define DECODE_CMDBUF_FLAGS_PROB_TBL_BUFFER                (0x00001000)
63 #define DECODE_CMDBUF_FLAGS_SESSION_CONTEXT_BUFFER         (0x00100000)
64
65 static bool vcn_dec_sw_ring = false;
66 static bool vcn_unified_ring = false;
67
68 #define H264_NAL_TYPE_NON_IDR_SLICE 1
69 #define H264_NAL_TYPE_DP_A_SLICE 2
70 #define H264_NAL_TYPE_DP_B_SLICE 3
71 #define H264_NAL_TYPE_DP_C_SLICE 0x4
72 #define H264_NAL_TYPE_IDR_SLICE 0x5
73 #define H264_NAL_TYPE_SEI 0x6
74 #define H264_NAL_TYPE_SEQ_PARAM 0x7
75 #define H264_NAL_TYPE_PIC_PARAM 0x8
76 #define H264_NAL_TYPE_ACCESS_UNIT 0x9
77 #define H264_NAL_TYPE_END_OF_SEQ 0xa
78 #define H264_NAL_TYPE_END_OF_STREAM 0xb
79 #define H264_NAL_TYPE_FILLER_DATA 0xc
80 #define H264_NAL_TYPE_SEQ_EXTENSION 0xd
81
82 #define H264_START_CODE 0x000001
83
84 struct amdgpu_vcn_bo {
85         amdgpu_bo_handle handle;
86         amdgpu_va_handle va_handle;
87         uint64_t addr;
88         uint64_t size;
89         uint8_t *ptr;
90 };
91
92 typedef struct rvcn_decode_buffer_s {
93         unsigned int valid_buf_flag;
94         unsigned int msg_buffer_address_hi;
95         unsigned int msg_buffer_address_lo;
96         unsigned int dpb_buffer_address_hi;
97         unsigned int dpb_buffer_address_lo;
98         unsigned int target_buffer_address_hi;
99         unsigned int target_buffer_address_lo;
100         unsigned int session_contex_buffer_address_hi;
101         unsigned int session_contex_buffer_address_lo;
102         unsigned int bitstream_buffer_address_hi;
103         unsigned int bitstream_buffer_address_lo;
104         unsigned int context_buffer_address_hi;
105         unsigned int context_buffer_address_lo;
106         unsigned int feedback_buffer_address_hi;
107         unsigned int feedback_buffer_address_lo;
108         unsigned int luma_hist_buffer_address_hi;
109         unsigned int luma_hist_buffer_address_lo;
110         unsigned int prob_tbl_buffer_address_hi;
111         unsigned int prob_tbl_buffer_address_lo;
112         unsigned int sclr_coeff_buffer_address_hi;
113         unsigned int sclr_coeff_buffer_address_lo;
114         unsigned int it_sclr_table_buffer_address_hi;
115         unsigned int it_sclr_table_buffer_address_lo;
116         unsigned int sclr_target_buffer_address_hi;
117         unsigned int sclr_target_buffer_address_lo;
118         unsigned int cenc_size_info_buffer_address_hi;
119         unsigned int cenc_size_info_buffer_address_lo;
120         unsigned int mpeg2_pic_param_buffer_address_hi;
121         unsigned int mpeg2_pic_param_buffer_address_lo;
122         unsigned int mpeg2_mb_control_buffer_address_hi;
123         unsigned int mpeg2_mb_control_buffer_address_lo;
124         unsigned int mpeg2_idct_coeff_buffer_address_hi;
125         unsigned int mpeg2_idct_coeff_buffer_address_lo;
126 } rvcn_decode_buffer_t;
127
128 typedef struct rvcn_decode_ib_package_s {
129         unsigned int package_size;
130         unsigned int package_type;
131 } rvcn_decode_ib_package_t;
132
133
134 struct amdgpu_vcn_reg {
135         uint32_t data0;
136         uint32_t data1;
137         uint32_t cmd;
138         uint32_t nop;
139         uint32_t cntl;
140 };
141
142 typedef struct BufferInfo_t {
143         uint32_t numOfBitsInBuffer;
144         const uint8_t *decBuffer;
145         uint8_t decData;
146         uint32_t decBufferSize;
147         const uint8_t *end;
148 } bufferInfo;
149
150 typedef struct h264_decode_t {
151         uint8_t profile;
152         uint8_t level_idc;
153         uint8_t nal_ref_idc;
154         uint8_t nal_unit_type;
155         uint32_t pic_width, pic_height;
156         uint32_t slice_type;
157 } h264_decode;
158
159 static amdgpu_device_handle device_handle;
160 static uint32_t major_version;
161 static uint32_t minor_version;
162 static uint32_t family_id;
163 static uint32_t chip_rev;
164 static uint32_t chip_id;
165 static uint32_t asic_id;
166 static uint32_t chip_rev;
167 static struct amdgpu_vcn_bo enc_buf;
168 static struct amdgpu_vcn_bo cpb_buf;
169 static uint32_t enc_task_id;
170
171 static amdgpu_context_handle context_handle;
172 static amdgpu_bo_handle ib_handle;
173 static amdgpu_va_handle ib_va_handle;
174 static uint64_t ib_mc_address;
175 static uint32_t *ib_cpu;
176 static uint32_t *ib_checksum;
177 static uint32_t *ib_size_in_dw;
178
179 static rvcn_decode_buffer_t *decode_buffer;
180
181 static amdgpu_bo_handle resources[MAX_RESOURCES];
182 static unsigned num_resources;
183
184 static uint8_t vcn_reg_index;
185 static struct amdgpu_vcn_reg reg[] = {
186         {0x81c4, 0x81c5, 0x81c3, 0x81ff, 0x81c6},
187         {0x504, 0x505, 0x503, 0x53f, 0x506},
188         {0x10, 0x11, 0xf, 0x29, 0x26d},
189 };
190
191 uint32_t gWidth, gHeight, gSliceType;
192 static uint32_t vcn_ip_version_major;
193 static uint32_t vcn_ip_version_minor;
194 static void amdgpu_cs_vcn_dec_create(void);
195 static void amdgpu_cs_vcn_dec_decode(void);
196 static void amdgpu_cs_vcn_dec_destroy(void);
197
198 static void amdgpu_cs_vcn_enc_create(void);
199 static void amdgpu_cs_vcn_enc_encode(void);
200 static void amdgpu_cs_vcn_enc_destroy(void);
201
202 static void amdgpu_cs_sq_head(uint32_t *base, int *offset, bool enc);
203 static void amdgpu_cs_sq_ib_tail(uint32_t *end);
204 static void h264_check_0s (bufferInfo * bufInfo, int count);
205 static int32_t h264_se (bufferInfo * bufInfo);
206 static inline uint32_t bs_read_u1(bufferInfo *bufinfo);
207 static inline int bs_eof(bufferInfo *bufinfo);
208 static inline uint32_t bs_read_u(bufferInfo* bufinfo, int n);
209 static inline uint32_t bs_read_ue(bufferInfo* bufinfo);
210 static uint32_t remove_03 (uint8_t *bptr, uint32_t len);
211 static void scaling_list (uint32_t ix, uint32_t sizeOfScalingList, bufferInfo *bufInfo);
212 static void h264_parse_sequence_parameter_set (h264_decode * dec, bufferInfo *bufInfo);
213 static void h264_slice_header (h264_decode *dec, bufferInfo *bufInfo);
214 static uint8_t h264_parse_nal (h264_decode *dec, bufferInfo *bufInfo);
215 static uint32_t h264_find_next_start_code (uint8_t *pBuf, uint32_t bufLen);
216 static int verify_checksum(uint8_t *buffer, uint32_t buffer_size);
217
218 CU_TestInfo vcn_tests[] = {
219
220         { "VCN DEC create",  amdgpu_cs_vcn_dec_create },
221         { "VCN DEC decode",  amdgpu_cs_vcn_dec_decode },
222         { "VCN DEC destroy",  amdgpu_cs_vcn_dec_destroy },
223
224         { "VCN ENC create",  amdgpu_cs_vcn_enc_create },
225         { "VCN ENC encode",  amdgpu_cs_vcn_enc_encode },
226         { "VCN ENC destroy",  amdgpu_cs_vcn_enc_destroy },
227         CU_TEST_INFO_NULL,
228 };
229
230 CU_BOOL suite_vcn_tests_enable(void)
231 {
232         struct drm_amdgpu_info_hw_ip info;
233         bool enc_ring, dec_ring;
234         int r;
235
236         if (amdgpu_device_initialize(drm_amdgpu[0], &major_version,
237                                    &minor_version, &device_handle))
238                 return CU_FALSE;
239
240         family_id = device_handle->info.family_id;
241         asic_id = device_handle->info.asic_id;
242         chip_rev = device_handle->info.chip_rev;
243         chip_id = device_handle->info.chip_external_rev;
244
245         r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_VCN_ENC, 0, &info);
246         if (!r) {
247                 vcn_ip_version_major = info.hw_ip_version_major;
248                 vcn_ip_version_minor = info.hw_ip_version_minor;
249                 enc_ring = !!info.available_rings;
250                 /* in vcn 4.0 it re-uses encoding queue as unified queue */
251                 if (vcn_ip_version_major >= 4) {
252                         vcn_unified_ring = true;
253                         vcn_dec_sw_ring = true;
254                         dec_ring = enc_ring;
255                 } else {
256                         r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_VCN_DEC, 0, &info);
257                         dec_ring = !!info.available_rings;
258                 }
259         }
260
261         if (amdgpu_device_deinitialize(device_handle))
262                 return CU_FALSE;
263
264         if (r) {
265                 printf("\n\nASIC query hw info failed\n");
266                 return CU_FALSE;
267         }
268
269         if (!(dec_ring || enc_ring) ||
270             (family_id < AMDGPU_FAMILY_RV &&
271              (family_id == AMDGPU_FAMILY_AI &&
272               (chip_id - chip_rev) < 0x32))) {  /* Arcturus */
273                 printf("\n\nThe ASIC NOT support VCN, suite disabled\n");
274                 return CU_FALSE;
275         }
276
277         if (!dec_ring) {
278                 amdgpu_set_test_active("VCN Tests", "VCN DEC create", CU_FALSE);
279                 amdgpu_set_test_active("VCN Tests", "VCN DEC decode", CU_FALSE);
280                 amdgpu_set_test_active("VCN Tests", "VCN DEC destroy", CU_FALSE);
281         }
282
283         if (family_id == AMDGPU_FAMILY_AI || !enc_ring) {
284                 amdgpu_set_test_active("VCN Tests", "VCN ENC create", CU_FALSE);
285                 amdgpu_set_test_active("VCN Tests", "VCN ENC encode", CU_FALSE);
286                 amdgpu_set_test_active("VCN Tests", "VCN ENC destroy", CU_FALSE);
287         }
288
289         if (vcn_ip_version_major == 1)
290                 vcn_reg_index = 0;
291         else if (vcn_ip_version_major == 2 && vcn_ip_version_minor == 0)
292                 vcn_reg_index = 1;
293         else if ((vcn_ip_version_major == 2 && vcn_ip_version_minor >= 5) ||
294                                 vcn_ip_version_major == 3)
295                 vcn_reg_index = 2;
296
297         return CU_TRUE;
298 }
299
300 int suite_vcn_tests_init(void)
301 {
302         int r;
303
304         r = amdgpu_device_initialize(drm_amdgpu[0], &major_version,
305                                      &minor_version, &device_handle);
306         if (r)
307                 return CUE_SINIT_FAILED;
308
309         family_id = device_handle->info.family_id;
310
311         r = amdgpu_cs_ctx_create(device_handle, &context_handle);
312         if (r)
313                 return CUE_SINIT_FAILED;
314
315         r = amdgpu_bo_alloc_and_map(device_handle, IB_SIZE, 4096,
316                                     AMDGPU_GEM_DOMAIN_GTT, 0,
317                                     &ib_handle, (void**)&ib_cpu,
318                                     &ib_mc_address, &ib_va_handle);
319         if (r)
320                 return CUE_SINIT_FAILED;
321
322         return CUE_SUCCESS;
323 }
324
325 int suite_vcn_tests_clean(void)
326 {
327         int r;
328
329         r = amdgpu_bo_unmap_and_free(ib_handle, ib_va_handle,
330                              ib_mc_address, IB_SIZE);
331         if (r)
332                 return CUE_SCLEAN_FAILED;
333
334         r = amdgpu_cs_ctx_free(context_handle);
335         if (r)
336                 return CUE_SCLEAN_FAILED;
337
338         r = amdgpu_device_deinitialize(device_handle);
339         if (r)
340                 return CUE_SCLEAN_FAILED;
341
342         return CUE_SUCCESS;
343 }
344
345 static void amdgpu_cs_sq_head(uint32_t *base, int *offset, bool enc)
346 {
347         /* signature */
348         *(base + (*offset)++) = 0x00000010;
349         *(base + (*offset)++) = 0x30000002;
350         ib_checksum = base + (*offset)++;
351         ib_size_in_dw = base + (*offset)++;
352
353         /* engine info */
354         *(base + (*offset)++) = 0x00000010;
355         *(base + (*offset)++) = 0x30000001;
356         *(base + (*offset)++) = enc ? 2 : 3;
357         *(base + (*offset)++) = 0x00000000;
358 }
359
360 static void amdgpu_cs_sq_ib_tail(uint32_t *end)
361 {
362         uint32_t size_in_dw;
363         uint32_t checksum = 0;
364
365         /* if the pointers are invalid, no need to process */
366         if (ib_checksum == NULL || ib_size_in_dw == NULL)
367                 return;
368
369         size_in_dw = end - ib_size_in_dw - 1;
370         *ib_size_in_dw = size_in_dw;
371         *(ib_size_in_dw + 4) = size_in_dw * sizeof(uint32_t);
372
373         for (int i = 0; i < size_in_dw; i++)
374                 checksum += *(ib_checksum + 2 + i);
375
376         *ib_checksum = checksum;
377
378         ib_checksum = NULL;
379         ib_size_in_dw = NULL;
380 }
381
382 static int submit(unsigned ndw, unsigned ip)
383 {
384         struct amdgpu_cs_request ibs_request = {0};
385         struct amdgpu_cs_ib_info ib_info = {0};
386         struct amdgpu_cs_fence fence_status = {0};
387         uint32_t expired;
388         int r;
389
390         ib_info.ib_mc_address = ib_mc_address;
391         ib_info.size = ndw;
392
393         ibs_request.ip_type = ip;
394
395         r = amdgpu_bo_list_create(device_handle, num_resources, resources,
396                                   NULL, &ibs_request.resources);
397         if (r)
398                 return r;
399
400         ibs_request.number_of_ibs = 1;
401         ibs_request.ibs = &ib_info;
402         ibs_request.fence_info.handle = NULL;
403
404         r = amdgpu_cs_submit(context_handle, 0, &ibs_request, 1);
405         if (r)
406                 return r;
407
408         r = amdgpu_bo_list_destroy(ibs_request.resources);
409         if (r)
410                 return r;
411
412         fence_status.context = context_handle;
413         fence_status.ip_type = ip;
414         fence_status.fence = ibs_request.seq_no;
415
416         r = amdgpu_cs_query_fence_status(&fence_status,
417                                          AMDGPU_TIMEOUT_INFINITE,
418                                          0, &expired);
419         if (r)
420                 return r;
421
422         return 0;
423 }
424
425 static void alloc_resource(struct amdgpu_vcn_bo *vcn_bo,
426                         unsigned size, unsigned domain)
427 {
428         struct amdgpu_bo_alloc_request req = {0};
429         amdgpu_bo_handle buf_handle;
430         amdgpu_va_handle va_handle;
431         uint64_t va = 0;
432         int r;
433
434         req.alloc_size = ALIGN(size, 4096);
435         req.preferred_heap = domain;
436         r = amdgpu_bo_alloc(device_handle, &req, &buf_handle);
437         CU_ASSERT_EQUAL(r, 0);
438         r = amdgpu_va_range_alloc(device_handle,
439                                   amdgpu_gpu_va_range_general,
440                                   req.alloc_size, 1, 0, &va,
441                                   &va_handle, 0);
442         CU_ASSERT_EQUAL(r, 0);
443         r = amdgpu_bo_va_op(buf_handle, 0, req.alloc_size, va, 0,
444                             AMDGPU_VA_OP_MAP);
445         CU_ASSERT_EQUAL(r, 0);
446         vcn_bo->addr = va;
447         vcn_bo->handle = buf_handle;
448         vcn_bo->size = req.alloc_size;
449         vcn_bo->va_handle = va_handle;
450         r = amdgpu_bo_cpu_map(vcn_bo->handle, (void **)&vcn_bo->ptr);
451         CU_ASSERT_EQUAL(r, 0);
452         memset(vcn_bo->ptr, 0, size);
453         r = amdgpu_bo_cpu_unmap(vcn_bo->handle);
454         CU_ASSERT_EQUAL(r, 0);
455 }
456
457 static void free_resource(struct amdgpu_vcn_bo *vcn_bo)
458 {
459         int r;
460
461         r = amdgpu_bo_va_op(vcn_bo->handle, 0, vcn_bo->size,
462                             vcn_bo->addr, 0, AMDGPU_VA_OP_UNMAP);
463         CU_ASSERT_EQUAL(r, 0);
464
465         r = amdgpu_va_range_free(vcn_bo->va_handle);
466         CU_ASSERT_EQUAL(r, 0);
467
468         r = amdgpu_bo_free(vcn_bo->handle);
469         CU_ASSERT_EQUAL(r, 0);
470         memset(vcn_bo, 0, sizeof(*vcn_bo));
471 }
472
473 static void vcn_dec_cmd(uint64_t addr, unsigned cmd, int *idx)
474 {
475         if (vcn_dec_sw_ring == false) {
476                 ib_cpu[(*idx)++] = reg[vcn_reg_index].data0;
477                 ib_cpu[(*idx)++] = addr;
478                 ib_cpu[(*idx)++] = reg[vcn_reg_index].data1;
479                 ib_cpu[(*idx)++] = addr >> 32;
480                 ib_cpu[(*idx)++] = reg[vcn_reg_index].cmd;
481                 ib_cpu[(*idx)++] = cmd << 1;
482                 return;
483         }
484
485         /* Support decode software ring message */
486         if (!(*idx)) {
487                 rvcn_decode_ib_package_t *ib_header;
488
489                 if (vcn_unified_ring)
490                         amdgpu_cs_sq_head(ib_cpu, idx, false);
491
492                 ib_header = (rvcn_decode_ib_package_t *)&ib_cpu[*idx];
493                 ib_header->package_size = sizeof(struct rvcn_decode_buffer_s) +
494                         sizeof(struct rvcn_decode_ib_package_s);
495
496                 (*idx)++;
497                 ib_header->package_type = (DECODE_IB_PARAM_DECODE_BUFFER);
498                 (*idx)++;
499
500                 decode_buffer = (rvcn_decode_buffer_t *)&(ib_cpu[*idx]);
501                 *idx += sizeof(struct rvcn_decode_buffer_s) / 4;
502                 memset(decode_buffer, 0, sizeof(struct rvcn_decode_buffer_s));
503         }
504
505         switch(cmd) {
506                 case DECODE_CMD_MSG_BUFFER:
507                         decode_buffer->valid_buf_flag |= DECODE_CMDBUF_FLAGS_MSG_BUFFER;
508                         decode_buffer->msg_buffer_address_hi = (addr >> 32);
509                         decode_buffer->msg_buffer_address_lo = (addr);
510                 break;
511                 case DECODE_CMD_DPB_BUFFER:
512                         decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_DPB_BUFFER);
513                         decode_buffer->dpb_buffer_address_hi = (addr >> 32);
514                         decode_buffer->dpb_buffer_address_lo = (addr);
515                 break;
516                 case DECODE_CMD_DECODING_TARGET_BUFFER:
517                         decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_DECODING_TARGET_BUFFER);
518                         decode_buffer->target_buffer_address_hi = (addr >> 32);
519                         decode_buffer->target_buffer_address_lo = (addr);
520                 break;
521                 case DECODE_CMD_FEEDBACK_BUFFER:
522                         decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_FEEDBACK_BUFFER);
523                         decode_buffer->feedback_buffer_address_hi = (addr >> 32);
524                         decode_buffer->feedback_buffer_address_lo = (addr);
525                 break;
526                 case DECODE_CMD_PROB_TBL_BUFFER:
527                         decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_PROB_TBL_BUFFER);
528                         decode_buffer->prob_tbl_buffer_address_hi = (addr >> 32);
529                         decode_buffer->prob_tbl_buffer_address_lo = (addr);
530                 break;
531                 case DECODE_CMD_SESSION_CONTEXT_BUFFER:
532                         decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_SESSION_CONTEXT_BUFFER);
533                         decode_buffer->session_contex_buffer_address_hi = (addr >> 32);
534                         decode_buffer->session_contex_buffer_address_lo = (addr);
535                 break;
536                 case DECODE_CMD_BITSTREAM_BUFFER:
537                         decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_BITSTREAM_BUFFER);
538                         decode_buffer->bitstream_buffer_address_hi = (addr >> 32);
539                         decode_buffer->bitstream_buffer_address_lo = (addr);
540                 break;
541                 case DECODE_CMD_IT_SCALING_TABLE_BUFFER:
542                         decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_IT_SCALING_BUFFER);
543                         decode_buffer->it_sclr_table_buffer_address_hi = (addr >> 32);
544                         decode_buffer->it_sclr_table_buffer_address_lo = (addr);
545                 break;
546                 case DECODE_CMD_CONTEXT_BUFFER:
547                         decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_CONTEXT_BUFFER);
548                         decode_buffer->context_buffer_address_hi = (addr >> 32);
549                         decode_buffer->context_buffer_address_lo = (addr);
550                 break;
551                 default:
552                         printf("Not Support!\n");
553         }
554 }
555
556 static void amdgpu_cs_vcn_dec_create(void)
557 {
558         struct amdgpu_vcn_bo msg_buf;
559         unsigned ip;
560         int len, r;
561
562         num_resources  = 0;
563         alloc_resource(&msg_buf, 4096, AMDGPU_GEM_DOMAIN_GTT);
564         resources[num_resources++] = msg_buf.handle;
565         resources[num_resources++] = ib_handle;
566
567         r = amdgpu_bo_cpu_map(msg_buf.handle, (void **)&msg_buf.ptr);
568         CU_ASSERT_EQUAL(r, 0);
569
570         memset(msg_buf.ptr, 0, 4096);
571         memcpy(msg_buf.ptr, vcn_dec_create_msg, sizeof(vcn_dec_create_msg));
572
573         len = 0;
574         if (vcn_dec_sw_ring == true)
575                 vcn_dec_cmd(msg_buf.addr, 0, &len);
576         else {
577                 ib_cpu[len++] = reg[vcn_reg_index].data0;
578                 ib_cpu[len++] = msg_buf.addr;
579                 ib_cpu[len++] = reg[vcn_reg_index].data1;
580                 ib_cpu[len++] = msg_buf.addr >> 32;
581                 ib_cpu[len++] = reg[vcn_reg_index].cmd;
582                 ib_cpu[len++] = 0;
583                 for (; len % 16; ) {
584                         ib_cpu[len++] = reg[vcn_reg_index].nop;
585                         ib_cpu[len++] = 0;
586                 }
587         }
588
589         if (vcn_unified_ring) {
590                 amdgpu_cs_sq_ib_tail(ib_cpu + len);
591                 ip = AMDGPU_HW_IP_VCN_ENC;
592         } else
593                 ip = AMDGPU_HW_IP_VCN_DEC;
594
595         r = submit(len, ip);
596
597         CU_ASSERT_EQUAL(r, 0);
598
599         free_resource(&msg_buf);
600 }
601
602 static void amdgpu_cs_vcn_dec_decode(void)
603 {
604         const unsigned dpb_size = 15923584, dt_size = 737280;
605         uint64_t msg_addr, fb_addr, bs_addr, dpb_addr, ctx_addr, dt_addr, it_addr, sum;
606         struct amdgpu_vcn_bo dec_buf;
607         int size, len, i, r;
608         unsigned ip;
609         uint8_t *dec;
610
611         size = 4*1024; /* msg */
612         size += 4*1024; /* fb */
613         size += 4096; /*it_scaling_table*/
614         size += ALIGN(sizeof(uvd_bitstream), 4*1024);
615         size += ALIGN(dpb_size, 4*1024);
616         size += ALIGN(dt_size, 4*1024);
617
618         num_resources = 0;
619         alloc_resource(&dec_buf, size, AMDGPU_GEM_DOMAIN_GTT);
620         resources[num_resources++] = dec_buf.handle;
621         resources[num_resources++] = ib_handle;
622
623         r = amdgpu_bo_cpu_map(dec_buf.handle, (void **)&dec_buf.ptr);
624         dec = dec_buf.ptr;
625
626         CU_ASSERT_EQUAL(r, 0);
627         memset(dec_buf.ptr, 0, size);
628         memcpy(dec_buf.ptr, vcn_dec_decode_msg, sizeof(vcn_dec_decode_msg));
629         memcpy(dec_buf.ptr + sizeof(vcn_dec_decode_msg),
630                         avc_decode_msg, sizeof(avc_decode_msg));
631
632         dec += 4*1024;
633         memcpy(dec, feedback_msg, sizeof(feedback_msg));
634         dec += 4*1024;
635         memcpy(dec, uvd_it_scaling_table, sizeof(uvd_it_scaling_table));
636
637         dec += 4*1024;
638         memcpy(dec, uvd_bitstream, sizeof(uvd_bitstream));
639
640         dec += ALIGN(sizeof(uvd_bitstream), 4*1024);
641
642         dec += ALIGN(dpb_size, 4*1024);
643
644         msg_addr = dec_buf.addr;
645         fb_addr = msg_addr + 4*1024;
646         it_addr = fb_addr + 4*1024;
647         bs_addr = it_addr + 4*1024;
648         dpb_addr = ALIGN(bs_addr + sizeof(uvd_bitstream), 4*1024);
649         ctx_addr = ALIGN(dpb_addr + 0x006B9400, 4*1024);
650         dt_addr = ALIGN(dpb_addr + dpb_size, 4*1024);
651
652         len = 0;
653         vcn_dec_cmd(msg_addr, 0x0, &len);
654         vcn_dec_cmd(dpb_addr, 0x1, &len);
655         vcn_dec_cmd(dt_addr, 0x2, &len);
656         vcn_dec_cmd(fb_addr, 0x3, &len);
657         vcn_dec_cmd(bs_addr, 0x100, &len);
658         vcn_dec_cmd(it_addr, 0x204, &len);
659         vcn_dec_cmd(ctx_addr, 0x206, &len);
660
661         if (vcn_dec_sw_ring == false) {
662                 ib_cpu[len++] = reg[vcn_reg_index].cntl;
663                 ib_cpu[len++] = 0x1;
664                 for (; len % 16; ) {
665                         ib_cpu[len++] = reg[vcn_reg_index].nop;
666                         ib_cpu[len++] = 0;
667                 }
668         }
669
670         if (vcn_unified_ring) {
671                 amdgpu_cs_sq_ib_tail(ib_cpu + len);
672                 ip = AMDGPU_HW_IP_VCN_ENC;
673         } else
674                 ip = AMDGPU_HW_IP_VCN_DEC;
675
676         r = submit(len, ip);
677         CU_ASSERT_EQUAL(r, 0);
678
679         for (i = 0, sum = 0; i < dt_size; ++i)
680                 sum += dec[i];
681
682         CU_ASSERT_EQUAL(sum, SUM_DECODE);
683
684         free_resource(&dec_buf);
685 }
686
687 static void amdgpu_cs_vcn_dec_destroy(void)
688 {
689         struct amdgpu_vcn_bo msg_buf;
690         unsigned ip;
691         int len, r;
692
693         num_resources = 0;
694         alloc_resource(&msg_buf, 1024, AMDGPU_GEM_DOMAIN_GTT);
695         resources[num_resources++] = msg_buf.handle;
696         resources[num_resources++] = ib_handle;
697
698         r = amdgpu_bo_cpu_map(msg_buf.handle, (void **)&msg_buf.ptr);
699         CU_ASSERT_EQUAL(r, 0);
700
701         memset(msg_buf.ptr, 0, 1024);
702         memcpy(msg_buf.ptr, vcn_dec_destroy_msg, sizeof(vcn_dec_destroy_msg));
703
704         len = 0;
705         if (vcn_dec_sw_ring == true)
706                 vcn_dec_cmd(msg_buf.addr, 0, &len);
707         else {
708                 ib_cpu[len++] = reg[vcn_reg_index].data0;
709                 ib_cpu[len++] = msg_buf.addr;
710                 ib_cpu[len++] = reg[vcn_reg_index].data1;
711                 ib_cpu[len++] = msg_buf.addr >> 32;
712                 ib_cpu[len++] = reg[vcn_reg_index].cmd;
713                 ib_cpu[len++] = 0;
714                 for (; len % 16; ) {
715                         ib_cpu[len++] = reg[vcn_reg_index].nop;
716                         ib_cpu[len++] = 0;
717                 }
718         }
719
720         if (vcn_unified_ring) {
721                 amdgpu_cs_sq_ib_tail(ib_cpu + len);
722                 ip = AMDGPU_HW_IP_VCN_ENC;
723         } else
724                 ip = AMDGPU_HW_IP_VCN_DEC;
725
726         r = submit(len, ip);
727         CU_ASSERT_EQUAL(r, 0);
728
729         free_resource(&msg_buf);
730 }
731
732 static void amdgpu_cs_vcn_enc_create(void)
733 {
734         int len, r;
735         uint32_t *p_task_size = NULL;
736         uint32_t task_offset = 0, st_offset;
737         uint32_t *st_size = NULL;
738         unsigned width = 160, height = 128, buf_size;
739         uint32_t fw_maj = 1, fw_min = 9;
740
741         if (vcn_ip_version_major == 2) {
742                 fw_maj = 1;
743                 fw_min = 1;
744         } else if (vcn_ip_version_major == 3) {
745                 fw_maj = 1;
746                 fw_min = 0;
747         }
748
749         gWidth = width;
750         gHeight = height;
751         buf_size = ALIGN(width, 256) * ALIGN(height, 32) * 3 / 2;
752         enc_task_id = 1;
753
754         num_resources = 0;
755         alloc_resource(&enc_buf, 128 * 1024, AMDGPU_GEM_DOMAIN_GTT);
756         alloc_resource(&cpb_buf, buf_size * 2, AMDGPU_GEM_DOMAIN_GTT);
757         resources[num_resources++] = enc_buf.handle;
758         resources[num_resources++] = cpb_buf.handle;
759         resources[num_resources++] = ib_handle;
760
761         r = amdgpu_bo_cpu_map(enc_buf.handle, (void**)&enc_buf.ptr);
762         memset(enc_buf.ptr, 0, 128 * 1024);
763         r = amdgpu_bo_cpu_unmap(enc_buf.handle);
764
765         r = amdgpu_bo_cpu_map(cpb_buf.handle, (void**)&enc_buf.ptr);
766         memset(enc_buf.ptr, 0, buf_size * 2);
767         r = amdgpu_bo_cpu_unmap(cpb_buf.handle);
768
769         len = 0;
770
771         if (vcn_unified_ring)
772                 amdgpu_cs_sq_head(ib_cpu, &len, true);
773
774         /* session info */
775         st_offset = len;
776         st_size = &ib_cpu[len++];       /* size */
777         ib_cpu[len++] = 0x00000001;     /* RENCODE_IB_PARAM_SESSION_INFO */
778         ib_cpu[len++] = ((fw_maj << 16) | (fw_min << 0));
779         ib_cpu[len++] = enc_buf.addr >> 32;
780         ib_cpu[len++] = enc_buf.addr;
781         ib_cpu[len++] = 1;      /* RENCODE_ENGINE_TYPE_ENCODE; */
782         *st_size = (len - st_offset) * 4;
783
784         /* task info */
785         task_offset = len;
786         st_offset = len;
787         st_size = &ib_cpu[len++];       /* size */
788         ib_cpu[len++] = 0x00000002;     /* RENCODE_IB_PARAM_TASK_INFO */
789         p_task_size = &ib_cpu[len++];
790         ib_cpu[len++] = enc_task_id++;  /* task_id */
791         ib_cpu[len++] = 0;      /* feedback */
792         *st_size = (len - st_offset) * 4;
793
794         /* op init */
795         st_offset = len;
796         st_size = &ib_cpu[len++];       /* size */
797         ib_cpu[len++] = 0x01000001;     /* RENCODE_IB_OP_INITIALIZE */
798         *st_size = (len - st_offset) * 4;
799
800         /* session_init */
801         st_offset = len;
802         st_size = &ib_cpu[len++];       /* size */
803         ib_cpu[len++] = 0x00000003;     /* RENCODE_IB_PARAM_SESSION_INIT */
804         ib_cpu[len++] = 1;      /* RENCODE_ENCODE_STANDARD_H264 */
805         ib_cpu[len++] = width;
806         ib_cpu[len++] = height;
807         ib_cpu[len++] = 0;
808         ib_cpu[len++] = 0;
809         ib_cpu[len++] = 0;      /* pre encode mode */
810         ib_cpu[len++] = 0;      /* chroma enabled : false */
811         ib_cpu[len++] = 0;
812         ib_cpu[len++] = 0;
813         *st_size = (len - st_offset) * 4;
814
815         /* slice control */
816         st_offset = len;
817         st_size = &ib_cpu[len++];       /* size */
818         ib_cpu[len++] = 0x00200001;     /* RENCODE_H264_IB_PARAM_SLICE_CONTROL */
819         ib_cpu[len++] = 0;      /* RENCODE_H264_SLICE_CONTROL_MODE_FIXED_MBS */
820         ib_cpu[len++] = ALIGN(width, 16) / 16 * ALIGN(height, 16) / 16;
821         *st_size = (len - st_offset) * 4;
822
823         /* enc spec misc */
824         st_offset = len;
825         st_size = &ib_cpu[len++];       /* size */
826         ib_cpu[len++] = 0x00200002;     /* RENCODE_H264_IB_PARAM_SPEC_MISC */
827         ib_cpu[len++] = 0;      /* constrained intra pred flag */
828         ib_cpu[len++] = 0;      /* cabac enable */
829         ib_cpu[len++] = 0;      /* cabac init idc */
830         ib_cpu[len++] = 1;      /* half pel enabled */
831         ib_cpu[len++] = 1;      /* quarter pel enabled */
832         ib_cpu[len++] = 100;    /* BASELINE profile */
833         ib_cpu[len++] = 11;     /* level */
834         if (vcn_ip_version_major >= 3) {
835                 ib_cpu[len++] = 0;      /* b_picture_enabled */
836                 ib_cpu[len++] = 0;      /* weighted_bipred_idc */
837         }
838         *st_size = (len - st_offset) * 4;
839
840         /* deblocking filter */
841         st_offset = len;
842         st_size = &ib_cpu[len++];       /* size */
843         ib_cpu[len++] = 0x00200004;     /* RENCODE_H264_IB_PARAM_DEBLOCKING_FILTER */
844         ib_cpu[len++] = 0;      /* disable deblocking filter idc */
845         ib_cpu[len++] = 0;      /* alpha c0 offset */
846         ib_cpu[len++] = 0;      /* tc offset */
847         ib_cpu[len++] = 0;      /* cb offset */
848         ib_cpu[len++] = 0;      /* cr offset */
849         *st_size = (len - st_offset) * 4;
850
851         /* layer control */
852         st_offset = len;
853         st_size = &ib_cpu[len++];       /* size */
854         ib_cpu[len++] = 0x00000004;     /* RENCODE_IB_PARAM_LAYER_CONTROL */
855         ib_cpu[len++] = 1;      /* max temporal layer */
856         ib_cpu[len++] = 1;      /* no of temporal layer */
857         *st_size = (len - st_offset) * 4;
858
859         /* rc_session init */
860         st_offset = len;
861         st_size = &ib_cpu[len++];       /* size */
862         ib_cpu[len++] = 0x00000006;     /* RENCODE_IB_PARAM_RATE_CONTROL_SESSION_INIT */
863         ib_cpu[len++] = 0;      /* rate control */
864         ib_cpu[len++] = 48;     /* vbv buffer level */
865         *st_size = (len - st_offset) * 4;
866
867         /* quality params */
868         st_offset = len;
869         st_size = &ib_cpu[len++];       /* size */
870         ib_cpu[len++] = 0x00000009;     /* RENCODE_IB_PARAM_QUALITY_PARAMS */
871         ib_cpu[len++] = 0;      /* vbaq mode */
872         ib_cpu[len++] = 0;      /* scene change sensitivity */
873         ib_cpu[len++] = 0;      /* scene change min idr interval */
874         ib_cpu[len++] = 0;
875         if (vcn_ip_version_major >= 3)
876                 ib_cpu[len++] = 0;
877         *st_size = (len - st_offset) * 4;
878
879         /* layer select */
880         st_offset = len;
881         st_size = &ib_cpu[len++];       /* size */
882         ib_cpu[len++] = 0x00000005;     /* RENCODE_IB_PARAM_LAYER_SELECT */
883         ib_cpu[len++] = 0;      /* temporal layer */
884         *st_size = (len - st_offset) * 4;
885
886         /* rc layer init */
887         st_offset = len;
888         st_size = &ib_cpu[len++];       /* size */
889         ib_cpu[len++] = 0x00000007;     /* RENCODE_IB_PARAM_RATE_CONTROL_LAYER_INIT */
890         ib_cpu[len++] = 0;
891         ib_cpu[len++] = 0;
892         ib_cpu[len++] = 25;
893         ib_cpu[len++] = 1;
894         ib_cpu[len++] = 0x01312d00;
895         ib_cpu[len++] = 0;
896         ib_cpu[len++] = 0;
897         ib_cpu[len++] = 0;
898         *st_size = (len - st_offset) * 4;
899
900         /* layer select */
901         st_offset = len;
902         st_size = &ib_cpu[len++];       /* size */
903         ib_cpu[len++] = 0x00000005;     /* RENCODE_IB_PARAM_LAYER_SELECT */
904         ib_cpu[len++] = 0;      /* temporal layer */
905         *st_size = (len - st_offset) * 4;
906
907         /* rc per pic */
908         st_offset = len;
909         st_size = &ib_cpu[len++];       /* size */
910         ib_cpu[len++] = 0x00000008;     /* RENCODE_IB_PARAM_RATE_CONTROL_PER_PICTURE */
911         ib_cpu[len++] = 20;
912         ib_cpu[len++] = 0;
913         ib_cpu[len++] = 51;
914         ib_cpu[len++] = 0;
915         ib_cpu[len++] = 1;
916         ib_cpu[len++] = 0;
917         ib_cpu[len++] = 1;
918         ib_cpu[len++] = 0;
919         *st_size = (len - st_offset) * 4;
920
921         /* op init rc */
922         st_offset = len;
923         st_size = &ib_cpu[len++];       /* size */
924         ib_cpu[len++] = 0x01000004;     /* RENCODE_IB_OP_INIT_RC */
925         *st_size = (len - st_offset) * 4;
926
927         /* op init rc vbv */
928         st_offset = len;
929         st_size = &ib_cpu[len++];       /* size */
930         ib_cpu[len++] = 0x01000005;     /* RENCODE_IB_OP_INIT_RC_VBV_BUFFER_LEVEL */
931         *st_size = (len - st_offset) * 4;
932
933         *p_task_size = (len - task_offset) * 4;
934
935         if (vcn_unified_ring)
936                 amdgpu_cs_sq_ib_tail(ib_cpu + len);
937
938         r = submit(len, AMDGPU_HW_IP_VCN_ENC);
939         CU_ASSERT_EQUAL(r, 0);
940 }
941
942 static int32_t h264_se (bufferInfo * bufInfo)
943 {
944         uint32_t ret;
945
946         ret = bs_read_ue (bufInfo);
947         if ((ret & 0x1) == 0) {
948                 ret >>= 1;
949                 int32_t temp = 0 - ret;
950                 return temp;
951         }
952
953         return (ret + 1) >> 1;
954 }
955
956 static void h264_check_0s (bufferInfo * bufInfo, int count)
957 {
958         uint32_t val;
959
960         val = bs_read_u (bufInfo, count);
961         if (val != 0) {
962                 printf ("field error - %d bits should be 0 is %x\n", count, val);
963         }
964 }
965
966 static inline int bs_eof(bufferInfo * bufinfo)
967 {
968         if (bufinfo->decBuffer >= bufinfo->end)
969                 return 1;
970         else
971                 return 0;
972 }
973
974 static inline uint32_t bs_read_u1(bufferInfo *bufinfo)
975 {
976         uint32_t r = 0;
977         uint32_t temp = 0;
978
979         bufinfo->numOfBitsInBuffer--;
980         if (! bs_eof(bufinfo)) {
981                 temp = (((bufinfo->decData)) >> bufinfo->numOfBitsInBuffer);
982                 r = temp & 0x01;
983         }
984
985         if (bufinfo->numOfBitsInBuffer == 0) {
986                 bufinfo->decBuffer++;
987                 bufinfo->decData = *bufinfo->decBuffer;
988                 bufinfo->numOfBitsInBuffer = 8;
989         }
990
991         return r;
992 }
993
994 static inline uint32_t bs_read_u(bufferInfo* bufinfo, int n)
995 {
996         uint32_t r = 0;
997         int i;
998
999         for (i = 0; i < n; i++) {
1000                 r |= ( bs_read_u1(bufinfo) << ( n - i - 1 ) );
1001         }
1002
1003         return r;
1004 }
1005
1006 static inline uint32_t bs_read_ue(bufferInfo* bufinfo)
1007 {
1008         int32_t r = 0;
1009         int i = 0;
1010
1011         while( (bs_read_u1(bufinfo) == 0) && (i < 32) && (!bs_eof(bufinfo))) {
1012                 i++;
1013         }
1014         r = bs_read_u(bufinfo, i);
1015         r += (1 << i) - 1;
1016         return r;
1017 }
1018
1019 static uint32_t remove_03 (uint8_t * bptr, uint32_t len)
1020 {
1021         uint32_t nal_len = 0;
1022         while (nal_len + 2 < len) {
1023                 if (bptr[0] == 0 && bptr[1] == 0 && bptr[2] == 3) {
1024                         bptr += 2;
1025                         nal_len += 2;
1026                         len--;
1027                         memmove (bptr, bptr + 1, len - nal_len);
1028                 } else {
1029                         bptr++;
1030                         nal_len++;
1031                 }
1032         }
1033         return len;
1034 }
1035
1036 static void scaling_list (uint32_t ix, uint32_t sizeOfScalingList, bufferInfo * bufInfo)
1037 {
1038         uint32_t lastScale = 8, nextScale = 8;
1039         uint32_t jx;
1040         int deltaScale;
1041
1042         for (jx = 0; jx < sizeOfScalingList; jx++) {
1043                 if (nextScale != 0) {
1044                         deltaScale = h264_se (bufInfo);
1045                         nextScale = (lastScale + deltaScale + 256) % 256;
1046                 }
1047                 if (nextScale == 0) {
1048                         lastScale = lastScale;
1049                 } else {
1050                         lastScale = nextScale;
1051                 }
1052         }
1053 }
1054
1055 static void h264_parse_sequence_parameter_set (h264_decode * dec, bufferInfo * bufInfo)
1056 {
1057         uint32_t temp;
1058
1059         dec->profile = bs_read_u (bufInfo, 8);
1060         bs_read_u (bufInfo, 1);         /* constaint_set0_flag */
1061         bs_read_u (bufInfo, 1);         /* constaint_set1_flag */
1062         bs_read_u (bufInfo, 1);         /* constaint_set2_flag */
1063         bs_read_u (bufInfo, 1);         /* constaint_set3_flag */
1064         bs_read_u (bufInfo, 1);         /* constaint_set4_flag */
1065         bs_read_u (bufInfo, 1);         /* constaint_set5_flag */
1066
1067
1068         h264_check_0s (bufInfo, 2);
1069         dec->level_idc = bs_read_u (bufInfo, 8);
1070         bs_read_ue (bufInfo);   /* SPS id*/
1071
1072         if (dec->profile == 100 || dec->profile == 110 ||
1073                 dec->profile == 122 || dec->profile == 144) {
1074                 uint32_t chroma_format_idc = bs_read_ue (bufInfo);
1075                 if (chroma_format_idc == 3) {
1076                         bs_read_u (bufInfo, 1); /* residual_colour_transform_flag */
1077                 }
1078                 bs_read_ue (bufInfo);   /* bit_depth_luma_minus8 */
1079                 bs_read_ue (bufInfo);   /* bit_depth_chroma_minus8 */
1080                 bs_read_u (bufInfo, 1); /* qpprime_y_zero_transform_bypass_flag */
1081                 uint32_t seq_scaling_matrix_present_flag = bs_read_u (bufInfo, 1);
1082
1083                 if (seq_scaling_matrix_present_flag) {
1084                         for (uint32_t ix = 0; ix < 8; ix++) {
1085                                 temp = bs_read_u (bufInfo, 1);
1086                                 if (temp) {
1087                                         scaling_list (ix, ix < 6 ? 16 : 64, bufInfo);
1088                                 }
1089                         }
1090                 }
1091         }
1092
1093         bs_read_ue (bufInfo);   /* log2_max_frame_num_minus4 */
1094         uint32_t pic_order_cnt_type = bs_read_ue (bufInfo);
1095
1096         if (pic_order_cnt_type == 0) {
1097                 bs_read_ue (bufInfo);   /* log2_max_pic_order_cnt_lsb_minus4 */
1098         } else if (pic_order_cnt_type == 1) {
1099                 bs_read_u (bufInfo, 1); /* delta_pic_order_always_zero_flag */
1100                 h264_se (bufInfo);      /* offset_for_non_ref_pic */
1101                 h264_se (bufInfo);      /* offset_for_top_to_bottom_field */
1102                 temp = bs_read_ue (bufInfo);
1103                 for (uint32_t ix = 0; ix < temp; ix++) {
1104                          h264_se (bufInfo);     /* offset_for_ref_frame[index] */
1105                 }
1106         }
1107         bs_read_ue (bufInfo);   /* num_ref_frames */
1108         bs_read_u (bufInfo, 1); /* gaps_in_frame_num_flag */
1109         uint32_t PicWidthInMbs = bs_read_ue (bufInfo) + 1;
1110
1111         dec->pic_width = PicWidthInMbs * 16;
1112         uint32_t PicHeightInMapUnits = bs_read_ue (bufInfo) + 1;
1113
1114         dec->pic_height = PicHeightInMapUnits * 16;
1115         uint32_t frame_mbs_only_flag = bs_read_u (bufInfo, 1);
1116         if (!frame_mbs_only_flag) {
1117                 bs_read_u (bufInfo, 1); /* mb_adaptive_frame_field_flag */
1118         }
1119         bs_read_u (bufInfo, 1); /* direct_8x8_inference_flag */
1120         temp = bs_read_u (bufInfo, 1);
1121         if (temp) {
1122                 bs_read_ue (bufInfo);   /* frame_crop_left_offset */
1123                 bs_read_ue (bufInfo);   /* frame_crop_right_offset */
1124                 bs_read_ue (bufInfo);   /* frame_crop_top_offset */
1125                 bs_read_ue (bufInfo);   /* frame_crop_bottom_offset */
1126         }
1127         temp = bs_read_u (bufInfo, 1);  /* VUI Parameters  */
1128 }
1129
1130 static void h264_slice_header (h264_decode * dec, bufferInfo * bufInfo)
1131 {
1132         uint32_t temp;
1133
1134         bs_read_ue (bufInfo);   /* first_mb_in_slice */
1135         temp = bs_read_ue (bufInfo);
1136         dec->slice_type = ((temp > 5) ? (temp - 5) : temp);
1137 }
1138
1139 static uint8_t h264_parse_nal (h264_decode * dec, bufferInfo * bufInfo)
1140 {
1141         uint8_t type = 0;
1142
1143         h264_check_0s (bufInfo, 1);
1144         dec->nal_ref_idc = bs_read_u (bufInfo, 2);
1145         dec->nal_unit_type = type = bs_read_u (bufInfo, 5);
1146         switch (type)
1147         {
1148         case H264_NAL_TYPE_NON_IDR_SLICE:
1149         case H264_NAL_TYPE_IDR_SLICE:
1150                 h264_slice_header (dec, bufInfo);
1151                 break;
1152         case H264_NAL_TYPE_SEQ_PARAM:
1153                 h264_parse_sequence_parameter_set (dec, bufInfo);
1154                 break;
1155         case H264_NAL_TYPE_PIC_PARAM:
1156         case H264_NAL_TYPE_SEI:
1157         case H264_NAL_TYPE_ACCESS_UNIT:
1158         case H264_NAL_TYPE_SEQ_EXTENSION:
1159                 /* NOP */
1160                 break;
1161         default:
1162                 printf ("Nal type unknown %d \n ", type);
1163                 break;
1164         }
1165         return type;
1166 }
1167
1168 static uint32_t h264_find_next_start_code (uint8_t * pBuf, uint32_t bufLen)
1169 {
1170         uint32_t val;
1171         uint32_t offset, startBytes;
1172
1173         offset = startBytes = 0;
1174         if (pBuf[0] == 0 && pBuf[1] == 0 && pBuf[2] == 0 && pBuf[3] == 1) {
1175                 pBuf += 4;
1176                 offset = 4;
1177                 startBytes = 1;
1178         } else if (pBuf[0] == 0 && pBuf[1] == 0 && pBuf[2] == 1) {
1179                 pBuf += 3;
1180                 offset = 3;
1181                 startBytes = 1;
1182         }
1183         val = 0xffffffff;
1184         while (offset < bufLen - 3) {
1185                 val <<= 8;
1186                 val |= *pBuf++;
1187                 offset++;
1188                 if (val == H264_START_CODE)
1189                         return offset - 4;
1190
1191                 if ((val & 0x00ffffff) == H264_START_CODE)
1192                         return offset - 3;
1193         }
1194         if (bufLen - offset <= 3 && startBytes == 0) {
1195                 startBytes = 0;
1196                 return 0;
1197         }
1198
1199         return offset;
1200 }
1201
1202 static int verify_checksum(uint8_t *buffer, uint32_t buffer_size)
1203 {
1204         uint32_t buffer_pos = 0;
1205         int done = 0;
1206         h264_decode dec;
1207
1208         memset(&dec, 0, sizeof(h264_decode));
1209         do {
1210                 uint32_t ret;
1211
1212                 ret = h264_find_next_start_code (buffer + buffer_pos,
1213                                  buffer_size - buffer_pos);
1214                 if (ret == 0) {
1215                         done = 1;
1216                         if (buffer_pos == 0) {
1217                                 fprintf (stderr,
1218                                  "couldn't find start code in buffer from 0\n");
1219                         }
1220                 } else {
1221                 /* have a complete NAL from buffer_pos to end */
1222                         if (ret > 3) {
1223                                 uint32_t nal_len;
1224                                 bufferInfo bufinfo;
1225
1226                                 nal_len = remove_03 (buffer + buffer_pos, ret);
1227                                 bufinfo.decBuffer = buffer + buffer_pos + (buffer[buffer_pos + 2] == 1 ? 3 : 4);
1228                                 bufinfo.decBufferSize = (nal_len - (buffer[buffer_pos + 2] == 1 ? 3 : 4)) * 8;
1229                                 bufinfo.end = buffer + buffer_pos + nal_len;
1230                                 bufinfo.numOfBitsInBuffer = 8;
1231                                 bufinfo.decData = *bufinfo.decBuffer;
1232                                 h264_parse_nal (&dec, &bufinfo);
1233                         }
1234                         buffer_pos += ret;      /*  buffer_pos points to next code */
1235                 }
1236         } while (done == 0);
1237
1238         if ((dec.pic_width == gWidth) &&
1239                 (dec.pic_height == gHeight) &&
1240                 (dec.slice_type == gSliceType))
1241             return 0;
1242         else
1243                 return -1;
1244 }
1245
1246 static void check_result(struct amdgpu_vcn_bo fb_buf, struct amdgpu_vcn_bo bs_buf, int frame_type)
1247 {
1248         uint32_t *fb_ptr;
1249         uint8_t *bs_ptr;
1250         uint32_t size;
1251         int r;
1252 /*      uint64_t s[3] = {0, 1121279001727, 1059312481445}; */
1253
1254         r = amdgpu_bo_cpu_map(fb_buf.handle, (void **)&fb_buf.ptr);
1255         CU_ASSERT_EQUAL(r, 0);
1256         fb_ptr = (uint32_t*)fb_buf.ptr;
1257         size = fb_ptr[6];
1258         r = amdgpu_bo_cpu_unmap(fb_buf.handle);
1259         CU_ASSERT_EQUAL(r, 0);
1260         r = amdgpu_bo_cpu_map(bs_buf.handle, (void **)&bs_buf.ptr);
1261         CU_ASSERT_EQUAL(r, 0);
1262
1263         bs_ptr = (uint8_t*)bs_buf.ptr;
1264         r = verify_checksum(bs_ptr, size);
1265         CU_ASSERT_EQUAL(r, 0);
1266         r = amdgpu_bo_cpu_unmap(bs_buf.handle);
1267
1268         CU_ASSERT_EQUAL(r, 0);
1269 }
1270
1271 static void amdgpu_cs_vcn_ib_zero_count(int *len, int num)
1272 {
1273         for (int i = 0; i < num; i++)
1274                 ib_cpu[(*len)++] = 0;
1275 }
1276
1277 static void amdgpu_cs_vcn_enc_encode_frame(int frame_type)
1278 {
1279         struct amdgpu_vcn_bo bs_buf, fb_buf, input_buf;
1280         int len, r;
1281         unsigned width = 160, height = 128, buf_size;
1282         uint32_t *p_task_size = NULL;
1283         uint32_t task_offset = 0, st_offset;
1284         uint32_t *st_size = NULL;
1285         uint32_t fw_maj = 1, fw_min = 9;
1286
1287         if (vcn_ip_version_major == 2) {
1288                 fw_maj = 1;
1289                 fw_min = 1;
1290         } else if (vcn_ip_version_major == 3) {
1291                 fw_maj = 1;
1292                 fw_min = 0;
1293         }
1294         gSliceType = frame_type;
1295         buf_size = ALIGN(width, 256) * ALIGN(height, 32) * 3 / 2;
1296
1297         num_resources = 0;
1298         alloc_resource(&bs_buf, 4096, AMDGPU_GEM_DOMAIN_GTT);
1299         alloc_resource(&fb_buf, 4096, AMDGPU_GEM_DOMAIN_GTT);
1300         alloc_resource(&input_buf, buf_size, AMDGPU_GEM_DOMAIN_GTT);
1301         resources[num_resources++] = enc_buf.handle;
1302         resources[num_resources++] = cpb_buf.handle;
1303         resources[num_resources++] = bs_buf.handle;
1304         resources[num_resources++] = fb_buf.handle;
1305         resources[num_resources++] = input_buf.handle;
1306         resources[num_resources++] = ib_handle;
1307
1308
1309         r = amdgpu_bo_cpu_map(bs_buf.handle, (void**)&bs_buf.ptr);
1310         memset(bs_buf.ptr, 0, 4096);
1311         r = amdgpu_bo_cpu_unmap(bs_buf.handle);
1312
1313         r = amdgpu_bo_cpu_map(fb_buf.handle, (void**)&fb_buf.ptr);
1314         memset(fb_buf.ptr, 0, 4096);
1315         r = amdgpu_bo_cpu_unmap(fb_buf.handle);
1316
1317         r = amdgpu_bo_cpu_map(input_buf.handle, (void **)&input_buf.ptr);
1318         CU_ASSERT_EQUAL(r, 0);
1319
1320         for (int i = 0; i < ALIGN(height, 32) * 3 / 2; i++)
1321                 memcpy(input_buf.ptr + i * ALIGN(width, 256), frame + i * width, width);
1322
1323         r = amdgpu_bo_cpu_unmap(input_buf.handle);
1324         CU_ASSERT_EQUAL(r, 0);
1325
1326         len = 0;
1327
1328         if (vcn_unified_ring)
1329                 amdgpu_cs_sq_head(ib_cpu, &len, true);
1330
1331         /* session info */
1332         st_offset = len;
1333         st_size = &ib_cpu[len++];       /* size */
1334         ib_cpu[len++] = 0x00000001;     /* RENCODE_IB_PARAM_SESSION_INFO */
1335         ib_cpu[len++] = ((fw_maj << 16) | (fw_min << 0));
1336         ib_cpu[len++] = enc_buf.addr >> 32;
1337         ib_cpu[len++] = enc_buf.addr;
1338         ib_cpu[len++] = 1;      /* RENCODE_ENGINE_TYPE_ENCODE */;
1339         *st_size = (len - st_offset) * 4;
1340
1341         /* task info */
1342         task_offset = len;
1343         st_offset = len;
1344         st_size = &ib_cpu[len++];       /* size */
1345         ib_cpu[len++] = 0x00000002;     /* RENCODE_IB_PARAM_TASK_INFO */
1346         p_task_size = &ib_cpu[len++];
1347         ib_cpu[len++] = enc_task_id++;  /* task_id */
1348         ib_cpu[len++] = 1;      /* feedback */
1349         *st_size = (len - st_offset) * 4;
1350
1351         if (frame_type == 2) {
1352                 /* sps */
1353                 st_offset = len;
1354                 st_size = &ib_cpu[len++];       /* size */
1355                 if(vcn_ip_version_major == 1)
1356                         ib_cpu[len++] = 0x00000020;     /* RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU vcn 1 */
1357                 else
1358                         ib_cpu[len++] = 0x0000000a;     /* RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU other vcn */
1359                 ib_cpu[len++] = 0x00000002;     /* RENCODE_DIRECT_OUTPUT_NALU_TYPE_SPS */
1360                 ib_cpu[len++] = 0x00000011;     /* sps len */
1361                 ib_cpu[len++] = 0x00000001;     /* start code */
1362                 ib_cpu[len++] = 0x6764440b;
1363                 ib_cpu[len++] = 0xac54c284;
1364                 ib_cpu[len++] = 0x68078442;
1365                 ib_cpu[len++] = 0x37000000;
1366                 *st_size = (len - st_offset) * 4;
1367
1368                 /* pps */
1369                 st_offset = len;
1370                 st_size = &ib_cpu[len++];       /* size */
1371                 if(vcn_ip_version_major == 1)
1372                         ib_cpu[len++] = 0x00000020;     /* RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU vcn 1*/
1373                 else
1374                         ib_cpu[len++] = 0x0000000a;     /* RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU other vcn*/
1375                 ib_cpu[len++] = 0x00000003;     /* RENCODE_DIRECT_OUTPUT_NALU_TYPE_PPS */
1376                 ib_cpu[len++] = 0x00000008;     /* pps len */
1377                 ib_cpu[len++] = 0x00000001;     /* start code */
1378                 ib_cpu[len++] = 0x68ce3c80;
1379                 *st_size = (len - st_offset) * 4;
1380         }
1381
1382         /* slice header */
1383         st_offset = len;
1384         st_size = &ib_cpu[len++];       /* size */
1385         if(vcn_ip_version_major == 1)
1386                 ib_cpu[len++] = 0x0000000a; /* RENCODE_IB_PARAM_SLICE_HEADER vcn 1 */
1387         else
1388                 ib_cpu[len++] = 0x0000000b; /* RENCODE_IB_PARAM_SLICE_HEADER other vcn */
1389         if (frame_type == 2) {
1390                 ib_cpu[len++] = 0x65000000;
1391                 ib_cpu[len++] = 0x11040000;
1392         } else {
1393                 ib_cpu[len++] = 0x41000000;
1394                 ib_cpu[len++] = 0x34210000;
1395         }
1396         ib_cpu[len++] = 0xe0000000;
1397         amdgpu_cs_vcn_ib_zero_count(&len, 13);
1398
1399         ib_cpu[len++] = 0x00000001;
1400         ib_cpu[len++] = 0x00000008;
1401         ib_cpu[len++] = 0x00020000;
1402         ib_cpu[len++] = 0x00000000;
1403         ib_cpu[len++] = 0x00000001;
1404         ib_cpu[len++] = 0x00000015;
1405         ib_cpu[len++] = 0x00020001;
1406         ib_cpu[len++] = 0x00000000;
1407         ib_cpu[len++] = 0x00000001;
1408         ib_cpu[len++] = 0x00000003;
1409         amdgpu_cs_vcn_ib_zero_count(&len, 22);
1410         *st_size = (len - st_offset) * 4;
1411
1412         /* encode params */
1413         st_offset = len;
1414         st_size = &ib_cpu[len++];       /* size */
1415         if(vcn_ip_version_major == 1)
1416                 ib_cpu[len++] = 0x0000000b;     /* RENCODE_IB_PARAM_ENCODE_PARAMS vcn 1 */
1417         else
1418                 ib_cpu[len++] = 0x0000000f;     /* RENCODE_IB_PARAM_ENCODE_PARAMS other vcn */
1419         ib_cpu[len++] = frame_type;
1420         ib_cpu[len++] = 0x0001f000;
1421         ib_cpu[len++] = input_buf.addr >> 32;
1422         ib_cpu[len++] = input_buf.addr;
1423         ib_cpu[len++] = (input_buf.addr + ALIGN(width, 256) * ALIGN(height, 32)) >> 32;
1424         ib_cpu[len++] = input_buf.addr + ALIGN(width, 256) * ALIGN(height, 32);
1425         ib_cpu[len++] = 0x00000100;
1426         ib_cpu[len++] = 0x00000080;
1427         ib_cpu[len++] = 0x00000000;
1428         ib_cpu[len++] = 0xffffffff;
1429         ib_cpu[len++] = 0x00000000;
1430         *st_size = (len - st_offset) * 4;
1431
1432         /* encode params h264 */
1433         st_offset = len;
1434         st_size = &ib_cpu[len++];       /* size */
1435         ib_cpu[len++] = 0x00200003;     /* RENCODE_H264_IB_PARAM_ENCODE_PARAMS */
1436         if (vcn_ip_version_major <= 2) {
1437                 ib_cpu[len++] = 0x00000000;
1438                 ib_cpu[len++] = 0x00000000;
1439                 ib_cpu[len++] = 0x00000000;
1440                 ib_cpu[len++] = 0xffffffff;
1441         } else {
1442                 ib_cpu[len++] = 0x00000000;
1443                 ib_cpu[len++] = 0x00000000;
1444                 ib_cpu[len++] = 0x00000000;
1445                 ib_cpu[len++] = 0x00000000;
1446                 ib_cpu[len++] = 0x00000000;
1447                 ib_cpu[len++] = 0x00000000;
1448                 ib_cpu[len++] = 0x00000000;
1449                 ib_cpu[len++] = 0xffffffff;
1450                 ib_cpu[len++] = 0x00000000;
1451                 ib_cpu[len++] = 0x00000000;
1452                 ib_cpu[len++] = 0x00000000;
1453                 ib_cpu[len++] = 0x00000000;
1454                 ib_cpu[len++] = 0xffffffff;
1455                 ib_cpu[len++] = 0x00000000;
1456                 ib_cpu[len++] = 0x00000000;
1457                 ib_cpu[len++] = 0x00000000;
1458                 ib_cpu[len++] = 0x00000000;
1459                 ib_cpu[len++] = 0x00000001;
1460         }
1461         *st_size = (len - st_offset) * 4;
1462
1463         /* encode context */
1464         st_offset = len;
1465         st_size = &ib_cpu[len++];       /* size */
1466         if(vcn_ip_version_major == 1)
1467                 ib_cpu[len++] = 0x0000000d;     /* ENCODE_CONTEXT_BUFFER  vcn 1 */
1468         else
1469                 ib_cpu[len++] = 0x00000011;     /* ENCODE_CONTEXT_BUFFER  other vcn */
1470         ib_cpu[len++] = cpb_buf.addr >> 32;
1471         ib_cpu[len++] = cpb_buf.addr;
1472         ib_cpu[len++] = 0x00000000;     /* swizzle mode */
1473         ib_cpu[len++] = 0x00000100;     /* luma pitch */
1474         ib_cpu[len++] = 0x00000100;     /* chroma pitch */
1475         ib_cpu[len++] = 0x00000002; /* no reconstructed picture */
1476         ib_cpu[len++] = 0x00000000;     /* reconstructed pic 1 luma offset */
1477         ib_cpu[len++] = ALIGN(width, 256) * ALIGN(height, 32);  /* pic1 chroma offset */
1478         if(vcn_ip_version_major == 4)
1479                 amdgpu_cs_vcn_ib_zero_count(&len, 2);
1480         ib_cpu[len++] = ALIGN(width, 256) * ALIGN(height, 32) * 3 / 2;  /* pic2 luma offset */
1481         ib_cpu[len++] = ALIGN(width, 256) * ALIGN(height, 32) * 5 / 2;  /* pic2 chroma offset */
1482
1483         amdgpu_cs_vcn_ib_zero_count(&len, 280);
1484         *st_size = (len - st_offset) * 4;
1485
1486         /* bitstream buffer */
1487         st_offset = len;
1488         st_size = &ib_cpu[len++];       /* size */
1489         if(vcn_ip_version_major == 1)
1490                 ib_cpu[len++] = 0x0000000e;     /* VIDEO_BITSTREAM_BUFFER vcn 1 */
1491         else
1492                 ib_cpu[len++] = 0x00000012;     /* VIDEO_BITSTREAM_BUFFER other vcn */
1493
1494         ib_cpu[len++] = 0x00000000;     /* mode */
1495         ib_cpu[len++] = bs_buf.addr >> 32;
1496         ib_cpu[len++] = bs_buf.addr;
1497         ib_cpu[len++] = 0x0001f000;
1498         ib_cpu[len++] = 0x00000000;
1499         *st_size = (len - st_offset) * 4;
1500
1501         /* feedback */
1502         st_offset = len;
1503         st_size = &ib_cpu[len++];       /* size */
1504         if(vcn_ip_version_major == 1)
1505                 ib_cpu[len++] = 0x00000010;     /* FEEDBACK_BUFFER vcn 1 */
1506         else
1507                 ib_cpu[len++] = 0x00000015;     /* FEEDBACK_BUFFER vcn 2,3 */
1508         ib_cpu[len++] = 0x00000000;
1509         ib_cpu[len++] = fb_buf.addr >> 32;
1510         ib_cpu[len++] = fb_buf.addr;
1511         ib_cpu[len++] = 0x00000010;
1512         ib_cpu[len++] = 0x00000028;
1513         *st_size = (len - st_offset) * 4;
1514
1515         /* intra refresh */
1516         st_offset = len;
1517         st_size = &ib_cpu[len++];
1518         if(vcn_ip_version_major == 1)
1519                 ib_cpu[len++] = 0x0000000c;     /* INTRA_REFRESH vcn 1 */
1520         else
1521                 ib_cpu[len++] = 0x00000010;     /* INTRA_REFRESH vcn 2,3 */
1522         ib_cpu[len++] = 0x00000000;
1523         ib_cpu[len++] = 0x00000000;
1524         ib_cpu[len++] = 0x00000000;
1525         *st_size = (len - st_offset) * 4;
1526
1527         if(vcn_ip_version_major != 1) {
1528                 /* Input Format */
1529                 st_offset = len;
1530                 st_size = &ib_cpu[len++];
1531                 ib_cpu[len++] = 0x0000000c;
1532                 ib_cpu[len++] = 0x00000000;     /* RENCODE_COLOR_VOLUME_G22_BT709 */
1533                 ib_cpu[len++] = 0x00000000;
1534                 ib_cpu[len++] = 0x00000000;
1535                 ib_cpu[len++] = 0x00000000;
1536                 ib_cpu[len++] = 0x00000000;
1537                 ib_cpu[len++] = 0x00000000;     /* RENCODE_COLOR_BIT_DEPTH_8_BIT */
1538                 ib_cpu[len++] = 0x00000000;     /* RENCODE_COLOR_PACKING_FORMAT_NV12 */
1539                 *st_size = (len - st_offset) * 4;
1540
1541                 /* Output Format */
1542                 st_offset = len;
1543                 st_size = &ib_cpu[len++];
1544                 ib_cpu[len++] = 0x0000000d;
1545                 ib_cpu[len++] = 0x00000000;     /* RENCODE_COLOR_VOLUME_G22_BT709 */
1546                 ib_cpu[len++] = 0x00000000;
1547                 ib_cpu[len++] = 0x00000000;
1548                 ib_cpu[len++] = 0x00000000;     /* RENCODE_COLOR_BIT_DEPTH_8_BIT */
1549                 *st_size = (len - st_offset) * 4;
1550         }
1551         /* op_speed */
1552         st_offset = len;
1553         st_size = &ib_cpu[len++];
1554         ib_cpu[len++] = 0x01000006;     /* SPEED_ENCODING_MODE */
1555         *st_size = (len - st_offset) * 4;
1556
1557         /* op_enc */
1558         st_offset = len;
1559         st_size = &ib_cpu[len++];
1560         ib_cpu[len++] = 0x01000003;
1561         *st_size = (len - st_offset) * 4;
1562
1563         *p_task_size = (len - task_offset) * 4;
1564
1565         if (vcn_unified_ring)
1566                 amdgpu_cs_sq_ib_tail(ib_cpu + len);
1567
1568         r = submit(len, AMDGPU_HW_IP_VCN_ENC);
1569         CU_ASSERT_EQUAL(r, 0);
1570
1571         /* check result */
1572         check_result(fb_buf, bs_buf, frame_type);
1573
1574         free_resource(&fb_buf);
1575         free_resource(&bs_buf);
1576         free_resource(&input_buf);
1577 }
1578
1579 static void amdgpu_cs_vcn_enc_encode(void)
1580 {
1581         amdgpu_cs_vcn_enc_encode_frame(2);      /* IDR frame */
1582 }
1583
1584 static void amdgpu_cs_vcn_enc_destroy(void)
1585 {
1586         int len = 0, r;
1587         uint32_t *p_task_size = NULL;
1588         uint32_t task_offset = 0, st_offset;
1589         uint32_t *st_size = NULL;
1590         uint32_t fw_maj = 1, fw_min = 9;
1591
1592         if (vcn_ip_version_major == 2) {
1593                 fw_maj = 1;
1594                 fw_min = 1;
1595         } else if (vcn_ip_version_major == 3) {
1596                 fw_maj = 1;
1597                 fw_min = 0;
1598         }
1599
1600         num_resources = 0;
1601 /*      alloc_resource(&enc_buf, 128 * 1024, AMDGPU_GEM_DOMAIN_GTT); */
1602         resources[num_resources++] = enc_buf.handle;
1603         resources[num_resources++] = ib_handle;
1604
1605         if (vcn_unified_ring)
1606                 amdgpu_cs_sq_head(ib_cpu, &len, true);
1607
1608         /* session info */
1609         st_offset = len;
1610         st_size = &ib_cpu[len++];       /* size */
1611         ib_cpu[len++] = 0x00000001;     /* RENCODE_IB_PARAM_SESSION_INFO */
1612         ib_cpu[len++] = ((fw_maj << 16) | (fw_min << 0));
1613         ib_cpu[len++] = enc_buf.addr >> 32;
1614         ib_cpu[len++] = enc_buf.addr;
1615         ib_cpu[len++] = 1;      /* RENCODE_ENGINE_TYPE_ENCODE; */
1616         *st_size = (len - st_offset) * 4;
1617
1618         /* task info */
1619         task_offset = len;
1620         st_offset = len;
1621         st_size = &ib_cpu[len++];       /* size */
1622         ib_cpu[len++] = 0x00000002;     /* RENCODE_IB_PARAM_TASK_INFO */
1623         p_task_size = &ib_cpu[len++];
1624         ib_cpu[len++] = enc_task_id++;  /* task_id */
1625         ib_cpu[len++] = 0;      /* feedback */
1626         *st_size = (len - st_offset) * 4;
1627
1628         /*  op close */
1629         st_offset = len;
1630         st_size = &ib_cpu[len++];
1631         ib_cpu[len++] = 0x01000002;     /* RENCODE_IB_OP_CLOSE_SESSION */
1632         *st_size = (len - st_offset) * 4;
1633
1634         *p_task_size = (len - task_offset) * 4;
1635
1636         if (vcn_unified_ring)
1637                 amdgpu_cs_sq_ib_tail(ib_cpu + len);
1638
1639         r = submit(len, AMDGPU_HW_IP_VCN_ENC);
1640         CU_ASSERT_EQUAL(r, 0);
1641
1642         free_resource(&cpb_buf);
1643         free_resource(&enc_buf);
1644 }