summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2017-11-16 16:57:31 +0100
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2017-11-22 11:46:42 +0100
commit42ee3f94f2c5c3258930c22da7c1b497dd635346 (patch)
tree3dab53d1c281e5e747a262b7c43fb5d60a0d076c /lib
parenta839b53b790d9bc26cc775fe6a0d0a1e81ee7e1f (diff)
lib/igt_kms: Handle changing rotation property correctly
The rotation property sucks because it may affect whether drmModeSetPlane succeeds or not. Add some code to handle this. First try to set rotation directly, if that succeeds we return immediately. If it fails we disable the plane, set the rotation property and run the rest of the code. This will hopefully make legacy rotation work in more cases when scaling is not supported. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'lib')
-rw-r--r--lib/igt_kms.c71
-rw-r--r--lib/igt_kms.h1
2 files changed, 66 insertions, 6 deletions
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index f144f0d3..92dcd3ca 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -1604,11 +1604,8 @@ static void igt_plane_reset(igt_plane_t *plane)
igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, 0);
/* Use default rotation */
- if (igt_plane_has_prop(plane, IGT_PLANE_ROTATION)) {
- plane->values[IGT_PLANE_ROTATION] =
- igt_plane_get_prop(plane, IGT_PLANE_ROTATION);
- igt_plane_clear_prop_changed(plane, IGT_PLANE_ROTATION);
- }
+ if (igt_plane_has_prop(plane, IGT_PLANE_ROTATION))
+ igt_plane_set_prop_value(plane, IGT_PLANE_ROTATION, IGT_ROTATION_0);
igt_plane_clear_prop_changed(plane, IGT_PLANE_IN_FENCE_FD);
plane->values[IGT_PLANE_IN_FENCE_FD] = ~0ULL;
@@ -1666,6 +1663,12 @@ void igt_display_reset(igt_display_t *display)
enum pipe pipe;
int i;
+ /*
+ * Allow resetting rotation on all planes, which is normally
+ * prohibited on the primary and cursor plane for legacy commits.
+ */
+ display->first_commit = true;
+
for_each_pipe(display, pipe) {
igt_pipe_t *pipe_obj = &display->pipes[pipe];
igt_plane_t *plane;
@@ -2298,7 +2301,8 @@ static int igt_primary_plane_commit_legacy(igt_plane_t *primary,
igt_assert((primary->values[IGT_PLANE_CRTC_X] == 0 && primary->values[IGT_PLANE_CRTC_Y] == 0));
/* nor rotated */
- igt_assert(!igt_plane_is_prop_changed(primary, IGT_PLANE_ROTATION));
+ if (!pipe->display->first_commit)
+ igt_assert(!igt_plane_is_prop_changed(primary, IGT_PLANE_ROTATION));
if (!igt_plane_is_prop_changed(primary, IGT_PLANE_FB_ID) &&
!(primary->changed & IGT_PLANE_COORD_CHANGED_MASK) &&
@@ -2351,6 +2355,48 @@ static int igt_primary_plane_commit_legacy(igt_plane_t *primary,
return 0;
}
+static int igt_plane_fixup_rotation(igt_plane_t *plane,
+ igt_pipe_t *pipe)
+{
+ int ret;
+
+ if (!igt_plane_has_prop(plane, IGT_PLANE_ROTATION))
+ return 0;
+
+ LOG(pipe->display, "Fixing up initial rotation pipe %s, plane %d\n",
+ kmstest_pipe_name(pipe->pipe), plane->index);
+
+ /* First try the easy case, can we change rotation without problems? */
+ ret = igt_plane_set_property(plane, plane->props[IGT_PLANE_ROTATION],
+ plane->values[IGT_PLANE_ROTATION]);
+ if (!ret)
+ return 0;
+
+ /* Disable the plane, while we tinker with rotation */
+ ret = drmModeSetPlane(pipe->display->drm_fd,
+ plane->drm_plane->plane_id,
+ pipe->crtc_id, 0, /* fb_id */
+ 0, /* flags */
+ 0, 0, 0, 0, /* crtc_x, crtc_y, crtc_w, crtc_h */
+ IGT_FIXED(0,0), IGT_FIXED(0,0), /* src_x, src_y */
+ IGT_FIXED(0,0), IGT_FIXED(0,0)); /* src_w, src_h */
+
+ if (ret && plane->type != DRM_PLANE_TYPE_PRIMARY)
+ return ret;
+
+ /* For primary plane, fall back to disabling the crtc. */
+ if (ret) {
+ ret = drmModeSetCrtc(pipe->display->drm_fd,
+ pipe->crtc_id, 0, 0, 0, NULL, 0, NULL);
+
+ if (ret)
+ return ret;
+ }
+
+ /* and finally, set rotation property. */
+ return igt_plane_set_property(plane, plane->props[IGT_PLANE_ROTATION],
+ plane->values[IGT_PLANE_ROTATION]);
+}
/*
* Commit position and fb changes to a plane. The value of @s will determine
@@ -2361,6 +2407,14 @@ static int igt_plane_commit(igt_plane_t *plane,
enum igt_commit_style s,
bool fail_on_error)
{
+ if (pipe->display->first_commit || (s == COMMIT_UNIVERSAL &&
+ igt_plane_is_prop_changed(plane, IGT_PLANE_ROTATION))) {
+ int ret;
+
+ ret = igt_plane_fixup_rotation(plane, pipe);
+ CHECK_RETURN(ret, fail_on_error);
+ }
+
if (plane->type == DRM_PLANE_TYPE_CURSOR && s == COMMIT_LEGACY) {
return igt_cursor_commit_legacy(plane, pipe, fail_on_error);
} else if (plane->type == DRM_PLANE_TYPE_PRIMARY && s == COMMIT_LEGACY) {
@@ -2783,6 +2837,9 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
!(plane->type == DRM_PLANE_TYPE_PRIMARY ||
plane->type == DRM_PLANE_TYPE_CURSOR))
plane->changed &= ~LEGACY_PLANE_COMMIT_MASK;
+
+ if (display->first_commit)
+ igt_plane_clear_prop_changed(plane, IGT_PLANE_ROTATION);
}
}
}
@@ -2796,6 +2853,8 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
/* no modeset in universal commit, no change to crtc. */
output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
}
+
+ display->first_commit = false;
}
/*
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index e1883bf1..2a480bf3 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -349,6 +349,7 @@ struct igt_display {
igt_pipe_t *pipes;
bool has_cursor_plane;
bool is_atomic;
+ bool first_commit;
};
void igt_display_init(igt_display_t *display, int drm_fd);