From: Jyoti Yadav <jyoti.r.yadav@xxxxxxxxx> Added subtests to cover below gaps. 1. scaler with pixelformat and tiling. 2. scaler with rotation 3. scaler with multiple planes 4. scaler with multi pipe 5. scaler with clipping/clamping scenario Signed-off-by: Jyoti Yadav <jyoti.r.yadav@xxxxxxxxx> --- tests/kms_plane_scaling.c | 480 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 476 insertions(+), 4 deletions(-) diff --git a/tests/kms_plane_scaling.c b/tests/kms_plane_scaling.c index 403df47..2be6acc 100644 --- a/tests/kms_plane_scaling.c +++ b/tests/kms_plane_scaling.c @@ -43,10 +43,11 @@ typedef struct { struct igt_fb fb1; struct igt_fb fb2; struct igt_fb fb3; + struct igt_fb fb4; int fb_id1; int fb_id2; int fb_id3; - + int fb_id4; igt_plane_t *plane1; igt_plane_t *plane2; igt_plane_t *plane3; @@ -54,6 +55,51 @@ typedef struct { } data_t; #define FILE_NAME "1080p-left.png" +#define MIN_SRC_WIDTH 8 +#define MAX_SRC_WIDTH 4096 +static uint32_t check_pixel_format(uint32_t pixel_format) +{ + const uint32_t *igt_formats; + int num_igt_formats; + int i; + + + igt_get_all_cairo_formats(&igt_formats, &num_igt_formats); + for (i = 0; i < num_igt_formats; i++) { + if (pixel_format == igt_formats[i]) + return 0; + } + + return -1; +} +bool is_igt_output_connected(igt_output_t *output) +{ + /* Something went wrong during probe? */ + if (!output->config.connector) + return false; + + if (output->config.connector->connection == DRM_MODE_CONNECTED) + return true; + + return false; +} + +static igt_output_t *get_next_valid_output(igt_display_t *data, int i) +{ + int j = 0, valid_output = 0; + drmModeModeInfo *mode; + for (j = 0; j < data->n_outputs; j++) { + if (is_igt_output_connected(&data->outputs[j])) { + mode = igt_output_get_mode(&data->outputs[j]); + if (mode->hdisplay != 0 && mode->vdisplay != 0) { + valid_output++; + if (valid_output == i) + return &data->outputs[j]; + } + } + } + return NULL; +} static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe, igt_plane_t *plane, drmModeModeInfo *mode, enum igt_commit_style s) @@ -298,7 +344,418 @@ static void test_plane_scaling(data_t *d) igt_require_f(valid_tests, "no valid crtc/connector combinations found\n"); } -igt_simple_main +uint64_t get_tiling(int i) +{ + switch (i) { + case 0: + return LOCAL_DRM_FORMAT_MOD_NONE; + break; + case 1: + return LOCAL_I915_FORMAT_MOD_X_TILED; + break; + case 2: + return LOCAL_I915_FORMAT_MOD_Y_TILED; + break; + case 3: + return LOCAL_I915_FORMAT_MOD_Yf_TILED; + break; + default: + return -1; + } +} + +void loop_plane_scaling(data_t *d, igt_plane_t *plane, uint32_t pixel_format, + uint64_t tiling, enum pipe pipe, igt_output_t *output) +{ + igt_display_t *display = &d->display; + int width, height; + /* create buffer in the range of min and max source side limit.*/ + for (width = MIN_SRC_WIDTH; width <= MAX_SRC_WIDTH; width = width + 500) { + igt_output_set_pipe(output, pipe); + height = width + 10; + d->fb_id1 = igt_create_pattern_fb(display->drm_fd, width, height, + pixel_format, tiling, &d->fb1); + igt_assert(d->fb_id1); + igt_plane_set_fb(plane, &d->fb1); + /* check upscaling */ + igt_fb_set_position(&d->fb1, plane, 0, 0); + igt_fb_set_size(&d->fb1, plane, d->fb1.width, d->fb1.height); + igt_plane_set_position(plane, 10, 10); + igt_plane_set_size(plane, width*2, height*2); + igt_display_commit2(display, COMMIT_ATOMIC); + igt_plane_set_fb(plane, NULL); + igt_plane_set_position(plane, 0, 0); + if (d->fb_id1) { + igt_remove_fb(d->drm_fd, &d->fb1); + d->fb_id1 = 0; + } + } +} +void test_scaler_with_pixel_format(data_t *d) +{ + igt_display_t *display = &d->display; + igt_output_t *output; + enum pipe pipe; + igt_plane_t *plane; + int valid_tests = 0; + igt_require(d->num_scalers); + for_each_pipe_with_valid_output(display, pipe, output) { + drmModeModeInfo *mode; + igt_output_set_pipe(output, pipe); + mode = igt_output_get_mode(output); + for_each_plane_on_pipe(display, pipe, plane) { + /* check if plane is cursor. */ + if (plane->type == DRM_PLANE_TYPE_CURSOR) + continue; + /* run loop for all pixel formats.*/ + drmModePlanePtr plane_kms; + plane_kms = plane->drm_plane; + for (int j = 0; j < plane_kms->count_formats; j++) { + /* check plane pixel format is supported in + * cairo pixel formats. + */ + if (check_pixel_format(plane_kms->formats[j]) == 0) { + /* loop for tiling */ + igt_require_fb_modifiers(d->drm_fd); + for (int i = 0; i < 4; i++) { + uint64_t tiling = get_tiling(i); + loop_plane_scaling(d, plane, plane_kms->formats[j], + tiling, pipe, output); + } + } + } + } + } +} + +static igt_rotation_t get_rotation_angle(int i) +{ + switch (i) { + case 0: + return IGT_ROTATION_0; + break; + case 1: + return IGT_ROTATION_90; + break; + case 2: + return IGT_ROTATION_180; + break; + case 3: + return IGT_ROTATION_270; + break; + default: + return -1; + } +} + +void test_scaler_with_rotation(data_t *d) +{ + igt_display_t *display = &d->display; + igt_output_t *output; + enum pipe pipe; + igt_plane_t *plane; + int valid_tests = 0; + igt_require(d->num_scalers); + for_each_pipe_with_valid_output(display, pipe, output) { + drmModeModeInfo *mode; + mode = igt_output_get_mode(output); + for_each_plane_on_pipe(display, pipe, plane) { + if (plane->type == DRM_PLANE_TYPE_CURSOR) + continue; + /* run loop for all pixel formats.*/ + drmModePlanePtr plane_kms; + plane_kms = plane->drm_plane; + for (int j = 0; j < plane_kms->count_formats; j++) { + /* 90/270 degree rotation is not supported on RGB565 and C8 pixel + * formats + */ + if (plane_kms->formats[j] == DRM_FORMAT_RGB565 || + plane_kms->formats[j] == DRM_FORMAT_C8) { + continue; + } + if (check_pixel_format(plane_kms->formats[j]) == 0) { + igt_output_set_pipe(output, pipe); + d->fb_id1 = igt_create_pattern_fb(display->drm_fd, + mode->hdisplay, mode->vdisplay, + plane_kms->formats[j], + LOCAL_I915_FORMAT_MOD_Y_TILED, &d->fb1); + igt_assert(d->fb_id1); + /* check all the supported rotation format*/ + for (int i = 0; i < 4; i++) { + igt_plane_set_fb(plane, &d->fb1); + /* check upscaling */ + igt_fb_set_position(&d->fb1, plane, 0, 0); + igt_fb_set_size(&d->fb1, plane, 300, 400); + igt_plane_set_position(plane, 0, 0); + igt_plane_set_size(plane, mode->hdisplay-200, mode->vdisplay-200); + igt_plane_set_rotation(plane, get_rotation_angle(i)); + igt_display_commit2(display, COMMIT_ATOMIC); + /* check downscaling */ + igt_fb_set_position(&d->fb1, plane, 0, 0); + igt_fb_set_size(&d->fb1, plane, 300, 400); + igt_plane_set_position(plane, 0, 0); + igt_plane_set_size(plane, 350, 250); /* downscale by 50 pixels*/ + igt_plane_set_rotation(plane, get_rotation_angle(i)); + igt_display_commit2(display, COMMIT_ATOMIC); + /* disable Plane*/ + igt_plane_set_fb(plane, NULL); + igt_plane_set_position(plane, 0, 0); + } + if (d->fb_id1) { + igt_remove_fb(d->drm_fd, &d->fb1); + d->fb_id1 = 0; + } + } + } + } + } +} + +void test_scaler_with_multiple_planes(data_t *d) +{ + igt_display_t *display = &d->display; + igt_output_t *output; + enum pipe pipe; + int valid_tests = 0; + igt_require(d->num_scalers); + for_each_pipe_with_valid_output(display, pipe, output) { + /* For Gen 9, Pipe C supports only 1 scaler*/ + if (intel_gen(d->devid) == 9 && pipe == PIPE_C) + continue; + drmModeModeInfo *mode; + igt_output_set_pipe(output, pipe); + mode = igt_output_get_mode(output); + /* Create 2 Framebuffers */ + d->fb_id2 = igt_create_pattern_fb(d->drm_fd, mode->hdisplay, mode->vdisplay, + DRM_FORMAT_XRGB8888, + LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */ + &d->fb2); + igt_assert(d->fb_id2); + + d->fb_id3 = igt_create_pattern_fb(d->drm_fd, + mode->hdisplay, mode->vdisplay, + DRM_FORMAT_XRGB8888, + LOCAL_I915_FORMAT_MOD_Y_TILED, /* tiled */ + &d->fb3); + igt_assert(d->fb_id3); + + d->plane1 = igt_output_get_plane(output, 0); + igt_plane_set_fb(d->plane1, &d->fb2); + d->plane2 = igt_output_get_plane(output, 1); + igt_plane_set_fb(d->plane2, &d->fb3); + /* plane upscaling on 2 planes*/ + igt_fb_set_position(&d->fb2, d->plane1, 0, 0); + igt_fb_set_size(&d->fb2, d->plane1, 300, 300); + igt_plane_set_position(d->plane1, 0, 0); + igt_plane_set_size(d->plane1, 400, 400); + + igt_fb_set_position(&d->fb3, d->plane2, 0, 0); + igt_fb_set_size(&d->fb3, d->plane2, 400, 400); + igt_plane_set_position(d->plane2, 100, 100); + igt_plane_set_size(d->plane2, 500, 500); + + igt_display_commit2(display, COMMIT_ATOMIC); + /* disbale above 2planes*/ + igt_plane_set_fb(d->plane1, NULL); + igt_plane_set_position(d->plane1, 0, 0); + igt_plane_set_fb(d->plane2, NULL); + igt_plane_set_position(d->plane2, 0, 0); + + /* Switch scaler from above 2 planes to next 2 planes*/ + d->plane3 = igt_output_get_plane(output, 2); + igt_plane_set_fb(d->plane3, &d->fb2); + d->plane4 = igt_output_get_plane(output, 3); + igt_plane_set_fb(d->plane4, &d->fb3); + + igt_fb_set_position(&d->fb2, d->plane3, 0, 0); + igt_fb_set_size(&d->fb2, d->plane3, 300, 300); + igt_plane_set_position(d->plane3, 0, 0); + igt_plane_set_size(d->plane3, 600, 600); + + igt_fb_set_position(&d->fb3, d->plane4, 0, 0); + igt_fb_set_size(&d->fb3, d->plane4, 400, 400); + igt_plane_set_position(d->plane4, 100, 100); + igt_plane_set_size(d->plane4, 700, 700); + + igt_display_commit2(display, COMMIT_ATOMIC); + /* disbale above 2planes and remove FB*/ + igt_plane_set_fb(d->plane3, NULL); + igt_plane_set_position(d->plane3, 0, 0); + igt_plane_set_fb(d->plane4, NULL); + igt_plane_set_position(d->plane4, 0, 0); + if (d->fb_id2) { + igt_remove_fb(d->drm_fd, &d->fb2); + d->fb_id2 = 0; + } + if (d->fb_id3) { + igt_remove_fb(d->drm_fd, &d->fb3); + d->fb_id3 = 0; + } + } +} + +void test_scaler_with_clipping_clamping_scenario(data_t *d) +{ + igt_display_t *display = &d->display; + igt_output_t *output; + enum pipe pipe; + int valid_tests = 0; + igt_require(d->num_scalers); + + for_each_pipe_with_valid_output(display, pipe, output) { + + if (intel_gen(d->devid) == 9 && pipe == PIPE_C) + continue; + drmModeModeInfo *mode; + igt_output_set_pipe(output, pipe); + mode = igt_output_get_mode(output); + /* allocate fb2 and fb3 */ + d->fb_id2 = igt_create_pattern_fb(d->drm_fd, mode->hdisplay, mode->vdisplay, + DRM_FORMAT_XRGB8888, + LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */ + &d->fb2); + igt_assert(d->fb_id2); + + d->fb_id3 = igt_create_pattern_fb(d->drm_fd, + mode->hdisplay, mode->vdisplay, + DRM_FORMAT_XRGB8888, + LOCAL_I915_FORMAT_MOD_Y_TILED, /* tiled */ + &d->fb3); + igt_assert(d->fb_id3); + + /* Set up display with plane 1 */ + d->plane1 = igt_output_get_plane(output, 0); + igt_plane_set_fb(d->plane1, &d->fb2); + d->plane2 = igt_output_get_plane(output, 1); + igt_plane_set_fb(d->plane2, &d->fb3); + + /* plane upscaling on 2 planes*/ + igt_fb_set_position(&d->fb2, d->plane1, 0, 0); + igt_fb_set_size(&d->fb2, d->plane1, 300, 300); + igt_plane_set_position(d->plane1, 100, 400); + /* scaled window size is outside the modeset area.*/ + igt_plane_set_size(d->plane1, mode->hdisplay + 200, mode->vdisplay + 200); + + igt_fb_set_position(&d->fb3, d->plane2, 0, 0); + igt_fb_set_size(&d->fb3, d->plane2, 400, 400); + igt_plane_set_position(d->plane2, 100, 100); + /* scaled window size is outside the modeset area.*/ + igt_plane_set_size(d->plane2, mode->hdisplay + 100, mode->vdisplay + 100); + igt_display_commit2(display, COMMIT_ATOMIC); + /* disbale above 2planes*/ + igt_plane_set_fb(d->plane1, NULL); + igt_plane_set_position(d->plane1, 0, 0); + igt_plane_set_fb(d->plane2, NULL); + igt_plane_set_position(d->plane2, 0, 0); + if (d->fb_id2) { + igt_remove_fb(d->drm_fd, &d->fb2); + d->fb_id2 = 0; + } + if (d->fb_id3) { + igt_remove_fb(d->drm_fd, &d->fb3); + d->fb_id3 = 0; + } + } +} + +void test_scaler_with_multi_pipe_plane(data_t *d) +{ + igt_display_t *display = &d->display; + igt_output_t *output1, *output2; + /*check whether 2 connectors are active .*/ + igt_skip_on(display->n_outputs < 2); + output1 = get_next_valid_output(display, 1); + output2 = get_next_valid_output(display, 2); + igt_output_set_pipe(output1, 0); + igt_output_set_pipe(output2, 1); + d->plane1 = igt_output_get_plane_type(output1, DRM_PLANE_TYPE_PRIMARY); + d->plane2 = igt_output_get_plane_type(output1, DRM_PLANE_TYPE_OVERLAY); + d->plane3 = igt_output_get_plane_type(output2, DRM_PLANE_TYPE_PRIMARY); + d->plane4 = igt_output_get_plane_type(output2, DRM_PLANE_TYPE_OVERLAY); + drmModeModeInfo *mode1, *mode2; + mode1 = igt_output_get_mode(output1); + mode2 = igt_output_get_mode(output2); + /* allocate fb with mode size */ + d->fb_id1 = igt_create_pattern_fb(d->drm_fd, mode1->hdisplay, mode1->vdisplay, + DRM_FORMAT_XRGB8888, LOCAL_I915_FORMAT_MOD_X_TILED, /* tiled */ + &d->fb1); + igt_assert(d->fb_id1); + + d->fb_id2 = igt_create_pattern_fb(d->drm_fd, + mode1->hdisplay, mode1->vdisplay, + DRM_FORMAT_XRGB8888, + LOCAL_I915_FORMAT_MOD_Y_TILED, /* tiled */ + &d->fb2); + igt_assert(d->fb_id2); + d->fb_id3 = igt_create_pattern_fb(d->drm_fd, mode2->hdisplay, mode2->vdisplay, + DRM_FORMAT_XRGB8888, + LOCAL_I915_FORMAT_MOD_Y_TILED, /* tiled */ + &d->fb3); + igt_assert(d->fb_id3); + + d->fb_id4 = igt_create_pattern_fb(d->drm_fd, + mode2->hdisplay, mode2->vdisplay, + DRM_FORMAT_XRGB8888, + LOCAL_DRM_FORMAT_MOD_NONE, /* tiled */ + &d->fb4); + igt_assert(d->fb_id4); + /* Set up display with plane 1 */ + igt_plane_set_fb(d->plane1, &d->fb1); + igt_plane_set_fb(d->plane2, &d->fb2); + igt_plane_set_fb(d->plane3, &d->fb3); + igt_plane_set_fb(d->plane4, &d->fb4); + + /* plane upscaling on 2 planes*/ + igt_fb_set_position(&d->fb1, d->plane1, 0, 0); + igt_fb_set_size(&d->fb1, d->plane1, 300, 300); + igt_plane_set_position(d->plane1, 100, 100); + igt_plane_set_size(d->plane1, mode1->hdisplay - 100, mode1->vdisplay - 50); + + igt_fb_set_position(&d->fb2, d->plane2, 100, 100); + igt_fb_set_size(&d->fb2, d->plane2, d->fb2.width - 100, d->fb2.height - 100); + igt_plane_set_position(d->plane2, 100, 100); + /* downscale by 50 pixels*/ + igt_plane_set_size(d->plane2, d->fb2.width - 150, d->fb2.height - 150); + + igt_fb_set_position(&d->fb3, d->plane3, 0, 0); + igt_fb_set_size(&d->fb3, d->plane3, 400, 400); + igt_plane_set_position(d->plane3, 100, 100); + igt_plane_set_size(d->plane3, mode2->hdisplay - 50, mode2->vdisplay - 50); + + igt_fb_set_position(&d->fb4, d->plane4, 100, 100); + igt_fb_set_size(&d->fb2, d->plane4, d->fb4.width - 100, d->fb4.height - 100); + igt_plane_set_position(d->plane4, 100, 100); + /* downscale by 50 pixels*/ + igt_plane_set_size(d->plane4, d->fb4.width - 150, d->fb4.height - 150); + + igt_display_commit2(display, COMMIT_ATOMIC); + /* disbale above 4 planes*/ + igt_plane_set_fb(d->plane1, NULL); + igt_plane_set_position(d->plane1, 0, 0); + igt_plane_set_fb(d->plane2, NULL); + igt_plane_set_position(d->plane2, 0, 0); + igt_plane_set_fb(d->plane3, NULL); + igt_plane_set_position(d->plane3, 0, 0); + igt_plane_set_fb(d->plane4, NULL); + igt_plane_set_position(d->plane4, 0, 0); + if (d->fb_id1) { + igt_remove_fb(d->drm_fd, &d->fb1); + d->fb_id1 = 0; + } + if (d->fb_id2) { + igt_remove_fb(d->drm_fd, &d->fb2); + d->fb_id2 = 0; + } + if (d->fb_id3) { + igt_remove_fb(d->drm_fd, &d->fb3); + d->fb_id3 = 0; + } + if (d->fb_id4) { + igt_remove_fb(d->drm_fd, &d->fb4); + d->fb_id4 = 0; + } +} +igt_main { data_t data = {}; @@ -308,11 +765,26 @@ igt_simple_main data.drm_fd = drm_open_driver(DRIVER_INTEL); igt_require_pipe_crc(data.drm_fd); igt_display_init(&data.display, data.drm_fd); + igt_require(data.display.is_atomic); data.devid = intel_get_drm_devid(data.drm_fd); data.num_scalers = intel_gen(data.devid) >= 9 ? 2 : 0; - test_plane_scaling(&data); - + //test_plane_scaling(&data); + igt_subtest_f("scaler_with_pixel_format") { + test_scaler_with_pixel_format(&data); + } + igt_subtest_f("scaler_with_rotation") { + test_scaler_with_rotation(&data); + } + igt_subtest_f("scaler_with_multiple_planes") { + test_scaler_with_multiple_planes(&data); + } + igt_subtest_f("scaler_with_clipping_clamping") { + test_scaler_with_clipping_clamping_scenario(&data); + } + igt_subtest_f("scaler_with_multi_pipe_plane") { + test_scaler_with_multi_pipe_plane(&data); + } igt_display_fini(&data.display); } -- 2.7.4 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx