diff options
Diffstat (limited to 'tests/kms_atomic_transition.c')
-rw-r--r-- | tests/kms_atomic_transition.c | 217 |
1 files changed, 151 insertions, 66 deletions
diff --git a/tests/kms_atomic_transition.c b/tests/kms_atomic_transition.c index 0c0848d7..3b981e51 100644 --- a/tests/kms_atomic_transition.c +++ b/tests/kms_atomic_transition.c @@ -111,6 +111,151 @@ enum transition_type { TRANSITION_MODESET_DISABLE, }; +static void set_sprite_wh(igt_display_t *display, enum pipe pipe, + struct plane_parms *parms, struct igt_fb *sprite_fb, + bool alpha, unsigned w, unsigned h) +{ + igt_plane_t *plane; + + for_each_plane_on_pipe(display, pipe, plane) { + int i = plane->index; + + if (plane->is_primary || plane->is_cursor) + continue; + + parms[i].width = w; + parms[i].height = h; + } + + igt_remove_fb(display->drm_fd, sprite_fb); + igt_create_fb(display->drm_fd, w, h, + alpha ? DRM_FORMAT_ARGB8888 : DRM_FORMAT_XRGB8888, + LOCAL_DRM_FORMAT_MOD_NONE, sprite_fb); +} + +static void setup_parms(igt_display_t *display, enum pipe pipe, + const drmModeModeInfo *mode, + struct igt_fb *argb_fb, + struct igt_fb *sprite_fb, + struct plane_parms *parms) +{ + uint64_t cursor_width, cursor_height; + unsigned sprite_width, sprite_height, prev_w, prev_h; + bool max_sprite_width, max_sprite_height, alpha = true; + uint32_t n_planes = display->pipes[pipe].n_planes; + igt_plane_t *plane; + + do_or_die(drmGetCap(display->drm_fd, DRM_CAP_CURSOR_WIDTH, &cursor_width)); + if (cursor_width >= mode->hdisplay) + cursor_width = mode->hdisplay; + + do_or_die(drmGetCap(display->drm_fd, DRM_CAP_CURSOR_HEIGHT, &cursor_height)); + if (cursor_height >= mode->vdisplay) + cursor_height = mode->vdisplay; + + for_each_plane_on_pipe(display, pipe, plane) { + int i = plane->index; + + if (plane->is_primary) + parms[i].fb = plane->fb; + else if (plane->is_cursor) + parms[i].fb = argb_fb; + else + parms[i].fb = sprite_fb; + + if (plane->is_primary) { + parms[i].width = mode->hdisplay; + parms[i].height = mode->vdisplay; + } else if (plane->is_cursor) { + parms[i].width = cursor_width; + parms[i].height = cursor_height; + } + } + + igt_create_fb(display->drm_fd, cursor_width, cursor_height, + DRM_FORMAT_ARGB8888, LOCAL_DRM_FORMAT_MOD_NONE, argb_fb); + + igt_create_fb(display->drm_fd, cursor_width, cursor_height, + DRM_FORMAT_ARGB8888, LOCAL_DRM_FORMAT_MOD_NONE, sprite_fb); + + if (n_planes < 3) + return; + + /* + * Pre gen9 not all sizes are supported, find the biggest possible + * size that can be enabled on all sprite planes. + */ +retry: + prev_w = sprite_width = cursor_width; + prev_h = sprite_height = cursor_height; + + max_sprite_width = (sprite_width == mode->hdisplay); + max_sprite_height = (sprite_height == mode->vdisplay); + + while (1) { + int ret; + + set_sprite_wh(display, pipe, parms, sprite_fb, + alpha, sprite_width, sprite_height); + + wm_setup_plane(display, pipe, (1 << n_planes) - 1, parms); + ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); + + if (ret == -EINVAL) { + if (cursor_width == sprite_width && + cursor_height == sprite_height) { + igt_assert_f(alpha, + "Cannot configure the test with all sprite planes enabled\n"); + + /* retry once with XRGB format. */ + alpha = false; + goto retry; + } + + sprite_width = prev_w; + sprite_height = prev_h; + + if (max_sprite_width && max_sprite_height) { + set_sprite_wh(display, pipe, parms, sprite_fb, + alpha, sprite_width, sprite_height); + break; + } + + if (!max_sprite_width) + max_sprite_width = true; + else + max_sprite_height = true; + } else { + prev_w = sprite_width; + prev_h = sprite_height; + } + + if (!max_sprite_width) { + sprite_width *= 2; + + if (sprite_width >= mode->hdisplay) { + max_sprite_width = true; + + sprite_width = mode->hdisplay; + } + } else if (!max_sprite_height) { + sprite_height *= 2; + + if (sprite_height >= mode->vdisplay) { + max_sprite_height = true; + + sprite_height = mode->vdisplay; + } + } else + /* Max sized sprites for all! */ + break; + } + + igt_info("Running test on pipe %s with resolution %dx%d and sprite size %dx%d alpha %i\n", + kmstest_pipe_name(pipe), mode->hdisplay, mode->vdisplay, + sprite_width, sprite_height, alpha); +} + /* * 1. Set primary plane to a known fb. * 2. Make sure getcrtc returns the correct fb id. @@ -121,14 +266,13 @@ enum transition_type { * so test this and make sure it works. */ static void -run_transition_test(igt_display_t *display, enum pipe pipe, igt_output_t *output, enum transition_type type, bool nonblocking) +run_transition_test(igt_display_t *display, enum pipe pipe, igt_output_t *output, + enum transition_type type, bool nonblocking) { - struct igt_fb fb, argb_fb; + struct igt_fb fb, argb_fb, sprite_fb; drmModeModeInfo *mode, override_mode; igt_plane_t *plane; - uint64_t cursor_width, cursor_height; - uint32_t n_planes = display->pipes[pipe].n_planes; - uint32_t iter_max = 1 << n_planes, i; + uint32_t iter_max = 1 << display->pipes[pipe].n_planes, i; struct plane_parms parms[IGT_MAX_PLANES]; bool skip_test = false; unsigned flags = DRM_MODE_PAGE_FLIP_EVENT; @@ -146,17 +290,6 @@ run_transition_test(igt_display_t *display, enum pipe pipe, igt_output_t *output igt_create_fb(display->drm_fd, mode->hdisplay, mode->vdisplay, DRM_FORMAT_XRGB8888, LOCAL_DRM_FORMAT_MOD_NONE, &fb); - igt_create_fb(display->drm_fd, mode->hdisplay, mode->vdisplay, - DRM_FORMAT_ARGB8888, LOCAL_DRM_FORMAT_MOD_NONE, &argb_fb); - - do_or_die(drmGetCap(display->drm_fd, DRM_CAP_CURSOR_WIDTH, &cursor_width)); - if (cursor_width > mode->hdisplay) - cursor_width = mode->hdisplay; - - do_or_die(drmGetCap(display->drm_fd, DRM_CAP_CURSOR_HEIGHT, &cursor_height)); - if (cursor_height > mode->vdisplay) - cursor_height = mode->vdisplay; - igt_output_set_pipe(output, pipe); wm_setup_plane(display, pipe, 0, NULL); @@ -173,58 +306,9 @@ run_transition_test(igt_display_t *display, enum pipe pipe, igt_output_t *output igt_output_set_pipe(output, pipe); } - for_each_plane_on_pipe(display, pipe, plane) { - i = plane->index; - - if (plane->is_primary) - parms[i].fb = &fb; - else - parms[i].fb = &argb_fb; - - if (plane->is_cursor) { - parms[i].width = cursor_width; - parms[i].height = cursor_height; - } else { - parms[i].width = mode->hdisplay; - parms[i].height = mode->vdisplay; - } - } - igt_display_commit2(display, COMMIT_ATOMIC); - /* - * In some configurations the tests may not run to completion with all - * sprite planes lit up at 4k resolution, try decreasing width/size of secondary - * planes to fix this - */ - while (1) { - int ret; - - wm_setup_plane(display, pipe, iter_max - 1, parms); - ret = igt_display_try_commit_atomic(display, DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL); - - if (ret != -EINVAL || n_planes < 3) - break; - - ret = 0; - for_each_plane_on_pipe(display, pipe, plane) { - i = plane->index; - - if (plane->is_primary || plane->is_cursor) - continue; - - if (parms[i].width <= 512) - continue; - - parms[i].width /= 2; - ret = 1; - igt_info("Reducing sprite %i to %ux%u\n", i - 1, parms[i].width, parms[i].height); - break; - } - - if (!ret) - igt_skip("Cannot run tests without proper size sprite planes\n"); - } + setup_parms(display, pipe, mode, &argb_fb, &sprite_fb, parms); for (i = 0; i < iter_max; i++) { igt_output_set_pipe(output, pipe); @@ -275,6 +359,7 @@ cleanup: igt_remove_fb(display->drm_fd, &fb); igt_remove_fb(display->drm_fd, &argb_fb); + igt_remove_fb(display->drm_fd, &sprite_fb); if (skip_test) igt_skip("Atomic nonblocking modesets are not supported.\n"); } |