2 * Copyright 2017 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
27 #include "CUnit/Basic.h"
29 #include "util_math.h"
31 #include "amdgpu_test.h"
32 #include "amdgpu_drm.h"
33 #include "amdgpu_internal.h"
34 #include "decode_messages.h"
37 #define MAX_RESOURCES 16
39 struct amdgpu_vcn_bo
{
40 amdgpu_bo_handle handle
;
41 amdgpu_va_handle va_handle
;
47 struct amdgpu_vcn_reg
{
55 static amdgpu_device_handle device_handle
;
56 static uint32_t major_version
;
57 static uint32_t minor_version
;
58 static uint32_t family_id
;
59 static uint32_t chip_rev
;
60 static uint32_t chip_id
;
61 static uint32_t asic_id
;
62 static uint32_t chip_rev
;
63 static uint32_t chip_id
;
65 static amdgpu_context_handle context_handle
;
66 static amdgpu_bo_handle ib_handle
;
67 static amdgpu_va_handle ib_va_handle
;
68 static uint64_t ib_mc_address
;
69 static uint32_t *ib_cpu
;
71 static amdgpu_bo_handle resources
[MAX_RESOURCES
];
72 static unsigned num_resources
;
73 static struct amdgpu_vcn_reg reg
;
75 static void amdgpu_cs_vcn_dec_create(void);
76 static void amdgpu_cs_vcn_dec_decode(void);
77 static void amdgpu_cs_vcn_dec_destroy(void);
79 static void amdgpu_cs_vcn_enc_create(void);
80 static void amdgpu_cs_vcn_enc_encode(void);
81 static void amdgpu_cs_vcn_enc_destroy(void);
83 CU_TestInfo vcn_tests
[] = {
85 { "VCN DEC create", amdgpu_cs_vcn_dec_create
},
86 { "VCN DEC decode", amdgpu_cs_vcn_dec_decode
},
87 { "VCN DEC destroy", amdgpu_cs_vcn_dec_destroy
},
89 { "VCN ENC create", amdgpu_cs_vcn_enc_create
},
90 { "VCN ENC decode", amdgpu_cs_vcn_enc_encode
},
91 { "VCN ENC destroy", amdgpu_cs_vcn_enc_destroy
},
95 CU_BOOL
suite_vcn_tests_enable(void)
97 struct drm_amdgpu_info_hw_ip info
;
100 if (amdgpu_device_initialize(drm_amdgpu
[0], &major_version
,
101 &minor_version
, &device_handle
))
104 family_id
= device_handle
->info
.family_id
;
105 asic_id
= device_handle
->info
.asic_id
;
106 chip_rev
= device_handle
->info
.chip_rev
;
107 chip_id
= device_handle
->info
.chip_external_rev
;
109 r
= amdgpu_query_hw_ip_info(device_handle
, AMDGPU_HW_IP_VCN_DEC
, 0, &info
);
111 if (amdgpu_device_deinitialize(device_handle
))
114 if (r
!= 0 || !info
.available_rings
||
115 (family_id
< AMDGPU_FAMILY_RV
&&
116 (family_id
== AMDGPU_FAMILY_AI
&&
117 (chip_id
- chip_rev
) < 0x32))) { /* Arcturus */
118 printf("\n\nThe ASIC NOT support VCN, suite disabled\n");
122 if (family_id
== AMDGPU_FAMILY_AI
) {
123 amdgpu_set_test_active("VCN Tests", "VCN ENC create", CU_FALSE
);
124 amdgpu_set_test_active("VCN Tests", "VCN ENC decode", CU_FALSE
);
125 amdgpu_set_test_active("VCN Tests", "VCN ENC destroy", CU_FALSE
);
128 if (family_id
== AMDGPU_FAMILY_RV
) {
129 if (chip_id
>= (chip_rev
+ 0x91)) {
142 } else if (family_id
== AMDGPU_FAMILY_NV
) {
143 if (chip_id
== (chip_rev
+ 0x28) ||
144 chip_id
== (chip_rev
+ 0x32) ||
145 chip_id
== (chip_rev
+ 0x3c)) {
159 } else if (family_id
== AMDGPU_FAMILY_AI
) {
171 int suite_vcn_tests_init(void)
175 r
= amdgpu_device_initialize(drm_amdgpu
[0], &major_version
,
176 &minor_version
, &device_handle
);
178 return CUE_SINIT_FAILED
;
180 family_id
= device_handle
->info
.family_id
;
182 r
= amdgpu_cs_ctx_create(device_handle
, &context_handle
);
184 return CUE_SINIT_FAILED
;
186 r
= amdgpu_bo_alloc_and_map(device_handle
, IB_SIZE
, 4096,
187 AMDGPU_GEM_DOMAIN_GTT
, 0,
188 &ib_handle
, (void**)&ib_cpu
,
189 &ib_mc_address
, &ib_va_handle
);
191 return CUE_SINIT_FAILED
;
196 int suite_vcn_tests_clean(void)
200 r
= amdgpu_bo_unmap_and_free(ib_handle
, ib_va_handle
,
201 ib_mc_address
, IB_SIZE
);
203 return CUE_SCLEAN_FAILED
;
205 r
= amdgpu_cs_ctx_free(context_handle
);
207 return CUE_SCLEAN_FAILED
;
209 r
= amdgpu_device_deinitialize(device_handle
);
211 return CUE_SCLEAN_FAILED
;
216 static int submit(unsigned ndw
, unsigned ip
)
218 struct amdgpu_cs_request ibs_request
= {0};
219 struct amdgpu_cs_ib_info ib_info
= {0};
220 struct amdgpu_cs_fence fence_status
= {0};
224 ib_info
.ib_mc_address
= ib_mc_address
;
227 ibs_request
.ip_type
= ip
;
229 r
= amdgpu_bo_list_create(device_handle
, num_resources
, resources
,
230 NULL
, &ibs_request
.resources
);
234 ibs_request
.number_of_ibs
= 1;
235 ibs_request
.ibs
= &ib_info
;
236 ibs_request
.fence_info
.handle
= NULL
;
238 r
= amdgpu_cs_submit(context_handle
, 0, &ibs_request
, 1);
242 r
= amdgpu_bo_list_destroy(ibs_request
.resources
);
246 fence_status
.context
= context_handle
;
247 fence_status
.ip_type
= ip
;
248 fence_status
.fence
= ibs_request
.seq_no
;
250 r
= amdgpu_cs_query_fence_status(&fence_status
,
251 AMDGPU_TIMEOUT_INFINITE
,
259 static void alloc_resource(struct amdgpu_vcn_bo
*vcn_bo
,
260 unsigned size
, unsigned domain
)
262 struct amdgpu_bo_alloc_request req
= {0};
263 amdgpu_bo_handle buf_handle
;
264 amdgpu_va_handle va_handle
;
268 req
.alloc_size
= ALIGN(size
, 4096);
269 req
.preferred_heap
= domain
;
270 r
= amdgpu_bo_alloc(device_handle
, &req
, &buf_handle
);
271 CU_ASSERT_EQUAL(r
, 0);
272 r
= amdgpu_va_range_alloc(device_handle
,
273 amdgpu_gpu_va_range_general
,
274 req
.alloc_size
, 1, 0, &va
,
276 CU_ASSERT_EQUAL(r
, 0);
277 r
= amdgpu_bo_va_op(buf_handle
, 0, req
.alloc_size
, va
, 0,
279 CU_ASSERT_EQUAL(r
, 0);
281 vcn_bo
->handle
= buf_handle
;
282 vcn_bo
->size
= req
.alloc_size
;
283 vcn_bo
->va_handle
= va_handle
;
284 r
= amdgpu_bo_cpu_map(vcn_bo
->handle
, (void **)&vcn_bo
->ptr
);
285 CU_ASSERT_EQUAL(r
, 0);
286 memset(vcn_bo
->ptr
, 0, size
);
287 r
= amdgpu_bo_cpu_unmap(vcn_bo
->handle
);
288 CU_ASSERT_EQUAL(r
, 0);
291 static void free_resource(struct amdgpu_vcn_bo
*vcn_bo
)
295 r
= amdgpu_bo_va_op(vcn_bo
->handle
, 0, vcn_bo
->size
,
296 vcn_bo
->addr
, 0, AMDGPU_VA_OP_UNMAP
);
297 CU_ASSERT_EQUAL(r
, 0);
299 r
= amdgpu_va_range_free(vcn_bo
->va_handle
);
300 CU_ASSERT_EQUAL(r
, 0);
302 r
= amdgpu_bo_free(vcn_bo
->handle
);
303 CU_ASSERT_EQUAL(r
, 0);
304 memset(vcn_bo
, 0, sizeof(*vcn_bo
));
307 static void vcn_dec_cmd(uint64_t addr
, unsigned cmd
, int *idx
)
309 ib_cpu
[(*idx
)++] = reg
.data0
;
310 ib_cpu
[(*idx
)++] = addr
;
311 ib_cpu
[(*idx
)++] = reg
.data1
;
312 ib_cpu
[(*idx
)++] = addr
>> 32;
313 ib_cpu
[(*idx
)++] = reg
.cmd
;
314 ib_cpu
[(*idx
)++] = cmd
<< 1;
317 static void amdgpu_cs_vcn_dec_create(void)
319 struct amdgpu_vcn_bo msg_buf
;
323 alloc_resource(&msg_buf
, 4096, AMDGPU_GEM_DOMAIN_GTT
);
324 resources
[num_resources
++] = msg_buf
.handle
;
325 resources
[num_resources
++] = ib_handle
;
327 r
= amdgpu_bo_cpu_map(msg_buf
.handle
, (void **)&msg_buf
.ptr
);
328 CU_ASSERT_EQUAL(r
, 0);
330 memset(msg_buf
.ptr
, 0, 4096);
331 memcpy(msg_buf
.ptr
, vcn_dec_create_msg
, sizeof(vcn_dec_create_msg
));
334 ib_cpu
[len
++] = reg
.data0
;
335 ib_cpu
[len
++] = msg_buf
.addr
;
336 ib_cpu
[len
++] = reg
.data1
;
337 ib_cpu
[len
++] = msg_buf
.addr
>> 32;
338 ib_cpu
[len
++] = reg
.cmd
;
341 ib_cpu
[len
++] = reg
.nop
;
345 r
= submit(len
, AMDGPU_HW_IP_VCN_DEC
);
346 CU_ASSERT_EQUAL(r
, 0);
348 free_resource(&msg_buf
);
351 static void amdgpu_cs_vcn_dec_decode(void)
353 const unsigned dpb_size
= 15923584, dt_size
= 737280;
354 uint64_t msg_addr
, fb_addr
, bs_addr
, dpb_addr
, ctx_addr
, dt_addr
, it_addr
, sum
;
355 struct amdgpu_vcn_bo dec_buf
;
359 size
= 4*1024; /* msg */
360 size
+= 4*1024; /* fb */
361 size
+= 4096; /*it_scaling_table*/
362 size
+= ALIGN(sizeof(uvd_bitstream
), 4*1024);
363 size
+= ALIGN(dpb_size
, 4*1024);
364 size
+= ALIGN(dt_size
, 4*1024);
367 alloc_resource(&dec_buf
, size
, AMDGPU_GEM_DOMAIN_GTT
);
368 resources
[num_resources
++] = dec_buf
.handle
;
369 resources
[num_resources
++] = ib_handle
;
371 r
= amdgpu_bo_cpu_map(dec_buf
.handle
, (void **)&dec_buf
.ptr
);
374 CU_ASSERT_EQUAL(r
, 0);
375 memset(dec_buf
.ptr
, 0, size
);
376 memcpy(dec_buf
.ptr
, vcn_dec_decode_msg
, sizeof(vcn_dec_decode_msg
));
377 memcpy(dec_buf
.ptr
+ sizeof(vcn_dec_decode_msg
),
378 avc_decode_msg
, sizeof(avc_decode_msg
));
381 memcpy(dec
, feedback_msg
, sizeof(feedback_msg
));
383 memcpy(dec
, uvd_it_scaling_table
, sizeof(uvd_it_scaling_table
));
386 memcpy(dec
, uvd_bitstream
, sizeof(uvd_bitstream
));
388 dec
+= ALIGN(sizeof(uvd_bitstream
), 4*1024);
390 dec
+= ALIGN(dpb_size
, 4*1024);
392 msg_addr
= dec_buf
.addr
;
393 fb_addr
= msg_addr
+ 4*1024;
394 it_addr
= fb_addr
+ 4*1024;
395 bs_addr
= it_addr
+ 4*1024;
396 dpb_addr
= ALIGN(bs_addr
+ sizeof(uvd_bitstream
), 4*1024);
397 ctx_addr
= ALIGN(dpb_addr
+ 0x006B9400, 4*1024);
398 dt_addr
= ALIGN(dpb_addr
+ dpb_size
, 4*1024);
401 vcn_dec_cmd(msg_addr
, 0x0, &len
);
402 vcn_dec_cmd(dpb_addr
, 0x1, &len
);
403 vcn_dec_cmd(dt_addr
, 0x2, &len
);
404 vcn_dec_cmd(fb_addr
, 0x3, &len
);
405 vcn_dec_cmd(bs_addr
, 0x100, &len
);
406 vcn_dec_cmd(it_addr
, 0x204, &len
);
407 vcn_dec_cmd(ctx_addr
, 0x206, &len
);
409 ib_cpu
[len
++] = reg
.cntl
;
412 ib_cpu
[len
++] = reg
.nop
;
416 r
= submit(len
, AMDGPU_HW_IP_VCN_DEC
);
417 CU_ASSERT_EQUAL(r
, 0);
419 for (i
= 0, sum
= 0; i
< dt_size
; ++i
)
422 CU_ASSERT_EQUAL(sum
, SUM_DECODE
);
424 free_resource(&dec_buf
);
427 static void amdgpu_cs_vcn_dec_destroy(void)
429 struct amdgpu_vcn_bo msg_buf
;
433 alloc_resource(&msg_buf
, 1024, AMDGPU_GEM_DOMAIN_GTT
);
434 resources
[num_resources
++] = msg_buf
.handle
;
435 resources
[num_resources
++] = ib_handle
;
437 r
= amdgpu_bo_cpu_map(msg_buf
.handle
, (void **)&msg_buf
.ptr
);
438 CU_ASSERT_EQUAL(r
, 0);
440 memset(msg_buf
.ptr
, 0, 1024);
441 memcpy(msg_buf
.ptr
, vcn_dec_destroy_msg
, sizeof(vcn_dec_destroy_msg
));
444 ib_cpu
[len
++] = reg
.data0
;
445 ib_cpu
[len
++] = msg_buf
.addr
;
446 ib_cpu
[len
++] = reg
.data1
;
447 ib_cpu
[len
++] = msg_buf
.addr
>> 32;
448 ib_cpu
[len
++] = reg
.cmd
;
451 ib_cpu
[len
++] = reg
.nop
;
455 r
= submit(len
, AMDGPU_HW_IP_VCN_DEC
);
456 CU_ASSERT_EQUAL(r
, 0);
458 free_resource(&msg_buf
);
461 static void amdgpu_cs_vcn_enc_create(void)
466 static void amdgpu_cs_vcn_enc_encode(void)
471 static void amdgpu_cs_vcn_enc_destroy(void)