From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM10-MW2-obe.outbound.protection.outlook.com (mail-mw2nam10on20630.outbound.protection.outlook.com [IPv6:2a01:111:f400:7e89::630]) by gabe.freedesktop.org (Postfix) with ESMTPS id F35D310E151 for ; Mon, 3 Jul 2023 04:34:39 +0000 (UTC) From: To: Date: Mon, 3 Jul 2023 00:34:17 -0400 Message-ID: <20230703043420.50705-3-vitaly.prosyak@amd.com> In-Reply-To: <20230703043420.50705-1-vitaly.prosyak@amd.com> References: <20230703043420.50705-1-vitaly.prosyak@amd.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain Subject: [igt-dev] [PATCH 3/6] tests/amdgpu: add uvd encoder test List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alexander.deucher@amd.com, boyuan.zhang@amd.com, leo.liu@amd.com, christian.koenig@amd.com Errors-To: igt-dev-bounces@lists.freedesktop.org Sender: "igt-dev" List-ID: From: Vitaly Prosyak Ported and refactored drmlib uvd_enc_tests.c and the following is done: 1. Remove everywhere global variables. 2. Reuse common functions from amd_mmd_shared.h 3. Properly formatted code to meet igt guidelines. Signed-off-by: Vitaly Prosyak Change-Id: Ifb59c45ed0fbd80929070829d049cc312a441393 --- tests/amdgpu/amd_uvd_enc.c | 337 +++++++++++++++++++++++++++++++++++++ tests/amdgpu/meson.build | 1 + 2 files changed, 338 insertions(+) create mode 100644 tests/amdgpu/amd_uvd_enc.c diff --git a/tests/amdgpu/amd_uvd_enc.c b/tests/amdgpu/amd_uvd_enc.c new file mode 100644 index 000000000..e3e85522f --- /dev/null +++ b/tests/amdgpu/amd_uvd_enc.c @@ -0,0 +1,337 @@ +// SPDX-License-Identifier: MIT +// Copyright 2023 Advanced Micro Devices, Inc. +// Copyright 2017 Advanced Micro Devices, Inc. + +#include "lib/amdgpu/amd_mmd_shared.h" + +static bool +is_uvd_enc_enable(amdgpu_device_handle device_handle) +{ + int r; + struct drm_amdgpu_info_hw_ip info = {}; + + r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_UVD_ENC, 0, &info); + + if (!info.available_rings) + igt_info("\n\nThe ASIC NOT support UVD ENC, test skipped\n"); + + return (r == 0 && (info.available_rings ? true : false)); +} + +static void +amdgpu_uvd_enc_create(amdgpu_device_handle device_handle, + struct uvd_enc_context *context) +{ + context->enc.width = 160; + context->enc.height = 128; + + context->uvd.num_resources = 0; + alloc_resource(device_handle, &context->enc.session, + 128 * 1024, AMDGPU_GEM_DOMAIN_GTT); + context->uvd.resources[context->uvd.num_resources++] = context->enc.session.handle; + context->uvd.resources[context->uvd.num_resources++] = context->uvd.ib_handle; +} + +static void +check_result(struct amdgpu_uvd_enc *enc) +{ + uint64_t sum; + uint32_t s = 175602; + uint32_t *ptr, size; + int j, r; + + r = amdgpu_bo_cpu_map(enc->fb.handle, (void **)&enc->fb.ptr); + igt_assert_eq(r, 0); + ptr = (uint32_t *)enc->fb.ptr; + size = ptr[6]; + r = amdgpu_bo_cpu_unmap(enc->fb.handle); + igt_assert_eq(r, 0); + r = amdgpu_bo_cpu_map(enc->bs.handle, (void **)&enc->bs.ptr); + igt_assert_eq(r, 0); + for (j = 0, sum = 0; j < size; ++j) + sum += enc->bs.ptr[j]; + igt_assert_eq(sum, s); + r = amdgpu_bo_cpu_unmap(enc->bs.handle); + igt_assert_eq(r, 0); + +} + +static void +amdgpu_uvd_enc_session_init(amdgpu_device_handle device_handle, + struct uvd_enc_context *context) +{ + int len, r; + + len = 0; + memcpy((context->uvd.ib_cpu + len), uve_session_info, sizeof(uve_session_info)); + len += sizeof(uve_session_info) / 4; + context->uvd.ib_cpu[len++] = context->enc.session.addr >> 32; + context->uvd.ib_cpu[len++] = context->enc.session.addr; + + memcpy((context->uvd.ib_cpu + len), uve_task_info, sizeof(uve_task_info)); + len += sizeof(uve_task_info) / 4; + context->uvd.ib_cpu[len++] = 0x000000d8; + context->uvd.ib_cpu[len++] = 0x00000000; + context->uvd.ib_cpu[len++] = 0x00000000; + + memcpy((context->uvd.ib_cpu + len), uve_op_init, sizeof(uve_op_init)); + len += sizeof(uve_op_init) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_session_init, sizeof(uve_session_init)); + len += sizeof(uve_session_init) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_layer_ctrl, sizeof(uve_layer_ctrl)); + len += sizeof(uve_layer_ctrl) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_slice_ctrl, sizeof(uve_slice_ctrl)); + len += sizeof(uve_slice_ctrl) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_spec_misc, sizeof(uve_spec_misc)); + len += sizeof(uve_spec_misc) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_rc_session_init, + sizeof(uve_rc_session_init)); + len += sizeof(uve_rc_session_init) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_deblocking_filter, + sizeof(uve_deblocking_filter)); + len += sizeof(uve_deblocking_filter) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_quality_params, + sizeof(uve_quality_params)); + len += sizeof(uve_quality_params) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_op_init_rc, sizeof(uve_op_init_rc)); + len += sizeof(uve_op_init_rc) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_op_init_rc_vbv_level, + sizeof(uve_op_init_rc_vbv_level)); + len += sizeof(uve_op_init_rc_vbv_level) / 4; + + r = submit(device_handle, &context->uvd, len, AMDGPU_HW_IP_UVD_ENC); + igt_assert_eq(r, 0); +} + +static void +amdgpu_uvd_enc_encode(amdgpu_device_handle device_handle, + struct uvd_enc_context *context) +{ + int len, r, i; + uint64_t luma_offset, chroma_offset; + unsigned int luma_size; + uint32_t vbuf_size, bs_size = 0x003f4800, cpb_size; + unsigned int align = (context->uvd.family_id >= AMDGPU_FAMILY_AI) ? 256 : 16; + + vbuf_size = ALIGN(context->enc.width, align) * + ALIGN(context->enc.height, 16) * 1.5; + cpb_size = vbuf_size * 10; + context->uvd.num_resources = 0; + alloc_resource(device_handle, &context->enc.fb, 4096, + AMDGPU_GEM_DOMAIN_VRAM); + context->uvd.resources[context->uvd.num_resources++] = context->enc.fb.handle; + alloc_resource(device_handle, &context->enc.bs, bs_size, + AMDGPU_GEM_DOMAIN_VRAM); + context->uvd.resources[context->uvd.num_resources++] = context->enc.bs.handle; + alloc_resource(device_handle, &context->enc.vbuf, vbuf_size, + AMDGPU_GEM_DOMAIN_VRAM); + context->uvd.resources[context->uvd.num_resources++] = context->enc.vbuf.handle; + alloc_resource(device_handle, &context->enc.cpb, cpb_size, + AMDGPU_GEM_DOMAIN_VRAM); + context->uvd.resources[context->uvd.num_resources++] = context->enc.cpb.handle; + context->uvd.resources[context->uvd.num_resources++] = context->uvd.ib_handle; + + r = amdgpu_bo_cpu_map(context->enc.vbuf.handle, (void **)&context->enc.vbuf.ptr); + igt_assert_eq(r, 0); + + memset(context->enc.vbuf.ptr, 0, vbuf_size); + for (i = 0; i < context->enc.height; ++i) { + memcpy(context->enc.vbuf.ptr, (frame + i * context->enc.width), + context->enc.width); + context->enc.vbuf.ptr += ALIGN(context->enc.width, align); + } + for (i = 0; i < context->enc.height / 2; ++i) { + memcpy(context->enc.vbuf.ptr, ((frame + context->enc.height * + context->enc.width) + i * context->enc.width), context->enc.width); + context->enc.vbuf.ptr += ALIGN(context->enc.width, align); + } + + r = amdgpu_bo_cpu_unmap(context->enc.vbuf.handle); + igt_assert_eq(r, 0); + + len = 0; + memcpy((context->uvd.ib_cpu + len), uve_session_info, sizeof(uve_session_info)); + len += sizeof(uve_session_info) / 4; + context->uvd.ib_cpu[len++] = context->enc.session.addr >> 32; + context->uvd.ib_cpu[len++] = context->enc.session.addr; + + memcpy((context->uvd.ib_cpu + len), uve_task_info, sizeof(uve_task_info)); + len += sizeof(uve_task_info) / 4; + context->uvd.ib_cpu[len++] = 0x000005e0; + context->uvd.ib_cpu[len++] = 0x00000001; + context->uvd.ib_cpu[len++] = 0x00000001; + + memcpy((context->uvd.ib_cpu + len), uve_nalu_buffer_1, sizeof(uve_nalu_buffer_1)); + len += sizeof(uve_nalu_buffer_1) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_nalu_buffer_2, sizeof(uve_nalu_buffer_2)); + len += sizeof(uve_nalu_buffer_2) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_nalu_buffer_3, sizeof(uve_nalu_buffer_3)); + len += sizeof(uve_nalu_buffer_3) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_nalu_buffer_4, sizeof(uve_nalu_buffer_4)); + len += sizeof(uve_nalu_buffer_4) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_slice_header, sizeof(uve_slice_header)); + len += sizeof(uve_slice_header) / 4; + + context->uvd.ib_cpu[len++] = 0x00000254; + context->uvd.ib_cpu[len++] = 0x00000010; + context->uvd.ib_cpu[len++] = context->enc.cpb.addr >> 32; + context->uvd.ib_cpu[len++] = context->enc.cpb.addr; + memcpy((context->uvd.ib_cpu + len), uve_ctx_buffer, sizeof(uve_ctx_buffer)); + len += sizeof(uve_ctx_buffer) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_bitstream_buffer, + sizeof(uve_bitstream_buffer)); + len += sizeof(uve_bitstream_buffer) / 4; + context->uvd.ib_cpu[len++] = 0x00000000; + context->uvd.ib_cpu[len++] = context->enc.bs.addr >> 32; + context->uvd.ib_cpu[len++] = context->enc.bs.addr; + context->uvd.ib_cpu[len++] = 0x003f4800; + context->uvd.ib_cpu[len++] = 0x00000000; + + memcpy((context->uvd.ib_cpu + len), uve_feedback_buffer, + sizeof(uve_feedback_buffer)); + len += sizeof(uve_feedback_buffer) / 4; + context->uvd.ib_cpu[len++] = context->enc.fb.addr >> 32; + context->uvd.ib_cpu[len++] = context->enc.fb.addr; + context->uvd.ib_cpu[len++] = 0x00000010; + context->uvd.ib_cpu[len++] = 0x00000028; + + memcpy((context->uvd.ib_cpu + len), uve_feedback_buffer_additional, + sizeof(uve_feedback_buffer_additional)); + len += sizeof(uve_feedback_buffer_additional) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_intra_refresh, sizeof(uve_intra_refresh)); + len += sizeof(uve_intra_refresh) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_layer_select, sizeof(uve_layer_select)); + len += sizeof(uve_layer_select) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_rc_layer_init, sizeof(uve_rc_layer_init)); + len += sizeof(uve_rc_layer_init) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_layer_select, sizeof(uve_layer_select)); + len += sizeof(uve_layer_select) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_rc_per_pic, sizeof(uve_rc_per_pic)); + len += sizeof(uve_rc_per_pic) / 4; + + luma_size = ALIGN(context->enc.width, align) * ALIGN(context->enc.height, 16); + luma_offset = context->enc.vbuf.addr; + chroma_offset = luma_offset + luma_size; + context->uvd.ib_cpu[len++] = 0x00000054; + context->uvd.ib_cpu[len++] = 0x0000000c; + context->uvd.ib_cpu[len++] = 0x00000002; + context->uvd.ib_cpu[len++] = 0x003f4800; + context->uvd.ib_cpu[len++] = luma_offset >> 32; + context->uvd.ib_cpu[len++] = luma_offset; + context->uvd.ib_cpu[len++] = chroma_offset >> 32; + context->uvd.ib_cpu[len++] = chroma_offset; + memcpy((context->uvd.ib_cpu + len), uve_encode_param, sizeof(uve_encode_param)); + context->uvd.ib_cpu[len] = ALIGN(context->enc.width, align); + context->uvd.ib_cpu[len + 1] = ALIGN(context->enc.width, align); + len += sizeof(uve_encode_param) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_op_speed_enc_mode, + sizeof(uve_op_speed_enc_mode)); + len += sizeof(uve_op_speed_enc_mode) / 4; + + memcpy((context->uvd.ib_cpu + len), uve_op_encode, sizeof(uve_op_encode)); + len += sizeof(uve_op_encode) / 4; + + r = submit(device_handle, &context->uvd, len, AMDGPU_HW_IP_UVD_ENC); + igt_assert_eq(r, 0); + + check_result(&context->enc); + + free_resource(&context->enc.fb); + free_resource(&context->enc.bs); + free_resource(&context->enc.vbuf); + free_resource(&context->enc.cpb); +} + +static void +amdgpu_uvd_enc_destroy(amdgpu_device_handle device_handle, + struct uvd_enc_context *context) +{ + int len, r; + + context->uvd.num_resources = 0; + context->uvd.resources[context->uvd.num_resources++] = context->uvd.ib_handle; + + len = 0; + memcpy((context->uvd.ib_cpu + len), uve_session_info, sizeof(uve_session_info)); + len += sizeof(uve_session_info) / 4; + context->uvd.ib_cpu[len++] = context->enc.session.addr >> 32; + context->uvd.ib_cpu[len++] = context->enc.session.addr; + + memcpy((context->uvd.ib_cpu + len), uve_task_info, sizeof(uve_task_info)); + len += sizeof(uve_task_info) / 4; + context->uvd.ib_cpu[len++] = 0xffffffff; + context->uvd.ib_cpu[len++] = 0x00000002; + context->uvd.ib_cpu[len++] = 0x00000000; + + memcpy((context->uvd.ib_cpu + len), uve_op_close, sizeof(uve_op_close)); + len += sizeof(uve_op_close) / 4; + + r = submit(device_handle, &context->uvd, len, AMDGPU_HW_IP_UVD_ENC); + igt_assert_eq(r, 0); + + free_resource(&context->enc.session); +} + +igt_main +{ + amdgpu_device_handle device; + struct uvd_enc_context context = {}; + int fd = -1; + + igt_fixture { + uint32_t major, minor; + int err; + + fd = drm_open_driver(DRIVER_AMDGPU); + err = amdgpu_device_initialize(fd, &major, &minor, &device); + igt_require(err == 0); + igt_info("Initialized amdgpu, driver version %d.%d\n", + major, minor); + err = mmd_context_init(device, &context.uvd); + igt_require(err == 0); + + igt_skip_on(!is_uvd_enc_enable(device)); + } + + igt_describe("Test whether uvd enc is created"); + igt_subtest("uvd_enc_create") + amdgpu_uvd_enc_create(device, &context); + + igt_describe("Test whether uvd enc session init"); + igt_subtest("amdgpu_uvd_enc_session_init") + amdgpu_uvd_enc_session_init(device, &context); + + igt_describe("Test whether uvd enc encode"); + igt_subtest("amdgpu_uvd_enc_encode") + amdgpu_uvd_enc_encode(device, &context); + + igt_describe("Test whether uvd enc is destroyed"); + igt_subtest("uvd_enc_destroy") + amdgpu_uvd_enc_destroy(device, &context); + + igt_fixture { + mmd_context_clean(device, &context.uvd); + amdgpu_device_deinitialize(device); + drm_close_driver(fd); + } +} diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build index 690bc38db..576333aab 100644 --- a/tests/amdgpu/meson.build +++ b/tests/amdgpu/meson.build @@ -25,6 +25,7 @@ if libdrm_amdgpu.found() 'amd_prime', 'amd_psr', 'amd_uvd_dec', + 'amd_uvd_enc', 'amd_vrr_range', ] amdgpu_deps += libdrm_amdgpu -- 2.25.1