summaryrefslogtreecommitdiff
path: root/tests/kms_atomic_transition.c
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2016-11-23 16:08:44 +0100
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2016-11-23 16:43:21 +0100
commit3ce1bc0c0e378090e74ba84ad1e2530b659310dd (patch)
tree53945274013aad777ca95a6b17ca10c5210d14e2 /tests/kms_atomic_transition.c
parentcddf9960788103e472a53416c77323a2399396a8 (diff)
kms_atomic_transition: Respect limits for sprite planes on earlier platforms.
Usually there is a maximum amount of width/height that a sprite plane can have, and on earlier platforms alpha sprite planes are usually unsupported. In case of SKL+ and VLV/CHV this is handled by only setting a maximum width, but on earlier platforms there's a hardware limitation for stride, width and height. Handle this by starting from cursor dimensions, and then increase width to max, followed by height to max. If the TEST_ONLY commit fails immediately with -EINVAL with cursor width/height in ARGB format, assume that ARGB is unsupported and fallback to XRGB. If that fails too fail the test. This should allow tests to pass on all earlier platforms too. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Diffstat (limited to 'tests/kms_atomic_transition.c')
-rw-r--r--tests/kms_atomic_transition.c217
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");
}