From: Marius Vlad <marius.c.vlad@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH i-g-t] lib/igt_kms: Add COMIT_ATOMIC to igt_display_commit2()
Date: Fri, 15 Jan 2016 11:06:24 +0200 [thread overview]
Message-ID: <1452848784-7970-1-git-send-email-marius.c.vlad@intel.com> (raw)
So far, we had only COMMIT_UNIVERSAL and COMMIT_LEGACY, using
drmModeSetPlane()/drmSetCrtc(). This patch adds COMMIT_ATOMIC
to igt_display_commit2() that makes use of drmModeAtomicCommit().
Signed-off-by: Marius Vlad <marius.c.vlad@intel.com>
---
lib/igt_kms.c | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
lib/igt_kms.h | 33 +++++++++-
2 files changed, 221 insertions(+), 2 deletions(-)
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 497118a..61f7a39 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -1306,6 +1306,191 @@ static uint32_t igt_plane_get_fb_gem_handle(igt_plane_t *plane)
igt_assert(r == 0); \
}
+static const char *igt_plane_prop_names[IGT_NUM_PLANE_PROPS] = {
+ "SRC_X",
+ "SRC_Y",
+ "SRC_W",
+ "SRC_H",
+ "CRTC_X",
+ "CRTC_Y",
+ "CRTC_W",
+ "CRTC_H",
+ "FB_ID",
+ "CRTC_ID",
+ "type"
+};
+
+/*
+ * Retrieve all the properies specified in props_name and store them into
+ * plane->atomic_props_plane.
+ */
+static void
+igt_atomic_fill_plane_props(igt_display_t *display, igt_plane_t *plane,
+ int type, int num_props, const char **prop_names)
+{
+ drmModeObjectPropertiesPtr props;
+ int i, j, fd;
+
+ fd = display->drm_fd;
+
+ props = drmModeObjectGetProperties(fd, plane->drm_plane->plane_id, type);
+ igt_assert(props);
+
+ for (i = 0; i < props->count_props; i++) {
+ drmModePropertyPtr prop =
+ drmModeGetProperty(fd, props->props[i]);
+
+ for (j = 0; j < num_props; j++) {
+ if (strcmp(prop->name, prop_names[j]) != 0)
+ continue;
+ plane->atomic_props_plane[j] = props->props[i];
+ break;
+ }
+
+ drmModeFreeProperty(prop);
+ }
+
+ drmModeFreeObjectProperties(props);
+}
+
+/*
+ * Commit position and fb changes to a DRM plane via the AtomicCommit()
+ * ioctl; if the DRM call to program the plane fails, we'll either fail
+ * immediately (for tests that expect the commit to succeed) or return the
+ * failure code (for tests that expect a specific error code).
+ */
+static int
+igt_atomic_plane_commit(igt_plane_t *plane, igt_output_t *output,
+ bool fail_on_error)
+{
+ igt_display_t *display = output->display;
+
+ uint32_t fb_id, crtc_id;
+ int ret;
+ uint32_t src_x;
+ uint32_t src_y;
+ uint32_t src_w;
+ uint32_t src_h;
+ int32_t crtc_x;
+ int32_t crtc_y;
+ uint32_t crtc_w;
+ uint32_t crtc_h;
+ drmModeAtomicReq *req;
+
+ igt_assert(plane->drm_plane);
+
+ do_or_die(drmSetClientCap(display->drm_fd, DRM_CLIENT_CAP_ATOMIC, 1));
+
+ /* 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 = output->config.crtc->crtc_id;
+
+ if ((plane->fb_changed || plane->size_changed) && fb_id == 0) {
+
+ LOG(display,
+ "%s: drmModeAtomicCommit pipe %s, plane %d, disabling\n",
+ igt_output_name(output),
+ kmstest_pipe_name(output->config.pipe),
+ plane->index);
+
+ req = drmModeAtomicAlloc();
+ igt_atomic_fill_plane_props(display, plane,
+ DRM_MODE_OBJECT_PLANE,
+ IGT_NUM_PLANE_PROPS,
+ igt_plane_prop_names);
+
+ drmModeAtomicSetCursor(req, 0);
+
+ /* populate plane req */
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_ID, crtc_id);
+
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_X, IGT_FIXED(0, 0));
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_Y, IGT_FIXED(0, 0));
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_W, IGT_FIXED(0, 0));
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_H, IGT_FIXED(0, 0));
+
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_X, 0);
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_Y, 0);
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_W, 0);
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_H, 0);
+
+ ret = drmModeAtomicCommit(display->drm_fd, req, 0, NULL);
+ drmModeAtomicFree(req);
+
+ CHECK_RETURN(ret, fail_on_error);
+
+ } else if (plane->fb_changed || plane->position_changed ||
+ plane->size_changed) {
+
+ src_x = IGT_FIXED(plane->fb->src_x,0); /* src_x */
+ src_y = IGT_FIXED(plane->fb->src_y,0); /* src_y */
+ src_w = IGT_FIXED(plane->fb->src_w,0); /* src_w */
+ src_h = IGT_FIXED(plane->fb->src_h,0); /* src_h */
+ crtc_x = plane->crtc_x;
+ crtc_y = plane->crtc_y;
+ crtc_w = plane->crtc_w;
+ crtc_h = plane->crtc_h;
+
+ LOG(display,
+ "%s: drmModeAtomicCommit %s.%d, fb %u, src = (%d, %d) "
+ "%ux%u dst = (%u, %u) %ux%u\n",
+ igt_output_name(output),
+ kmstest_pipe_name(output->config.pipe),
+ plane->index,
+ fb_id,
+ src_x >> 16, src_y >> 16, src_w >> 16, src_h >> 16,
+ crtc_x, crtc_y, crtc_w, crtc_h);
+
+
+ req = drmModeAtomicAlloc();
+ igt_atomic_fill_plane_props(display, plane,
+ DRM_MODE_OBJECT_PLANE,
+ IGT_NUM_PLANE_PROPS,
+ igt_plane_prop_names);
+
+ drmModeAtomicSetCursor(req, 0);
+
+ /* populate plane req */
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_ID, crtc_id);
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_FB_ID, fb_id);
+
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_X, src_x);
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_Y, src_y);
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_W, src_w);
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_SRC_H, src_h);
+
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_X, crtc_x);
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_Y, crtc_y);
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_W, crtc_w);
+ igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_H, crtc_h);
+
+ ret = drmModeAtomicCommit(display->drm_fd, req, 0, NULL);
+ drmModeAtomicFree(req);
+
+ CHECK_RETURN(ret, fail_on_error);
+ }
+
+ plane->fb_changed = false;
+ plane->position_changed = false;
+ plane->size_changed = false;
+
+
+ if (plane->rotation_changed) {
+ ret = igt_plane_set_property(plane, plane->rotation_property,
+ plane->rotation);
+
+ plane->rotation_changed = false;
+ CHECK_RETURN(ret, fail_on_error);
+ }
+
+ return 0;
+}
+
+
+
/*
* Commit position and fb changes to a DRM plane via the SetPlane ioctl; if the
* DRM call to program the plane fails, we'll either fail immediately (for
@@ -1558,7 +1743,10 @@ static int igt_plane_commit(igt_plane_t *plane,
return igt_primary_plane_commit_legacy(plane, output,
fail_on_error);
} else {
- return igt_drm_plane_commit(plane, output, fail_on_error);
+ if (s == COMMIT_ATOMIC)
+ return igt_atomic_plane_commit(plane, output, fail_on_error);
+ else
+ return igt_drm_plane_commit(plane, output, fail_on_error);
}
}
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 94f315f..81d8dd7 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -156,9 +156,27 @@ 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_ATOMIC,
};
+enum igt_atomic_plane_properties {
+ IGT_PLANE_SRC_X = 0,
+ IGT_PLANE_SRC_Y,
+ IGT_PLANE_SRC_W,
+ IGT_PLANE_SRC_H,
+
+ IGT_PLANE_CRTC_X,
+ IGT_PLANE_CRTC_Y,
+ IGT_PLANE_CRTC_W,
+ IGT_PLANE_CRTC_H,
+
+ IGT_PLANE_FB_ID,
+ IGT_PLANE_CRTC_ID,
+ IGT_PLANE_TYPE,
+ IGT_NUM_PLANE_PROPS
+};
+
+
typedef struct igt_display igt_display_t;
typedef struct igt_pipe igt_pipe_t;
typedef uint32_t igt_fixed_t; /* 16.16 fixed point */
@@ -200,6 +218,7 @@ typedef struct {
/* panning offset within the fb */
unsigned int pan_x, pan_y;
igt_rotation_t rotation;
+ uint32_t atomic_props_plane[IGT_NUM_PLANE_PROPS];
} igt_plane_t;
struct igt_pipe {
@@ -281,6 +300,18 @@ void igt_wait_for_vblank(int drm_fd, enum pipe pipe);
#define IGT_FIXED(i,f) ((i) << 16 | (f))
+/**
+ * igt_atomic_populate_plane_req:
+ * @req: A pointer to drmModeAtomicReq
+ * @plane: A pointer igt_plane_t
+ * @prop: one of igt_atomic_plane_properties
+ * @value: the value to add
+ */
+#define igt_atomic_populate_plane_req(req, plane, prop, value) \
+ igt_assert_lt(0, drmModeAtomicAddProperty(req, plane->drm_plane->plane_id,\
+ plane->atomic_props_plane[prop], value))
+
+
void igt_enable_connectors(void);
void igt_reset_connectors(void);
--
2.6.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
next reply other threads:[~2016-01-15 9:05 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-15 9:06 Marius Vlad [this message]
2016-01-20 14:52 ` [PATCH i-g-t] lib/igt_kms: Add COMIT_ATOMIC to igt_display_commit2() Maarten Lankhorst
2016-01-20 15:08 ` Daniel Stone
2016-01-21 18:57 ` Matt Roper
2016-01-22 5:43 ` Palleti, Avinash Reddy
2016-01-22 10:54 ` Marius Vlad
2016-01-22 16:00 ` Matt Roper
2016-01-25 16:17 ` Daniel Vetter
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=1452848784-7970-1-git-send-email-marius.c.vlad@intel.com \
--to=marius.c.vlad@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