From: Karolina Stolarek <karolina.stolarek@intel.com>
To: "Zbigniew Kempczyński" <zbigniew.kempczynski@intel.com>
Cc: igt-dev@lists.freedesktop.org
Subject: Re: [igt-dev] [PATCH i-g-t v2 15/16] tests/xe_exercise_blt: Check blitter library fast-copy for Xe
Date: Tue, 11 Jul 2023 13:15:03 +0200 [thread overview]
Message-ID: <927132e0-c141-3029-2c08-5e59c760378f@intel.com> (raw)
In-Reply-To: <20230711110746.ygtjalifew5eeqfp@zkempczy-mobl2>
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 <zbigniew.kempczynski@intel.com>
>>> ---
>>> 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);
>>> + }
>>> +}
next prev parent reply other threads:[~2023-07-11 11:15 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-06 6:05 [igt-dev] [PATCH i-g-t v2 00/16] Extend intel_blt to work on Xe Zbigniew Kempczyński
2023-07-06 6:05 ` [igt-dev] [PATCH i-g-t v2 01/16] tests/api_intel_allocator: Don't use allocator ahnd aliasing api Zbigniew Kempczyński
2023-07-06 9:04 ` Karolina Stolarek
2023-07-06 6:05 ` [igt-dev] [PATCH i-g-t v2 02/16] lib/intel_allocator: Drop aliasing allocator handle api Zbigniew Kempczyński
2023-07-06 8:31 ` Karolina Stolarek
2023-07-06 11:20 ` Zbigniew Kempczyński
2023-07-06 13:28 ` Karolina Stolarek
2023-07-06 6:05 ` [igt-dev] [PATCH i-g-t v2 03/16] lib/intel_allocator: Remove extensive debugging Zbigniew Kempczyński
2023-07-06 9:30 ` Karolina Stolarek
2023-07-06 6:05 ` [igt-dev] [PATCH i-g-t v2 04/16] lib/xe_query: Use vramN when returning string region name Zbigniew Kempczyński
2023-07-06 6:05 ` [igt-dev] [PATCH i-g-t v2 05/16] lib/xe_query: Add xe_region_class() helper Zbigniew Kempczyński
2023-07-06 6:05 ` [igt-dev] [PATCH i-g-t v2 06/16] lib/drmtest: Add get_intel_driver() helper Zbigniew Kempczyński
2023-07-06 6:05 ` [igt-dev] [PATCH i-g-t v2 07/16] lib/xe_util: Return dynamic subtest name for Xe Zbigniew Kempczyński
2023-07-06 9:37 ` Karolina Stolarek
2023-07-06 6:05 ` [igt-dev] [PATCH i-g-t v2 08/16] lib/xe_util: Add vm bind/unbind helper " Zbigniew Kempczyński
2023-07-06 10:27 ` Karolina Stolarek
2023-07-06 6:05 ` [igt-dev] [PATCH i-g-t v2 09/16] lib/intel_allocator: Add field to distinquish underlying driver Zbigniew Kempczyński
2023-07-06 10:34 ` Karolina Stolarek
2023-07-06 6:05 ` [igt-dev] [PATCH i-g-t v2 10/16] lib/intel_allocator: Add intel_allocator_bind() Zbigniew Kempczyński
2023-07-06 13:02 ` Karolina Stolarek
2023-07-06 16:09 ` Zbigniew Kempczyński
2023-07-07 8:01 ` Karolina Stolarek
2023-07-06 6:05 ` [igt-dev] [PATCH i-g-t v2 11/16] lib/intel_ctx: Add xe context information Zbigniew Kempczyński
2023-07-07 8:31 ` Karolina Stolarek
2023-07-11 9:06 ` Zbigniew Kempczyński
2023-07-11 10:38 ` Karolina Stolarek
2023-07-06 6:05 ` [igt-dev] [PATCH i-g-t v2 12/16] lib/intel_blt: Introduce blt_copy_init() helper to cache driver Zbigniew Kempczyński
2023-07-07 8:51 ` Karolina Stolarek
2023-07-11 9:23 ` Zbigniew Kempczyński
2023-07-06 6:05 ` [igt-dev] [PATCH i-g-t v2 13/16] lib/intel_blt: Extend blitter library to support xe driver Zbigniew Kempczyński
2023-07-07 9:26 ` Karolina Stolarek
2023-07-11 10:16 ` Zbigniew Kempczyński
2023-07-11 10:41 ` Karolina Stolarek
2023-07-06 6:05 ` [igt-dev] [PATCH i-g-t v2 14/16] tests/xe_ccs: Check if flatccs is working with block-copy for Xe Zbigniew Kempczyński
2023-07-07 10:05 ` Karolina Stolarek
2023-07-11 10:45 ` Zbigniew Kempczyński
2023-07-11 10:51 ` Karolina Stolarek
2023-07-12 7:00 ` Zbigniew Kempczyński
2023-07-06 6:05 ` [igt-dev] [PATCH i-g-t v2 15/16] tests/xe_exercise_blt: Check blitter library fast-copy " Zbigniew Kempczyński
2023-07-07 11:10 ` Karolina Stolarek
2023-07-11 11:07 ` Zbigniew Kempczyński
2023-07-11 11:15 ` Karolina Stolarek [this message]
2023-07-06 6:05 ` [igt-dev] [PATCH i-g-t v2 16/16] tests/api-intel-allocator: Adopt to exercise allocator to Xe Zbigniew Kempczyński
2023-07-07 10:11 ` Karolina Stolarek
2023-07-06 6:58 ` [igt-dev] ✓ Fi.CI.BAT: success for Extend intel_blt to work on Xe (rev2) Patchwork
2023-07-06 9:26 ` [igt-dev] ✓ Fi.CI.IGT: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=927132e0-c141-3029-2c08-5e59c760378f@intel.com \
--to=karolina.stolarek@intel.com \
--cc=igt-dev@lists.freedesktop.org \
--cc=zbigniew.kempczynski@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox