[PATCH i-g-t, v9 3/9] tests/kms_sharpness_filter: Add adaptive sharpness basic filter tests
Nautiyal, Ankit K
ankit.k.nautiyal at intel.com
Wed Dec 11 04:25:10 UTC 2024
On 12/9/2024 5:16 PM, Swati Sharma wrote:
> New test is added to validate adaptive sharpness filter on
> LNL platform. Various testcases are added to validate this
> feature. These are non CRC based tests and manual verification
> is required.
>
> Pipe scaler is repurposed to perform a portion of this work.
> This means pipe scaling will be unavailable while the sharpening
> function is being used. The other scaler can be used for plane
> scaler.
>
> 5 subtests are added:
> -basic: verify basic functionality
> -modifiers: verify casf with different modifiers
> -rotation: verify casf with different rotation
> -formats: verify casf with different formats
> -strength: vary strength and check difference in sharpness
Use imperative mood in commit message.
>
> TODO: -Enable casf with varying output formats (YCBCR/RGB)
>
> v2: -Updated modifier type to uint64_t.
> -Replaced IGT_CRTC_SHARPENESS_STRENGTH with IGT_CRTC_SHARPNESS_STRENGTH.
> v3: -Updated setup_fb with height and width.
> v4: -Renamed tests/intel/kms_sharpness_filter.c -> tests/kms_sharpness_filter.c (Ankit)
> -Added subtest invalid filter with connector. (Ankit)
> -Updated documentation. (Bhanu)
> -Used driver_close_driver instead close. (Bhanu)
> -Added check to avoid debug print for invalid tests and filter strength = 0. (Ankit)
> v5: -Instead of using default strength as MAX, use MID value strength.
> -Add relevant debug print for test skip.
> -Fix indentation.
> -Renamed invalid-filter-with-connector -> invalid-filter-with-scaling-mode
> -Reworked on invalid-filter-with-scaling-mode(), added provision to
> validate other scaling modes.
> v6: -Skip test if ret=-EINVAL for downscaling test.
> -Change if() for tap subtest.
> v8: -Optimize tap-filter subtest (Ankit)
> v9: -Logically split tests (Ankit)
> -Fix alignment (Ankit)
>
> Signed-off-by: Swati Sharma <swati2.sharma at intel.com>
> ---
> tests/kms_sharpness_filter.c | 346 +++++++++++++++++++++++++++++++++++
> tests/meson.build | 1 +
> 2 files changed, 347 insertions(+)
> create mode 100644 tests/kms_sharpness_filter.c
>
> diff --git a/tests/kms_sharpness_filter.c b/tests/kms_sharpness_filter.c
> new file mode 100644
> index 000000000..bf660cb02
> --- /dev/null
> +++ b/tests/kms_sharpness_filter.c
> @@ -0,0 +1,346 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2024 Intel Corporation
> + */
> +
> +/**
> + * TEST: kms sharpness filter
> + * Category: Display
> + * Description: Test to validate content adaptive sharpness filter
> + * Driver requirement: xe
> + * Functionality: casf
> + * Mega feature: General Display Features
> + * Test category: functionality test
> + */
> +
> +#include "igt.h"
> +#include "igt_kms.h"
> +
> +/**
> + * SUBTEST: filter-basic
> + * Description: Verify basic content adaptive sharpness filter.
> + *
> + * SUBTEST: filter-strength
> + * Description: Verify that varying strength (0-255), affects the degree of sharpeness applied.
> + *
> + * SUBTEST: filter-modifiers
> + * Description: Verify content adaptive sharpness filter with varying modifiers.
> + * Functionality: casf, tiling
> + *
> + * SUBTEST: filter-rotations
> + * Description: Verify content adaptive sharpness filter with varying rotations.
> + * Functionality: casf, rotation
> + *
> + * SUBTEST: filter-formats
> + * Description: Verify content adaptive sharpness filter with varying formats.
> + * Functionality: casf, pixel-format
> +*/
> +
> +IGT_TEST_DESCRIPTION("Test to validate content adaptive sharpness filter");
> +
> +/*
> + * Until the CRC support is added test needs to be invoked with
> + * --interactive|--i to manually verify if "sharpened" image
> + * is seen without corruption for each subtest.
> + */
> +
> +#define MIN_FILTER_STRENGTH 1
> +#define MID_FILTER_STRENGTH 128
> +#define MAX_FILTER_STRENGTH 255
> +
> +enum test_type {
> + TEST_FILTER_BASIC,
> + TEST_FILTER_MODIFIERS,
> + TEST_FILTER_ROTATION,
> + TEST_FILTER_FORMATS,
> + TEST_FILTER_STRENGTH,
> +};
> +
> +const int filter_strength_list[] = {
> + MIN_FILTER_STRENGTH,
> + (MIN_FILTER_STRENGTH + MID_FILTER_STRENGTH) / 2,
> + MID_FILTER_STRENGTH,
> + (MID_FILTER_STRENGTH + MAX_FILTER_STRENGTH) / 2,
> + MAX_FILTER_STRENGTH,
> +};
> +static const struct {
> + uint64_t modifier;
> + const char *name;
> +} modifiers[] = {
> + { DRM_FORMAT_MOD_LINEAR, "linear", },
> + { I915_FORMAT_MOD_X_TILED, "x-tiled", },
> + { I915_FORMAT_MOD_4_TILED, "4-tiled", },
> +};
> +static const int formats[] = {
> + DRM_FORMAT_NV12,
> + DRM_FORMAT_RGB565,
> + DRM_FORMAT_XRGB8888,
> + DRM_FORMAT_XBGR16161616F,
> +};
> +static const igt_rotation_t rotations[] = {
> + IGT_ROTATION_0,
> + IGT_ROTATION_180,
> +};
> +
> +typedef struct {
> + int drm_fd;
> + bool limited;
> + enum pipe pipe_id;
> + struct igt_fb fb[4];
> + igt_pipe_t *pipe;
> + igt_display_t display;
> + igt_output_t *output;
> + igt_plane_t *plane[4];
> + drmModeModeInfo *mode;
> + int filter_strength;
> + uint64_t modifier;
> + const char *modifier_name;
> + uint32_t format;
> + igt_rotation_t rotation;
> +} data_t;
> +
> +static void set_filter_strength_on_pipe(data_t *data)
> +{
> + igt_pipe_set_prop_value(&data->display, data->pipe_id,
> + IGT_CRTC_SHARPNESS_STRENGTH,
> + data->filter_strength);
> +}
> +
> +static void paint_image(igt_fb_t *fb)
> +{
> + cairo_t *cr = igt_get_cairo_ctx(fb->fd, fb);
> + int img_x, img_y, img_w, img_h;
> + const char *file = "1080p-left.png";
> +
> + img_x = img_y = 0;
> + img_w = fb->width;
> + img_h = fb->height;
> +
> + igt_paint_image(cr, file, img_x, img_y, img_w, img_h);
> +
> + igt_put_cairo_ctx(cr);
> +}
> +
> +static void setup_fb(int fd, int width, int height, uint32_t format,
> + uint64_t modifier, struct igt_fb *fb)
> +{
> + int fb_id;
> +
> + fb_id = igt_create_fb(fd, width, height, format, modifier, fb);
> + igt_assert(fb_id);
> +
> + paint_image(fb);
> +}
> +
> +static void cleanup_fbs(data_t *data)
> +{
> + for (int i = 0; i < ARRAY_SIZE(data->fb); i++)
> + igt_remove_fb(data->drm_fd, &data->fb[i]);
> +}
> +
> +static void cleanup(data_t *data)
> +{
> + igt_display_reset(&data->display);
> +
> + cleanup_fbs(data);
> +}
> +
> +static void test_sharpness_filter(data_t *data, enum test_type type)
> +{
> + drmModeModeInfo *mode = data->mode;
> + int height = mode->hdisplay;
> + int width = mode->vdisplay;
> + int ret;
> +
> + data->plane[0] = igt_pipe_get_plane_type(data->pipe, DRM_PLANE_TYPE_PRIMARY);
> + igt_skip_on_f(!igt_plane_has_format_mod(data->plane[0], data->format, data->modifier),
> + "No requested format/modifier on pipe %s\n", kmstest_pipe_name(data->pipe_id));
> +
> + setup_fb(data->drm_fd, height, width, data->format, data->modifier, &data->fb[0]);
> + igt_plane_set_fb(data->plane[0], &data->fb[0]);
> +
> + if (igt_plane_has_rotation(data->plane[0], data->rotation))
> + igt_plane_set_rotation(data->plane[0], data->rotation);
> + else
> + igt_skip("No requested rotation on pipe %s\n", kmstest_pipe_name(data->pipe_id));
Perhaps this should be checked only for rotation test.
Apart from minor things above, the patch looks good to me.
Reviewed-by: Ankit Nautiyal <ankit.k.nautiyal at intel.com>
Regards,
Ankit
> +
> + set_filter_strength_on_pipe(data);
> +
> + if (data->filter_strength != 0)
> + igt_debug("Sharpened image should be observed for filter strength > 0\n");
> +
> + ret = igt_display_try_commit2(&data->display, COMMIT_ATOMIC);
> +
> + igt_assert_eq(ret, 0);
> +
> + cleanup(data);
> +}
> +
> +static bool has_sharpness_filter(igt_pipe_t *pipe)
> +{
> + return igt_pipe_obj_has_prop(pipe, IGT_CRTC_SHARPNESS_STRENGTH);
> +}
> +
> +static void
> +run_sharpness_filter_test(data_t *data, enum test_type type)
> +{
> + igt_display_t *display = &data->display;
> + igt_output_t *output;
> + enum pipe pipe;
> + char name[40];
> +
> + for_each_connected_output(display, output) {
> + for_each_pipe(display, pipe) {
> + igt_display_reset(display);
> +
> + data->output = output;
> + data->pipe_id = pipe;
> + data->pipe = &display->pipes[data->pipe_id];
> + data->mode = igt_output_get_mode(data->output);
> +
> + if (!has_sharpness_filter(data->pipe)) {
> + igt_info("%s: Doesn't support IGT_CRTC_SHARPNESS_STRENGTH.\n",
> + kmstest_pipe_name(data->pipe_id));
> + continue;
> + }
> +
> + igt_output_set_pipe(data->output, data->pipe_id);
> +
> + if (!intel_pipe_output_combo_valid(display)) {
> + igt_output_set_pipe(data->output, PIPE_NONE);
> + continue;
> + }
> +
> + switch (type) {
> + case TEST_FILTER_BASIC:
> + snprintf(name, sizeof(name), "-basic");
> + break;
> + case TEST_FILTER_MODIFIERS:
> + snprintf(name, sizeof(name), "-%s", data->modifier_name);
> + break;
> + case TEST_FILTER_ROTATION:
> + snprintf(name, sizeof(name), "-%srot", igt_plane_rotation_name(data->rotation));
> + break;
> + case TEST_FILTER_FORMATS:
> + snprintf(name, sizeof(name), "-%s", igt_format_str(data->format));
> + break;
> + case TEST_FILTER_STRENGTH:
> + snprintf(name, sizeof(name), "-strength-%d", data->filter_strength);
> + break;
> + default:
> + igt_assert(0);
> + }
> +
> + igt_dynamic_f("pipe-%s-%s%s", kmstest_pipe_name(data->pipe_id), data->output->name, name)
> + test_sharpness_filter(data, type);
> +
> + if (data->limited)
> + break;
> + }
> + }
> +}
> +
> +static int opt_handler(int opt, int opt_index, void *_data)
> +{
> + data_t *data = _data;
> +
> + switch (opt) {
> + case 'l':
> + data->limited = true;
> + break;
> + default:
> + return IGT_OPT_HANDLER_ERROR;
> + }
> +
> + return IGT_OPT_HANDLER_SUCCESS;
> +}
> +
> +static const char help_str[] =
> + " --limited|-l\t\tLimit execution to 1 valid pipe-output combo\n";
> +
> +data_t data = {};
> +
> +igt_main_args("l", NULL, help_str, opt_handler, &data)
> +{
> + igt_fixture {
> + data.drm_fd = drm_open_driver_master(DRIVER_ANY);
> +
> + kmstest_set_vt_graphics_mode();
> +
> + igt_display_require(&data.display, data.drm_fd);
> + igt_require(data.display.is_atomic);
> + igt_display_require_output(&data.display);
> + }
> +
> + igt_describe("Verify basic content adaptive sharpness filter.");
> + igt_subtest_with_dynamic("filter-basic") {
> + data.modifier = DRM_FORMAT_MOD_LINEAR;
> + data.rotation = IGT_ROTATION_0;
> + data.format = DRM_FORMAT_XRGB8888;
> + data.filter_strength = MID_FILTER_STRENGTH;
> +
> + run_sharpness_filter_test(&data, TEST_FILTER_BASIC);
> + }
> +
> + igt_describe("Verify that varying strength(0-255), affects "
> + "the degree of sharpeness applied.");
> + igt_subtest_with_dynamic("filter-strength") {
> + data.modifier = DRM_FORMAT_MOD_LINEAR;
> + data.rotation = IGT_ROTATION_0;
> + data.format = DRM_FORMAT_XRGB8888;
> +
> + for (int k = 0; k < ARRAY_SIZE(filter_strength_list); k++) {
> + data.filter_strength = filter_strength_list[k];
> +
> + run_sharpness_filter_test(&data, TEST_FILTER_STRENGTH);
> + }
> + }
> +
> + igt_describe("Verify content adaptive sharpness filter with "
> + "varying modifiers.");
> + igt_subtest_with_dynamic("filter-modifiers") {
> + data.rotation = IGT_ROTATION_0;
> + data.format = DRM_FORMAT_XRGB8888;
> + data.filter_strength = MID_FILTER_STRENGTH;
> +
> + for (int k = 0; k < ARRAY_SIZE(modifiers); k++) {
> + data.modifier = modifiers[k].modifier;
> + data.modifier_name = modifiers[k].name;
> +
> + run_sharpness_filter_test(&data, TEST_FILTER_MODIFIERS);
> + }
> + }
> +
> + igt_describe("Verify content adaptive sharpness filter with "
> + "varying rotations.");
> + igt_subtest_with_dynamic("filter-rotations") {
> + data.modifier = DRM_FORMAT_MOD_LINEAR;
> + data.format = DRM_FORMAT_XRGB8888;
> + data.filter_strength = MID_FILTER_STRENGTH;
> +
> + for (int k = 0; k < ARRAY_SIZE(rotations); k++) {
> + data.rotation = rotations[k];
> +
> + run_sharpness_filter_test(&data, TEST_FILTER_ROTATION);
> + }
> + }
> +
> + igt_describe("Verify content adaptive sharpness filter with "
> + "varying formats.");
> + igt_subtest_with_dynamic("filter-formats") {
> + data.modifier = DRM_FORMAT_MOD_LINEAR;
> + data.rotation = IGT_ROTATION_0;
> + data.filter_strength = MID_FILTER_STRENGTH;
> +
> + for (int k = 0; k < ARRAY_SIZE(formats); k++) {
> + data.format = formats[k];
> +
> + run_sharpness_filter_test(&data, TEST_FILTER_FORMATS);
> + }
> + }
> +
> + igt_fixture {
> + igt_display_fini(&data.display);
> + drm_close_driver(data.drm_fd);
> + }
> +}
> diff --git a/tests/meson.build b/tests/meson.build
> index 2724c7a9a..84d8bed4b 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -58,6 +58,7 @@ test_progs = [
> 'kms_sequence',
> 'kms_setmode',
> 'kms_sysfs_edid_timing',
> + 'kms_sharpness_filter',
> 'kms_tiled_display',
> 'kms_tv_load_detect',
> 'kms_universal_plane',
More information about the igt-dev
mailing list