From: Matt Roper <matthew.d.roper@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH i-g-t 2/3] lib/kms: Add nuclear pageflip commit style
Date: Mon, 19 Jan 2015 20:05:12 -0800 [thread overview]
Message-ID: <1421726713-32115-3-git-send-email-matthew.d.roper@intel.com> (raw)
In-Reply-To: <1421726713-32115-1-git-send-email-matthew.d.roper@intel.com>
This commit style only covers the "nuclear pageflip" subset of the
atomic API (i.e., single CRTC, plane updates only). In the future when
our kernel driver has full atomic modeset support, we'll add another
commit style 'atomic' which will re-use the same plane commit calls
added here, but will generate and commit property sets in the display's
commit handler rather than the output's commit handler.
Since nuclear pageflip (and full atomic eventually) depend on very new
(currently unreleased) libdrm, use autoconf to check for support so that
we can still run with just legacy + universal styles when built with
older libdrm's.
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
configure.ac | 3 ++
lib/igt_kms.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
lib/igt_kms.h | 19 ++++++-
3 files changed, 181 insertions(+), 10 deletions(-)
diff --git a/configure.ac b/configure.ac
index 16d6a2e..1e3c2f1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -87,6 +87,9 @@ PKG_CHECK_MODULES(PCIACCESS, [pciaccess >= 0.10])
PKG_CHECK_MODULES(OVERLAY_XVLIB, [xv x11 xext dri2proto >= 2.6], enable_overlay_xvlib=yes, enable_overlay_xvlib=no)
PKG_CHECK_MODULES(OVERLAY_XLIB, [cairo-xlib dri2proto >= 2.6], enable_overlay_xlib=yes, enable_overlay_xlib=no)
+# Check for atomic modeset support in libdrm
+AC_CHECK_LIB(drm, drmModePropertySetCommit, AC_DEFINE(HAVE_ATOMIC, [], [Atomic modeset supported]))
+
AM_CONDITIONAL(BUILD_OVERLAY_XVLIB, [test "x$enable_overlay_xvlib" = xyes])
AM_CONDITIONAL(BUILD_OVERLAY_XLIB, [test "x$enable_overlay_xlib" = xyes])
AM_CONDITIONAL(BUILD_OVERLAY, [test "x$enable_overlay_xlib" = xyes -o "x$enable_overlay_xvlib"])
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index bb72c68..26e4913 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -50,13 +50,15 @@
#include "igt_debugfs.h"
/*
- * There hasn't been a release of libdrm containing these #define's yet, so
- * copy them here to allow compilation to succeed in the mean time.
+ * Universal plane bits didn't show up until libdrm 2.4.55 and atomic hasn't
+ * landed in a release yet, so copy the relevant #define's here to allow
+ * compilation to succeeed on older libdrm's.
*
* We can drop these #define's and just make i-g-t depend on the proper libdrm
* version in the future.
*/
#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
+#define DRM_CLIENT_CAP_ATOMIC 3
#define DRM_PLANE_TYPE_OVERLAY 0
#define DRM_PLANE_TYPE_PRIMARY 1
#define DRM_PLANE_TYPE_CURSOR 2
@@ -944,6 +946,42 @@ static int get_drm_plane_type(int drm_fd, uint32_t plane_id)
return DRM_PLANE_TYPE_OVERLAY;
}
+/*
+ * Lookup all of the properties we use for a plane.
+ */
+static void lookup_plane_properties(int drm_fd,
+ igt_plane_t *plane)
+{
+ uint64_t prop_value;
+
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "rotation",
+ &plane->rotation_property, &prop_value, NULL);
+ plane->rotation = (igt_rotation_t)prop_value;
+
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "FB_ID",
+ &plane->fb_property, NULL, NULL);
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "CRTC_ID",
+ &plane->crtc_property, NULL, NULL);
+
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "CRTC_X",
+ &plane->dstx_property, NULL, NULL);
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "CRTC_Y",
+ &plane->dsty_property, NULL, NULL);
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "CRTC_W",
+ &plane->dstw_property, NULL, NULL);
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "CRTC_H",
+ &plane->dsth_property, NULL, NULL);
+
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "SRC_X",
+ &plane->srcx_property, NULL, NULL);
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "SRC_Y",
+ &plane->srcy_property, NULL, NULL);
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "SRC_W",
+ &plane->srcw_property, NULL, NULL);
+ get_plane_property(drm_fd, plane->drm_plane->plane_id, "SRC_H",
+ &plane->srch_property, NULL, NULL);
+}
+
void igt_display_init(igt_display_t *display, int drm_fd)
{
drmModeRes *resources;
@@ -966,6 +1004,7 @@ void igt_display_init(igt_display_t *display, int drm_fd)
display->n_pipes = resources->count_crtcs;
drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
+ drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1);
plane_resources = drmModeGetPlaneResources(display->drm_fd);
igt_assert(plane_resources);
@@ -981,7 +1020,6 @@ void igt_display_init(igt_display_t *display, int drm_fd)
/* add the planes that can be used with that pipe */
for (j = 0; j < plane_resources->count_planes; j++) {
drmModePlane *drm_plane;
- uint64_t prop_value;
drm_plane = drmModeGetPlane(display->drm_fd,
plane_resources->planes[j]);
@@ -1023,12 +1061,21 @@ void igt_display_init(igt_display_t *display, int drm_fd)
plane->pipe = pipe;
plane->drm_plane = drm_plane;
- get_plane_property(display->drm_fd, drm_plane->plane_id,
- "rotation",
- &plane->rotation_property,
- &prop_value,
- NULL);
- plane->rotation = (igt_rotation_t)prop_value;
+ lookup_plane_properties(display->drm_fd, plane);
+#ifdef HAVE_ATOMIC
+ display->has_atomic_props =
+ (plane->fb_property &&
+ plane->crtc_property &&
+ plane->rotation_property &&
+ plane->dstx_property &&
+ plane->dsty_property &&
+ plane->dstw_property &&
+ plane->dsth_property &&
+ plane->srcx_property &&
+ plane->srcy_property &&
+ plane->srcw_property &&
+ plane->srch_property);
+#endif
}
if (display->has_universal_planes) {
@@ -1336,6 +1383,79 @@ static int igt_drm_plane_commit(igt_plane_t *plane,
return 0;
}
+#ifdef HAVE_ATOMIC
+/*
+ * Apply plane changes for an atomic operation. Note that we don't actually
+ * perform the commit here; we just push the proper values into the atomic
+ * property set and let either igt_output_commit (nuclear) or
+ * igt_display_commit (atomic) issue the actual commit.
+ */
+static int igt_drm_plane_commit_atomic(igt_plane_t *plane,
+ igt_output_t *output,
+ drmModePropertySetPtr set,
+ bool fail_on_error)
+{
+ uint32_t fb_id, crtc_id, plane_id;
+
+ igt_assert(set);
+ igt_assert(plane->drm_plane);
+
+ /* it's an error to try an unsupported feature */
+ igt_assert(igt_plane_supports_rotation(plane) ||
+ !plane->rotation_changed);
+
+ fb_id = igt_plane_get_fb_id(plane);
+ crtc_id = fb_id ? output->config.crtc->crtc_id : 0;
+ plane_id = plane->drm_plane->plane_id;
+
+ if (plane->fb_changed) {
+ drmModePropertySetAdd(set, plane_id, plane->fb_property,
+ fb_id);
+ drmModePropertySetAdd(set, plane_id,
+ plane->crtc_property, crtc_id);
+ }
+
+ if (plane->fb &&
+ (plane->fb_changed || plane->position_changed || plane->panning_changed)) {
+ /* Source coordinates */
+ drmModePropertySetAdd(set, plane_id,
+ plane->srcx_property,
+ IGT_FIXED(plane->pan_x,0));
+ drmModePropertySetAdd(set, plane_id,
+ plane->srcy_property,
+ IGT_FIXED(plane->pan_y,0));
+ drmModePropertySetAdd(set, plane_id,
+ plane->srcw_property,
+ IGT_FIXED(plane->fb->width - plane->pan_x,0));
+ drmModePropertySetAdd(set, plane_id,
+ plane->srch_property,
+ IGT_FIXED(plane->fb->height - plane->pan_y,0));
+
+ /* Destination coordinates */
+ drmModePropertySetAdd(set, plane_id, plane->dstx_property,
+ plane->crtc_x);
+ drmModePropertySetAdd(set, plane_id, plane->dsty_property,
+ plane->crtc_y);
+ drmModePropertySetAdd(set, plane_id, plane->dstw_property,
+ plane->crtc_w);
+ drmModePropertySetAdd(set, plane_id, plane->dsth_property,
+ plane->crtc_h);
+ }
+
+ if (plane->rotation_changed)
+ drmModePropertySetAdd(set, plane_id, plane->rotation_property,
+ plane->rotation);
+
+
+ plane->fb_changed = false;
+ plane->position_changed = false;
+ plane->panning_changed = false;
+ plane->rotation = false;
+
+ return 0;
+}
+#endif
+
/*
* Commit position and fb changes to a cursor via legacy ioctl's. If commit
* fails, we'll either fail immediately (for tests that expect the commit to
@@ -1486,6 +1606,11 @@ static int igt_plane_commit(igt_plane_t *plane,
} else if (plane->is_primary && s == COMMIT_LEGACY) {
return igt_primary_plane_commit_legacy(plane, output,
fail_on_error);
+#ifdef HAVE_ATOMIC
+ } else if (s == COMMIT_NUCLEAR) {
+ return igt_drm_plane_commit_atomic(plane, output, output->set,
+ fail_on_error);
+#endif
} else {
return igt_drm_plane_commit(plane, output, fail_on_error);
}
@@ -1513,6 +1638,13 @@ static int igt_output_commit(igt_output_t *output,
pipe = igt_output_get_driving_pipe(output);
+#ifdef HAVE_ATOMIC
+ if (s == COMMIT_NUCLEAR) {
+ output->set = drmModePropertySetAlloc();
+ igt_assert(output->set);
+ }
+#endif
+
for (i = 0; i < pipe->n_planes; i++) {
igt_plane_t *plane = &pipe->planes[i];
@@ -1523,6 +1655,17 @@ static int igt_output_commit(igt_output_t *output,
CHECK_RETURN(ret, fail_on_error);
}
+#ifdef HAVE_ATOMIC
+ /* Nuclear pageflip commit */
+ if (s == COMMIT_NUCLEAR) {
+ ret = drmModePropertySetCommit(display->drm_fd, 0, NULL,
+ output->set);
+ drmModePropertySetFree(output->set);
+ output->set = NULL;
+ CHECK_RETURN(ret, fail_on_error);
+ }
+#endif
+
/*
* If the crtc is enabled, wait until the next vblank before returning
* if we made changes to any of the planes.
@@ -1551,6 +1694,14 @@ static int do_display_commit(igt_display_t *display,
LOG_INDENT(display, "commit");
+#ifndef HAVE_ATOMIC
+ /*
+ * If our libdrm doesn't support atomic; skip any tests that explicitly
+ * ask for nuclear pageflip or atomic modeset.
+ */
+ igt_skip_on(s == COMMIT_NUCLEAR);
+#endif
+
igt_debug_wait_for_keypress("commit");
igt_display_refresh(display);
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index a1483a4..2fab30e 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -154,7 +154,8 @@ void kmstest_unset_all_crtcs(int drm_fd, drmModeResPtr resources);
enum igt_commit_style {
COMMIT_LEGACY = 0,
COMMIT_UNIVERSAL,
- /* We'll add atomic here eventually. */
+ COMMIT_NUCLEAR, /* atomic plane operations on single crtc only */
+ /* We'll add full atomic here eventually. */
};
typedef struct igt_display igt_display_t;
@@ -189,6 +190,16 @@ typedef struct {
struct igt_fb *fb;
uint32_t rotation_property;
+ uint32_t fb_property;
+ uint32_t crtc_property;
+ uint32_t dstx_property;
+ uint32_t dsty_property;
+ uint32_t dstw_property;
+ uint32_t dsth_property;
+ uint32_t srcx_property;
+ uint32_t srcy_property;
+ uint32_t srcw_property;
+ uint32_t srch_property;
/* position within pipe_src_w x pipe_src_h */
int crtc_x, crtc_y;
@@ -216,6 +227,11 @@ typedef struct {
char *name;
bool valid;
unsigned long pending_crtc_idx_mask;
+
+#ifdef HAVE_ATOMIC
+ /* Property set for nuclear pageflip */
+ drmModePropertySetPtr set;
+#endif
} igt_output_t;
struct igt_display {
@@ -227,6 +243,7 @@ struct igt_display {
igt_output_t *outputs;
igt_pipe_t pipes[I915_MAX_PIPES];
bool has_universal_planes;
+ bool has_atomic_props;
};
void igt_display_init(igt_display_t *display, int drm_fd);
--
1.8.5.1
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2015-01-20 4:05 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-20 4:05 [PATCH i-g-t 0/3] IGT support for nuclear pageflip Matt Roper
2015-01-20 4:05 ` [PATCH i-g-t 1/3] lib/kms: Let display commits wait for keypress while debugging Matt Roper
2015-01-20 4:05 ` Matt Roper [this message]
2015-03-17 11:53 ` [PATCH i-g-t 2/3] lib/kms: Add nuclear pageflip commit style Ander Conselvan De Oliveira
2015-01-20 4:05 ` [PATCH i-g-t 3/3] tests: Introduce kms_nuclear Matt Roper
2015-01-20 18:17 ` Thomas Wood
2015-01-26 17:14 ` [PATCH i-g-t 3/3] tests: Introduce kms_nuclear (v2) Matt Roper
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1421726713-32115-3-git-send-email-matthew.d.roper@intel.com \
--to=matthew.d.roper@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox