From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id 68F8F10E37D for ; Tue, 11 Jul 2023 11:15:26 +0000 (UTC) Message-ID: <927132e0-c141-3029-2c08-5e59c760378f@intel.com> Date: Tue, 11 Jul 2023 13:15:03 +0200 Content-Language: en-US To: =?UTF-8?Q?Zbigniew_Kempczy=c5=84ski?= References: <20230706060555.282757-1-zbigniew.kempczynski@intel.com> <20230706060555.282757-16-zbigniew.kempczynski@intel.com> <4554c6e7-dea9-3e50-3899-95b748636d45@intel.com> <20230711110746.ygtjalifew5eeqfp@zkempczy-mobl2> From: Karolina Stolarek In-Reply-To: <20230711110746.ygtjalifew5eeqfp@zkempczy-mobl2> Content-Type: text/plain; charset="UTF-8"; format=flowed Content-Transfer-Encoding: 8bit MIME-Version: 1.0 Subject: Re: [igt-dev] [PATCH i-g-t v2 15/16] tests/xe_exercise_blt: Check blitter library fast-copy for Xe List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: igt-dev@lists.freedesktop.org Errors-To: igt-dev-bounces@lists.freedesktop.org Sender: "igt-dev" List-ID: On 11.07.2023 13:07, Zbigniew Kempczyński wrote: > On Fri, Jul 07, 2023 at 01:10:52PM +0200, Karolina Stolarek wrote: >> On 6.07.2023 08:05, Zbigniew Kempczyński wrote: >>> Port this test to work on xe. Instead of adding conditional code for >>> xe code which would decrease readability this is new test for xe. >>> >>> Signed-off-by: Zbigniew Kempczyński >>> --- >>> tests/meson.build | 1 + >>> tests/xe/xe_exercise_blt.c | 372 +++++++++++++++++++++++++++++++++++++ >>> 2 files changed, 373 insertions(+) >>> create mode 100644 tests/xe/xe_exercise_blt.c >>> >>> diff --git a/tests/meson.build b/tests/meson.build >>> index 9bca57a5e8..137a5cf01f 100644 >>> --- a/tests/meson.build >>> +++ b/tests/meson.build >>> @@ -257,6 +257,7 @@ xe_progs = [ >>> 'xe_exec_reset', >>> 'xe_exec_store', >>> 'xe_exec_threads', >>> + 'xe_exercise_blt', >>> 'xe_gpgpu_fill', >>> 'xe_guc_pc', >>> 'xe_huc_copy', >>> diff --git a/tests/xe/xe_exercise_blt.c b/tests/xe/xe_exercise_blt.c >>> new file mode 100644 >>> index 0000000000..8340cf7148 >>> --- /dev/null >>> +++ b/tests/xe/xe_exercise_blt.c >>> @@ -0,0 +1,372 @@ >>> +// SPDX-License-Identifier: MIT >>> +/* >>> + * Copyright © 2023 Intel Corporation >>> + */ >>> + >>> +#include "igt.h" >>> +#include "drm.h" >>> +#include "lib/intel_chipset.h" >>> +#include "intel_blt.h" >>> +#include "intel_mocs.h" >>> +#include "xe/xe_ioctl.h" >>> +#include "xe/xe_query.h" >>> +#include "xe/xe_util.h" >>> + >>> +/** >>> + * TEST: xe exercise blt >>> + * Description: Exercise blitter commands on Xe >>> + * Feature: blitter >>> + * Run type: FULL >>> + * Test category: GEM_Legacy >>> + * >>> + * SUBTEST: fast-copy >>> + * Description: >>> + * Check fast-copy blit >>> + * blitter >>> + * >>> + * SUBTEST: fast-copy-emit >>> + * Description: >>> + * Check multiple fast-copy in one batch >>> + * blitter >>> + */ >>> + >>> +IGT_TEST_DESCRIPTION("Exercise blitter commands on Xe"); >>> + >>> +static struct param { >>> + int tiling; >>> + bool write_png; >>> + bool print_bb; >>> + bool print_surface_info; >>> + int width; >>> + int height; >>> +} param = { >>> + .tiling = -1, >>> + .write_png = false, >>> + .print_bb = false, >>> + .print_surface_info = false, >>> + .width = 512, >>> + .height = 512, >>> +}; >>> + >>> +#define PRINT_SURFACE_INFO(name, obj) do { \ >>> + if (param.print_surface_info) \ >>> + blt_surface_info((name), (obj)); } while (0) >>> + >>> +#define WRITE_PNG(fd, id, name, obj, w, h) do { \ >>> + if (param.write_png) \ >>> + blt_surface_to_png((fd), (id), (name), (obj), (w), (h)); } while (0) >>> + >> >> My suggestion with shared functions applies here as well >> >>> +struct blt_fast_copy_data { >>> + int xe; >>> + struct blt_copy_object src; >>> + struct blt_copy_object mid; >>> + struct blt_copy_object dst; >>> + >>> + struct blt_copy_batch bb; >>> + enum blt_color_depth color_depth; >>> + >>> + /* debug stuff */ >>> + bool print_bb; >>> +}; >>> + >>> +static int fast_copy_one_bb(int xe, >>> + const intel_ctx_t *ctx, >>> + uint64_t ahnd, >>> + const struct blt_fast_copy_data *blt) >>> +{ >>> + struct blt_copy_data blt_tmp; >>> + uint64_t bb_offset, alignment; >>> + uint64_t bb_pos = 0; >>> + int ret = 0; >>> + >>> + alignment = xe_get_default_alignment(xe); >>> + >>> + get_offset(ahnd, blt->src.handle, blt->src.size, alignment); >>> + get_offset(ahnd, blt->mid.handle, blt->mid.size, alignment); >>> + get_offset(ahnd, blt->dst.handle, blt->dst.size, alignment); >>> + bb_offset = get_offset(ahnd, blt->bb.handle, blt->bb.size, alignment); >>> + >>> + /* First blit */ >>> + blt_copy_init(xe, &blt_tmp); >>> + blt_tmp.src = blt->src; >>> + blt_tmp.dst = blt->mid; >>> + blt_tmp.bb = blt->bb; >>> + blt_tmp.color_depth = blt->color_depth; >>> + blt_tmp.print_bb = blt->print_bb; >>> + bb_pos = emit_blt_fast_copy(xe, ahnd, &blt_tmp, bb_pos, false); >>> + >>> + /* Second blit */ >>> + blt_copy_init(xe, &blt_tmp); >>> + blt_tmp.src = blt->mid; >>> + blt_tmp.dst = blt->dst; >>> + blt_tmp.bb = blt->bb; >>> + blt_tmp.color_depth = blt->color_depth; >>> + blt_tmp.print_bb = blt->print_bb; >>> + bb_pos = emit_blt_fast_copy(xe, ahnd, &blt_tmp, bb_pos, true); >>> + >>> + intel_ctx_xe_exec(ctx, ahnd, bb_offset); >>> + >>> + return ret; >>> +} >>> + >>> +static void fast_copy_emit(int xe, const intel_ctx_t *ctx, >>> + uint32_t region1, uint32_t region2, >>> + enum blt_tiling_type mid_tiling) >>> +{ >>> + struct blt_copy_data bltinit = {}; >>> + struct blt_fast_copy_data blt = {}; >>> + struct blt_copy_object *src, *mid, *dst; >>> + const uint32_t bpp = 32; >>> + uint64_t bb_size = xe_get_default_alignment(xe); >>> + uint64_t ahnd = intel_allocator_open_full(xe, ctx->vm, 0, 0, >>> + INTEL_ALLOCATOR_SIMPLE, >>> + ALLOC_STRATEGY_LOW_TO_HIGH, 0); >>> + uint32_t bb, width = param.width, height = param.height; >>> + int result; >>> + >>> + bb = xe_bo_create_flags(xe, 0, bb_size, region1); >>> + >>> + blt_copy_init(xe, &bltinit); >>> + src = blt_create_object(&bltinit, region1, width, height, bpp, 0, >>> + T_LINEAR, COMPRESSION_DISABLED, 0, true); >>> + mid = blt_create_object(&bltinit, region2, width, height, bpp, 0, >>> + mid_tiling, COMPRESSION_DISABLED, 0, true); >>> + dst = blt_create_object(&bltinit, region1, width, height, bpp, 0, >>> + T_LINEAR, COMPRESSION_DISABLED, 0, true); >>> + igt_assert(src->size == dst->size); >>> + >>> + PRINT_SURFACE_INFO("src", src); >>> + PRINT_SURFACE_INFO("mid", mid); >>> + PRINT_SURFACE_INFO("dst", dst); >>> + >>> + blt_surface_fill_rect(xe, src, width, height); >>> + WRITE_PNG(xe, mid_tiling, "src", src, width, height); >>> + >>> + memset(&blt, 0, sizeof(blt)); >>> + blt.color_depth = CD_32bit; >>> + blt.print_bb = param.print_bb; >>> + blt_set_copy_object(&blt.src, src); >>> + blt_set_copy_object(&blt.mid, mid); >>> + blt_set_copy_object(&blt.dst, dst); >>> + blt_set_batch(&blt.bb, bb, bb_size, region1); >>> + >>> + fast_copy_one_bb(xe, ctx, ahnd, &blt); >>> + >>> + WRITE_PNG(xe, mid_tiling, "mid", &blt.mid, width, height); >>> + WRITE_PNG(xe, mid_tiling, "dst", &blt.dst, width, height); >>> + >>> + result = memcmp(src->ptr, blt.dst.ptr, src->size); >>> + >>> + blt_destroy_object(xe, src); >>> + blt_destroy_object(xe, mid); >>> + blt_destroy_object(xe, dst); >> >> I see that in block_copy tests we also call put_offset() for all copy >> objects' handles. Although we have a different allocator, I think that we >> should free the ranges on object destruction. >> > > I was a little bit surprised we put_offset() in fast-copy and surf-copy. > I mean this will rebind offsets unnecessary. Finally we should put them > before releasing ahnd, but for vm-bind (xe) destroying vm just does > the job (and intel_allocator_init() is freeing the dangling memory > which wasn't released explicitly). I see, good to know! Thanks for the explaination. All the best, Karolina > >>> + gem_close(xe, bb); >>> + put_ahnd(ahnd); >>> + >>> + munmap(&bb, bb_size); >>> + >>> + igt_assert_f(!result, "source and destination surfaces differs!\n"); >>> +} >>> + >>> +static void fast_copy(int xe, const intel_ctx_t *ctx, >>> + uint32_t region1, uint32_t region2, >>> + enum blt_tiling_type mid_tiling) >>> +{ >>> + struct blt_copy_data blt = {}; >>> + struct blt_copy_object *src, *mid, *dst; >>> + const uint32_t bpp = 32; >>> + uint64_t bb_size = xe_get_default_alignment(xe); >>> + uint64_t ahnd = intel_allocator_open_full(xe, ctx->vm, 0, 0, >>> + INTEL_ALLOCATOR_SIMPLE, >>> + ALLOC_STRATEGY_LOW_TO_HIGH, 0); >>> + uint32_t bb; >>> + uint32_t width = param.width, height = param.height; >>> + int result; >>> + >>> + bb = xe_bo_create_flags(xe, 0, bb_size, region1); >>> + >>> + blt_copy_init(xe, &blt); >>> + src = blt_create_object(&blt, region1, width, height, bpp, 0, >>> + T_LINEAR, COMPRESSION_DISABLED, 0, true); >>> + mid = blt_create_object(&blt, region2, width, height, bpp, 0, >>> + mid_tiling, COMPRESSION_DISABLED, 0, true); >>> + dst = blt_create_object(&blt, region1, width, height, bpp, 0, >>> + T_LINEAR, COMPRESSION_DISABLED, 0, true); >>> + igt_assert(src->size == dst->size); >>> + >>> + blt_surface_fill_rect(xe, src, width, height); >>> + >>> + blt.color_depth = CD_32bit; >>> + blt.print_bb = param.print_bb; >>> + blt_set_copy_object(&blt.src, src); >>> + blt_set_copy_object(&blt.dst, mid); >>> + blt_set_batch(&blt.bb, bb, bb_size, region1); >>> + >>> + blt_fast_copy(xe, ctx, NULL, ahnd, &blt); >>> + >>> + WRITE_PNG(xe, mid_tiling, "src", &blt.src, width, height); >>> + WRITE_PNG(xe, mid_tiling, "mid", &blt.dst, width, height); >>> + >>> + blt_copy_init(xe, &blt); >>> + blt.color_depth = CD_32bit; >>> + blt.print_bb = param.print_bb; >>> + blt_set_copy_object(&blt.src, mid); >>> + blt_set_copy_object(&blt.dst, dst); >>> + blt_set_batch(&blt.bb, bb, bb_size, region1); >>> + >>> + blt_fast_copy(xe, ctx, NULL, ahnd, &blt); >>> + >>> + WRITE_PNG(xe, mid_tiling, "dst", &blt.dst, width, height); >>> + >>> + result = memcmp(src->ptr, blt.dst.ptr, src->size); >>> + >>> + blt_destroy_object(xe, src); >>> + blt_destroy_object(xe, mid); >>> + blt_destroy_object(xe, dst); >>> + gem_close(xe, bb); >>> + put_ahnd(ahnd); >>> + >>> + igt_assert_f(!result, "source and destination surfaces differs!\n"); >>> +} >>> + >>> +enum fast_copy_func { >>> + FAST_COPY, >>> + FAST_COPY_EMIT >>> +}; >>> + >>> +static char >>> + *full_subtest_str(char *regtxt, enum blt_tiling_type tiling, >>> + enum fast_copy_func func) >>> +{ >>> + char *name; >>> + uint32_t len; >>> + >>> + len = asprintf(&name, "%s-%s%s", blt_tiling_name(tiling), regtxt, >>> + func == FAST_COPY_EMIT ? "-emit" : ""); >>> + >>> + igt_assert_f(len >= 0, "asprintf failed!\n"); >>> + >>> + return name; >>> +} >>> + >>> +static void fast_copy_test(int xe, >>> + struct igt_collection *set, >>> + enum fast_copy_func func) >>> +{ >>> + struct drm_xe_engine_class_instance inst = { >>> + .engine_class = DRM_XE_ENGINE_CLASS_COPY, >>> + }; >>> + struct igt_collection *regions; >>> + void (*copy_func)(int xe, const intel_ctx_t *ctx, >>> + uint32_t r1, uint32_t r2, enum blt_tiling_type tiling); >>> + intel_ctx_t *ctx; >>> + int tiling; >>> + >>> + for_each_tiling(tiling) { >>> + if (!blt_fast_copy_supports_tiling(xe, tiling)) >>> + continue; >>> + >>> + for_each_variation_r(regions, 2, set) { >>> + uint32_t region1, region2; >>> + uint32_t vm, engine; >>> + char *regtxt, *test_name; >>> + >>> + region1 = igt_collection_get_value(regions, 0); >>> + region2 = igt_collection_get_value(regions, 1); >>> + >>> + vm = xe_vm_create(xe, DRM_XE_VM_CREATE_ASYNC_BIND_OPS, 0); >>> + engine = xe_engine_create(xe, vm, &inst, 0); >>> + ctx = intel_ctx_xe(xe, vm, engine, 0, 0, 0); >>> + >>> + copy_func = (func == FAST_COPY) ? fast_copy : fast_copy_emit; >>> + regtxt = xe_memregion_dynamic_subtest_name(xe, regions); >>> + test_name = full_subtest_str(regtxt, tiling, func); >>> + >>> + igt_dynamic_f("%s", test_name) { >>> + copy_func(xe, ctx, >>> + region1, region2, >>> + tiling); >>> + } >>> + >>> + free(regtxt); >>> + free(test_name); >>> + xe_engine_destroy(xe, engine); >>> + xe_vm_destroy(xe, vm); >>> + free(ctx); >>> + } >>> + } >>> +} >>> + >>> +static int opt_handler(int opt, int opt_index, void *data) >>> +{ >>> + switch (opt) { >>> + case 'b': >>> + param.print_bb = true; >>> + igt_debug("Print bb: %d\n", param.print_bb); >>> + break; >>> + case 'p': >>> + param.write_png = true; >>> + igt_debug("Write png: %d\n", param.write_png); >>> + break; >>> + case 's': >>> + param.print_surface_info = true; >>> + igt_debug("Print surface info: %d\n", param.print_surface_info); >>> + break; >>> + case 't': >>> + param.tiling = atoi(optarg); >>> + igt_debug("Tiling: %d\n", param.tiling); >>> + break; >>> + case 'W': >>> + param.width = atoi(optarg); >>> + igt_debug("Width: %d\n", param.width); >>> + break; >>> + case 'H': >>> + param.height = atoi(optarg); >>> + igt_debug("Height: %d\n", param.height); >>> + break; >>> + default: >>> + return IGT_OPT_HANDLER_ERROR; >>> + } >>> + >>> + return IGT_OPT_HANDLER_SUCCESS; >>> +} >>> + >>> +const char *help_str = >>> + " -b\tPrint bb\n" >>> + " -p\tWrite PNG\n" >>> + " -s\tPrint surface info\n" >>> + " -t\tTiling format (0 - linear, 1 - XMAJOR, 2 - YMAJOR, 3 - TILE4, 4 - TILE64, 5 - YFMAJOR)\n" >>> + " -W\tWidth (default 512)\n" >>> + " -H\tHeight (default 512)" >>> + ; >>> + >>> +igt_main_args("b:pst:W:H:", NULL, help_str, opt_handler, NULL) >>> +{ >>> + struct igt_collection *set; >>> + int xe; >>> + >>> + igt_fixture { >>> + xe = drm_open_driver(DRIVER_XE); >>> + igt_require(blt_has_block_copy(xe)); >> >> Should be blt_has_fast_copy(xe) > > Yes, missed that during copying fixture from xe_ccs. Thanks for spotting > this. > > -- > Zbigniew > >> >> All the best, >> Karolina >>> + >>> + xe_device_get(xe); >>> + >>> + set = xe_get_memory_region_set(xe, >>> + XE_MEM_REGION_CLASS_SYSMEM, >>> + XE_MEM_REGION_CLASS_VRAM); >>> + } >>> + >>> + igt_describe("Check fast-copy blit"); >>> + igt_subtest_with_dynamic("fast-copy") { >>> + fast_copy_test(xe, set, FAST_COPY); >>> + } >>> + >>> + igt_describe("Check multiple fast-copy in one batch"); >>> + igt_subtest_with_dynamic("fast-copy-emit") { >>> + fast_copy_test(xe, set, FAST_COPY_EMIT); >>> + } >>> + >>> + igt_fixture { >>> + drm_close_driver(xe); >>> + } >>> +}