All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic.
@ 2017-10-12 11:54 Maarten Lankhorst
  2017-10-12 11:54 ` [PATCH i-g-t v2 01/14] lib/igt_kms: Rework connector properties to be more atomic, v2 Maarten Lankhorst
                   ` (17 more replies)
  0 siblings, 18 replies; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-12 11:54 UTC (permalink / raw)
  To: intel-gfx

The future is atomic!

Currently when we add new properties, each one requires new API to be added,
even though the core wouldn't have to know anything about it. This can easily
be fixed by making everything a property, and having the core functions handle
some properties like fb and position separately.

Even with this in place it still makes sense to allow direct control of
properties, so add some new API to allow this manipulation. How powerful it is
can be seen in kms_atomic, which can finally be rewritten to use the new api.

We also extend the legacy paths to handle custom properties, so any tests
aren't required to use the atomic api.

Changes since v1:
- Small fixes to chamelium compilation. Patchwork messed up so resending all.

Maarten Lankhorst (14):
  lib/igt_kms: Rework connector properties to be more atomic, v2.
  lib/igt_kms: Rework plane properties to be more atomic, v5.
  lib/igt_kms: Rework pipe properties to be more atomic, v7.
  lib/igt_kms: Allow setting any plane property through the universal
    path
  lib/igt_kms: Allow setting any output property through the !atomic
    paths
  lib/igt_kms: Export property blob functions for output/pipe/plane, v2.
  lib/igt_kms: Unexport broadcast rgb API.
  lib/igt_kms: Add igt_$obj_has_prop functions
  lib/igt_kms: Add igt_$obj_get_prop functions
  lib/igt_kms: Remove igt_pipe_get_property
  lib/igt_kms: Remove igt_crtc_set_background()
  tests/kms_color: Rework tests slightly to work better with new atomic
    api
  tests/chamelium: Remove reliance on output->config.pipe
  tests/kms_atomic: Convert/rewrite tests to use igt_kms framework

 lib/igt_kms.c                     |  897 +++++++++++---------
 lib/igt_kms.h                     |  267 +++---
 tests/chamelium.c                 |   26 +-
 tests/kms_atomic.c                | 1668 ++++++++++++-------------------------
 tests/kms_atomic_interruptible.c  |   24 +-
 tests/kms_atomic_transition.c     |    2 +-
 tests/kms_color.c                 |  229 ++---
 tests/kms_crtc_background_color.c |   20 +-
 tests/kms_panel_fitting.c         |    2 +-
 tests/kms_rotation_crc.c          |   10 +-
 10 files changed, 1303 insertions(+), 1842 deletions(-)

-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* [PATCH i-g-t v2 01/14] lib/igt_kms: Rework connector properties to be more atomic, v2.
  2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
@ 2017-10-12 11:54 ` Maarten Lankhorst
  2017-10-12 11:54 ` [PATCH i-g-t v2 02/14] lib/igt_kms: Rework plane properties to be more atomic, v5 Maarten Lankhorst
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-12 11:54 UTC (permalink / raw)
  To: intel-gfx

In the future I want to allow tests to commit more properties,
but for this to work I have to fix all properties to work better
with atomic commit. Instead of special casing each
property make a bitmask for all property changed flags, and try to
commit all properties.

Changs since v1:
- Mention which properties we set to what.
- Assert the property to be set is valid.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
---
 lib/igt_kms.c                    | 44 +++++++++++++++++++---------------------
 lib/igt_kms.h                    | 35 +++++++++++++++++++-------------
 tests/kms_atomic_interruptible.c |  4 ++--
 tests/kms_panel_fitting.c        |  2 +-
 4 files changed, 45 insertions(+), 40 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 379bd0c383fd..e6fa8f4af455 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -248,7 +248,7 @@ igt_atomic_fill_connector_props(igt_display_t *display, igt_output_t *output,
 			if (strcmp(prop->name, conn_prop_names[j]) != 0)
 				continue;
 
-			output->config.atomic_props_connector[j] = props->props[i];
+			output->props[j] = props->props[i];
 			break;
 		}
 
@@ -1834,7 +1834,7 @@ void igt_display_init(igt_display_t *display, int drm_fd)
 
 		igt_output_refresh(output);
 
-		output->config.pipe_changed = true;
+		igt_output_set_prop_changed(output, IGT_CONNECTOR_CRTC_ID);
 	}
 
 	drmModeFreePlaneResources(plane_resources);
@@ -2514,23 +2514,24 @@ static void igt_atomic_prepare_crtc_commit(igt_pipe_t *pipe_obj, drmModeAtomicRe
 static void igt_atomic_prepare_connector_commit(igt_output_t *output, drmModeAtomicReq *req)
 {
 
-	struct kmstest_connector_config *config = &output->config;
+	int i;
 
-	if (config->connector_scaling_mode_changed)
-		igt_atomic_populate_connector_req(req, output, IGT_CONNECTOR_SCALING_MODE, config->connector_scaling_mode);
+	for (i = 0; i < IGT_NUM_CONNECTOR_PROPS; i++) {
+		if (!igt_output_is_prop_changed(output, i))
+			continue;
 
-	if (config->pipe_changed) {
-		uint32_t crtc_id = 0;
+		/* it's an error to try an unsupported feature */
+		igt_assert(output->props[i]);
 
-		if (output->config.pipe != PIPE_NONE)
-			crtc_id = output->config.crtc->crtc_id;
+		igt_debug("%s: Setting property \"%s\" to 0x%"PRIx64"/%"PRIi64"\n",
+			  igt_output_name(output), igt_connector_prop_names[i],
+			  output->values[i], output->values[i]);
 
-		igt_atomic_populate_connector_req(req, output, IGT_CONNECTOR_CRTC_ID, crtc_id);
+		igt_assert_lt(0, drmModeAtomicAddProperty(req,
+					  output->config.connector->connector_id,
+					  output->props[i],
+					  output->values[i]));
 	}
-	/*
-	 *	TODO: Add all other connector level properties here
-	 */
-
 }
 
 /*
@@ -2625,11 +2626,10 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
 	for (i = 0; i < display->n_outputs; i++) {
 		igt_output_t *output = &display->outputs[i];
 
-		if (s != COMMIT_UNIVERSAL)
-			output->config.pipe_changed = false;
-
 		if (s == COMMIT_ATOMIC)
-			output->config.connector_scaling_mode_changed = false;
+			output->changed = 0;
+		else if (s != COMMIT_UNIVERSAL)
+			igt_output_clear_prop_changed(output, IGT_CONNECTOR_CRTC_ID);
 	}
 }
 
@@ -2873,18 +2873,16 @@ void igt_output_set_pipe(igt_output_t *output, enum pipe pipe)
 	if (pipe != PIPE_NONE)
 		display->pipes[pipe].mode_changed = true;
 
-	output->config.pipe_changed = true;
+	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID, pipe == PIPE_NONE ? 0 : display->pipes[pipe].crtc_id);
 
 	igt_output_refresh(output);
 }
 
 void igt_output_set_scaling_mode(igt_output_t *output, uint64_t scaling_mode)
 {
-	output->config.connector_scaling_mode_changed = true;
-
-	output->config.connector_scaling_mode = scaling_mode;
+	igt_output_set_prop_value(output, IGT_CONNECTOR_SCALING_MODE, scaling_mode);
 
-	igt_require(output->config.atomic_props_connector[IGT_CONNECTOR_SCALING_MODE]);
+	igt_require(output->props[IGT_CONNECTOR_SCALING_MODE]);
 }
 
 igt_plane_t *igt_output_get_plane(igt_output_t *output, int plane_idx)
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 8dc118c961b7..1ef10e7d525c 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -131,10 +131,7 @@ struct kmstest_connector_config {
 	drmModeConnector *connector;
 	drmModeEncoder *encoder;
 	drmModeModeInfo default_mode;
-	uint64_t connector_scaling_mode;
-	bool connector_scaling_mode_changed;
-	bool pipe_changed;
-	uint32_t atomic_props_connector[IGT_NUM_CONNECTOR_PROPS];
+
 	int pipe;
 	unsigned valid_crtc_idx_mask;
 };
@@ -364,6 +361,12 @@ typedef struct {
 	enum pipe pending_pipe;
 	bool use_override_mode;
 	drmModeModeInfo override_mode;
+
+	/* bitmask of changed properties */
+	uint64_t changed;
+
+	uint32_t props[IGT_NUM_CONNECTOR_PROPS];
+	uint64_t values[IGT_NUM_CONNECTOR_PROPS];
 } igt_output_t;
 
 struct igt_display {
@@ -545,16 +548,20 @@ static inline bool igt_output_is_connected(igt_output_t *output)
 #define igt_atomic_populate_crtc_req(req, pipe, prop, value) \
 	igt_assert_lt(0, drmModeAtomicAddProperty(req, pipe->crtc_id,\
 						  pipe->atomic_props_crtc[prop], value))
-/**
- * igt_atomic_populate_connector_req:
- * @req: A pointer to drmModeAtomicReq
- * @output: A pointer igt_output_t
- * @prop: one of igt_atomic_connector_properties
- * @value: the value to add
- */
-#define igt_atomic_populate_connector_req(req, output, prop, value) \
-	igt_assert_lt(0, drmModeAtomicAddProperty(req, output->config.connector->connector_id,\
-						  output->config.atomic_props_connector[prop], value))
+
+#define igt_output_is_prop_changed(output, prop) \
+	(!!((output)->changed & (1 << (prop))))
+#define igt_output_set_prop_changed(output, prop) \
+	(output)->changed |= 1 << (prop)
+
+#define igt_output_clear_prop_changed(output, prop) \
+	(output)->changed &= ~(1 << (prop))
+
+#define igt_output_set_prop_value(output, prop, value) \
+	do { \
+		(output)->values[prop] = (value); \
+		igt_output_set_prop_changed(output, prop); \
+	} while (0)
 
 /*
  * igt_pipe_refresh:
diff --git a/tests/kms_atomic_interruptible.c b/tests/kms_atomic_interruptible.c
index a9f9cb137776..dcdbc267d3ef 100644
--- a/tests/kms_atomic_interruptible.c
+++ b/tests/kms_atomic_interruptible.c
@@ -161,7 +161,7 @@ static void run_plane_test(igt_display_t *display, enum pipe pipe, igt_output_t
 					plane->pipe->atomic_props_crtc[IGT_CRTC_MODE_ID],
 					plane->pipe->atomic_props_crtc[IGT_CRTC_ACTIVE],
 					/* connector: 1 prop */
-					output->config.atomic_props_connector[IGT_CONNECTOR_CRTC_ID],
+					output->props[IGT_CONNECTOR_CRTC_ID],
 					/* plane: remainder props */
 					plane->atomic_props_plane[IGT_PLANE_CRTC_ID],
 					plane->atomic_props_plane[IGT_PLANE_FB_ID],
@@ -206,7 +206,7 @@ static void run_plane_test(igt_display_t *display, enum pipe pipe, igt_output_t
 			case test_legacy_dpms: {
 				struct drm_mode_connector_set_property prop = {
 					.value = DRM_MODE_DPMS_OFF,
-					.prop_id = output->config.atomic_props_connector[IGT_CONNECTOR_DPMS],
+					.prop_id = output->props[IGT_CONNECTOR_DPMS],
 					.connector_id = output->id,
 				};
 
diff --git a/tests/kms_panel_fitting.c b/tests/kms_panel_fitting.c
index 85a231e60ea2..e4ea355611c3 100644
--- a/tests/kms_panel_fitting.c
+++ b/tests/kms_panel_fitting.c
@@ -275,7 +275,7 @@ static void test_atomic_fastset(igt_display_t *display)
 	igt_require(intel_gen(intel_get_drm_devid(display->drm_fd)) >= 5);
 
 	for_each_pipe_with_valid_output(display, pipe, output) {
-		if (!output->config.atomic_props_connector[IGT_CONNECTOR_SCALING_MODE])
+		if (!output->props[IGT_CONNECTOR_SCALING_MODE])
 			continue;
 
 		test_panel_fitting_fastset(display, pipe, output);
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH i-g-t v2 02/14] lib/igt_kms: Rework plane properties to be more atomic, v5.
  2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
  2017-10-12 11:54 ` [PATCH i-g-t v2 01/14] lib/igt_kms: Rework connector properties to be more atomic, v2 Maarten Lankhorst
@ 2017-10-12 11:54 ` Maarten Lankhorst
  2017-10-19  9:08   ` Mika Kahola
  2017-10-12 11:54 ` [PATCH i-g-t v2 03/14] lib/igt_kms: Rework pipe properties to be more atomic, v7 Maarten Lankhorst
                   ` (15 subsequent siblings)
  17 siblings, 1 reply; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-12 11:54 UTC (permalink / raw)
  To: intel-gfx

In the future I want to allow tests to commit more properties,
but for this to work I have to fix all properties to work better
with atomic commit. Instead of special casing each
property make a bitmask for all property changed flags, and try to
commit all properties.

Changes since v1:
- Remove special dumping of src and crtc coordinates.
- Dump all modified coordinates.
Changes since v2:
- Move igt_plane_set_prop_changed up slightly.
Changes since v3:
- Fix wrong ordering of set_position in kms_plane_lowres causing a test failure.
Changes since v4:
- Back out resetting crtc position in igt_plane_set_fb() and
  document it during init. Tests appear to rely on it being preserved.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 lib/igt_kms.c                    | 299 +++++++++++++++++----------------------
 lib/igt_kms.h                    |  59 ++++----
 tests/kms_atomic_interruptible.c |  12 +-
 tests/kms_rotation_crc.c         |   4 +-
 4 files changed, 165 insertions(+), 209 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index e6fa8f4af455..e77ae5d696da 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -192,11 +192,11 @@ const char *igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
 
 /*
  * Retrieve all the properies specified in props_name and store them into
- * plane->atomic_props_plane.
+ * plane->props.
  */
 static void
-igt_atomic_fill_plane_props(igt_display_t *display, igt_plane_t *plane,
-			int num_props, const char **prop_names)
+igt_fill_plane_props(igt_display_t *display, igt_plane_t *plane,
+		     int num_props, const char **prop_names)
 {
 	drmModeObjectPropertiesPtr props;
 	int i, j, fd;
@@ -214,7 +214,7 @@ igt_atomic_fill_plane_props(igt_display_t *display, igt_plane_t *plane,
 			if (strcmp(prop->name, prop_names[j]) != 0)
 				continue;
 
-			plane->atomic_props_plane[j] = props->props[i];
+			plane->props[j] = props->props[i];
 			break;
 		}
 
@@ -1659,7 +1659,6 @@ void igt_display_init(igt_display_t *display, int drm_fd)
 	drmModeRes *resources;
 	drmModePlaneRes *plane_resources;
 	int i;
-	int is_atomic = 0;
 
 	memset(display, 0, sizeof(igt_display_t));
 
@@ -1679,7 +1678,9 @@ void igt_display_init(igt_display_t *display, int drm_fd)
 	igt_assert_f(display->pipes, "Failed to allocate memory for %d pipes\n", display->n_pipes);
 
 	drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
-	is_atomic = drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1);
+	if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1) == 0)
+		display->is_atomic = 1;
+
 	plane_resources = drmModeGetPlaneResources(display->drm_fd);
 	igt_assert(plane_resources);
 
@@ -1776,19 +1777,27 @@ void igt_display_init(igt_display_t *display, int drm_fd)
 			plane->type = type;
 			plane->pipe = pipe;
 			plane->drm_plane = drm_plane;
-			plane->fence_fd = -1;
+			plane->values[IGT_PLANE_IN_FENCE_FD] = ~0ULL;
 
-			if (is_atomic == 0) {
-				display->is_atomic = 1;
-				igt_atomic_fill_plane_props(display, plane, IGT_NUM_PLANE_PROPS, igt_plane_prop_names);
-			}
+			igt_fill_plane_props(display, plane, IGT_NUM_PLANE_PROPS, igt_plane_prop_names);
 
 			get_plane_property(display->drm_fd, drm_plane->plane_id,
 					   "rotation",
-					   &plane->rotation_property,
-					   &prop_value,
+					   &plane->props[IGT_PLANE_ROTATION],
+					   &plane->values[IGT_PLANE_ROTATION],
 					   NULL);
-			plane->rotation = (igt_rotation_t)prop_value;
+
+			/* Clear any residual framebuffer info on first commit. */
+			igt_plane_set_prop_changed(plane, IGT_PLANE_FB_ID);
+			igt_plane_set_prop_changed(plane, IGT_PLANE_CRTC_ID);
+
+			/*
+			 * CRTC_X/Y are not changed in igt_plane_set_fb, so
+			 * force them to be sanitized in case they contain
+			 * garbage.
+			 */
+			igt_plane_set_prop_changed(plane, IGT_PLANE_CRTC_X);
+			igt_plane_set_prop_changed(plane, IGT_PLANE_CRTC_Y);
 		}
 
 		/*
@@ -1805,9 +1814,6 @@ void igt_display_init(igt_display_t *display, int drm_fd)
 
 		pipe->n_planes = n_planes;
 
-		for_each_plane_on_pipe(display, i, plane)
-			plane->fb_changed = true;
-
 		pipe->mode_changed = true;
 	}
 
@@ -2070,18 +2076,7 @@ bool igt_pipe_get_property(igt_pipe_t *pipe, const char *name,
 
 static uint32_t igt_plane_get_fb_id(igt_plane_t *plane)
 {
-	if (plane->fb)
-		return plane->fb->fb_id;
-	else
-		return 0;
-}
-
-static uint32_t igt_plane_get_fb_gem_handle(igt_plane_t *plane)
-{
-	if (plane->fb)
-		return plane->fb->gem_handle;
-	else
-		return 0;
+	return plane->values[IGT_PLANE_FB_ID];
 }
 
 #define CHECK_RETURN(r, fail) {	\
@@ -2090,9 +2085,6 @@ static uint32_t igt_plane_get_fb_gem_handle(igt_plane_t *plane)
 	igt_assert_eq(r, 0);	\
 }
 
-
-
-
 /*
  * Add position and fb changes of a plane to the atomic property set
  */
@@ -2101,63 +2093,31 @@ igt_atomic_prepare_plane_commit(igt_plane_t *plane, igt_pipe_t *pipe,
 	drmModeAtomicReq *req)
 {
 	igt_display_t *display = pipe->display;
-	uint32_t fb_id, crtc_id;
+	int i;
 
 	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 = pipe->crtc_id;
-
 	LOG(display,
 	    "populating plane data: %s.%d, fb %u\n",
 	    kmstest_pipe_name(pipe->pipe),
 	    plane->index,
-	    fb_id);
-
-	if (plane->fence_fd >= 0) {
-		uint64_t fence_fd = (int64_t) plane->fence_fd;
-		igt_atomic_populate_plane_req(req, plane, IGT_PLANE_IN_FENCE_FD, fence_fd);
-	}
+	    igt_plane_get_fb_id(plane));
 
-	if (plane->fb_changed) {
-		igt_atomic_populate_plane_req(req, plane, IGT_PLANE_CRTC_ID, fb_id ? crtc_id : 0);
-		igt_atomic_populate_plane_req(req, plane, IGT_PLANE_FB_ID, fb_id);
-	}
-
-	if (plane->position_changed || plane->size_changed) {
-		uint32_t src_x = IGT_FIXED(plane->src_x, 0); /* src_x */
-		uint32_t src_y = IGT_FIXED(plane->src_y, 0); /* src_y */
-		uint32_t src_w = IGT_FIXED(plane->src_w, 0); /* src_w */
-		uint32_t src_h = IGT_FIXED(plane->src_h, 0); /* src_h */
-		int32_t crtc_x = plane->crtc_x;
-		int32_t crtc_y = plane->crtc_y;
-		uint32_t crtc_w = plane->crtc_w;
-		uint32_t crtc_h = plane->crtc_h;
+	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++) {
+		if (!igt_plane_is_prop_changed(plane, i))
+			continue;
 
-		LOG(display,
-		"src = (%d, %d) %u x %u "
-		"dst = (%d, %d) %u x %u\n",
-		src_x >> 16, src_y >> 16, src_w >> 16, src_h >> 16,
-		crtc_x, crtc_y, crtc_w, crtc_h);
+		/* it's an error to try an unsupported feature */
+		igt_assert(plane->props[i]);
 
-		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_debug("plane %s.%d: Setting property \"%s\" to 0x%"PRIx64"/%"PRIi64"\n",
+			kmstest_pipe_name(pipe->pipe), plane->index, igt_plane_prop_names[i],
+			plane->values[i], plane->values[i]);
 
-		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);
+		igt_assert_lt(0, drmModeAtomicAddProperty(req, plane->drm_plane->plane_id,
+						  plane->props[i],
+						  plane->values[i]));
 	}
-
-	if (plane->rotation_changed)
-		igt_atomic_populate_plane_req(req, plane,
-			IGT_PLANE_ROTATION, plane->rotation);
 }
 
 
@@ -2183,17 +2143,20 @@ static int igt_drm_plane_commit(igt_plane_t *plane,
 	int32_t crtc_y;
 	uint32_t crtc_w;
 	uint32_t crtc_h;
+	bool setplane =
+		igt_plane_is_prop_changed(plane, IGT_PLANE_FB_ID) ||
+		plane->changed & IGT_PLANE_COORD_CHANGED_MASK;
 
 	igt_assert(plane->drm_plane);
 
 	/* it's an error to try an unsupported feature */
 	igt_assert(igt_plane_supports_rotation(plane) ||
-		   !plane->rotation_changed);
+		   !igt_plane_is_prop_changed(plane, IGT_PLANE_ROTATION));
 
 	fb_id = igt_plane_get_fb_id(plane);
 	crtc_id = pipe->crtc_id;
 
-	if ((plane->fb_changed || plane->size_changed) && fb_id == 0) {
+	if (setplane && fb_id == 0) {
 		LOG(display,
 		    "SetPlane pipe %s, plane %d, disabling\n",
 		    kmstest_pipe_name(pipe->pipe),
@@ -2212,16 +2175,15 @@ static int igt_drm_plane_commit(igt_plane_t *plane,
 				      IGT_FIXED(0,0) /* src_h */);
 
 		CHECK_RETURN(ret, fail_on_error);
-	} else if (plane->fb_changed || plane->position_changed ||
-		plane->size_changed) {
-		src_x = IGT_FIXED(plane->src_x,0); /* src_x */
-		src_y = IGT_FIXED(plane->src_y,0); /* src_y */
-		src_w = IGT_FIXED(plane->src_w,0); /* src_w */
-		src_h = IGT_FIXED(plane->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;
+	} else if (setplane) {
+		src_x = plane->values[IGT_PLANE_SRC_X];
+		src_y = plane->values[IGT_PLANE_SRC_Y];
+		src_w = plane->values[IGT_PLANE_SRC_W];
+		src_h = plane->values[IGT_PLANE_SRC_H];
+		crtc_x = plane->values[IGT_PLANE_CRTC_X];
+		crtc_y = plane->values[IGT_PLANE_CRTC_Y];
+		crtc_w = plane->values[IGT_PLANE_CRTC_W];
+		crtc_h = plane->values[IGT_PLANE_CRTC_H];
 
 		LOG(display,
 		    "SetPlane %s.%d, fb %u, src = (%d, %d) "
@@ -2245,9 +2207,10 @@ static int igt_drm_plane_commit(igt_plane_t *plane,
 		CHECK_RETURN(ret, fail_on_error);
 	}
 
-	if (plane->rotation_changed) {
-		ret = igt_plane_set_property(plane, plane->rotation_property,
-				       plane->rotation);
+	if (igt_plane_is_prop_changed(plane, IGT_PLANE_ROTATION)) {
+		ret = igt_plane_set_property(plane,
+					     plane->props[IGT_PLANE_ROTATION],
+					     plane->values[IGT_PLANE_ROTATION]);
 
 		CHECK_RETURN(ret, fail_on_error);
 	}
@@ -2269,35 +2232,30 @@ static int igt_cursor_commit_legacy(igt_plane_t *cursor,
 	uint32_t crtc_id = pipe->crtc_id;
 	int ret;
 
-	if (cursor->fb_changed) {
-		uint32_t gem_handle = igt_plane_get_fb_gem_handle(cursor);
-
-		if (gem_handle) {
+	if (igt_plane_is_prop_changed(cursor, IGT_PLANE_FB_ID)) {
+		if (cursor->gem_handle)
 			LOG(display,
 			    "SetCursor pipe %s, fb %u %dx%d\n",
 			    kmstest_pipe_name(pipe->pipe),
-			    gem_handle,
-			    cursor->crtc_w, cursor->crtc_h);
-
-			ret = drmModeSetCursor(display->drm_fd, crtc_id,
-					       gem_handle,
-					       cursor->crtc_w,
-					       cursor->crtc_h);
-		} else {
+			    cursor->gem_handle,
+			    (unsigned)cursor->values[IGT_PLANE_CRTC_W],
+			    (unsigned)cursor->values[IGT_PLANE_CRTC_H]);
+		else
 			LOG(display,
 			    "SetCursor pipe %s, disabling\n",
 			    kmstest_pipe_name(pipe->pipe));
 
-			ret = drmModeSetCursor(display->drm_fd, crtc_id,
-					       0, 0, 0);
-		}
-
+		ret = drmModeSetCursor(display->drm_fd, crtc_id,
+				       cursor->gem_handle,
+				       cursor->values[IGT_PLANE_CRTC_W],
+				       cursor->values[IGT_PLANE_CRTC_H]);
 		CHECK_RETURN(ret, fail_on_error);
 	}
 
-	if (cursor->position_changed) {
-		int x = cursor->crtc_x;
-		int y = cursor->crtc_y;
+	if (igt_plane_is_prop_changed(cursor, IGT_PLANE_CRTC_X) ||
+	    igt_plane_is_prop_changed(cursor, IGT_PLANE_CRTC_Y)) {
+		int x = cursor->values[IGT_PLANE_CRTC_X];
+		int y = cursor->values[IGT_PLANE_CRTC_Y];
 
 		LOG(display,
 		    "MoveCursor pipe %s, (%d, %d)\n",
@@ -2326,13 +2284,14 @@ static int igt_primary_plane_commit_legacy(igt_plane_t *primary,
 	int ret;
 
 	/* Primary planes can't be windowed when using a legacy commit */
-	igt_assert((primary->crtc_x == 0 && primary->crtc_y == 0));
+	igt_assert((primary->values[IGT_PLANE_CRTC_X] == 0 && primary->values[IGT_PLANE_CRTC_Y] == 0));
 
 	/* nor rotated */
-	igt_assert(!primary->rotation_changed);
+	igt_assert(!igt_plane_is_prop_changed(primary, IGT_PLANE_ROTATION));
 
-	if (!primary->fb_changed && !primary->position_changed &&
-	    !primary->size_changed && !primary->pipe->mode_changed)
+	if (!igt_plane_is_prop_changed(primary, IGT_PLANE_FB_ID) &&
+	    !(primary->changed & IGT_PLANE_COORD_CHANGED_MASK) &&
+	    !primary->pipe->mode_changed)
 		return 0;
 
 	crtc_id = pipe->crtc_id;
@@ -2343,19 +2302,22 @@ static int igt_primary_plane_commit_legacy(igt_plane_t *primary,
 		mode = NULL;
 
 	if (fb_id) {
+		uint32_t src_x = primary->values[IGT_PLANE_SRC_X] >> 16;
+		uint32_t src_y = primary->values[IGT_PLANE_SRC_Y] >> 16;
+
 		LOG(display,
 		    "%s: SetCrtc pipe %s, fb %u, src (%d, %d), "
 		    "mode %dx%d\n",
 		    igt_output_name(output),
 		    kmstest_pipe_name(pipe->pipe),
 		    fb_id,
-		    primary->src_x, primary->src_y,
+		    src_x, src_y,
 		    mode->hdisplay, mode->vdisplay);
 
 		ret = drmModeSetCrtc(display->drm_fd,
 				     crtc_id,
 				     fb_id,
-				     primary->src_x, primary->src_y,
+				     src_x, src_y,
 				     &output->id,
 				     1,
 				     mode);
@@ -2608,18 +2570,27 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
 		}
 
 		for_each_plane_on_pipe(display, pipe, plane) {
-			plane->fb_changed = false;
-			plane->position_changed = false;
-			plane->size_changed = false;
+			if (s == COMMIT_ATOMIC) {
+				int fd;
+				plane->changed = 0;
 
-			if (s != COMMIT_LEGACY ||
-			    !(plane->type == DRM_PLANE_TYPE_PRIMARY ||
-			      plane->type == DRM_PLANE_TYPE_CURSOR))
-				plane->rotation_changed = false;
+				fd = plane->values[IGT_PLANE_IN_FENCE_FD];
+				if (fd != -1)
+					close(fd);
 
-			if (s == COMMIT_ATOMIC)
 				/* reset fence_fd to prevent it from being set for the next commit */
-				igt_plane_set_fence_fd(plane, -1);
+				plane->values[IGT_PLANE_IN_FENCE_FD] = -1;
+			} else {
+				plane->changed &= ~IGT_PLANE_COORD_CHANGED_MASK;
+
+				igt_plane_clear_prop_changed(plane, IGT_PLANE_CRTC_ID);
+				igt_plane_clear_prop_changed(plane, IGT_PLANE_FB_ID);
+
+				if (s != COMMIT_LEGACY ||
+				    !(plane->type == DRM_PLANE_TYPE_PRIMARY ||
+				      plane->type == DRM_PLANE_TYPE_CURSOR))
+					igt_plane_clear_prop_changed(plane, IGT_PLANE_ROTATION);
+			}
 		}
 	}
 
@@ -2913,30 +2884,29 @@ void igt_plane_set_fb(igt_plane_t *plane, struct igt_fb *fb)
 	LOG(display, "%s.%d: plane_set_fb(%d)\n", kmstest_pipe_name(pipe->pipe),
 	    plane->index, fb ? fb->fb_id : 0);
 
-	plane->fb = fb;
+	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, fb ? pipe->crtc_id : 0);
+	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, fb ? fb->fb_id : 0);
+
+	if (plane->type == DRM_PLANE_TYPE_CURSOR && fb)
+		plane->gem_handle = fb->gem_handle;
+	else
+		plane->gem_handle = 0;
+
 	/* hack to keep tests working that don't call igt_plane_set_size() */
 	if (fb) {
 		/* set default plane size as fb size */
-		plane->crtc_w = fb->width;
-		plane->crtc_h = fb->height;
+		igt_plane_set_size(plane, fb->width, fb->height);
 
 		/* set default src pos/size as fb size */
-		plane->src_x = 0;
-		plane->src_y = 0;
-		plane->src_w = fb->width;
-		plane->src_h = fb->height;
+		igt_fb_set_position(fb, plane, 0, 0);
+		igt_fb_set_size(fb, plane, fb->width, fb->height);
 	} else {
-		plane->src_x = 0;
-		plane->src_y = 0;
-		plane->src_w = 0;
-		plane->src_h = 0;
+		igt_plane_set_size(plane, 0, 0);
 
-		plane->crtc_w = 0;
-		plane->crtc_h = 0;
+		/* set default src pos/size as fb size */
+		igt_fb_set_position(fb, plane, 0, 0);
+		igt_fb_set_size(fb, plane, 0, 0);
 	}
-
-	plane->fb_changed = true;
-	plane->size_changed = true;
 }
 
 /**
@@ -2949,12 +2919,19 @@ void igt_plane_set_fb(igt_plane_t *plane, struct igt_fb *fb)
  */
 void igt_plane_set_fence_fd(igt_plane_t *plane, int fence_fd)
 {
-	close(plane->fence_fd);
+	int64_t fd;
 
-	if (fcntl(fence_fd, F_GETFD) != -1)
-		plane->fence_fd = dup(fence_fd);
-	else
-		plane->fence_fd = -1;
+	fd = plane->values[IGT_PLANE_IN_FENCE_FD];
+	if (fd != -1)
+		close(fd);
+
+	if (fence_fd != -1) {
+		fd = dup(fence_fd);
+		igt_fail_on(fd == -1);
+	} else
+		fd = -1;
+
+	igt_plane_set_prop_value(plane, IGT_PLANE_IN_FENCE_FD, fd);
 }
 
 void igt_plane_set_position(igt_plane_t *plane, int x, int y)
@@ -2965,10 +2942,8 @@ void igt_plane_set_position(igt_plane_t *plane, int x, int y)
 	LOG(display, "%s.%d: plane_set_position(%d,%d)\n",
 	    kmstest_pipe_name(pipe->pipe), plane->index, x, y);
 
-	plane->crtc_x = x;
-	plane->crtc_y = y;
-
-	plane->position_changed = true;
+	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_X, x);
+	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_Y, y);
 }
 
 /**
@@ -2989,10 +2964,8 @@ void igt_plane_set_size(igt_plane_t *plane, int w, int h)
 	LOG(display, "%s.%d: plane_set_size (%dx%d)\n",
 	    kmstest_pipe_name(pipe->pipe), plane->index, w, h);
 
-	plane->crtc_w = w;
-	plane->crtc_h = h;
-
-	plane->size_changed = true;
+	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_W, w);
+	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_H, h);
 }
 
 /**
@@ -3014,10 +2987,8 @@ void igt_fb_set_position(struct igt_fb *fb, igt_plane_t *plane,
 	LOG(display, "%s.%d: fb_set_position(%d,%d)\n",
 	    kmstest_pipe_name(pipe->pipe), plane->index, x, y);
 
-	plane->src_x = x;
-	plane->src_y = y;
-
-	plane->fb_changed = true;
+	igt_plane_set_prop_value(plane, IGT_PLANE_SRC_X, IGT_FIXED(x, 0));
+	igt_plane_set_prop_value(plane, IGT_PLANE_SRC_Y, IGT_FIXED(y, 0));
 }
 
 /**
@@ -3040,10 +3011,8 @@ void igt_fb_set_size(struct igt_fb *fb, igt_plane_t *plane,
 	LOG(display, "%s.%d: fb_set_size(%dx%d)\n",
 	    kmstest_pipe_name(pipe->pipe), plane->index, w, h);
 
-	plane->src_w = w;
-	plane->src_h = h;
-
-	plane->fb_changed = true;
+	igt_plane_set_prop_value(plane, IGT_PLANE_SRC_W, IGT_FIXED(w, 0));
+	igt_plane_set_prop_value(plane, IGT_PLANE_SRC_H, IGT_FIXED(h, 0));
 }
 
 static const char *rotation_name(igt_rotation_t rotation)
@@ -3071,9 +3040,7 @@ void igt_plane_set_rotation(igt_plane_t *plane, igt_rotation_t rotation)
 	    kmstest_pipe_name(pipe->pipe),
 	    plane->index, rotation_name(rotation));
 
-	plane->rotation = rotation;
-
-	plane->rotation_changed = true;
+	igt_plane_set_prop_value(plane, IGT_PLANE_ROTATION, rotation);
 }
 
 /**
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 1ef10e7d525c..f87f8be31421 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -252,6 +252,9 @@ enum igt_atomic_plane_properties {
        IGT_PLANE_CRTC_W,
        IGT_PLANE_CRTC_H,
 
+/* Append new properties after IGT_PLANE_COORD_CHANGED_MASK */
+#define IGT_PLANE_COORD_CHANGED_MASK 0xff
+
        IGT_PLANE_FB_ID,
        IGT_PLANE_CRTC_ID,
        IGT_PLANE_IN_FENCE_FD,
@@ -286,37 +289,19 @@ typedef struct {
 	int index;
 	/* capabilities */
 	int type;
-	/* state tracking */
-	unsigned int fb_changed       : 1;
-	unsigned int position_changed : 1;
-	unsigned int rotation_changed : 1;
-	unsigned int size_changed     : 1;
+
 	/*
 	 * drm_plane can be NULL for primary and cursor planes (when not
 	 * using the atomic modeset API)
 	 */
 	drmModePlane *drm_plane;
-	struct igt_fb *fb;
-
-	uint32_t rotation_property;
-
-	/* position within pipe_src_w x pipe_src_h */
-	int crtc_x, crtc_y;
-	/* size within pipe_src_w x pipe_src_h */
-	int crtc_w, crtc_h;
 
-	/* position within the framebuffer */
-	uint32_t src_x;
-	uint32_t src_y;
-	/* size within the framebuffer*/
-	uint32_t src_w;
-	uint32_t src_h;
+	/* gem handle for fb */
+	uint32_t gem_handle;
 
-	igt_rotation_t rotation;
-
-	/* in fence fd */
-	int fence_fd;
-	uint32_t atomic_props_plane[IGT_NUM_PLANE_PROPS];
+	uint64_t changed;
+	uint32_t props[IGT_NUM_PLANE_PROPS];
+	uint64_t values[IGT_NUM_PLANE_PROPS];
 } igt_plane_t;
 
 struct igt_pipe {
@@ -407,7 +392,7 @@ bool igt_pipe_get_property(igt_pipe_t *pipe, const char *name,
 
 static inline bool igt_plane_supports_rotation(igt_plane_t *plane)
 {
-	return plane->rotation_property != 0;
+	return plane->props[IGT_PLANE_ROTATION] != 0;
 }
 void igt_pipe_request_out_fence(igt_pipe_t *pipe);
 void igt_pipe_set_degamma_lut(igt_pipe_t *pipe, void *ptr, size_t length);
@@ -527,16 +512,20 @@ static inline bool igt_output_is_connected(igt_output_t *output)
 
 #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))
+#define igt_plane_is_prop_changed(plane, prop) \
+	(!!((plane)->changed & (1 << (prop))))
+
+#define igt_plane_set_prop_changed(plane, prop) \
+	(plane)->changed |= 1 << (prop)
+
+#define igt_plane_clear_prop_changed(plane, prop) \
+	(plane)->changed &= ~(1 << (prop))
+
+#define igt_plane_set_prop_value(plane, prop, value) \
+	do { \
+		plane->values[prop] = value; \
+		igt_plane_set_prop_changed(plane, prop); \
+	} while (0)
 
 /**
  * igt_atomic_populate_crtc_req:
diff --git a/tests/kms_atomic_interruptible.c b/tests/kms_atomic_interruptible.c
index dcdbc267d3ef..4a2a577412cc 100644
--- a/tests/kms_atomic_interruptible.c
+++ b/tests/kms_atomic_interruptible.c
@@ -163,12 +163,12 @@ static void run_plane_test(igt_display_t *display, enum pipe pipe, igt_output_t
 					/* connector: 1 prop */
 					output->props[IGT_CONNECTOR_CRTC_ID],
 					/* plane: remainder props */
-					plane->atomic_props_plane[IGT_PLANE_CRTC_ID],
-					plane->atomic_props_plane[IGT_PLANE_FB_ID],
-					plane->atomic_props_plane[IGT_PLANE_SRC_W],
-					plane->atomic_props_plane[IGT_PLANE_SRC_H],
-					plane->atomic_props_plane[IGT_PLANE_CRTC_W],
-					plane->atomic_props_plane[IGT_PLANE_CRTC_H]
+					plane->props[IGT_PLANE_CRTC_ID],
+					plane->props[IGT_PLANE_FB_ID],
+					plane->props[IGT_PLANE_SRC_W],
+					plane->props[IGT_PLANE_SRC_H],
+					plane->props[IGT_PLANE_CRTC_W],
+					plane->props[IGT_PLANE_CRTC_H]
 				};
 				uint64_t prop_vals[] = {
 					/* crtc */
diff --git a/tests/kms_rotation_crc.c b/tests/kms_rotation_crc.c
index 5aec8fa39671..b8327dfa0d83 100644
--- a/tests/kms_rotation_crc.c
+++ b/tests/kms_rotation_crc.c
@@ -122,11 +122,11 @@ static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
 	igt_plane_set_fb(primary, &data->fb_modeset);
 
 	if (commit < COMMIT_ATOMIC) {
-		primary->rotation_changed = false;
+		igt_plane_clear_prop_changed(primary, IGT_PLANE_ROTATION);
 		igt_display_commit(display);
 
 		if (plane->type == DRM_PLANE_TYPE_PRIMARY)
-			primary->rotation_changed = true;
+			igt_plane_set_prop_changed(primary, IGT_PLANE_ROTATION);
 	}
 
 	igt_plane_set_fb(plane, NULL);
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH i-g-t v2 03/14] lib/igt_kms: Rework pipe properties to be more atomic, v7.
  2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
  2017-10-12 11:54 ` [PATCH i-g-t v2 01/14] lib/igt_kms: Rework connector properties to be more atomic, v2 Maarten Lankhorst
  2017-10-12 11:54 ` [PATCH i-g-t v2 02/14] lib/igt_kms: Rework plane properties to be more atomic, v5 Maarten Lankhorst
@ 2017-10-12 11:54 ` Maarten Lankhorst
  2017-10-19 10:28   ` Mika Kahola
  2018-03-05 14:37     ` [igt-dev] [Intel-gfx] " Maxime Ripard
  2017-10-12 11:54 ` [PATCH i-g-t v2 04/14] lib/igt_kms: Allow setting any plane property through the universal path Maarten Lankhorst
                   ` (14 subsequent siblings)
  17 siblings, 2 replies; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-12 11:54 UTC (permalink / raw)
  To: intel-gfx

In the future I want to allow tests to commit more properties,
but for this to work I have to fix all properties to work better
with atomic commit. Instead of special casing each
property make a bitmask for all property changed flags, and try to
commit all properties.

This has been the most involved one, since legacy pipe commit still
handles a lot of the properties differently from the rest.

Changes since v1:
- Dump all changed properties on commit.
- Fix bug in igt_pipe_refresh().
Changes since v2:
- Set pipe ACTIVE property changed flag on init.
Changes since v3:
- Add a missing igt_pipe_refresh() to kms_atomic_interruptible.
Changes since v4:
- Perform error handling when setting custom crtc properties.
Changes since v5:
- Only attempt to commit changes properties.
Changes since v6:
- Clear OUT_FENCE_PTR on succesful commit.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 lib/igt_kms.c                     | 231 ++++++++++++++++++++------------------
 lib/igt_kms.h                     |  77 +++++--------
 tests/kms_atomic_interruptible.c  |   8 +-
 tests/kms_atomic_transition.c     |   2 +-
 tests/kms_crtc_background_color.c |   2 +-
 5 files changed, 159 insertions(+), 161 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index e77ae5d696da..02de39b8fc7f 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -259,8 +259,8 @@ igt_atomic_fill_connector_props(igt_display_t *display, igt_output_t *output,
 }
 
 static void
-igt_atomic_fill_pipe_props(igt_display_t *display, igt_pipe_t *pipe,
-			int num_crtc_props, const char **crtc_prop_names)
+igt_fill_pipe_props(igt_display_t *display, igt_pipe_t *pipe,
+		    int num_crtc_props, const char **crtc_prop_names)
 {
 	drmModeObjectPropertiesPtr props;
 	int i, j, fd;
@@ -278,7 +278,7 @@ igt_atomic_fill_pipe_props(igt_display_t *display, igt_pipe_t *pipe,
 			if (strcmp(prop->name, crtc_prop_names[j]) != 0)
 				continue;
 
-			pipe->atomic_props_crtc[j] = props->props[i];
+			pipe->props[j] = props->props[i];
 			break;
 		}
 
@@ -1620,13 +1620,6 @@ get_crtc_property(int drm_fd, uint32_t crtc_id, const char *name,
 				    name, prop_id, value, prop);
 }
 
-static void
-igt_crtc_set_property(igt_pipe_t *pipe, uint32_t prop_id, uint64_t value)
-{
-	drmModeObjectSetProperty(pipe->display->drm_fd,
-		pipe->crtc_id, DRM_MODE_OBJECT_CRTC, prop_id, value);
-}
-
 /*
  * Walk a plane's property list to determine its type.  If we don't
  * find a type property, then the kernel doesn't support universal
@@ -1690,7 +1683,6 @@ void igt_display_init(igt_display_t *display, int drm_fd)
 		int p = 1;
 		int j, type;
 		uint8_t last_plane = 0, n_planes = 0;
-		uint64_t prop_value;
 
 		pipe->crtc_id = resources->crtcs[i];
 		pipe->display = display;
@@ -1700,29 +1692,16 @@ void igt_display_init(igt_display_t *display, int drm_fd)
 		pipe->planes = NULL;
 		pipe->out_fence_fd = -1;
 
+		igt_fill_pipe_props(display, pipe, IGT_NUM_CRTC_PROPS, igt_crtc_prop_names);
+
+		/* Force modeset disable on first commit */
+		igt_pipe_obj_set_prop_changed(pipe, IGT_CRTC_MODE_ID);
+		igt_pipe_obj_set_prop_changed(pipe, IGT_CRTC_ACTIVE);
+
 		get_crtc_property(display->drm_fd, pipe->crtc_id,
-				    "background_color",
-				    &pipe->background_property,
-				    &prop_value,
+				    "background_color", NULL,
+				    &pipe->values[IGT_CRTC_BACKGROUND],
 				    NULL);
-		pipe->background = (uint32_t)prop_value;
-		get_crtc_property(display->drm_fd, pipe->crtc_id,
-				  "DEGAMMA_LUT",
-				  &pipe->degamma_property,
-				  NULL,
-				  NULL);
-		get_crtc_property(display->drm_fd, pipe->crtc_id,
-				  "CTM",
-				  &pipe->ctm_property,
-				  NULL,
-				  NULL);
-		get_crtc_property(display->drm_fd, pipe->crtc_id,
-				  "GAMMA_LUT",
-				  &pipe->gamma_property,
-				  NULL,
-				  NULL);
-
-		igt_atomic_fill_pipe_props(display, pipe, IGT_NUM_CRTC_PROPS, igt_crtc_prop_names);
 
 		/* count number of valid planes */
 		for (j = 0; j < plane_resources->count_planes; j++) {
@@ -1813,8 +1792,6 @@ void igt_display_init(igt_display_t *display, int drm_fd)
 			igt_assert_eq(p, n_planes);
 
 		pipe->n_planes = n_planes;
-
-		pipe->mode_changed = true;
 	}
 
 	/*
@@ -2291,7 +2268,7 @@ static int igt_primary_plane_commit_legacy(igt_plane_t *primary,
 
 	if (!igt_plane_is_prop_changed(primary, IGT_PLANE_FB_ID) &&
 	    !(primary->changed & IGT_PLANE_COORD_CHANGED_MASK) &&
-	    !primary->pipe->mode_changed)
+	    !igt_pipe_obj_is_prop_changed(primary->pipe, IGT_CRTC_MODE_ID))
 		return 0;
 
 	crtc_id = pipe->crtc_id;
@@ -2360,6 +2337,16 @@ static int igt_plane_commit(igt_plane_t *plane,
 	}
 }
 
+static bool is_atomic_prop(enum igt_atomic_crtc_properties prop)
+{
+       if (prop == IGT_CRTC_MODE_ID ||
+	   prop == IGT_CRTC_ACTIVE ||
+	   prop == IGT_CRTC_OUT_FENCE_PTR)
+		return true;
+
+	return false;
+}
+
 /*
  * Commit all plane changes to an output.  Note that if @s is COMMIT_LEGACY,
  * enabling/disabling the primary plane will also enable/disable the CRTC.
@@ -2377,19 +2364,17 @@ static int igt_pipe_commit(igt_pipe_t *pipe,
 	int i;
 	int ret;
 
-	if (pipe->background_changed) {
-		igt_crtc_set_property(pipe, pipe->background_property,
-			pipe->background);
-	}
+	for (i = 0; i < IGT_NUM_CRTC_PROPS; i++)
+		if (igt_pipe_obj_is_prop_changed(pipe, i) &&
+		    !is_atomic_prop(i)) {
+			igt_assert(pipe->props[i]);
 
-	if (pipe->color_mgmt_changed) {
-		igt_crtc_set_property(pipe, pipe->degamma_property,
-				      pipe->degamma_blob);
-		igt_crtc_set_property(pipe, pipe->ctm_property,
-				      pipe->ctm_blob);
-		igt_crtc_set_property(pipe, pipe->gamma_property,
-				      pipe->gamma_blob);
-	}
+			ret = drmModeObjectSetProperty(pipe->display->drm_fd,
+				pipe->crtc_id, DRM_MODE_OBJECT_CRTC,
+				pipe->props[i], pipe->values[i]);
+
+			CHECK_RETURN(ret, fail_on_error);
+		}
 
 	for (i = 0; i < pipe->n_planes; i++) {
 		igt_plane_t *plane = &pipe->planes[i];
@@ -2402,9 +2387,10 @@ static int igt_pipe_commit(igt_pipe_t *pipe,
 }
 
 static void
-igt_pipe_replace_blob(igt_pipe_t *pipe, uint64_t *blob, void *ptr, size_t length)
+igt_pipe_replace_blob(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop, void *ptr, size_t length)
 {
 	igt_display_t *display = pipe->display;
+	uint64_t *blob = &pipe->values[prop];
 	uint32_t blob_id = 0;
 
 	if (*blob != 0)
@@ -2416,6 +2402,7 @@ igt_pipe_replace_blob(igt_pipe_t *pipe, uint64_t *blob, void *ptr, size_t length
 						     ptr, length, &blob_id) == 0);
 
 	*blob = blob_id;
+	igt_pipe_obj_set_prop_changed(pipe, prop);
 }
 
 /*
@@ -2423,51 +2410,23 @@ igt_pipe_replace_blob(igt_pipe_t *pipe, uint64_t *blob, void *ptr, size_t length
  */
 static void igt_atomic_prepare_crtc_commit(igt_pipe_t *pipe_obj, drmModeAtomicReq *req)
 {
-	if (pipe_obj->background_changed)
-		igt_atomic_populate_crtc_req(req, pipe_obj, IGT_CRTC_BACKGROUND, pipe_obj->background);
-
-	if (pipe_obj->color_mgmt_changed) {
-		igt_atomic_populate_crtc_req(req, pipe_obj, IGT_CRTC_DEGAMMA_LUT, pipe_obj->degamma_blob);
-		igt_atomic_populate_crtc_req(req, pipe_obj, IGT_CRTC_CTM, pipe_obj->ctm_blob);
-		igt_atomic_populate_crtc_req(req, pipe_obj, IGT_CRTC_GAMMA_LUT, pipe_obj->gamma_blob);
-	}
-
-	if (pipe_obj->mode_changed) {
-		igt_output_t *output = igt_pipe_get_output(pipe_obj);
-
-		if (!output) {
-			igt_pipe_replace_blob(pipe_obj, &pipe_obj->mode_blob, NULL, 0);
-
-			LOG(pipe_obj->display, "%s: Setting NULL mode\n",
-			    kmstest_pipe_name(pipe_obj->pipe));
-		} else {
-			drmModeModeInfo *mode = igt_output_get_mode(output);
+	int i;
 
-			igt_pipe_replace_blob(pipe_obj, &pipe_obj->mode_blob, mode, sizeof(*mode));
+	for (i = 0; i < IGT_NUM_CRTC_PROPS; i++) {
+		if (!igt_pipe_obj_is_prop_changed(pipe_obj, i))
+			continue;
 
-			LOG(pipe_obj->display, "%s: Setting mode %s from %s\n",
-			    kmstest_pipe_name(pipe_obj->pipe),
-			    mode->name, igt_output_name(output));
-		}
+		igt_debug("Pipe %s: Setting property \"%s\" to 0x%"PRIx64"/%"PRIi64"\n",
+			kmstest_pipe_name(pipe_obj->pipe), igt_crtc_prop_names[i],
+			pipe_obj->values[i], pipe_obj->values[i]);
 
-		igt_atomic_populate_crtc_req(req, pipe_obj, IGT_CRTC_MODE_ID, pipe_obj->mode_blob);
-		igt_atomic_populate_crtc_req(req, pipe_obj, IGT_CRTC_ACTIVE, !!output);
+		igt_assert_lt(0, drmModeAtomicAddProperty(req, pipe_obj->crtc_id, pipe_obj->props[i], pipe_obj->values[i]));
 	}
 
 	if (pipe_obj->out_fence_fd != -1) {
 		close(pipe_obj->out_fence_fd);
 		pipe_obj->out_fence_fd = -1;
 	}
-
-	if (pipe_obj->out_fence_requested)
-	{
-		igt_atomic_populate_crtc_req(req, pipe_obj, IGT_CRTC_OUT_FENCE_PTR,
-		    (uint64_t)(uintptr_t) &pipe_obj->out_fence_fd);
-	}
-
-	/*
-	 *	TODO: Add all crtc level properties here
-	 */
 }
 
 /*
@@ -2558,15 +2517,22 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
 		igt_pipe_t *pipe_obj = &display->pipes[pipe];
 		igt_plane_t *plane;
 
-		pipe_obj->color_mgmt_changed = false;
-		pipe_obj->background_changed = false;
+		if (s == COMMIT_ATOMIC) {
+			if (igt_pipe_obj_is_prop_changed(pipe_obj, IGT_CRTC_OUT_FENCE_PTR))
+				igt_assert(pipe_obj->out_fence_fd >= 0);
 
-		if (s != COMMIT_UNIVERSAL)
-			pipe_obj->mode_changed = false;
-
-		if (s == COMMIT_ATOMIC && pipe_obj->out_fence_requested) {
-			pipe_obj->out_fence_requested = false;
-			igt_assert(pipe_obj->out_fence_fd >= 0);
+			pipe_obj->values[IGT_CRTC_OUT_FENCE_PTR] = 0;
+			pipe_obj->changed = 0;
+		} else {
+			igt_pipe_obj_clear_prop_changed(pipe_obj, IGT_CRTC_BACKGROUND);
+			igt_pipe_obj_clear_prop_changed(pipe_obj, IGT_CRTC_CTM);
+			igt_pipe_obj_clear_prop_changed(pipe_obj, IGT_CRTC_DEGAMMA_LUT);
+			igt_pipe_obj_clear_prop_changed(pipe_obj, IGT_CRTC_GAMMA_LUT);
+
+			if (s != COMMIT_UNIVERSAL) {
+				igt_pipe_obj_clear_prop_changed(pipe_obj, IGT_CRTC_MODE_ID);
+				igt_pipe_obj_clear_prop_changed(pipe_obj, IGT_CRTC_ACTIVE);
+			}
 		}
 
 		for_each_plane_on_pipe(display, pipe, plane) {
@@ -2820,33 +2786,83 @@ void igt_output_override_mode(igt_output_t *output, drmModeModeInfo *mode)
 
 	output->use_override_mode = !!mode;
 
-	if (pipe)
-		pipe->mode_changed = true;
+	if (pipe) {
+		if (output->display->is_atomic)
+			igt_pipe_replace_blob(pipe, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(*mode));
+		else
+			igt_pipe_obj_set_prop_changed(pipe, IGT_CRTC_MODE_ID);
+	}
 }
 
 void igt_output_set_pipe(igt_output_t *output, enum pipe pipe)
 {
 	igt_display_t *display = output->display;
-	igt_pipe_t *old_pipe;
+	igt_pipe_t *old_pipe = NULL, *pipe_obj = NULL;;
 
 	igt_assert(output->name);
 
-	if (output->pending_pipe != PIPE_NONE) {
+	if (output->pending_pipe != PIPE_NONE)
 		old_pipe = igt_output_get_driving_pipe(output);
 
-		old_pipe->mode_changed = true;
-	}
+	if (pipe != PIPE_NONE)
+		pipe_obj = &display->pipes[pipe];
 
 	LOG(display, "%s: set_pipe(%s)\n", igt_output_name(output),
 	    kmstest_pipe_name(pipe));
 	output->pending_pipe = pipe;
 
-	if (pipe != PIPE_NONE)
-		display->pipes[pipe].mode_changed = true;
+	if (old_pipe) {
+		igt_output_t *old_output;
+
+		old_output = igt_pipe_get_output(old_pipe);
+		if (!old_output) {
+			if (display->is_atomic)
+				igt_pipe_replace_blob(old_pipe, IGT_CRTC_MODE_ID, NULL, 0);
+			else
+				igt_pipe_obj_set_prop_changed(old_pipe, IGT_CRTC_MODE_ID);
+
+			igt_pipe_obj_set_prop_value(old_pipe, IGT_CRTC_ACTIVE, 0);
+		}
+	}
 
 	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID, pipe == PIPE_NONE ? 0 : display->pipes[pipe].crtc_id);
 
 	igt_output_refresh(output);
+
+	if (pipe_obj) {
+		if (display->is_atomic)
+			igt_pipe_replace_blob(pipe_obj, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(drmModeModeInfo));
+		else
+			igt_pipe_obj_set_prop_changed(pipe_obj, IGT_CRTC_MODE_ID);
+
+		igt_pipe_obj_set_prop_value(pipe_obj, IGT_CRTC_ACTIVE, 1);
+	}
+}
+
+/*
+ * igt_pipe_refresh:
+ * @display: a pointer to an #igt_display_t structure
+ * @pipe: Pipe to refresh
+ * @force: Should be set to true if mode_blob is no longer considered
+ * to be valid, for example after doing an atomic commit during fork or closing display fd.
+ *
+ * Requests the pipe to be part of the state on next update.
+ * This is useful when state may have been out of sync after
+ * a fork, or we just want to be sure the pipe is included
+ * in the next commit.
+ */
+void igt_pipe_refresh(igt_display_t *display, enum pipe pipe, bool force)
+{
+	igt_pipe_t *pipe_obj = &display->pipes[pipe];
+
+	if (force && display->is_atomic) {
+		igt_output_t *output = igt_pipe_get_output(pipe_obj);
+
+		pipe_obj->values[IGT_CRTC_MODE_ID] = 0;
+		if (output)
+			igt_pipe_replace_blob(pipe_obj, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(drmModeModeInfo));
+	} else
+		igt_pipe_obj_set_prop_changed(pipe_obj, IGT_CRTC_MODE_ID);
 }
 
 void igt_output_set_scaling_mode(igt_output_t *output, uint64_t scaling_mode)
@@ -3052,28 +3068,25 @@ void igt_plane_set_rotation(igt_plane_t *plane, igt_rotation_t rotation)
  */
 void igt_pipe_request_out_fence(igt_pipe_t *pipe)
 {
-	pipe->out_fence_requested = true;
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
 }
 
 void
 igt_pipe_set_degamma_lut(igt_pipe_t *pipe, void *ptr, size_t length)
 {
-	igt_pipe_replace_blob(pipe, &pipe->degamma_blob, ptr, length);
-	pipe->color_mgmt_changed = 1;
+	igt_pipe_replace_blob(pipe, IGT_CRTC_DEGAMMA_LUT, ptr, length);
 }
 
 void
 igt_pipe_set_ctm_matrix(igt_pipe_t *pipe, void *ptr, size_t length)
 {
-	igt_pipe_replace_blob(pipe, &pipe->ctm_blob, ptr, length);
-	pipe->color_mgmt_changed = 1;
+	igt_pipe_replace_blob(pipe, IGT_CRTC_CTM, ptr, length);
 }
 
 void
 igt_pipe_set_gamma_lut(igt_pipe_t *pipe, void *ptr, size_t length)
 {
-	igt_pipe_replace_blob(pipe, &pipe->gamma_blob, ptr, length);
-	pipe->color_mgmt_changed = 1;
+	igt_pipe_replace_blob(pipe, IGT_CRTC_GAMMA_LUT, ptr, length);
 }
 
 /**
@@ -3094,9 +3107,7 @@ void igt_crtc_set_background(igt_pipe_t *pipe, uint64_t background)
 	    kmstest_pipe_name(pipe->pipe),
 	    pipe->pipe, background);
 
-	pipe->background = background;
-
-	pipe->background_changed = true;
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_BACKGROUND, background);
 }
 
 void igt_wait_for_vblank_count(int drm_fd, enum pipe pipe, int count)
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index f87f8be31421..b53127ffef5f 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -313,27 +313,13 @@ struct igt_pipe {
 	int plane_primary;
 	igt_plane_t *planes;
 
-	uint32_t atomic_props_crtc[IGT_NUM_CRTC_PROPS];
-
-	uint64_t background; /* Background color MSB BGR 16bpc LSB */
-	uint32_t background_changed : 1;
-	uint32_t background_property;
-
-	uint64_t degamma_blob;
-	uint32_t degamma_property;
-	uint64_t ctm_blob;
-	uint32_t ctm_property;
-	uint64_t gamma_blob;
-	uint32_t gamma_property;
-	uint32_t color_mgmt_changed : 1;
+	uint64_t changed;
+	uint32_t props[IGT_NUM_CRTC_PROPS];
+	uint64_t values[IGT_NUM_CRTC_PROPS];
 
 	uint32_t crtc_id;
 
-	uint64_t mode_blob;
-	bool mode_changed;
-
 	int32_t out_fence_fd;
-	bool out_fence_requested;
 };
 
 typedef struct {
@@ -527,17 +513,6 @@ static inline bool igt_output_is_connected(igt_output_t *output)
 		igt_plane_set_prop_changed(plane, prop); \
 	} while (0)
 
-/**
- * igt_atomic_populate_crtc_req:
- * @req: A pointer to drmModeAtomicReq
- * @pipe: A pointer igt_pipe_t
- * @prop: one of igt_atomic_crtc_properties
- * @value: the value to add
- */
-#define igt_atomic_populate_crtc_req(req, pipe, prop, value) \
-	igt_assert_lt(0, drmModeAtomicAddProperty(req, pipe->crtc_id,\
-						  pipe->atomic_props_crtc[prop], value))
-
 #define igt_output_is_prop_changed(output, prop) \
 	(!!((output)->changed & (1 << (prop))))
 #define igt_output_set_prop_changed(output, prop) \
@@ -552,26 +527,34 @@ static inline bool igt_output_is_connected(igt_output_t *output)
 		igt_output_set_prop_changed(output, prop); \
 	} while (0)
 
-/*
- * igt_pipe_refresh:
- * @display: a pointer to an #igt_display_t structure
- * @pipe: Pipe to refresh
- * @force: Should be set to true if mode_blob is no longer considered
- * to be valid, for example after doing an atomic commit during fork or closing display fd.
- *
- * Requests the pipe to be part of the state on next update.
- * This is useful when state may have been out of sync after
- * a fork, or we just want to be sure the pipe is included
- * in the next commit.
- */
-static inline void
-igt_pipe_refresh(igt_display_t *display, enum pipe pipe, bool force)
-{
-	if (force)
-		display->pipes[pipe].mode_blob = 0;
+#define igt_pipe_obj_is_prop_changed(pipe_obj, prop) \
+	(!!((pipe_obj)->changed & (1 << (prop))))
 
-	display->pipes[pipe].mode_changed = true;
-}
+#define igt_pipe_is_prop_changed(display, pipe, prop) \
+	igt_pipe_obj_is_prop_changed(&(display)->pipes[(pipe)], prop)
+
+#define igt_pipe_obj_set_prop_changed(pipe_obj, prop) \
+	(pipe_obj)->changed |= 1 << (prop)
+
+#define igt_pipe_set_prop_changed(display, pipe, prop) \
+	igt_pipe_obj_set_prop_changed(&(display)->pipes[(pipe)], prop)
+
+#define igt_pipe_obj_clear_prop_changed(pipe_obj, prop) \
+	(pipe_obj)->changed &= ~(1 << (prop))
+
+#define igt_pipe_clear_prop_changed(display, pipe, prop) \
+	igt_pipe_obj_clear_prop_changed(&(display)->pipes[(pipe)], prop)
+
+#define igt_pipe_obj_set_prop_value(pipe_obj, prop, value) \
+	do { \
+		(pipe_obj)->values[prop] = (value); \
+		igt_pipe_obj_set_prop_changed(pipe_obj, prop); \
+	} while (0)
+
+#define igt_pipe_set_prop_value(display, pipe, prop, value) \
+	igt_pipe_obj_set_prop_value(&(display)->pipes[(pipe)], prop, value)
+
+void igt_pipe_refresh(igt_display_t *display, enum pipe pipe, bool force);
 
 void igt_enable_connectors(void);
 void igt_reset_connectors(void);
diff --git a/tests/kms_atomic_interruptible.c b/tests/kms_atomic_interruptible.c
index 4a2a577412cc..64a005597a21 100644
--- a/tests/kms_atomic_interruptible.c
+++ b/tests/kms_atomic_interruptible.c
@@ -158,8 +158,8 @@ static void run_plane_test(igt_display_t *display, enum pipe pipe, igt_output_t
 				uint32_t count_props[3] = { 2, 1, 6 };
 				uint32_t props[] = {
 					/* crtc: 2 props */
-					plane->pipe->atomic_props_crtc[IGT_CRTC_MODE_ID],
-					plane->pipe->atomic_props_crtc[IGT_CRTC_ACTIVE],
+					plane->pipe->props[IGT_CRTC_MODE_ID],
+					plane->pipe->props[IGT_CRTC_ACTIVE],
 					/* connector: 1 prop */
 					output->props[IGT_CONNECTOR_CRTC_ID],
 					/* plane: remainder props */
@@ -255,6 +255,10 @@ static void run_plane_test(igt_display_t *display, enum pipe pipe, igt_output_t
 
 	igt_waitchildren();
 
+	/* The mode is unset by the forked helper, force a refresh here */
+	if (test_type == test_legacy_modeset || test_type == test_atomic_modeset)
+		igt_pipe_refresh(display, pipe, true);
+
 	igt_plane_set_fb(plane, NULL);
 	igt_plane_set_fb(primary, NULL);
 	igt_output_set_pipe(output, PIPE_NONE);
diff --git a/tests/kms_atomic_transition.c b/tests/kms_atomic_transition.c
index 2ae75f2d6630..7ddb65cea183 100644
--- a/tests/kms_atomic_transition.c
+++ b/tests/kms_atomic_transition.c
@@ -633,7 +633,7 @@ static unsigned set_combinations(igt_display_t *display, unsigned mask, struct i
 		drmModeModeInfo *mode = NULL;
 
 		if (!(mask & (1 << pipe))) {
-			if (display->pipes[pipe].mode_blob) {
+			if (igt_pipe_is_prop_changed(display, pipe, IGT_CRTC_ACTIVE)) {
 				event_mask |= 1 << pipe;
 				igt_plane_set_fb(plane, NULL);
 			}
diff --git a/tests/kms_crtc_background_color.c b/tests/kms_crtc_background_color.c
index e12e163449f8..659a30b90219 100644
--- a/tests/kms_crtc_background_color.c
+++ b/tests/kms_crtc_background_color.c
@@ -137,7 +137,7 @@ static void test_crtc_background(data_t *data)
 		igt_output_set_pipe(output, pipe);
 
 		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
-		igt_require(plane->pipe->background_property);
+		igt_require(plane->pipe->props[IGT_CRTC_BACKGROUND]);
 
 		prepare_crtc(data, output, pipe, plane, 1, PURPLE, BLACK64);
 
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH i-g-t v2 04/14] lib/igt_kms: Allow setting any plane property through the universal path
  2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
                   ` (2 preceding siblings ...)
  2017-10-12 11:54 ` [PATCH i-g-t v2 03/14] lib/igt_kms: Rework pipe properties to be more atomic, v7 Maarten Lankhorst
@ 2017-10-12 11:54 ` Maarten Lankhorst
  2017-10-19 11:04   ` Mika Kahola
  2017-10-12 11:54 ` [PATCH i-g-t v2 05/14] lib/igt_kms: Allow setting any output property through the !atomic paths Maarten Lankhorst
                   ` (13 subsequent siblings)
  17 siblings, 1 reply; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-12 11:54 UTC (permalink / raw)
  To: intel-gfx

Blacklist some explicit atomic properties. We could theoretically set
them but that's not what the legacy path is for. :)

When adding new properties, this means we could test those through
the legacy commit.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 lib/igt_kms.c | 39 +++++++++++++++++++++++++++++++++------
 1 file changed, 33 insertions(+), 6 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 02de39b8fc7f..be89632547e5 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -2097,7 +2097,22 @@ igt_atomic_prepare_plane_commit(igt_plane_t *plane, igt_pipe_t *pipe,
 	}
 }
 
-
+/*
+ * Properties that can be changed through legacy SetProperty:
+ * - Obviously not the XYWH SRC/CRTC coordinates.
+ * - Not CRTC_ID or FENCE_ID, done through SetPlane.
+ * - Can't set IN_FENCE_FD, that would be silly.
+ *
+ * Theoretically the above can all be set through the legacy path
+ * with the atomic cap set, but that's not how our legacy plane
+ * commit behaves, so blacklist it by default.
+ */
+#define LEGACY_PLANE_COMMIT_MASK \
+	(((1ULL << IGT_NUM_PLANE_PROPS) - 1) & \
+	 ~(IGT_PLANE_COORD_CHANGED_MASK | \
+	   (1ULL << IGT_PLANE_FB_ID) | \
+	   (1ULL << IGT_PLANE_CRTC_ID) | \
+	   (1ULL << IGT_PLANE_IN_FENCE_FD)))
 
 /*
  * Commit position and fb changes to a DRM plane via the SetPlane ioctl; if the
@@ -2111,7 +2126,7 @@ static int igt_drm_plane_commit(igt_plane_t *plane,
 {
 	igt_display_t *display = pipe->display;
 	uint32_t fb_id, crtc_id;
-	int ret;
+	int ret, i;
 	uint32_t src_x;
 	uint32_t src_y;
 	uint32_t src_w;
@@ -2120,6 +2135,7 @@ static int igt_drm_plane_commit(igt_plane_t *plane,
 	int32_t crtc_y;
 	uint32_t crtc_w;
 	uint32_t crtc_h;
+	uint64_t changed_mask;
 	bool setplane =
 		igt_plane_is_prop_changed(plane, IGT_PLANE_FB_ID) ||
 		plane->changed & IGT_PLANE_COORD_CHANGED_MASK;
@@ -2184,10 +2200,21 @@ static int igt_drm_plane_commit(igt_plane_t *plane,
 		CHECK_RETURN(ret, fail_on_error);
 	}
 
-	if (igt_plane_is_prop_changed(plane, IGT_PLANE_ROTATION)) {
+	changed_mask = plane->changed & LEGACY_PLANE_COMMIT_MASK;
+
+	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++) {
+		if (!(changed_mask & (1 << i)))
+			continue;
+
+		LOG(display, "SetProp plane %s.%d \"%s\" to 0x%"PRIx64"/%"PRIi64"\n",
+			kmstest_pipe_name(pipe->pipe), plane->index, igt_plane_prop_names[i],
+			plane->values[i], plane->values[i]);
+
+		igt_assert(plane->props[i]);
+
 		ret = igt_plane_set_property(plane,
-					     plane->props[IGT_PLANE_ROTATION],
-					     plane->values[IGT_PLANE_ROTATION]);
+					     plane->props[i],
+					     plane->values[i]);
 
 		CHECK_RETURN(ret, fail_on_error);
 	}
@@ -2555,7 +2582,7 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
 				if (s != COMMIT_LEGACY ||
 				    !(plane->type == DRM_PLANE_TYPE_PRIMARY ||
 				      plane->type == DRM_PLANE_TYPE_CURSOR))
-					igt_plane_clear_prop_changed(plane, IGT_PLANE_ROTATION);
+					plane->changed &= ~LEGACY_PLANE_COMMIT_MASK;
 			}
 		}
 	}
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH i-g-t v2 05/14] lib/igt_kms: Allow setting any output property through the !atomic paths
  2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
                   ` (3 preceding siblings ...)
  2017-10-12 11:54 ` [PATCH i-g-t v2 04/14] lib/igt_kms: Allow setting any plane property through the universal path Maarten Lankhorst
@ 2017-10-12 11:54 ` Maarten Lankhorst
  2017-10-20  9:38   ` Mika Kahola
  2017-10-12 11:54 ` [PATCH i-g-t v2 06/14] lib/igt_kms: Export property blob functions for output/pipe/plane, v2 Maarten Lankhorst
                   ` (12 subsequent siblings)
  17 siblings, 1 reply; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-12 11:54 UTC (permalink / raw)
  To: intel-gfx

Everything except CRTC_ID can be set in the legacy paths,
we even have 2, the legacy and universal path. Excercise both. :D

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 lib/igt_kms.c | 53 +++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 37 insertions(+), 16 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index be89632547e5..e7b9fbaba709 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -2413,6 +2413,36 @@ static int igt_pipe_commit(igt_pipe_t *pipe,
 	return 0;
 }
 
+static int igt_output_commit(igt_output_t *output,
+			     enum igt_commit_style s,
+			     bool fail_on_error)
+{
+	int i, ret;
+
+	for (i = 0; i < IGT_NUM_CONNECTOR_PROPS; i++) {
+		if (!igt_output_is_prop_changed(output, i))
+			continue;
+
+		/* CRTC_ID is set by calling drmModeSetCrtc in the legacy path. */
+		if (i == IGT_CONNECTOR_CRTC_ID)
+			continue;
+
+		igt_assert(output->props[i]);
+
+		if (s == COMMIT_LEGACY)
+			ret = drmModeConnectorSetProperty(output->display->drm_fd, output->id,
+							  output->props[i], output->values[i]);
+		else
+			ret = drmModeObjectSetProperty(output->display->drm_fd, output->id,
+						       DRM_MODE_OBJECT_CONNECTOR,
+						       output->props[i], output->values[i]);
+
+		CHECK_RETURN(ret, fail_on_error);
+	}
+
+	return 0;
+}
+
 static void
 igt_pipe_replace_blob(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop, void *ptr, size_t length)
 {
@@ -2590,10 +2620,11 @@ display_commit_changed(igt_display_t *display, enum igt_commit_style s)
 	for (i = 0; i < display->n_outputs; i++) {
 		igt_output_t *output = &display->outputs[i];
 
-		if (s == COMMIT_ATOMIC)
+		if (s != COMMIT_UNIVERSAL)
 			output->changed = 0;
-		else if (s != COMMIT_UNIVERSAL)
-			igt_output_clear_prop_changed(output, IGT_CONNECTOR_CRTC_ID);
+		else
+			/* no modeset in universal commit, no change to crtc. */
+			output->changed &= 1 << IGT_CONNECTOR_CRTC_ID;
 	}
 }
 
@@ -2610,7 +2641,7 @@ static int do_display_commit(igt_display_t *display,
 			     enum igt_commit_style s,
 			     bool fail_on_error)
 {
-	int ret;
+	int i, ret = 0;
 	enum pipe pipe;
 	LOG_INDENT(display, "commit");
 
@@ -2619,28 +2650,18 @@ static int do_display_commit(igt_display_t *display,
 	if (s == COMMIT_ATOMIC) {
 		ret = igt_atomic_commit(display, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
 	} else {
-		int valid_outs = 0;
-
 		for_each_pipe(display, pipe) {
 			igt_pipe_t *pipe_obj = &display->pipes[pipe];
-			igt_output_t *output = igt_pipe_get_output(pipe_obj);
-
-			if (output)
-				valid_outs++;
 
 			ret = igt_pipe_commit(pipe_obj, s, fail_on_error);
 			if (ret)
 				break;
 		}
 
-		if (valid_outs == 0) {
-			LOG_UNINDENT(display);
-
-			return -1;
-		}
+		for (i = 0; !ret && i < display->n_outputs; i++)
+			ret = igt_output_commit(&display->outputs[i], s, fail_on_error);
 	}
 
-
 	LOG_UNINDENT(display);
 	CHECK_RETURN(ret, fail_on_error);
 
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH i-g-t v2 06/14] lib/igt_kms: Export property blob functions for output/pipe/plane, v2.
  2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
                   ` (4 preceding siblings ...)
  2017-10-12 11:54 ` [PATCH i-g-t v2 05/14] lib/igt_kms: Allow setting any output property through the !atomic paths Maarten Lankhorst
@ 2017-10-12 11:54 ` Maarten Lankhorst
  2017-10-19 11:24   ` Mika Kahola
  2017-10-12 11:54 ` [PATCH i-g-t v2 07/14] lib/igt_kms: Unexport broadcast rgb API Maarten Lankhorst
                   ` (11 subsequent siblings)
  17 siblings, 1 reply; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-12 11:54 UTC (permalink / raw)
  To: intel-gfx

With the replace_prop_blob functions we can safely replace the blob for
any property, without having to care about error handling ourselves.

This will for example allow overriding color management blobs, or for
kms_atomic set invalid mode blobs.

The color management blob functions are removed, they can now be
replaced by direct calls to replace the properties.

Changes since v1:
- Fix chamelium tests.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 lib/igt_kms.c     | 117 +++++++++++++++++++++++++++++++++++++++---------------
 lib/igt_kms.h     |  19 +++++++--
 tests/chamelium.c |   6 +--
 tests/kms_color.c |  12 +++---
 4 files changed, 110 insertions(+), 44 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index e7b9fbaba709..5f54021350ac 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -2443,8 +2443,88 @@ static int igt_output_commit(igt_output_t *output,
 	return 0;
 }
 
-static void
-igt_pipe_replace_blob(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop, void *ptr, size_t length)
+/**
+ * igt_plane_replace_prop_blob:
+ * @plane: plane to set property on.
+ * @prop: property for which the blob will be replaced.
+ * @ptr: Pointer to contents for the property.
+ * @length: Length of contents.
+ *
+ * This function will destroy the old property blob for the given property,
+ * and will create a new property blob with the values passed to this function.
+ *
+ * The new property blob will be committed when you call igt_display_commit(),
+ * igt_display_commit2() or igt_display_commit_atomic().
+ */
+void
+igt_plane_replace_prop_blob(igt_plane_t *plane, enum igt_atomic_plane_properties prop, const void *ptr, size_t length)
+{
+	igt_display_t *display = plane->pipe->display;
+	uint64_t *blob = &plane->values[prop];
+	uint32_t blob_id = 0;
+
+	if (*blob != 0)
+		igt_assert(drmModeDestroyPropertyBlob(display->drm_fd,
+						      *blob) == 0);
+
+	if (length > 0)
+		igt_assert(drmModeCreatePropertyBlob(display->drm_fd,
+						     ptr, length, &blob_id) == 0);
+
+	*blob = blob_id;
+	igt_plane_set_prop_changed(plane, prop);
+}
+
+/**
+ * igt_output_replace_prop_blob:
+ * @output: output to set property on.
+ * @prop: property for which the blob will be replaced.
+ * @ptr: Pointer to contents for the property.
+ * @length: Length of contents.
+ *
+ * This function will destroy the old property blob for the given property,
+ * and will create a new property blob with the values passed to this function.
+ *
+ * The new property blob will be committed when you call igt_display_commit(),
+ * igt_display_commit2() or igt_display_commit_atomic().
+ */
+void
+igt_output_replace_prop_blob(igt_output_t *output, enum igt_atomic_connector_properties prop, const void *ptr, size_t length)
+{
+	igt_display_t *display = output->display;
+	uint64_t *blob = &output->values[prop];
+	uint32_t blob_id = 0;
+
+	if (*blob != 0)
+		igt_assert(drmModeDestroyPropertyBlob(display->drm_fd,
+						      *blob) == 0);
+
+	if (length > 0)
+		igt_assert(drmModeCreatePropertyBlob(display->drm_fd,
+						     ptr, length, &blob_id) == 0);
+
+	*blob = blob_id;
+	igt_output_set_prop_changed(output, prop);
+}
+
+/**
+ * igt_pipe_obj_replace_prop_blob:
+ * @pipe: pipe to set property on.
+ * @prop: property for which the blob will be replaced.
+ * @ptr: Pointer to contents for the property.
+ * @length: Length of contents.
+ *
+ * This function will destroy the old property blob for the given property,
+ * and will create a new property blob with the values passed to this function.
+ *
+ * The new property blob will be committed when you call igt_display_commit(),
+ * igt_display_commit2() or igt_display_commit_atomic().
+ *
+ * Please use igt_output_override_mode() if you want to set #IGT_CRTC_MODE_ID,
+ * it works better with legacy commit.
+ */
+void
+igt_pipe_obj_replace_prop_blob(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop, const void *ptr, size_t length)
 {
 	igt_display_t *display = pipe->display;
 	uint64_t *blob = &pipe->values[prop];
@@ -2836,7 +2916,7 @@ void igt_output_override_mode(igt_output_t *output, drmModeModeInfo *mode)
 
 	if (pipe) {
 		if (output->display->is_atomic)
-			igt_pipe_replace_blob(pipe, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(*mode));
+			igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(*mode));
 		else
 			igt_pipe_obj_set_prop_changed(pipe, IGT_CRTC_MODE_ID);
 	}
@@ -2865,7 +2945,7 @@ void igt_output_set_pipe(igt_output_t *output, enum pipe pipe)
 		old_output = igt_pipe_get_output(old_pipe);
 		if (!old_output) {
 			if (display->is_atomic)
-				igt_pipe_replace_blob(old_pipe, IGT_CRTC_MODE_ID, NULL, 0);
+				igt_pipe_obj_replace_prop_blob(old_pipe, IGT_CRTC_MODE_ID, NULL, 0);
 			else
 				igt_pipe_obj_set_prop_changed(old_pipe, IGT_CRTC_MODE_ID);
 
@@ -2879,7 +2959,7 @@ void igt_output_set_pipe(igt_output_t *output, enum pipe pipe)
 
 	if (pipe_obj) {
 		if (display->is_atomic)
-			igt_pipe_replace_blob(pipe_obj, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(drmModeModeInfo));
+			igt_pipe_obj_replace_prop_blob(pipe_obj, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(drmModeModeInfo));
 		else
 			igt_pipe_obj_set_prop_changed(pipe_obj, IGT_CRTC_MODE_ID);
 
@@ -2908,18 +2988,11 @@ void igt_pipe_refresh(igt_display_t *display, enum pipe pipe, bool force)
 
 		pipe_obj->values[IGT_CRTC_MODE_ID] = 0;
 		if (output)
-			igt_pipe_replace_blob(pipe_obj, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(drmModeModeInfo));
+			igt_pipe_obj_replace_prop_blob(pipe_obj, IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(drmModeModeInfo));
 	} else
 		igt_pipe_obj_set_prop_changed(pipe_obj, IGT_CRTC_MODE_ID);
 }
 
-void igt_output_set_scaling_mode(igt_output_t *output, uint64_t scaling_mode)
-{
-	igt_output_set_prop_value(output, IGT_CONNECTOR_SCALING_MODE, scaling_mode);
-
-	igt_require(output->props[IGT_CONNECTOR_SCALING_MODE]);
-}
-
 igt_plane_t *igt_output_get_plane(igt_output_t *output, int plane_idx)
 {
 	igt_pipe_t *pipe;
@@ -3119,24 +3192,6 @@ void igt_pipe_request_out_fence(igt_pipe_t *pipe)
 	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
 }
 
-void
-igt_pipe_set_degamma_lut(igt_pipe_t *pipe, void *ptr, size_t length)
-{
-	igt_pipe_replace_blob(pipe, IGT_CRTC_DEGAMMA_LUT, ptr, length);
-}
-
-void
-igt_pipe_set_ctm_matrix(igt_pipe_t *pipe, void *ptr, size_t length)
-{
-	igt_pipe_replace_blob(pipe, IGT_CRTC_CTM, ptr, length);
-}
-
-void
-igt_pipe_set_gamma_lut(igt_pipe_t *pipe, void *ptr, size_t length)
-{
-	igt_pipe_replace_blob(pipe, IGT_CRTC_GAMMA_LUT, ptr, length);
-}
-
 /**
  * igt_crtc_set_background:
  * @pipe: pipe pointer to which background color to be set
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index b53127ffef5f..2e4c23437f4e 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -366,7 +366,6 @@ const char *igt_output_name(igt_output_t *output);
 drmModeModeInfo *igt_output_get_mode(igt_output_t *output);
 void igt_output_override_mode(igt_output_t *output, drmModeModeInfo *mode);
 void igt_output_set_pipe(igt_output_t *output, enum pipe pipe);
-void igt_output_set_scaling_mode(igt_output_t *output, uint64_t scaling_mode);
 igt_plane_t *igt_output_get_plane(igt_output_t *output, int plane_idx);
 igt_plane_t *igt_output_get_plane_type(igt_output_t *output, int plane_type);
 igt_output_t *igt_output_from_connector(igt_display_t *display,
@@ -381,9 +380,6 @@ static inline bool igt_plane_supports_rotation(igt_plane_t *plane)
 	return plane->props[IGT_PLANE_ROTATION] != 0;
 }
 void igt_pipe_request_out_fence(igt_pipe_t *pipe);
-void igt_pipe_set_degamma_lut(igt_pipe_t *pipe, void *ptr, size_t length);
-void igt_pipe_set_ctm_matrix(igt_pipe_t *pipe, void *ptr, size_t length);
-void igt_pipe_set_gamma_lut(igt_pipe_t *pipe, void *ptr, size_t length);
 
 void igt_plane_set_fb(igt_plane_t *plane, struct igt_fb *fb);
 void igt_plane_set_fence_fd(igt_plane_t *plane, int fence_fd);
@@ -513,6 +509,10 @@ static inline bool igt_output_is_connected(igt_output_t *output)
 		igt_plane_set_prop_changed(plane, prop); \
 	} while (0)
 
+extern void igt_plane_replace_prop_blob(igt_plane_t *plane,
+					enum igt_atomic_plane_properties prop,
+					const void *ptr, size_t length);
+
 #define igt_output_is_prop_changed(output, prop) \
 	(!!((output)->changed & (1 << (prop))))
 #define igt_output_set_prop_changed(output, prop) \
@@ -527,6 +527,10 @@ static inline bool igt_output_is_connected(igt_output_t *output)
 		igt_output_set_prop_changed(output, prop); \
 	} while (0)
 
+extern void igt_output_replace_prop_blob(igt_output_t *output,
+					 enum igt_atomic_connector_properties prop,
+					 const void *ptr, size_t length);
+
 #define igt_pipe_obj_is_prop_changed(pipe_obj, prop) \
 	(!!((pipe_obj)->changed & (1 << (prop))))
 
@@ -554,6 +558,13 @@ static inline bool igt_output_is_connected(igt_output_t *output)
 #define igt_pipe_set_prop_value(display, pipe, prop, value) \
 	igt_pipe_obj_set_prop_value(&(display)->pipes[(pipe)], prop, value)
 
+extern void igt_pipe_obj_replace_prop_blob(igt_pipe_t *pipe_obj,
+					   enum igt_atomic_crtc_properties prop,
+					   const void *ptr, size_t length);
+
+#define igt_pipe_replace_prop_blob(display, pipe, prop, ptr, length) \
+	igt_pipe_obj_replace_prop_blob(&(display)->pipes[(pipe)], prop, ptr, length)
+
 void igt_pipe_refresh(igt_display_t *display, enum pipe pipe, bool force);
 
 void igt_enable_connectors(void);
diff --git a/tests/chamelium.c b/tests/chamelium.c
index e3d81357b32b..ae164920e86e 100644
--- a/tests/chamelium.c
+++ b/tests/chamelium.c
@@ -462,9 +462,9 @@ enable_output(data_t *data,
 	igt_output_set_pipe(output, output->config.pipe);
 
 	/* Clear any color correction values that might be enabled */
-	igt_pipe_set_degamma_lut(primary->pipe, NULL, 0);
-	igt_pipe_set_gamma_lut(primary->pipe, NULL, 0);
-	igt_pipe_set_ctm_matrix(primary->pipe, NULL, 0);
+	igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_DEGAMMA_LUT, NULL, 0);
+	igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_GAMMA_LUT, NULL, 0);
+	igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_CTM, NULL, 0);
 
 	kmstest_set_connector_broadcast_rgb(display->drm_fd, connector,
 					    BROADCAST_RGB_FULL);
diff --git a/tests/kms_color.c b/tests/kms_color.c
index bcd48d89875c..e30e6bf4e409 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -189,7 +189,7 @@ static void set_degamma(data_t *data,
 						   data->degamma_lut_size,
 						   data->color_depth, 0);
 
-	igt_pipe_set_degamma_lut(pipe, lut, size);
+	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_DEGAMMA_LUT, lut, size);
 
 	free(lut);
 }
@@ -204,7 +204,7 @@ static void set_gamma(data_t *data,
 						   data->gamma_lut_size,
 						   data->color_depth, 0);
 
-	igt_pipe_set_gamma_lut(pipe, lut, size);
+		igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_GAMMA_LUT, lut, size);
 
 	free(lut);
 }
@@ -224,12 +224,12 @@ static void set_ctm(igt_pipe_t *pipe, const double *coefficients)
 				(int64_t) (coefficients[i] * ((int64_t) 1L << 32));
 	}
 
-	igt_pipe_set_ctm_matrix(pipe, &ctm, sizeof(ctm));
+	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_CTM, &ctm, sizeof(ctm));
 }
 
-#define disable_degamma(pipe) igt_pipe_set_degamma_lut(pipe, NULL, 0)
-#define disable_gamma(pipe) igt_pipe_set_gamma_lut(pipe, NULL, 0)
-#define disable_ctm(pipe) igt_pipe_set_ctm_matrix(pipe, NULL, 0)
+#define disable_degamma(pipe) igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_DEGAMMA_LUT, NULL, 0)
+#define disable_gamma(pipe) igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_GAMMA_LUT, NULL, 0)
+#define disable_ctm(pipe) igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_CTM, NULL, 0)
 
 static void output_set_property_enum(igt_output_t *output,
 				     const char *property,
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH i-g-t v2 07/14] lib/igt_kms: Unexport broadcast rgb API.
  2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
                   ` (5 preceding siblings ...)
  2017-10-12 11:54 ` [PATCH i-g-t v2 06/14] lib/igt_kms: Export property blob functions for output/pipe/plane, v2 Maarten Lankhorst
@ 2017-10-12 11:54 ` Maarten Lankhorst
  2017-10-19 11:28   ` Mika Kahola
  2017-10-12 11:54 ` [PATCH i-g-t v2 08/14] lib/igt_kms: Add igt_$obj_has_prop functions Maarten Lankhorst
                   ` (10 subsequent siblings)
  17 siblings, 1 reply; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-12 11:54 UTC (permalink / raw)
  To: intel-gfx

Setting broadcast rgb was only used by chamelium, but is now handled
in igt_display by default. This means that chamelium doesn't need to
set it, and this can be hidden. The broadcast RGB property is intel
connector specific, so rename the enum to intel_broadcast_rgb_mode.

Keep the property and enum public in case someone wants to test the
property later.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 lib/igt_kms.c     | 44 ++++++--------------------------------------
 lib/igt_kms.h     |  7 +++----
 tests/chamelium.c |  3 ---
 3 files changed, 9 insertions(+), 45 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 5f54021350ac..ad0855d0c8fa 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -187,7 +187,8 @@ const char *igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
 const char *igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
 	"scaling mode",
 	"CRTC_ID",
-	"DPMS"
+	"DPMS",
+	"Broadcast RGB"
 };
 
 /*
@@ -1037,40 +1038,6 @@ void kmstest_set_connector_dpms(int fd, drmModeConnector *connector, int mode)
 					       dpms, mode) == 0);
 }
 
-/**
- * kmstest_set_connector_broadcast_rgb:
- * @fd: DRM fd
- * @connector: libdrm connector
- * @mode: Broadcast RGB mode
- *
- * This function sets the Broadcast RGB prop of @connector to @mode, if there
- * is one.
- *
- * Returns: true if we found and set the Broadcast RGB prop, false otherwise
- */
-bool kmstest_set_connector_broadcast_rgb(int fd, drmModeConnector *connector,
-					 enum kmstest_broadcast_rgb_mode mode)
-{
-	uint32_t prop_id;
-	int ret;
-
-	ret = kmstest_get_property(fd, connector->connector_id,
-				   DRM_MODE_OBJECT_CONNECTOR, "Broadcast RGB",
-				   &prop_id, NULL, NULL);
-	if (!ret) {
-		igt_debug("Broadcast RGB property not found on %d\n",
-			  connector->connector_id);
-		return false;
-	}
-
-	igt_debug("Setting Broadcast RGB mode on connector %d to %d\n",
-		  connector->connector_id, mode);
-	ret = drmModeConnectorSetProperty(fd, connector->connector_id, prop_id,
-					  mode);
-
-	return ret == 0;
-}
-
 /**
  * kmstest_get_property:
  * @drm_fd: drm file descriptor
@@ -1583,9 +1550,10 @@ static void igt_output_refresh(igt_output_t *output)
 		igt_atomic_fill_connector_props(display, output,
 			IGT_NUM_CONNECTOR_PROPS, igt_connector_prop_names);
 
-		kmstest_set_connector_broadcast_rgb(display->drm_fd,
-						    output->config.connector,
-						    BROADCAST_RGB_FULL);
+		if (output->props[IGT_CONNECTOR_BROADCAST_RGB])
+			igt_output_set_prop_value(output,
+						  IGT_CONNECTOR_BROADCAST_RGB,
+						  BROADCAST_RGB_FULL);
 	}
 
 	LOG(display, "%s: Selecting pipe %s\n", output->name,
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 2e4c23437f4e..b8a04af73e2f 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -115,6 +115,7 @@ enum igt_atomic_connector_properties {
        IGT_CONNECTOR_SCALING_MODE = 0,
        IGT_CONNECTOR_CRTC_ID,
        IGT_CONNECTOR_DPMS,
+       IGT_CONNECTOR_BROADCAST_RGB,
        IGT_NUM_CONNECTOR_PROPS
 };
 
@@ -171,13 +172,13 @@ enum kmstest_force_connector_state {
 };
 
 /**
- * kmstest_broadcast_rgb_mode:
+ * intel_broadcast_rgb_mode:
  * @BROADCAST_RGB_AUTO: Choose the color range to use automatically
  * @BROADCAST_RGB_FULL: Force the connector to use full color range
  * @BROADCAST_RGB_16_235: Force the connector to use a limited 16:235 color
  * range
  */
-enum kmstest_broadcast_rgb_mode {
+enum intel_broadcast_rgb_mode {
 	BROADCAST_RGB_AUTO = 0,
 	BROADCAST_RGB_FULL,
 	BROADCAST_RGB_16_235
@@ -203,8 +204,6 @@ bool kmstest_probe_connector_config(int drm_fd, uint32_t connector_id,
 void kmstest_free_connector_config(struct kmstest_connector_config *config);
 
 void kmstest_set_connector_dpms(int fd, drmModeConnector *connector, int mode);
-bool kmstest_set_connector_broadcast_rgb(int fd, drmModeConnector *connector,
-					 enum kmstest_broadcast_rgb_mode mode);
 bool kmstest_get_property(int drm_fd, uint32_t object_id, uint32_t object_type,
 			  const char *name, uint32_t *prop_id, uint64_t *value,
 			  drmModePropertyPtr *prop);
diff --git a/tests/chamelium.c b/tests/chamelium.c
index ae164920e86e..4ad29f9d178a 100644
--- a/tests/chamelium.c
+++ b/tests/chamelium.c
@@ -466,9 +466,6 @@ enable_output(data_t *data,
 	igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_GAMMA_LUT, NULL, 0);
 	igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_CTM, NULL, 0);
 
-	kmstest_set_connector_broadcast_rgb(display->drm_fd, connector,
-					    BROADCAST_RGB_FULL);
-
 	igt_display_commit(display);
 
 	if (chamelium_port_get_type(port) == DRM_MODE_CONNECTOR_VGA)
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH i-g-t v2 08/14] lib/igt_kms: Add igt_$obj_has_prop functions
  2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
                   ` (6 preceding siblings ...)
  2017-10-12 11:54 ` [PATCH i-g-t v2 07/14] lib/igt_kms: Unexport broadcast rgb API Maarten Lankhorst
@ 2017-10-12 11:54 ` Maarten Lankhorst
  2017-10-12 15:33   ` [PATCH i-g-t v2] lib/igt_kms: Add igt_$obj_has_prop functions, v2 Maarten Lankhorst
  2017-10-12 11:54 ` [PATCH i-g-t v2 09/14] lib/igt_kms: Add igt_$obj_get_prop functions Maarten Lankhorst
                   ` (9 subsequent siblings)
  17 siblings, 1 reply; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-12 11:54 UTC (permalink / raw)
  To: intel-gfx

This allows test to test whether a property is supported, in
a nice and clean way. It removes the need for special case
functions like igt_plane_supports_rotation.

Convert the users of igt_plane_supports_rotation and remove the
extra check in drm_plane_commit, this is already checked below
when setting plane properties.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 lib/igt_kms.c                     |  4 ---
 lib/igt_kms.h                     | 62 ++++++++++++++++++++++++++++++++++++---
 tests/kms_crtc_background_color.c |  2 +-
 tests/kms_rotation_crc.c          |  6 ++--
 4 files changed, 62 insertions(+), 12 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index ad0855d0c8fa..339c11843154 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -2110,10 +2110,6 @@ static int igt_drm_plane_commit(igt_plane_t *plane,
 
 	igt_assert(plane->drm_plane);
 
-	/* it's an error to try an unsupported feature */
-	igt_assert(igt_plane_supports_rotation(plane) ||
-		   !igt_plane_is_prop_changed(plane, IGT_PLANE_ROTATION));
-
 	fb_id = igt_plane_get_fb_id(plane);
 	crtc_id = pipe->crtc_id;
 
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index b8a04af73e2f..916cd359519a 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -374,10 +374,6 @@ bool igt_pipe_get_property(igt_pipe_t *pipe, const char *name,
 			   uint32_t *prop_id, uint64_t *value,
 			   drmModePropertyPtr *prop);
 
-static inline bool igt_plane_supports_rotation(igt_plane_t *plane)
-{
-	return plane->props[IGT_PLANE_ROTATION] != 0;
-}
 void igt_pipe_request_out_fence(igt_pipe_t *pipe);
 
 void igt_plane_set_fb(igt_plane_t *plane, struct igt_fb *fb);
@@ -493,6 +489,20 @@ static inline bool igt_output_is_connected(igt_output_t *output)
 
 #define IGT_FIXED(i,f)	((i) << 16 | (f))
 
+/**
+ * igt_plane_has_prop - Check whether plane supports a given property.
+ *
+ * @plane: Plane to check.
+ * @prop: Property to check.
+ *
+ * Returns: True if the property is supported, otherwise false.
+ */
+static inline bool
+igt_plane_has_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop)
+{
+	return plane->props[prop];
+}
+
 #define igt_plane_is_prop_changed(plane, prop) \
 	(!!((plane)->changed & (1 << (prop))))
 
@@ -512,6 +522,20 @@ extern void igt_plane_replace_prop_blob(igt_plane_t *plane,
 					enum igt_atomic_plane_properties prop,
 					const void *ptr, size_t length);
 
+/**
+ * igt_output_has_prop - Check whether output supports a given property.
+ *
+ * @output: Output to check.
+ * @prop: Property to check.
+ *
+ * Returns: True if the property is supported, otherwise false.
+ */
+static inline bool
+igt_output_has_prop(igt_output_t *output, enum igt_atomic_connector_properties prop)
+{
+	return output->props[prop];
+}
+
 #define igt_output_is_prop_changed(output, prop) \
 	(!!((output)->changed & (1 << (prop))))
 #define igt_output_set_prop_changed(output, prop) \
@@ -530,6 +554,36 @@ extern void igt_output_replace_prop_blob(igt_output_t *output,
 					 enum igt_atomic_connector_properties prop,
 					 const void *ptr, size_t length);
 
+/**
+ * igt_pipe_obj_has_prop - Check whether pipe supports a given property.
+ *
+ * @pipe: Pipe to check.
+ * @prop: Property to check.
+ *
+ * Returns: True if the property is supported, otherwise false.
+ */
+static inline bool
+igt_pipe_obj_has_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
+{
+	return pipe->props[prop];
+}
+
+/**
+ * igt_pipe_has_prop - Check whether pipe supports a given property.
+ *
+ * @display: Pointer to display.
+ * @pipe: Pipe to check.
+ * @prop: Property to check.
+ *
+ * Returns: True if the property is supported, otherwise false.
+ */
+static inline bool
+igt_pipe_has_prop(igt_display_t *display, enum pipe pipe,
+		  enum igt_atomic_connector_properties prop)
+{
+	return display->pipes[pipe].props[prop];
+}
+
 #define igt_pipe_obj_is_prop_changed(pipe_obj, prop) \
 	(!!((pipe_obj)->changed & (1 << (prop))))
 
diff --git a/tests/kms_crtc_background_color.c b/tests/kms_crtc_background_color.c
index 659a30b90219..414cc82f3e8b 100644
--- a/tests/kms_crtc_background_color.c
+++ b/tests/kms_crtc_background_color.c
@@ -137,7 +137,7 @@ static void test_crtc_background(data_t *data)
 		igt_output_set_pipe(output, pipe);
 
 		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
-		igt_require(plane->pipe->props[IGT_CRTC_BACKGROUND]);
+		igt_require(igt_plane_has_prop(plane, IGT_CRTC_BACKGROUND));
 
 		prepare_crtc(data, output, pipe, plane, 1, PURPLE, BLACK64);
 
diff --git a/tests/kms_rotation_crc.c b/tests/kms_rotation_crc.c
index b8327dfa0d83..27d1f8060234 100644
--- a/tests/kms_rotation_crc.c
+++ b/tests/kms_rotation_crc.c
@@ -351,7 +351,7 @@ static void test_plane_rotation(data_t *data, int plane_type)
 		igt_output_set_pipe(output, pipe);
 
 		plane = igt_output_get_plane_type(output, plane_type);
-		igt_require(igt_plane_supports_rotation(plane));
+		igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
 
 		prepare_crtc(data, output, pipe, plane, commit);
 
@@ -438,7 +438,7 @@ static void test_plane_rotation_ytiled_obj(data_t *data,
 	int ret;
 
 	plane = igt_output_get_plane_type(output, plane_type);
-	igt_require(igt_plane_supports_rotation(plane));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
 
 	if (plane_type == DRM_PLANE_TYPE_PRIMARY || plane_type == DRM_PLANE_TYPE_CURSOR)
 		commit = COMMIT_UNIVERSAL;
@@ -504,7 +504,7 @@ static void test_plane_rotation_exhaust_fences(data_t *data,
 	int i, ret;
 
 	plane = igt_output_get_plane_type(output, plane_type);
-	igt_require(igt_plane_supports_rotation(plane));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
 
 	if (plane_type == DRM_PLANE_TYPE_PRIMARY || plane_type == DRM_PLANE_TYPE_CURSOR)
 		commit = COMMIT_UNIVERSAL;
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH i-g-t v2 09/14] lib/igt_kms: Add igt_$obj_get_prop functions
  2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
                   ` (7 preceding siblings ...)
  2017-10-12 11:54 ` [PATCH i-g-t v2 08/14] lib/igt_kms: Add igt_$obj_has_prop functions Maarten Lankhorst
@ 2017-10-12 11:54 ` Maarten Lankhorst
  2017-10-19 12:58   ` Mika Kahola
  2017-10-12 11:54 ` [PATCH i-g-t v2 10/14] lib/igt_kms: Remove igt_pipe_get_property Maarten Lankhorst
                   ` (8 subsequent siblings)
  17 siblings, 1 reply; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-12 11:54 UTC (permalink / raw)
  To: intel-gfx

Some tests need to get the current kernel value for properties
as part of the test. Add get_prop functions that will retrieve
the current kernel value.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 lib/igt_kms.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_kms.h | 24 ++++++++++++++++++
 2 files changed, 105 insertions(+)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 339c11843154..176e6825a492 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -2407,6 +2407,51 @@ static int igt_output_commit(igt_output_t *output,
 	return 0;
 }
 
+static uint64_t igt_mode_object_get_prop(igt_display_t *display,
+					 uint32_t object_type,
+					 uint32_t object_id,
+					 uint32_t prop)
+{
+	drmModeObjectPropertiesPtr proplist;
+	bool found = false;
+	int i;
+	uint64_t ret;
+
+	proplist = drmModeObjectGetProperties(display->drm_fd, object_id, object_type);
+	for (i = 0; i < proplist->count_props; i++) {
+		if (proplist->props[i] != prop)
+			continue;
+
+		found = true;
+		break;
+	}
+
+	igt_assert(found);
+
+	ret = proplist->prop_values[i];
+
+	drmModeFreeObjectProperties(proplist);
+	return ret;
+}
+
+/**
+ * igt_plane_get_prop - Return current value on a plane for a given property.
+ *
+ * @plane: Target plane.
+ * @prop: Property to check.
+ *
+ * Returns: The value the property is set to, if this
+ * is a blob, the blob id is returned. This can be passed
+ * to drmModeGetPropertyBlob() to get the contents of the blob.
+ */
+uint64_t igt_plane_get_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop)
+{
+	igt_assert(igt_plane_has_prop(plane, prop));
+
+	return igt_mode_object_get_prop(plane->pipe->display, DRM_MODE_OBJECT_PLANE,
+					plane->drm_plane->plane_id, plane->props[prop]);
+}
+
 /**
  * igt_plane_replace_prop_blob:
  * @plane: plane to set property on.
@@ -2439,6 +2484,24 @@ igt_plane_replace_prop_blob(igt_plane_t *plane, enum igt_atomic_plane_properties
 	igt_plane_set_prop_changed(plane, prop);
 }
 
+/**
+ * igt_output_get_prop - Return current value on an output for a given property.
+ *
+ * @output: Target output.
+ * @prop: Property to return.
+ *
+ * Returns: The value the property is set to, if this
+ * is a blob, the blob id is returned. This can be passed
+ * to drmModeGetPropertyBlob() to get the contents of the blob.
+ */
+uint64_t igt_output_get_prop(igt_output_t *output, enum igt_atomic_connector_properties prop)
+{
+	igt_assert(igt_output_has_prop(output, prop));
+
+	return igt_mode_object_get_prop(output->display, DRM_MODE_OBJECT_CONNECTOR,
+					output->id, output->props[prop]);
+}
+
 /**
  * igt_output_replace_prop_blob:
  * @output: output to set property on.
@@ -2471,6 +2534,24 @@ igt_output_replace_prop_blob(igt_output_t *output, enum igt_atomic_connector_pro
 	igt_output_set_prop_changed(output, prop);
 }
 
+/**
+ * igt_pipe_obj_get_prop - Return current value on a pipe for a given property.
+ *
+ * @pipe: Target pipe.
+ * @prop: Property to return.
+ *
+ * Returns: The value the property is set to, if this
+ * is a blob, the blob id is returned. This can be passed
+ * to drmModeGetPropertyBlob() to get the contents of the blob.
+ */
+uint64_t igt_pipe_obj_get_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
+{
+	igt_assert(igt_pipe_obj_has_prop(pipe, prop));
+
+	return igt_mode_object_get_prop(pipe->display, DRM_MODE_OBJECT_CRTC,
+					pipe->crtc_id, pipe->props[prop]);
+}
+
 /**
  * igt_pipe_obj_replace_prop_blob:
  * @pipe: pipe to set property on.
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 916cd359519a..fda94cb640de 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -503,6 +503,8 @@ igt_plane_has_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop)
 	return plane->props[prop];
 }
 
+uint64_t igt_plane_get_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop);
+
 #define igt_plane_is_prop_changed(plane, prop) \
 	(!!((plane)->changed & (1 << (prop))))
 
@@ -536,6 +538,8 @@ igt_output_has_prop(igt_output_t *output, enum igt_atomic_connector_properties p
 	return output->props[prop];
 }
 
+uint64_t igt_output_get_prop(igt_output_t *output, enum igt_atomic_connector_properties prop);
+
 #define igt_output_is_prop_changed(output, prop) \
 	(!!((output)->changed & (1 << (prop))))
 #define igt_output_set_prop_changed(output, prop) \
@@ -568,6 +572,26 @@ igt_pipe_obj_has_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
 	return pipe->props[prop];
 }
 
+uint64_t igt_pipe_obj_get_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop);
+
+/**
+ * igt_pipe_get_prop - Return current value on a pipe for a given property.
+ *
+ * @display: Pointer to display.
+ * @pipe: Target pipe.
+ * @prop: Property to return.
+ *
+ * Returns: The value the property is set to, if this
+ * is a blob, the blob id is returned. This can be passed
+ * to drmModeGetPropertyBlob() to get the contents of the blob.
+ */
+static inline uint64_t
+igt_pipe_get_prop(igt_display_t *display, enum pipe pipe,
+		  enum igt_atomic_crtc_properties prop)
+{
+	return igt_pipe_obj_get_prop(&display->pipes[pipe], prop);
+}
+
 /**
  * igt_pipe_has_prop - Check whether pipe supports a given property.
  *
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH i-g-t v2 10/14] lib/igt_kms: Remove igt_pipe_get_property
  2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
                   ` (8 preceding siblings ...)
  2017-10-12 11:54 ` [PATCH i-g-t v2 09/14] lib/igt_kms: Add igt_$obj_get_prop functions Maarten Lankhorst
@ 2017-10-12 11:54 ` Maarten Lankhorst
  2017-10-19 13:18   ` Mika Kahola
  2017-10-12 11:54 ` [PATCH i-g-t v2 11/14] lib/igt_kms: Remove igt_crtc_set_background() Maarten Lankhorst
                   ` (7 subsequent siblings)
  17 siblings, 1 reply; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-12 11:54 UTC (permalink / raw)
  To: intel-gfx

igt_pipe_get_property has been replaced by igt_pipe_obj_get_prop.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 lib/igt_kms.c | 10 ----------
 lib/igt_kms.h |  3 ---
 2 files changed, 13 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 176e6825a492..70b104b24f8d 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -2009,16 +2009,6 @@ static igt_output_t *igt_pipe_get_output(igt_pipe_t *pipe)
 	return NULL;
 }
 
-bool igt_pipe_get_property(igt_pipe_t *pipe, const char *name,
-			   uint32_t *prop_id, uint64_t *value,
-			   drmModePropertyPtr *prop)
-{
-	return get_crtc_property(pipe->display->drm_fd,
-				 pipe->crtc_id,
-				 name,
-				 prop_id, value, prop);
-}
-
 static uint32_t igt_plane_get_fb_id(igt_plane_t *plane)
 {
 	return plane->values[IGT_PLANE_FB_ID];
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index fda94cb640de..dbba0cd53a25 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -370,9 +370,6 @@ igt_plane_t *igt_output_get_plane_type(igt_output_t *output, int plane_type);
 igt_output_t *igt_output_from_connector(igt_display_t *display,
     drmModeConnector *connector);
 igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
-bool igt_pipe_get_property(igt_pipe_t *pipe, const char *name,
-			   uint32_t *prop_id, uint64_t *value,
-			   drmModePropertyPtr *prop);
 
 void igt_pipe_request_out_fence(igt_pipe_t *pipe);
 
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH i-g-t v2 11/14] lib/igt_kms: Remove igt_crtc_set_background()
  2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
                   ` (9 preceding siblings ...)
  2017-10-12 11:54 ` [PATCH i-g-t v2 10/14] lib/igt_kms: Remove igt_pipe_get_property Maarten Lankhorst
@ 2017-10-12 11:54 ` Maarten Lankhorst
  2017-10-20  6:33   ` Mika Kahola
  2017-10-12 11:54 ` [PATCH i-g-t v2 12/14] tests/kms_color: Rework tests slightly to work better with new atomic api Maarten Lankhorst
                   ` (6 subsequent siblings)
  17 siblings, 1 reply; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-12 11:54 UTC (permalink / raw)
  To: intel-gfx

This can be handled by generic properties.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 lib/igt_kms.c                     | 21 ---------------------
 lib/igt_kms.h                     |  1 -
 tests/kms_crtc_background_color.c | 18 +++++++++---------
 3 files changed, 9 insertions(+), 31 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 70b104b24f8d..9cf4b68f4191 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -3227,27 +3227,6 @@ void igt_pipe_request_out_fence(igt_pipe_t *pipe)
 	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)&pipe->out_fence_fd);
 }
 
-/**
- * igt_crtc_set_background:
- * @pipe: pipe pointer to which background color to be set
- * @background: background color value in BGR 16bpc
- *
- * Sets background color for requested pipe. Color value provided here
- * will be actually submitted at output commit time via "background_color"
- * property.
- * For example to get red as background, set background = 0x00000000FFFF.
- */
-void igt_crtc_set_background(igt_pipe_t *pipe, uint64_t background)
-{
-	igt_display_t *display = pipe->display;
-
-	LOG(display, "%s.%d: crtc_set_background(%"PRIx64")\n",
-	    kmstest_pipe_name(pipe->pipe),
-	    pipe->pipe, background);
-
-	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_BACKGROUND, background);
-}
-
 void igt_wait_for_vblank_count(int drm_fd, enum pipe pipe, int count)
 {
 	drmVBlank wait_vbl;
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index dbba0cd53a25..e722f0be3757 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -378,7 +378,6 @@ void igt_plane_set_fence_fd(igt_plane_t *plane, int fence_fd);
 void igt_plane_set_position(igt_plane_t *plane, int x, int y);
 void igt_plane_set_size(igt_plane_t *plane, int w, int h);
 void igt_plane_set_rotation(igt_plane_t *plane, igt_rotation_t rotation);
-void igt_crtc_set_background(igt_pipe_t *pipe, uint64_t background);
 void igt_fb_set_position(struct igt_fb *fb, igt_plane_t *plane,
 	uint32_t x, uint32_t y);
 void igt_fb_set_size(struct igt_fb *fb, igt_plane_t *plane,
diff --git a/tests/kms_crtc_background_color.c b/tests/kms_crtc_background_color.c
index 414cc82f3e8b..6edb8de3bb24 100644
--- a/tests/kms_crtc_background_color.c
+++ b/tests/kms_crtc_background_color.c
@@ -97,7 +97,7 @@ static void prepare_crtc(data_t *data, igt_output_t *output, enum pipe pipe,
 	igt_assert(fb_id);
 
 	/* To make FB pixel win with background color, set alpha as full opaque */
-	igt_crtc_set_background(plane->pipe, pipe_background_color);
+	igt_pipe_set_prop_value(display, pipe, IGT_CRTC_BACKGROUND, pipe_background_color);
 	if (opaque_buffer)
 		alpha = 1.0;    /* alpha 1 is fully opque */
 	else
@@ -117,7 +117,7 @@ static void cleanup_crtc(data_t *data, igt_output_t *output, igt_plane_t *plane)
 
 	igt_remove_fb(data->gfx_fd, &data->fb);
 
-	igt_crtc_set_background(plane->pipe, BLACK64);
+	igt_pipe_obj_set_prop_value(plane->pipe, IGT_CRTC_BACKGROUND, BLACK64);
 	igt_plane_set_fb(plane, NULL);
 	igt_output_set_pipe(output, PIPE_ANY);
 
@@ -144,26 +144,26 @@ static void test_crtc_background(data_t *data)
 		/* Now set background without using a plane, i.e.,
 		 * Disable the plane to let hw background color win blend. */
 		igt_plane_set_fb(plane, NULL);
-		igt_crtc_set_background(plane->pipe, PURPLE64);
+		igt_pipe_set_prop_value(display, pipe, IGT_CRTC_BACKGROUND, PURPLE64);
 		igt_display_commit2(display, COMMIT_UNIVERSAL);
 
 		/* Try few other background colors */
-		igt_crtc_set_background(plane->pipe, CYAN64);
+		igt_pipe_set_prop_value(display, pipe, IGT_CRTC_BACKGROUND, CYAN64);
 		igt_display_commit2(display, COMMIT_UNIVERSAL);
 
-		igt_crtc_set_background(plane->pipe, YELLOW64);
+		igt_pipe_set_prop_value(display, pipe, IGT_CRTC_BACKGROUND, YELLOW64);
 		igt_display_commit2(display, COMMIT_UNIVERSAL);
 
-		igt_crtc_set_background(plane->pipe, RED64);
+		igt_pipe_set_prop_value(display, pipe, IGT_CRTC_BACKGROUND, RED64);
 		igt_display_commit2(display, COMMIT_UNIVERSAL);
 
-		igt_crtc_set_background(plane->pipe, GREEN64);
+		igt_pipe_set_prop_value(display, pipe, IGT_CRTC_BACKGROUND, GREEN64);
 		igt_display_commit2(display, COMMIT_UNIVERSAL);
 
-		igt_crtc_set_background(plane->pipe, BLUE64);
+		igt_pipe_set_prop_value(display, pipe, IGT_CRTC_BACKGROUND, BLUE64);
 		igt_display_commit2(display, COMMIT_UNIVERSAL);
 
-		igt_crtc_set_background(plane->pipe, WHITE64);
+		igt_pipe_set_prop_value(display, pipe, IGT_CRTC_BACKGROUND, WHITE64);
 		igt_display_commit2(display, COMMIT_UNIVERSAL);
 
 		valid_tests++;
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH i-g-t v2 12/14] tests/kms_color: Rework tests slightly to work better with new atomic api
  2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
                   ` (10 preceding siblings ...)
  2017-10-12 11:54 ` [PATCH i-g-t v2 11/14] lib/igt_kms: Remove igt_crtc_set_background() Maarten Lankhorst
@ 2017-10-12 11:54 ` Maarten Lankhorst
  2017-10-20  7:14   ` Mika Kahola
  2017-10-12 11:54 ` [PATCH i-g-t v2 13/14] tests/chamelium: Remove reliance on output->config.pipe Maarten Lankhorst
                   ` (5 subsequent siblings)
  17 siblings, 1 reply; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-12 11:54 UTC (permalink / raw)
  To: intel-gfx

igt_pipe_get_property is about to be removed, so use
igt_pipe_obj_get_prop instead. This requires adding 2 more properties
to the crtc property list. Also get rid of the Broadcast RGB call,
this is already handled in igt_kms.

Change order for DEGAMMA_LUT and GAMMA_LUT around, else this test will
fail if legacy gamma is set. In the legacy path, this will update
GAMMA_LUT to the new size before DEGAMMA_LUT is set.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 lib/igt_kms.c     |   4 +-
 lib/igt_kms.h     |   4 +-
 tests/kms_color.c | 217 +++++++++++++++++++-----------------------------------
 3 files changed, 83 insertions(+), 142 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 9cf4b68f4191..cb2bc2b8df98 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -177,8 +177,10 @@ const char *igt_plane_prop_names[IGT_NUM_PLANE_PROPS] = {
 const char *igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
 	"background_color",
 	"CTM",
-	"DEGAMMA_LUT",
 	"GAMMA_LUT",
+	"GAMMA_LUT_SIZE",
+	"DEGAMMA_LUT",
+	"DEGAMMA_LUT_SIZE",
 	"MODE_ID",
 	"ACTIVE",
 	"OUT_FENCE_PTR"
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index e722f0be3757..200f35e63308 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -95,8 +95,10 @@ void kmstest_restore_vt_mode(void);
 enum igt_atomic_crtc_properties {
        IGT_CRTC_BACKGROUND = 0,
        IGT_CRTC_CTM,
-       IGT_CRTC_DEGAMMA_LUT,
        IGT_CRTC_GAMMA_LUT,
+       IGT_CRTC_GAMMA_LUT_SIZE,
+       IGT_CRTC_DEGAMMA_LUT,
+       IGT_CRTC_DEGAMMA_LUT_SIZE,
        IGT_CRTC_MODE_ID,
        IGT_CRTC_ACTIVE,
        IGT_CRTC_OUT_FENCE_PTR,
diff --git a/tests/kms_color.c b/tests/kms_color.c
index e30e6bf4e409..dcda12de3a39 100644
--- a/tests/kms_color.c
+++ b/tests/kms_color.c
@@ -231,41 +231,6 @@ static void set_ctm(igt_pipe_t *pipe, const double *coefficients)
 #define disable_gamma(pipe) igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_GAMMA_LUT, NULL, 0)
 #define disable_ctm(pipe) igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_CTM, NULL, 0)
 
-static void output_set_property_enum(igt_output_t *output,
-				     const char *property,
-				     const char *enum_value)
-{
-	int i;
-	int32_t value = -1;
-	uint32_t prop_id;
-	drmModePropertyPtr prop;
-
-	if (!kmstest_get_property(output->display->drm_fd,
-				  output->id,
-				  DRM_MODE_OBJECT_CONNECTOR,
-				  property,
-				  &prop_id, NULL, &prop))
-		return;
-
-	igt_assert(prop->flags & DRM_MODE_PROP_ENUM);
-
-	for (i = 0; i < prop->count_enums; i++) {
-		if (!strcmp(prop->enums[i].name, enum_value)) {
-			value = prop->enums[i].value;
-			break;
-		}
-	}
-	igt_assert_neq(value, -1);
-
-	igt_assert_eq(drmModeObjectSetProperty(output->display->drm_fd,
-					       output->id,
-					       DRM_MODE_OBJECT_CONNECTOR,
-					       prop_id, value), 0);
-
-
-	drmModeFreeProperty(prop);
-}
-
 /*
  * Draw 3 gradient rectangles in red, green and blue, with a maxed out
  * degamma LUT and verify we have the same CRC as drawing solid color
@@ -531,23 +496,16 @@ static void test_pipe_legacy_gamma(data_t *data,
 }
 
 static drmModePropertyBlobPtr
-get_blob(data_t *data, igt_pipe_t *pipe, const char *property_name)
+get_blob(data_t *data, igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
 {
 	uint64_t prop_value;
-	drmModePropertyPtr prop;
-	drmModePropertyBlobPtr blob;
 
-	igt_assert(igt_pipe_get_property(pipe, property_name,
-					 NULL, &prop_value, &prop));
+	prop_value = igt_pipe_obj_get_prop(pipe, prop);
 
 	if (prop_value == 0)
 		return NULL;
 
-	igt_assert(prop->flags & DRM_MODE_PROP_BLOB);
-	blob = drmModeGetPropertyBlob(data->drm_fd, prop_value);
-	drmModeFreeProperty(prop);
-
-	return blob;
+	return drmModeGetPropertyBlob(data->drm_fd, prop_value);
 }
 
 /*
@@ -590,18 +548,18 @@ static void test_pipe_legacy_gamma_reset(data_t *data,
 		set_gamma(data, primary->pipe, gamma_zero);
 		igt_display_commit(&data->display);
 
-		blob = get_blob(data, primary->pipe, "DEGAMMA_LUT");
+		blob = get_blob(data, primary->pipe, IGT_CRTC_DEGAMMA_LUT);
 		igt_assert(blob &&
 			   blob->length == (sizeof(struct _drm_color_lut) *
 					    data->degamma_lut_size));
 		drmModeFreePropertyBlob(blob);
 
-		blob = get_blob(data, primary->pipe, "CTM");
+		blob = get_blob(data, primary->pipe, IGT_CRTC_CTM);
 		igt_assert(blob &&
 			   blob->length == sizeof(struct _drm_color_ctm));
 		drmModeFreePropertyBlob(blob);
 
-		blob = get_blob(data, primary->pipe, "GAMMA_LUT");
+		blob = get_blob(data, primary->pipe, IGT_CRTC_GAMMA_LUT);
 		igt_assert(blob &&
 			   blob->length == (sizeof(struct _drm_color_lut) *
 					    data->gamma_lut_size));
@@ -634,10 +592,10 @@ static void test_pipe_legacy_gamma_reset(data_t *data,
 		igt_display_commit(&data->display);
 
 		igt_assert(get_blob(data, primary->pipe,
-				    "DEGAMMA_LUT") == NULL);
-		igt_assert(get_blob(data, primary->pipe, "CTM") == NULL);
+				    IGT_CRTC_DEGAMMA_LUT) == NULL);
+		igt_assert(get_blob(data, primary->pipe, IGT_CRTC_CTM) == NULL);
 
-		blob = get_blob(data, primary->pipe, "GAMMA_LUT");
+		blob = get_blob(data, primary->pipe, IGT_CRTC_GAMMA_LUT);
 		igt_assert(blob &&
 			   blob->length == (sizeof(struct _drm_color_lut) *
 					    legacy_lut_size));
@@ -777,6 +735,7 @@ static void test_pipe_limited_range_ctm(data_t *data,
 			0.0, 0.0, 1.0 };
 	double *degamma_linear, *gamma_linear;
 	igt_output_t *output;
+	bool has_broadcast_rgb_output = false;
 
 	degamma_linear = generate_table(data->degamma_lut_size, 1.0);
 	gamma_linear = generate_table(data->gamma_lut_size, 1.0);
@@ -787,6 +746,11 @@ static void test_pipe_limited_range_ctm(data_t *data,
 		igt_crc_t crc_full, crc_limited;
 		int fb_id, fb_modeset_id;
 
+		if (!igt_output_has_prop(output, IGT_CONNECTOR_BROADCAST_RGB))
+			continue;
+
+		has_broadcast_rgb_output = true;
+
 		igt_output_set_pipe(output, primary->pipe->pipe);
 		mode = igt_output_get_mode(output);
 
@@ -812,7 +776,7 @@ static void test_pipe_limited_range_ctm(data_t *data,
 		set_gamma(data, primary->pipe, gamma_linear);
 		set_ctm(primary->pipe, ctm);
 
-		output_set_property_enum(output, "Broadcast RGB", "Full");
+		igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB, BROADCAST_RGB_FULL);
 		paint_rectangles(data, mode, red_green_blue_limited, &fb);
 		igt_plane_set_fb(primary, &fb);
 		igt_display_commit(&data->display);
@@ -820,31 +784,34 @@ static void test_pipe_limited_range_ctm(data_t *data,
 		igt_pipe_crc_collect_crc(data->pipe_crc, &crc_full);
 
 		/* Set the output into limited range. */
-		output_set_property_enum(output, "Broadcast RGB", "Limited 16:235");
+		igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB, BROADCAST_RGB_16_235);
 		paint_rectangles(data, mode, red_green_blue_full, &fb);
 		igt_plane_set_fb(primary, &fb);
 		igt_display_commit(&data->display);
 		igt_wait_for_vblank(data->drm_fd, primary->pipe->pipe);
 		igt_pipe_crc_collect_crc(data->pipe_crc, &crc_limited);
 
+		/* And reset.. */
+		igt_output_set_prop_value(output, IGT_CONNECTOR_BROADCAST_RGB, BROADCAST_RGB_FULL);
+		igt_plane_set_fb(primary, NULL);
+		igt_output_set_pipe(output, PIPE_NONE);
+
 		/* Verify that the CRC of the software computed output is
 		 * equal to the CRC of the CTM matrix transformation output.
 		 */
 		igt_assert_crc_equal(&crc_full, &crc_limited);
-
-		igt_plane_set_fb(primary, NULL);
-		igt_output_set_pipe(output, PIPE_NONE);
 	}
 
 	free(gamma_linear);
 	free(degamma_linear);
+
+	igt_require(has_broadcast_rgb_output);
 }
 #endif
 
 static void
 run_tests_for_pipe(data_t *data, enum pipe p)
 {
-	igt_output_t *output;
 	igt_pipe_t *pipe;
 	igt_plane_t *primary;
 	double delta;
@@ -856,8 +823,6 @@ run_tests_for_pipe(data_t *data, enum pipe p)
 	};
 
 	igt_fixture {
-		int valid_tests = 0;
-
 		igt_require_pipe_crc(data->drm_fd);
 
 		igt_require(p < data->display.n_pipes);
@@ -871,23 +836,18 @@ run_tests_for_pipe(data_t *data, enum pipe p)
 						  primary->pipe->pipe,
 						  INTEL_PIPE_CRC_SOURCE_AUTO);
 
-		igt_require(igt_pipe_get_property(&data->display.pipes[p],
-						  "DEGAMMA_LUT_SIZE",
-						  NULL,
-						  &data->degamma_lut_size,
-						  NULL));
-		igt_require(igt_pipe_get_property(&data->display.pipes[p],
-						  "GAMMA_LUT_SIZE",
-						  NULL,
-						  &data->gamma_lut_size,
-						  NULL));
-
-		for_each_valid_output_on_pipe(&data->display, p, output) {
-			output_set_property_enum(output, "Broadcast RGB", "Full");
-
-			valid_tests++;
-		}
-		igt_require_f(valid_tests, "no valid crtc/connector combinations found\n");
+		igt_require(igt_pipe_obj_has_prop(&data->display.pipes[p], IGT_CRTC_DEGAMMA_LUT_SIZE));
+		igt_require(igt_pipe_obj_has_prop(&data->display.pipes[p], IGT_CRTC_GAMMA_LUT_SIZE));
+
+		data->degamma_lut_size =
+			igt_pipe_obj_get_prop(&data->display.pipes[p],
+					      IGT_CRTC_DEGAMMA_LUT_SIZE);
+
+		data->gamma_lut_size =
+			igt_pipe_obj_get_prop(&data->display.pipes[p],
+					      IGT_CRTC_GAMMA_LUT_SIZE);
+
+		igt_display_require_output_on_pipe(&data->display, p);
 	}
 
 	/* We assume an 8bits depth per color for degamma/gamma LUTs
@@ -1050,9 +1010,6 @@ run_tests_for_pipe(data_t *data, enum pipe p)
 		test_pipe_legacy_gamma_reset(data, primary);
 
 	igt_fixture {
-		for_each_connected_output(&data->display, output)
-			output_set_property_enum(output, "Broadcast RGB", "Full");
-
 		disable_degamma(primary->pipe);
 		disable_gamma(primary->pipe);
 		disable_ctm(primary->pipe);
@@ -1064,93 +1021,76 @@ run_tests_for_pipe(data_t *data, enum pipe p)
 }
 
 static int
-pipe_set_property_blob_id(igt_pipe_t *pipe, const char *property, uint32_t blob_id)
+pipe_set_property_blob_id(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop, uint32_t blob_id)
 {
-	uint32_t prop_id;
-
-	igt_assert(kmstest_get_property(pipe->display->drm_fd,
-					pipe->crtc_id,
-					DRM_MODE_OBJECT_CRTC,
-					property,
-					&prop_id, NULL, NULL));
-
-	return drmModeObjectSetProperty(pipe->display->drm_fd,
-					pipe->crtc_id,
-					DRM_MODE_OBJECT_CRTC,
-					prop_id, blob_id);
-}
+	int ret;
 
-static int
-pipe_set_property_blob(igt_pipe_t *pipe, const char *property, void *ptr, size_t length)
-{
-	int ret = 0;
-	uint32_t blob_id = 0;
+	igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
 
-	if (length > 0)
-		igt_assert_eq(drmModeCreatePropertyBlob(pipe->display->drm_fd,
-							ptr, length,
-							&blob_id), 0);
+	igt_pipe_obj_set_prop_value(pipe, prop, blob_id);
 
-	ret = pipe_set_property_blob_id(pipe, property, blob_id);
+	ret = igt_display_try_commit2(pipe->display, pipe->display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
 
-	if (blob_id != 0)
-		igt_assert_eq(drmModeDestroyPropertyBlob(pipe->display->drm_fd, blob_id), 0);
+	igt_pipe_obj_set_prop_value(pipe, prop, 0);
 
 	return ret;
 }
 
+static int
+pipe_set_property_blob(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop, void *ptr, size_t length)
+{
+	igt_pipe_obj_replace_prop_blob(pipe, prop, ptr, length);
+
+	return igt_display_try_commit2(pipe->display, pipe->display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
+}
+
 static void
 invalid_lut_sizes(data_t *data)
 {
-	igt_pipe_t *pipe = &data->display.pipes[0];
+	igt_display_t *display = &data->display;
+	igt_pipe_t *pipe = &display->pipes[0];
 	size_t degamma_lut_size = data->degamma_lut_size * sizeof(struct _drm_color_lut);
 	size_t gamma_lut_size = data->gamma_lut_size * sizeof(struct _drm_color_lut);
 
 	struct _drm_color_lut *degamma_lut = malloc(data->degamma_lut_size * sizeof(struct _drm_color_lut) * 2);
 	struct _drm_color_lut *gamma_lut = malloc(data->gamma_lut_size * sizeof(struct _drm_color_lut) * 2);
 
-	if (kmstest_get_property(pipe->display->drm_fd,
-				 pipe->crtc_id,
-				 DRM_MODE_OBJECT_CRTC,
-				 "DEGAMMA_LUT",
-				 NULL, NULL, NULL)) {
-		igt_assert_eq(pipe_set_property_blob(pipe, "DEGAMMA_LUT",
+	igt_display_commit2(display, display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
+
+	if (igt_pipe_obj_has_prop(pipe, IGT_CRTC_DEGAMMA_LUT)) {
+		igt_assert_eq(pipe_set_property_blob(pipe, IGT_CRTC_DEGAMMA_LUT,
 						     degamma_lut, 1), -EINVAL);
-		igt_assert_eq(pipe_set_property_blob(pipe, "DEGAMMA_LUT",
+		igt_assert_eq(pipe_set_property_blob(pipe, IGT_CRTC_DEGAMMA_LUT,
 						     degamma_lut, degamma_lut_size + 1),
 			      -EINVAL);
-		igt_assert_eq(pipe_set_property_blob(pipe, "DEGAMMA_LUT",
+		igt_assert_eq(pipe_set_property_blob(pipe, IGT_CRTC_DEGAMMA_LUT,
 						     degamma_lut, degamma_lut_size - 1),
 			      -EINVAL);
-		igt_assert_eq(pipe_set_property_blob(pipe, "DEGAMMA_LUT",
+		igt_assert_eq(pipe_set_property_blob(pipe, IGT_CRTC_DEGAMMA_LUT,
 						     degamma_lut, degamma_lut_size + sizeof(struct _drm_color_lut)),
 			      -EINVAL);
-		igt_assert_eq(pipe_set_property_blob_id(pipe, "DEGAMMA_LUT", pipe->crtc_id),
+		igt_assert_eq(pipe_set_property_blob_id(pipe, IGT_CRTC_DEGAMMA_LUT, pipe->crtc_id),
 			      -EINVAL);
-		igt_assert_eq(pipe_set_property_blob_id(pipe, "DEGAMMA_LUT", 4096 * 4096),
+		igt_assert_eq(pipe_set_property_blob_id(pipe, IGT_CRTC_DEGAMMA_LUT, 4096 * 4096),
 			      -EINVAL);
 	}
 
-	if (kmstest_get_property(pipe->display->drm_fd,
-				 pipe->crtc_id,
-				 DRM_MODE_OBJECT_CRTC,
-				 "GAMMA_LUT",
-				 NULL, NULL, NULL)) {
-		igt_assert_eq(pipe_set_property_blob(pipe, "GAMMA_LUT",
+	if (igt_pipe_obj_has_prop(pipe, IGT_CRTC_GAMMA_LUT)) {
+		igt_assert_eq(pipe_set_property_blob(pipe, IGT_CRTC_GAMMA_LUT,
 						     gamma_lut, 1),
 			      -EINVAL);
-		igt_assert_eq(pipe_set_property_blob(pipe, "GAMMA_LUT",
+		igt_assert_eq(pipe_set_property_blob(pipe, IGT_CRTC_GAMMA_LUT,
 						     gamma_lut, gamma_lut_size + 1),
 			      -EINVAL);
-		igt_assert_eq(pipe_set_property_blob(pipe, "GAMMA_LUT",
+		igt_assert_eq(pipe_set_property_blob(pipe, IGT_CRTC_GAMMA_LUT,
 						     gamma_lut, gamma_lut_size - 1),
 			      -EINVAL);
-		igt_assert_eq(pipe_set_property_blob(pipe, "GAMMA_LUT",
+		igt_assert_eq(pipe_set_property_blob(pipe, IGT_CRTC_GAMMA_LUT,
 						     gamma_lut, gamma_lut_size + sizeof(struct _drm_color_lut)),
 			      -EINVAL);
-		igt_assert_eq(pipe_set_property_blob_id(pipe, "GAMMA_LUT", pipe->crtc_id),
+		igt_assert_eq(pipe_set_property_blob_id(pipe, IGT_CRTC_GAMMA_LUT, pipe->crtc_id),
 			      -EINVAL);
-		igt_assert_eq(pipe_set_property_blob_id(pipe, "GAMMA_LUT", 4096 * 4096),
+		igt_assert_eq(pipe_set_property_blob_id(pipe, IGT_CRTC_GAMMA_LUT, 4096 * 4096),
 			      -EINVAL);
 	}
 
@@ -1161,32 +1101,29 @@ invalid_lut_sizes(data_t *data)
 static void
 invalid_ctm_matrix_sizes(data_t *data)
 {
-	igt_pipe_t *pipe = &data->display.pipes[0];
+	igt_display_t *display = &data->display;
+	igt_pipe_t *pipe = &display->pipes[0];
 	void *ptr;
 
-	if (!kmstest_get_property(pipe->display->drm_fd,
-				  pipe->crtc_id,
-				  DRM_MODE_OBJECT_CRTC,
-				  "CTM",
-				  NULL, NULL, NULL))
+	if (!igt_pipe_obj_has_prop(pipe, IGT_CRTC_CTM))
 		return;
 
 	ptr = malloc(sizeof(struct _drm_color_ctm) * 4);
 
-	igt_assert_eq(pipe_set_property_blob(pipe, "CTM", ptr, 1),
+	igt_assert_eq(pipe_set_property_blob(pipe, IGT_CRTC_CTM, ptr, 1),
 		      -EINVAL);
-	igt_assert_eq(pipe_set_property_blob(pipe, "CTM", ptr,
+	igt_assert_eq(pipe_set_property_blob(pipe, IGT_CRTC_CTM, ptr,
 					     sizeof(struct _drm_color_ctm) + 1),
 		      -EINVAL);
-	igt_assert_eq(pipe_set_property_blob(pipe, "CTM", ptr,
+	igt_assert_eq(pipe_set_property_blob(pipe, IGT_CRTC_CTM, ptr,
 					     sizeof(struct _drm_color_ctm) - 1),
 		      -EINVAL);
-	igt_assert_eq(pipe_set_property_blob(pipe, "CTM", ptr,
+	igt_assert_eq(pipe_set_property_blob(pipe, IGT_CRTC_CTM, ptr,
 					     sizeof(struct _drm_color_ctm) * 2),
 		      -EINVAL);
-	igt_assert_eq(pipe_set_property_blob_id(pipe, "CTM", pipe->crtc_id),
+	igt_assert_eq(pipe_set_property_blob_id(pipe, IGT_CRTC_CTM, pipe->crtc_id),
 		      -EINVAL);
-	igt_assert_eq(pipe_set_property_blob_id(pipe, "CTM", 4096 * 4096),
+	igt_assert_eq(pipe_set_property_blob_id(pipe, IGT_CRTC_CTM, 4096 * 4096),
 		      -EINVAL);
 
 	free(ptr);
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH i-g-t v2 13/14] tests/chamelium: Remove reliance on output->config.pipe
  2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
                   ` (11 preceding siblings ...)
  2017-10-12 11:54 ` [PATCH i-g-t v2 12/14] tests/kms_color: Rework tests slightly to work better with new atomic api Maarten Lankhorst
@ 2017-10-12 11:54 ` Maarten Lankhorst
  2017-10-20  7:15   ` Mika Kahola
  2017-10-12 11:54 ` [PATCH i-g-t v2 14/14] tests/kms_atomic: Convert/rewrite tests to use igt_kms framework Maarten Lankhorst
                   ` (4 subsequent siblings)
  17 siblings, 1 reply; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-12 11:54 UTC (permalink / raw)
  To: intel-gfx

IGT has an api that can find a matching pipe for a given connector,
so use that.

igt_output_override_mode already forces a modeset on an affected pipe
since an earlier commit, so the second call to igt_output_set_pipe
can be removed.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 tests/chamelium.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/tests/chamelium.c b/tests/chamelium.c
index 4ad29f9d178a..d4a185e76873 100644
--- a/tests/chamelium.c
+++ b/tests/chamelium.c
@@ -416,6 +416,8 @@ prepare_output(data_t *data,
 	drmModeRes *res;
 	drmModeConnector *connector =
 		chamelium_port_get_connector(data->chamelium, port, false);
+	enum pipe pipe;
+	bool found = false;
 
 	igt_assert(res = drmModeGetResources(data->drm_fd));
 	kmstest_unset_all_crtcs(data->drm_fd, res);
@@ -433,7 +435,18 @@ prepare_output(data_t *data,
 
 	igt_assert(kmstest_probe_connector_config(
 		data->drm_fd, connector->connector_id, ~0, &output->config));
-	igt_output_set_pipe(output, output->config.pipe);
+
+	for_each_pipe(display, pipe) {
+		if (!igt_pipe_connector_valid(pipe, output))
+			continue;
+
+		found = true;
+		break;
+	}
+
+	igt_assert_f(found, "No pipe found for output %s\n", igt_output_name(output));
+
+	igt_output_set_pipe(output, pipe);
 
 	drmModeFreeConnector(connector);
 	drmModeFreeResources(res);
@@ -459,8 +472,6 @@ enable_output(data_t *data,
 	igt_plane_set_fb(primary, fb);
 	igt_output_override_mode(output, mode);
 
-	igt_output_set_pipe(output, output->config.pipe);
-
 	/* Clear any color correction values that might be enabled */
 	igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_DEGAMMA_LUT, NULL, 0);
 	igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_GAMMA_LUT, NULL, 0);
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH i-g-t v2 14/14] tests/kms_atomic: Convert/rewrite tests to use igt_kms framework
  2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
                   ` (12 preceding siblings ...)
  2017-10-12 11:54 ` [PATCH i-g-t v2 13/14] tests/chamelium: Remove reliance on output->config.pipe Maarten Lankhorst
@ 2017-10-12 11:54 ` Maarten Lankhorst
  2017-10-12 15:33   ` [PATCH i-g-t v2] tests/kms_atomic: Convert/rewrite tests to use igt_kms framework, v2 Maarten Lankhorst
  2017-10-12 12:28 ` ✓ Fi.CI.BAT: success for lib/igt_kms: Rewrite property handling to better match atomic. (rev4) Patchwork
                   ` (3 subsequent siblings)
  17 siblings, 1 reply; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-12 11:54 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Stone

Now that we can set individual properties through the igt_kms api,
we no longer need to duplicate functionality from igt_kms. Set invalid
properties directly, and rewrite kms_atomic.c to use igt_display.
This will allow us to remove a lot of code in kms_atomic.c,
and benefit from how igt_kms can set up a valid configuration,
instead of having to inherit it from fbcon.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Daniel Stone <daniels@collabora.com>
---
 tests/kms_atomic.c | 1668 ++++++++++++++++------------------------------------
 1 file changed, 510 insertions(+), 1158 deletions(-)

diff --git a/tests/kms_atomic.c b/tests/kms_atomic.c
index 042a7c263aab..32b9225cba89 100644
--- a/tests/kms_atomic.c
+++ b/tests/kms_atomic.c
@@ -46,10 +46,6 @@
 #include "igt_aux.h"
 #include "sw_sync.h"
 
-#ifndef DRM_CLIENT_CAP_ATOMIC
-#define DRM_CLIENT_CAP_ATOMIC 3
-#endif
-
 #ifndef DRM_CAP_CURSOR_WIDTH
 #define DRM_CAP_CURSOR_WIDTH 0x8
 #endif
@@ -58,23 +54,6 @@
 #define DRM_CAP_CURSOR_HEIGHT 0x9
 #endif
 
-#ifndef DRM_MODE_ATOMIC_TEST_ONLY
-#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
-#define DRM_MODE_ATOMIC_NONBLOCK 0x0200
-#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
-
-struct drm_mode_atomic {
-	__u32 flags;
-	__u32 count_objs;
-	__u64 objs_ptr;
-	__u64 count_props_ptr;
-	__u64 props_ptr;
-	__u64 prop_values_ptr;
-	__u64 reserved;
-	__u64 user_data;
-};
-#endif
-
 IGT_TEST_DESCRIPTION("Test atomic modesetting API");
 
 enum kms_atomic_check_relax {
@@ -83,1259 +62,652 @@ enum kms_atomic_check_relax {
 	PLANE_RELAX_FB = (1 << 1)
 };
 
-/**
- * KMS plane type enum
- *
- * KMS plane types are represented by enums, which do not have stable numeric
- * values, but must be looked up by their string value each time.
- *
- * To make the code more simple, we define a plane_type enum which maps to
- * each KMS enum value. These values must be looked up through the map, and
- * cannot be passed directly to KMS functions.
- */
-enum plane_type {
-	PLANE_TYPE_PRIMARY = 0,
-	PLANE_TYPE_OVERLAY,
-	PLANE_TYPE_CURSOR,
-	NUM_PLANE_TYPE_PROPS
-};
-
-static const char *plane_type_prop_names[NUM_PLANE_TYPE_PROPS] = {
-	"Primary",
-	"Overlay",
-	"Cursor"
-};
-
-struct kms_atomic_blob {
-	uint32_t id; /* 0 if not already allocated */
-	size_t len;
-	void *data;
-};
-
-struct kms_atomic_connector_state {
-	struct kms_atomic_state *state;
-	uint32_t obj;
-	uint32_t crtc_id;
-};
-
-struct kms_atomic_plane_state {
-	struct kms_atomic_state *state;
-	uint32_t obj;
-	enum plane_type type;
-	uint32_t crtc_mask;
-	uint32_t crtc_id; /* 0 to disable */
-	uint32_t fb_id; /* 0 to disable */
-	uint32_t src_x, src_y, src_w, src_h; /* 16.16 fixed-point */
-	uint32_t crtc_x, crtc_y, crtc_w, crtc_h; /* normal integers */
-	int32_t fence_fd;
-};
-
-struct kms_atomic_crtc_state {
-	struct kms_atomic_state *state;
-	uint32_t obj;
-	int idx;
-	bool active;
-	int32_t *out_fence_ptr;
-	struct kms_atomic_blob mode;
-};
-
-struct kms_atomic_state {
-	struct kms_atomic_connector_state *connectors;
-	int num_connectors;
-	struct kms_atomic_crtc_state *crtcs;
-	int num_crtcs;
-	struct kms_atomic_plane_state *planes;
-	int num_planes;
-	struct kms_atomic_desc *desc;
-};
-
-struct kms_atomic_desc {
-	int fd;
-	uint32_t props_connector[IGT_NUM_CONNECTOR_PROPS];
-	uint32_t props_crtc[IGT_NUM_CRTC_PROPS];
-	uint32_t props_plane[IGT_NUM_PLANE_PROPS];
-	uint64_t props_plane_type[NUM_PLANE_TYPE_PROPS];
-};
-
-static uint32_t blob_duplicate(int fd, uint32_t id_orig)
+static bool plane_filter(enum igt_atomic_plane_properties prop)
 {
-	drmModePropertyBlobPtr orig = drmModeGetPropertyBlob(fd, id_orig);
-	uint32_t id_new;
-
-	igt_assert(orig);
-	do_or_die(drmModeCreatePropertyBlob(fd, orig->data, orig->length,
-					    &id_new));
-	drmModeFreePropertyBlob(orig);
+	if ((1 << prop) & IGT_PLANE_COORD_CHANGED_MASK)
+		return false;
 
-	return id_new;
-}
-
-#define crtc_set_prop(req, crtc, prop, value) \
-	igt_assert_lt(0, drmModeAtomicAddProperty(req, crtc->obj, \
-						  crtc->state->desc->props_crtc[prop], \
-						  value));
-
-#define plane_set_prop(req, plane, prop, value) \
-	igt_assert_lt(0, drmModeAtomicAddProperty(req, plane->obj, \
-						  plane->state->desc->props_plane[prop], \
-						  value));
-
-#define do_atomic_commit(fd, req, flags) \
-	do_or_die(drmModeAtomicCommit(fd, req, flags, NULL));
+	if (prop == IGT_PLANE_CRTC_ID || prop == IGT_PLANE_FB_ID)
+		return false;
 
-#define do_atomic_commit_err(fd, req, flags, err) { \
-	igt_assert_neq(drmModeAtomicCommit(fd, req, flags, NULL), 0); \
-	igt_assert_eq(errno, err); \
-}
-
-#define crtc_commit_atomic(crtc, plane, req, relax, flags) { \
-	drmModeAtomicSetCursor(req, 0); \
-	crtc_populate_req(crtc, req); \
-	plane_populate_req(plane, req); \
-	do_atomic_commit((crtc)->state->desc->fd, req, flags); \
-	if (!(flags & DRM_MODE_ATOMIC_TEST_ONLY)) { \
-		crtc_check_current_state(crtc, plane, relax); \
-		plane_check_current_state(plane, relax); \
-	} \
-}
+	if (prop == IGT_PLANE_IN_FENCE_FD)
+		return false;
 
-#define crtc_commit_atomic_err(crtc, plane, crtc_old, plane_old, req, flags, relax, e) { \
-	drmModeAtomicSetCursor(req, 0); \
-	crtc_populate_req(crtc, req); \
-	plane_populate_req(plane, req); \
-	do_atomic_commit_err((crtc)->state->desc->fd, req, flags, e); \
-	crtc_check_current_state(crtc_old, plane_old, relax); \
-	plane_check_current_state(plane_old, relax); \
+	/* Don't care about other properties */
+	return true;
 }
 
-#define plane_commit_atomic(plane, req, relax) { \
-	drmModeAtomicSetCursor(req, 0); \
-	plane_populate_req(plane, req); \
-	do_atomic_commit((plane)->state->desc->fd, req, 0); \
-	plane_check_current_state(plane, relax); \
-}
-
-#define plane_commit_atomic_err(plane, plane_old, req, relax, e) { \
-	drmModeAtomicSetCursor(req, 0); \
-	plane_populate_req(plane, req); \
-	do_atomic_commit_err((plane)->state->desc->fd, req, 0, e); \
-	plane_check_current_state(plane_old, relax); \
-}
-
-static void
-connector_get_current_state(struct kms_atomic_connector_state *connector)
-{
-	drmModeObjectPropertiesPtr props;
-	int i;
-
-	props = drmModeObjectGetProperties(connector->state->desc->fd,
-					   connector->obj,
-					   DRM_MODE_OBJECT_CONNECTOR);
-	igt_assert(props);
-
-	for (i = 0; i < props->count_props; i++) {
-		uint32_t *prop_ids = connector->state->desc->props_connector;
-
-		if (props->props[i] == prop_ids[IGT_CONNECTOR_CRTC_ID])
-			connector->crtc_id = props->prop_values[i];
-	}
-	drmModeFreeObjectProperties(props);
-}
-
-#if 0
-/* XXX: Checking this repeatedly actually hangs the GPU. I have literally no
- *      idea why. */
-static void
-connector_check_current_state(struct kms_atomic_connector_state *connector)
-{
-	struct kms_atomic_connector_state connector_kernel;
-	drmModeConnectorPtr legacy;
-	uint32_t crtc_id;
-
-	legacy = drmModeGetConnectorCurrent(connector->state->desc->fd,
-					    connector->obj);
-	igt_assert(legacy);
-
-	if (legacy->encoder_id) {
-		drmModeEncoderPtr legacy_enc;
-
-		legacy_enc = drmModeGetEncoder(connector->state->desc->fd,
-					       legacy->encoder_id);
-		igt_assert(legacy_enc);
-
-		crtc_id = legacy_enc->crtc_id;
-		drmModeFreeEncoder(legacy_enc);
-	} else {
-		crtc_id = 0;
-	}
-
-	igt_assert_eq_u32(crtc_id, connector->crtc_id);
-
-	memcpy(&connector_kernel, connector, sizeof(connector_kernel));
-	connector_get_current_state(&connector_kernel);
-	do_or_die(memcmp(&connector_kernel, connector,
-			 sizeof(connector_kernel)));
-
-	drmModeFreeConnector(legacy);
-}
-#endif
-
-static struct kms_atomic_connector_state *
-find_connector(struct kms_atomic_state *state,
-	       struct kms_atomic_crtc_state *crtc)
+static void plane_get_current_state(igt_plane_t *plane, uint64_t *values)
 {
 	int i;
 
-	for (i = 0; i < state->num_connectors; i++) {
-		struct kms_atomic_connector_state *connector =
-			&state->connectors[i];
-
-		if (!connector->obj)
+	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++) {
+		if (plane_filter(i)) {
+			values[i] = 0;
 			continue;
-		if (crtc && connector->crtc_id != crtc->obj)
-			continue;
-
-		return connector;
-	}
-
-	return NULL;
-}
-
-static void plane_populate_req(struct kms_atomic_plane_state *plane,
-			       drmModeAtomicReq *req)
-{
-	if (plane->fence_fd)
-		plane_set_prop(req, plane, IGT_PLANE_IN_FENCE_FD, plane->fence_fd);
-
-	plane_set_prop(req, plane, IGT_PLANE_CRTC_ID, plane->crtc_id);
-	plane_set_prop(req, plane, IGT_PLANE_FB_ID, plane->fb_id);
-	plane_set_prop(req, plane, IGT_PLANE_SRC_X, plane->src_x);
-	plane_set_prop(req, plane, IGT_PLANE_SRC_Y, plane->src_y);
-	plane_set_prop(req, plane, IGT_PLANE_SRC_W, plane->src_w);
-	plane_set_prop(req, plane, IGT_PLANE_SRC_H, plane->src_h);
-	plane_set_prop(req, plane, IGT_PLANE_CRTC_X, plane->crtc_x);
-	plane_set_prop(req, plane, IGT_PLANE_CRTC_Y, plane->crtc_y);
-	plane_set_prop(req, plane, IGT_PLANE_CRTC_W, plane->crtc_w);
-	plane_set_prop(req, plane, IGT_PLANE_CRTC_H, plane->crtc_h);
-}
-
-static void plane_get_current_state(struct kms_atomic_plane_state *plane)
-{
-	struct kms_atomic_desc *desc = plane->state->desc;
-	drmModeObjectPropertiesPtr props;
-	int i;
-
-	props = drmModeObjectGetProperties(desc->fd, plane->obj,
-					   DRM_MODE_OBJECT_PLANE);
-	igt_assert(props);
-
-	for (i = 0; i < props->count_props; i++) {
-		uint32_t *prop_ids = desc->props_plane;
-
-		if (props->props[i] == prop_ids[IGT_PLANE_CRTC_ID])
-			plane->crtc_id = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_FB_ID])
-			plane->fb_id = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_CRTC_X])
-			plane->crtc_x = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_CRTC_Y])
-			plane->crtc_y = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_CRTC_W])
-			plane->crtc_w = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_CRTC_H])
-			plane->crtc_h = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_SRC_X])
-			plane->src_x = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_SRC_Y])
-			plane->src_y = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_SRC_W])
-			plane->src_w = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_SRC_H])
-			plane->src_h = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_TYPE]) {
-			int j;
-
-			for (j = 0; j < ARRAY_SIZE(desc->props_plane_type); j++) {
-				if (props->prop_values[i] == desc->props_plane_type[j]) {
-					plane->type = j;
-					break;
-				}
-			}
 		}
-	}
 
-	drmModeFreeObjectProperties(props);
+		values[i] = igt_plane_get_prop(plane, i);
+	}
 }
 
-static void plane_check_current_state(struct kms_atomic_plane_state *plane,
+static void plane_check_current_state(igt_plane_t *plane, const uint64_t *values,
 				      enum kms_atomic_check_relax relax)
 {
 	drmModePlanePtr legacy;
-	struct kms_atomic_plane_state plane_kernel;
+	uint64_t current_values[IGT_NUM_PLANE_PROPS];
+	int i;
 
-	legacy = drmModeGetPlane(plane->state->desc->fd, plane->obj);
+	legacy = drmModeGetPlane(plane->pipe->display->drm_fd, plane->drm_plane->plane_id);
 	igt_assert(legacy);
 
-	igt_assert_eq_u32(legacy->crtc_id, plane->crtc_id);
+	igt_assert_eq_u32(legacy->crtc_id, values[IGT_PLANE_CRTC_ID]);
 
 	if (!(relax & PLANE_RELAX_FB))
-		igt_assert_eq_u32(legacy->fb_id, plane->fb_id);
+		igt_assert_eq_u32(legacy->fb_id, values[IGT_PLANE_FB_ID]);
 
-	memcpy(&plane_kernel, plane, sizeof(plane_kernel));
-	plane_get_current_state(&plane_kernel);
+	plane_get_current_state(plane, current_values);
 
 	/* Legacy cursor ioctls create their own, unknowable, internal
 	 * framebuffer which we can't reason about. */
 	if (relax & PLANE_RELAX_FB)
-		plane_kernel.fb_id = plane->fb_id;
-	do_or_die(memcmp(&plane_kernel, plane, sizeof(plane_kernel)));
+		current_values[IGT_PLANE_FB_ID] = values[IGT_PLANE_FB_ID];
+
+	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++)
+		if (!plane_filter(i))
+			igt_assert_eq_u64(current_values[i], values[i]);
 
 	drmModeFreePlane(legacy);
 }
 
-static void plane_commit_legacy(struct kms_atomic_plane_state *plane,
+static void plane_commit(igt_plane_t *plane, enum igt_commit_style s,
                                 enum kms_atomic_check_relax relax)
 {
-	do_or_die(drmModeSetPlane(plane->state->desc->fd, plane->obj,
-				  plane->crtc_id,
-				  plane->fb_id, 0,
-				  plane->crtc_x, plane->crtc_y,
-				  plane->crtc_w, plane->crtc_h,
-				  plane->src_x, plane->src_y,
-				  plane->src_w, plane->src_h));
-	plane_check_current_state(plane, relax);
+	igt_display_commit2(plane->pipe->display, s);
+	plane_check_current_state(plane, plane->values, relax);
 }
 
-static struct kms_atomic_plane_state *
-find_plane(struct kms_atomic_state *state, enum plane_type type,
-	   struct kms_atomic_crtc_state *crtc)
+static void plane_commit_atomic_err(igt_plane_t *plane,
+				    enum kms_atomic_check_relax relax,
+				    int err)
 {
-	struct kms_atomic_plane_state *ret = NULL;
-	int i;
-
-	for (i = 0; i < state->num_planes; i++) {
-		struct kms_atomic_plane_state *plane = &state->planes[i];
-
-		if (!plane->obj)
-			continue;
-		if (type != NUM_PLANE_TYPE_PROPS && plane->type != type)
-			continue;
-		if (crtc && !(plane->crtc_mask & (1 << crtc->idx)))
-			continue;
+	uint64_t current_values[IGT_NUM_PLANE_PROPS];
 
-		plane_get_current_state(plane);
+	plane_get_current_state(plane, current_values);
 
-		/* Try to find a plane that's already on this CRTC. In
-		 * particular, this ensures that for special (primary/cursor)
-		 * planes that can be on multiple CRTCs, we find the same
-		 * one that the legacy ioctls will. */
-		if (!crtc || plane->crtc_id == crtc->obj)
-			return plane;
-
-		ret = plane;
-	}
+	igt_assert_eq(-err, igt_display_try_commit2(plane->pipe->display, COMMIT_ATOMIC));
 
-	return ret;
+	plane_check_current_state(plane, current_values, relax);
 }
 
-static void crtc_populate_req(struct kms_atomic_crtc_state *crtc,
-			      drmModeAtomicReq *req)
+static bool crtc_filter(enum igt_atomic_crtc_properties prop)
 {
-	if (crtc->out_fence_ptr)
-		crtc_set_prop(req, crtc, IGT_CRTC_OUT_FENCE_PTR,
-			      to_user_pointer(crtc->out_fence_ptr));
+	if (prop == IGT_CRTC_MODE_ID || prop == IGT_CRTC_ACTIVE)
+		return false;
 
-	crtc_set_prop(req, crtc, IGT_CRTC_MODE_ID, crtc->mode.id);
-	crtc_set_prop(req, crtc, IGT_CRTC_ACTIVE, crtc->active);
+	return true;
 }
 
-static void crtc_get_current_state(struct kms_atomic_crtc_state *crtc)
+static void crtc_get_current_state(igt_pipe_t *pipe, uint64_t *values)
 {
-	drmModeObjectPropertiesPtr props;
 	int i;
 
-	props = drmModeObjectGetProperties(crtc->state->desc->fd, crtc->obj,
-					   DRM_MODE_OBJECT_CRTC);
-	igt_assert(props);
-
-	for (i = 0; i < props->count_props; i++) {
-		uint32_t *prop_ids = crtc->state->desc->props_crtc;
-
-		if (props->props[i] == prop_ids[IGT_CRTC_MODE_ID]) {
-			drmModePropertyBlobPtr blob;
-
-			crtc->mode.id = props->prop_values[i];
-			if (!crtc->mode.id) {
-				crtc->mode.len = 0;
-				continue;
-			}
-
-			blob = drmModeGetPropertyBlob(crtc->state->desc->fd,
-						      crtc->mode.id);
-			igt_assert(blob);
-			igt_assert_eq_u32(blob->length,
-					  sizeof(struct drm_mode_modeinfo));
-
-			if (!crtc->mode.data ||
-			    memcmp(crtc->mode.data, blob->data, blob->length) != 0)
-				crtc->mode.data = blob->data;
-			crtc->mode.len = blob->length;
-		}
-		else if (props->props[i] == prop_ids[IGT_CRTC_ACTIVE]) {
-			crtc->active = props->prop_values[i];
+	for (i = 0; i < IGT_NUM_CRTC_PROPS; i++) {
+		if (crtc_filter(i)) {
+			values[i] = 0;
+			continue;
 		}
-	}
 
-	drmModeFreeObjectProperties(props);
+		values[i] = igt_pipe_obj_get_prop(pipe, i);
+	}
 }
 
-static void crtc_check_current_state(struct kms_atomic_crtc_state *crtc,
-				     struct kms_atomic_plane_state *primary,
+static void crtc_check_current_state(igt_pipe_t *pipe,
+				     const uint64_t *pipe_values,
+				     const uint64_t *primary_values,
 				     enum kms_atomic_check_relax relax)
 {
-	struct kms_atomic_crtc_state crtc_kernel;
+	uint64_t current_pipe_values[IGT_NUM_CRTC_PROPS];
 	drmModeCrtcPtr legacy;
+	drmModePropertyBlobRes *mode_prop = NULL;
+	struct drm_mode_modeinfo *mode = NULL;
 
-	legacy = drmModeGetCrtc(crtc->state->desc->fd, crtc->obj);
-	igt_assert(legacy);
-
-	igt_assert_eq_u32(legacy->crtc_id, crtc->obj);
-	igt_assert_eq_u32(legacy->x, primary->src_x >> 16);
-	igt_assert_eq_u32(legacy->y, primary->src_y >> 16);
-
-	if (crtc->active)
-		igt_assert_eq_u32(legacy->buffer_id, primary->fb_id);
-	else
-		igt_assert_eq_u32(legacy->buffer_id, 0);
+	if (pipe_values[IGT_CRTC_MODE_ID]) {
+		mode_prop = drmModeGetPropertyBlob(pipe->display->drm_fd,
+						   pipe_values[IGT_CRTC_MODE_ID]);
 
-	if (legacy->mode_valid) {
-		igt_assert_neq(legacy->mode_valid, 0);
-		igt_assert_eq(crtc->mode.len,
-		              sizeof(struct drm_mode_modeinfo));
-		do_or_die(memcmp(&legacy->mode, crtc->mode.data,
-		                 crtc->mode.len));
-		igt_assert_eq(legacy->width, legacy->mode.hdisplay);
-		igt_assert_eq(legacy->height, legacy->mode.vdisplay);
-	} else {
-		igt_assert_eq(legacy->mode_valid, 0);
-	}
+		igt_assert(mode_prop);
 
-	memcpy(&crtc_kernel, crtc, sizeof(crtc_kernel));
-	crtc_get_current_state(&crtc_kernel);
-
-	if (crtc_kernel.mode.id != 0)
-		igt_assert_eq(crtc_kernel.mode.len,
+		igt_assert_eq(mode_prop->length,
 		              sizeof(struct drm_mode_modeinfo));
-
-	/* Optionally relax the check for MODE_ID: using the legacy SetCrtc
-	 * API can potentially change MODE_ID even if the mode itself remains
-	 * unchanged. */
-	if (((relax & CRTC_RELAX_MODE) &&
-	    (crtc_kernel.mode.id != crtc->mode.id &&
-	     crtc_kernel.mode.id != 0 && crtc->mode.id != 0)) &&
-	    memcmp(crtc_kernel.mode.data, crtc->mode.data,
-		   sizeof(struct drm_mode_modeinfo)) == 0) {
-		crtc_kernel.mode.id = crtc->mode.id;
-		crtc_kernel.mode.data = crtc->mode.data;
-	}
-
-	do_or_die(memcmp(&crtc_kernel, crtc, sizeof(crtc_kernel)));
-
-	drmModeFreeCrtc(legacy);
-}
-
-static void crtc_commit_legacy(struct kms_atomic_crtc_state *crtc,
-			       struct kms_atomic_plane_state *plane,
-			       enum kms_atomic_check_relax relax)
-{
-	drmModeObjectPropertiesPtr props;
-	uint32_t *connectors;
-	int num_connectors = 0;
-	int i;
-
-	if (!crtc->active) {
-		do_or_die(drmModeSetCrtc(crtc->state->desc->fd,
-					 crtc->obj, 0, 0, 0, NULL, 0, NULL));
-		return;
-	}
-
-	connectors = calloc(crtc->state->num_connectors,
-			    sizeof(*connectors));
-	igt_assert(connectors);
-
-	igt_assert_neq_u32(crtc->mode.id, 0);
-
-	for (i = 0; i < crtc->state->num_connectors; i++) {
-		struct kms_atomic_connector_state *connector =
-			&crtc->state->connectors[i];
-
-		if (connector->crtc_id != crtc->obj)
-			continue;
-
-		connectors[num_connectors++] = connector->obj;
+		mode = mode_prop->data;
 	}
 
-	do_or_die(drmModeSetCrtc(crtc->state->desc->fd, crtc->obj,
-	                         plane->fb_id,
-				 plane->src_x >> 16, plane->src_y >> 16,
-				 (num_connectors) ? connectors : NULL,
-				 num_connectors,
-				 crtc->mode.data));
-	/* When doing a legacy commit, the core may update MODE_ID to be a new
-	 * blob implicitly created by the legacy request. Hence we backfill
-	 * the value in the state object to ensure they match. */
-	props = drmModeObjectGetProperties(crtc->state->desc->fd, crtc->obj,
-					   DRM_MODE_OBJECT_CRTC);
-	igt_assert(props);
-
-	for (i = 0; i < props->count_props; i++) {
-		if (props->props[i] !=
-		    crtc->state->desc->props_crtc[IGT_CRTC_MODE_ID])
-			continue;
-		crtc->mode.id = props->prop_values[i];
-		break;
-	}
+	legacy = drmModeGetCrtc(pipe->display->drm_fd, pipe->crtc_id);
+	igt_assert(legacy);
 
-	drmModeFreeObjectProperties(props);
+	igt_assert_eq_u32(legacy->crtc_id, pipe->crtc_id);
+	igt_assert_eq_u32(legacy->x, primary_values[IGT_PLANE_SRC_X] >> 16);
+	igt_assert_eq_u32(legacy->y, primary_values[IGT_PLANE_SRC_Y] >> 16);
 
-	crtc_check_current_state(crtc, plane, relax);
-	plane_check_current_state(plane, relax);
-}
+	igt_assert_eq_u32(legacy->buffer_id, primary_values[IGT_PLANE_FB_ID]);
 
-static struct kms_atomic_crtc_state *find_crtc(struct kms_atomic_state *state,
-					       bool must_be_enabled)
-{
-	int i;
+	if (legacy->mode_valid) {
+		igt_assert(mode_prop);
 
-	for (i = 0; i < state->num_crtcs; i++) {
-		struct kms_atomic_crtc_state *crtc = &state->crtcs[i];
+		do_or_die(memcmp(&legacy->mode, mode, sizeof(*mode)));
 
-		if (!crtc->obj)
-			continue;
-		if (must_be_enabled && !crtc->active)
-			continue;
+		igt_assert_eq(legacy->width, legacy->mode.hdisplay);
+		igt_assert_eq(legacy->height, legacy->mode.vdisplay);
 
-		crtc_get_current_state(crtc);
-		return crtc;
+		igt_assert_neq(pipe_values[IGT_CRTC_MODE_ID], 0);
+	} else {
+		igt_assert(!mode_prop);
 	}
 
-	return NULL;
-}
-
-static void fill_obj_props(int fd, uint32_t id, int type, int num_props,
-			   const char **prop_names, uint32_t *prop_ids)
-{
-	drmModeObjectPropertiesPtr props;
-	int i, j;
+	crtc_get_current_state(pipe, current_pipe_values);
 
-	props = drmModeObjectGetProperties(fd, id, type);
-	igt_assert(props);
+	/* Optionally relax the check for MODE_ID: using the legacy SetCrtc
+	 * API can potentially change MODE_ID even if the mode itself remains
+	 * unchanged. */
+	if (relax & CRTC_RELAX_MODE && mode && current_pipe_values[IGT_CRTC_MODE_ID] &&
+	    current_pipe_values[IGT_CRTC_MODE_ID] != pipe_values[IGT_CRTC_MODE_ID]) {
+		drmModePropertyBlobRes *cur_prop =
+			drmModeGetPropertyBlob(pipe->display->drm_fd,
+					       current_pipe_values[IGT_CRTC_MODE_ID]);
 
-	for (i = 0; i < props->count_props; i++) {
-		drmModePropertyPtr prop =
-			drmModeGetProperty(fd, props->props[i]);
+		igt_assert(cur_prop);
+		igt_assert_eq(cur_prop->length, sizeof(struct drm_mode_modeinfo));
 
-		for (j = 0; j < num_props; j++) {
-			if (strcmp(prop->name, prop_names[j]) != 0)
-				continue;
-			prop_ids[j] = props->props[i];
-			break;
-		}
+		if (!memcmp(cur_prop->data, mode, sizeof(*mode)))
+			current_pipe_values[IGT_CRTC_MODE_ID] = pipe_values[IGT_CRTC_MODE_ID];
 
-		drmModeFreeProperty(prop);
+		drmModeFreePropertyBlob(cur_prop);
 	}
 
-	drmModeFreeObjectProperties(props);
-}
-
-static void fill_obj_prop_map(int fd, uint32_t id, int type, const char *name,
-			      int num_enums, const char **enum_names,
-			      uint64_t *enum_ids)
-{
-	drmModeObjectPropertiesPtr props;
-	int i, j, k;
-
-	props = drmModeObjectGetProperties(fd, id, type);
-	igt_assert(props);
-
-	for (i = 0; i < props->count_props; i++) {
-		drmModePropertyPtr prop =
-			drmModeGetProperty(fd, props->props[i]);
-
-		igt_assert(prop);
-
-		if (strcmp(prop->name, name) != 0) {
-			drmModeFreeProperty(prop);
-			continue;
-		}
-
-		for (j = 0; j < prop->count_enums; j++) {
-			struct drm_mode_property_enum *e = &prop->enums[j];
-
-			for (k = 0; k < num_enums; k++) {
-				if (strcmp(e->name, enum_names[k]) != 0)
-					continue;
-
-				enum_ids[k] = e->value;
-				break;
-			}
-		}
+	do_or_die(memcmp(pipe_values, current_pipe_values, sizeof(current_pipe_values)));
 
-		drmModeFreeProperty(prop);
-	}
+	drmModeFreeCrtc(legacy);
+	drmModeFreePropertyBlob(mode_prop);
 }
 
-static void atomic_setup(struct kms_atomic_state *state)
+static void crtc_commit(igt_pipe_t *pipe, igt_plane_t *plane,
+			enum igt_commit_style s,
+			enum kms_atomic_check_relax relax)
 {
-	struct kms_atomic_desc *desc = state->desc;
-	drmModeResPtr res;
-	drmModePlaneResPtr res_plane;
-	int i;
-
-	desc->fd = drm_open_driver_master(DRIVER_ANY);
-	igt_assert_fd(desc->fd);
-
-	igt_skip_on(drmSetClientCap(desc->fd, DRM_CLIENT_CAP_ATOMIC, 1));
-
-	res = drmModeGetResources(desc->fd);
-	res_plane = drmModeGetPlaneResources(desc->fd);
-	igt_assert(res);
-	igt_assert(res_plane);
-
-	igt_assert_lt(0, res->count_crtcs);
-	state->num_crtcs = res->count_crtcs;
-	state->crtcs = calloc(state->num_crtcs, sizeof(*state->crtcs));
-	igt_assert(state->crtcs);
-
-	igt_assert_lt(0, res_plane->count_planes);
-	state->num_planes = res_plane->count_planes;
-	state->planes = calloc(state->num_planes, sizeof(*state->planes));
-	igt_assert(state->planes);
-
-	igt_assert_lt(0, res->count_connectors);
-	state->num_connectors = res->count_connectors;
-	state->connectors = calloc(state->num_connectors,
-				   sizeof(*state->connectors));
-	igt_assert(state->connectors);
-
-	fill_obj_props(desc->fd, res->crtcs[0],
-		       DRM_MODE_OBJECT_CRTC, IGT_NUM_CRTC_PROPS,
-		       igt_crtc_prop_names, desc->props_crtc);
-
-	fill_obj_props(desc->fd, res_plane->planes[0],
-		       DRM_MODE_OBJECT_PLANE, IGT_NUM_PLANE_PROPS,
-		       igt_plane_prop_names, desc->props_plane);
-	fill_obj_prop_map(desc->fd, res_plane->planes[0],
-			  DRM_MODE_OBJECT_PLANE, "type",
-			  NUM_PLANE_TYPE_PROPS, plane_type_prop_names,
-			  desc->props_plane_type);
-
-	fill_obj_props(desc->fd, res->connectors[0],
-		       DRM_MODE_OBJECT_CONNECTOR, IGT_NUM_CONNECTOR_PROPS,
-		       igt_connector_prop_names, desc->props_connector);
-
-	for (i = 0; i < state->num_crtcs; i++) {
-		struct kms_atomic_crtc_state *crtc = &state->crtcs[i];
-
-		crtc->state = state;
-		crtc->obj = res->crtcs[i];
-		crtc->idx = i;
-		crtc_get_current_state(crtc);
-
-		/* The blob pointed to by MODE_ID could well be transient,
-		 * and lose its last reference as we switch away from it.
-		 * Duplicate the blob here so we have a reference we know we
-		 * own. */
-		if (crtc->mode.id != 0)
-		    crtc->mode.id = blob_duplicate(desc->fd, crtc->mode.id);
-	}
-
-	for (i = 0; i < state->num_planes; i++) {
-		drmModePlanePtr plane =
-			drmModeGetPlane(desc->fd, res_plane->planes[i]);
-		igt_assert(plane);
-
-		state->planes[i].state = state;
-		state->planes[i].obj = res_plane->planes[i];
-		state->planes[i].crtc_mask = plane->possible_crtcs;
-		plane_get_current_state(&state->planes[i]);
-	}
+	igt_display_commit2(pipe->display, s);
 
-	for (i = 0; i < state->num_connectors; i++) {
-		state->connectors[i].state = state;
-		state->connectors[i].obj = res->connectors[i];
-		connector_get_current_state(&state->connectors[i]);
-	}
-
-	drmModeFreePlaneResources(res_plane);
-	drmModeFreeResources(res);
+	crtc_check_current_state(pipe, pipe->values, plane->values, relax);
+	plane_check_current_state(plane, plane->values, relax);
 }
 
-static struct kms_atomic_state *
-atomic_state_dup(const struct kms_atomic_state *state)
+static void crtc_commit_atomic_flags_err(igt_pipe_t *pipe, igt_plane_t *plane,
+					 unsigned flags,
+					 enum kms_atomic_check_relax relax,
+					 int err)
 {
-	struct kms_atomic_state *ret = calloc(1, sizeof(*ret));
-
-	igt_assert(ret);
-	*ret = *state;
-
-	ret->crtcs = calloc(ret->num_crtcs, sizeof(*ret->crtcs));
-	igt_assert(ret->crtcs);
-	memcpy(ret->crtcs, state->crtcs, ret->num_crtcs * sizeof(*ret->crtcs));
+	uint64_t current_pipe_values[IGT_NUM_CRTC_PROPS];
+	uint64_t current_plane_values[IGT_NUM_PLANE_PROPS];
 
-	ret->planes = calloc(ret->num_planes, sizeof(*ret->planes));
-	igt_assert(ret->planes);
-	memcpy(ret->planes, state->planes,
-	       ret->num_planes * sizeof(*ret->planes));
+	crtc_get_current_state(pipe, current_pipe_values);
+	plane_get_current_state(plane, current_plane_values);
 
-	ret->connectors = calloc(ret->num_connectors, sizeof(*ret->connectors));
-	igt_assert(ret->connectors);
-	memcpy(ret->connectors, state->connectors,
-	       ret->num_connectors * sizeof(*ret->connectors));
+	igt_assert_eq(-err, igt_display_try_commit_atomic(pipe->display, flags, NULL));
 
-	return ret;
+	crtc_check_current_state(pipe, current_pipe_values, current_plane_values, relax);
+	plane_check_current_state(plane, current_plane_values, relax);
 }
 
-static void atomic_state_free(struct kms_atomic_state *state)
-{
-	free(state->crtcs);
-	free(state->planes);
-	free(state->connectors);
-	free(state);
-}
+#define crtc_commit_atomic_err(pipe, plane, relax, err) \
+	crtc_commit_atomic_flags_err(pipe, plane, DRM_MODE_ATOMIC_ALLOW_MODESET, relax, err)
 
-static uint32_t plane_get_igt_format(struct kms_atomic_plane_state *plane)
+static uint32_t plane_get_igt_format(igt_plane_t *plane)
 {
 	drmModePlanePtr plane_kms;
 	const uint32_t *igt_formats;
-	uint32_t ret = 0;
 	int num_igt_formats;
 	int i;
 
-	plane_kms = drmModeGetPlane(plane->state->desc->fd, plane->obj);
-	igt_assert(plane_kms);
+	plane_kms = plane->drm_plane;
 
 	igt_get_all_cairo_formats(&igt_formats, &num_igt_formats);
 	for (i = 0; i < num_igt_formats; i++) {
 		int j;
 
 		for (j = 0; j < plane_kms->count_formats; j++) {
-			if (plane_kms->formats[j] == igt_formats[i]) {
-				ret = plane_kms->formats[j];
-				break;
-			}
+			if (plane_kms->formats[j] == igt_formats[i])
+				return plane_kms->formats[j];
 		}
 	}
 
-	drmModeFreePlane(plane_kms);
-	return ret;
+	return 0;
 }
 
 static void
-set_dpms(int fd, int mode)
+set_dpms(igt_output_t *output, int mode)
 {
-	int i;
-	drmModeConnector *connector;
-	uint32_t id;
-	drmModeRes *resources = drmModeGetResources(fd);
-
-	for (i = 0; i < resources->count_connectors; i++) {
-		id = resources->connectors[i];
-
-		connector = drmModeGetConnectorCurrent(fd, id);
-
-		kmstest_set_connector_dpms(fd, connector, mode);
-
-		drmModeFreeConnector(connector);
-	}
+	do_or_die(drmModeConnectorSetProperty(output->display->drm_fd, output->id,
+					      output->props[IGT_CONNECTOR_DPMS], mode));
 }
 
-static void plane_overlay(struct kms_atomic_crtc_state *crtc,
-			  struct kms_atomic_plane_state *plane_old)
+static void plane_overlay(igt_pipe_t *pipe, igt_output_t *output, igt_plane_t *plane)
 {
-	struct drm_mode_modeinfo *mode = crtc->mode.data;
-	struct kms_atomic_plane_state plane = *plane_old;
-	uint32_t format = plane_get_igt_format(&plane);
-	drmModeAtomicReq *req = drmModeAtomicAlloc();
+	drmModeModeInfo *mode = igt_output_get_mode(output);
+	uint32_t format = plane_get_igt_format(plane);
 	struct igt_fb fb;
+	uint32_t w = mode->hdisplay / 2;
+	uint32_t h = mode->vdisplay / 2;
 
-	igt_require(req);
 	igt_require(format != 0);
 
-	plane.src_x = 0;
-	plane.src_y = 0;
-	plane.src_w = (mode->hdisplay / 2) << 16;
-	plane.src_h = (mode->vdisplay / 2) << 16;
-	plane.crtc_x = mode->hdisplay / 4;
-	plane.crtc_y = mode->vdisplay / 4;
-	plane.crtc_w = mode->hdisplay / 2;
-	plane.crtc_h = mode->vdisplay / 2;
-	plane.crtc_id = crtc->obj;
-	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
-					    plane.crtc_w, plane.crtc_h,
-					    format, I915_TILING_NONE, &fb);
+	igt_create_pattern_fb(pipe->display->drm_fd, w, h,
+			      format, I915_TILING_NONE, &fb);
+
+	igt_plane_set_fb(plane, &fb);
+	igt_plane_set_position(plane, w/2, h/2);
 
 	/* Enable the overlay plane using the atomic API, and double-check
 	 * state is what we think it should be. */
-	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
+	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
 	/* Disable the plane and check the state matches the old. */
-	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
+	igt_plane_set_fb(plane, NULL);
+	igt_plane_set_position(plane, 0, 0);
+	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
 	/* Re-enable the plane through the legacy plane API, and verify through
 	 * atomic. */
-	plane_commit_legacy(&plane, ATOMIC_RELAX_NONE);
+	igt_plane_set_fb(plane, &fb);
+	igt_plane_set_position(plane, w/2, h/2);
+	plane_commit(plane, COMMIT_LEGACY, ATOMIC_RELAX_NONE);
 
 	/* Restore the plane to its original settings through the legacy plane
 	 * API, and verify through atomic. */
-	plane_commit_legacy(plane_old, ATOMIC_RELAX_NONE);
+	igt_plane_set_fb(plane, NULL);
+	igt_plane_set_position(plane, 0, 0);
+	plane_commit(plane, COMMIT_LEGACY, ATOMIC_RELAX_NONE);
 
-	drmModeAtomicFree(req);
+	igt_remove_fb(pipe->display->drm_fd, &fb);
 }
 
-static void plane_primary(struct kms_atomic_crtc_state *crtc,
-			  struct kms_atomic_plane_state *plane_old)
+static void plane_primary(igt_pipe_t *pipe, igt_plane_t *plane, struct igt_fb *fb)
 {
-	struct drm_mode_modeinfo *mode = crtc->mode.data;
-	struct kms_atomic_plane_state plane = *plane_old;
-	uint32_t format = plane_get_igt_format(&plane);
-	drmModeAtomicReq *req = drmModeAtomicAlloc();
-	struct igt_fb fb;
-	uint32_t flags = 0;
-	int ret;
-
-	igt_require(format != 0);
+	struct igt_fb fb2;
 
-	plane.src_x = 0;
-	plane.src_y = 0;
-	plane.src_w = mode->hdisplay << 16;
-	plane.src_h = mode->vdisplay << 16;
-	plane.crtc_x = 0;
-	plane.crtc_y = 0;
-	plane.crtc_w = mode->hdisplay;
-	plane.crtc_h = mode->vdisplay;
-	plane.crtc_id = crtc->obj;
-	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
-					    plane.crtc_w, plane.crtc_h,
-					    format, I915_TILING_NONE, &fb);
-
-	drmModeAtomicSetCursor(req, 0);
-	crtc_populate_req(crtc, req);
-	plane_populate_req(&plane, req);
-	ret = drmModeAtomicCommit(crtc->state->desc->fd, req,
-				  DRM_MODE_ATOMIC_TEST_ONLY, NULL);
-	/* Try harder in case the failure is caused by disallowing modeset. */
-	if (ret == -EINVAL)
-		flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
+	igt_create_color_pattern_fb(pipe->display->drm_fd,
+				    fb->width, fb->height,
+				    fb->drm_format, I915_TILING_NONE,
+				    0.2, 0.2, 0.2, &fb2);
 
 	/* Flip the primary plane using the atomic API, and double-check
 	 * state is what we think it should be. */
-	crtc_commit_atomic(crtc, &plane, req, ATOMIC_RELAX_NONE, flags);
+	igt_plane_set_fb(plane, &fb2);
+	crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
 	/* Restore the primary plane and check the state matches the old. */
-	crtc_commit_atomic(crtc, plane_old, req, ATOMIC_RELAX_NONE, flags);
+	igt_plane_set_fb(plane, fb);
+	crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
-	/* Re-enable the plane through the legacy CRTC/primary-plane API, and
+	/* Set the plane through the legacy CRTC/primary-plane API, and
 	 * verify through atomic. */
-	crtc_commit_legacy(crtc, &plane, CRTC_RELAX_MODE);
+	igt_plane_set_fb(plane, &fb2);
+	crtc_commit(pipe, plane, COMMIT_LEGACY, CRTC_RELAX_MODE);
 
 	/* Restore the plane to its original settings through the legacy CRTC
 	 * API, and verify through atomic. */
-	crtc_commit_legacy(crtc, plane_old, CRTC_RELAX_MODE);
+	igt_plane_set_fb(plane, fb);
+	crtc_commit(pipe, plane, COMMIT_LEGACY, CRTC_RELAX_MODE);
 
-	/* Finally, restore to the original state. */
-	crtc_commit_atomic(crtc, plane_old, req, ATOMIC_RELAX_NONE, flags);
-
-	drmModeAtomicFree(req);
+	/* Set the plane through the universal setplane API, and
+	 * verify through atomic. */
+	igt_plane_set_fb(plane, &fb2);
+	plane_commit(plane, COMMIT_UNIVERSAL, ATOMIC_RELAX_NONE);
 }
 
 /* test to ensure that DRM_MODE_ATOMIC_TEST_ONLY really only touches the
  * free-standing state objects and nothing else.
  */
-static void test_only(struct kms_atomic_crtc_state *crtc,
-		      struct kms_atomic_plane_state *plane_old)
+static void test_only(igt_pipe_t *pipe_obj,
+		      igt_plane_t *primary,
+		      igt_output_t *output)
 {
-	struct drm_mode_modeinfo *mode = crtc->mode.data;
-	struct kms_atomic_plane_state plane = *plane_old;
-	uint32_t format = plane_get_igt_format(&plane);
-	drmModeAtomicReq *req = drmModeAtomicAlloc();
+	drmModeModeInfo *mode = igt_output_get_mode(output);
+	uint32_t format = plane_get_igt_format(primary);
 	struct igt_fb fb;
-	int ret;
+	uint64_t old_plane_values[IGT_NUM_PLANE_PROPS], old_crtc_values[IGT_NUM_CRTC_PROPS];
 
 	igt_require(format != 0);
 
-	plane.src_x = 0;
-	plane.src_y = 0;
-	plane.src_w = mode->hdisplay << 16;
-	plane.src_h = mode->vdisplay << 16;
-	plane.crtc_x = 0;
-	plane.crtc_y = 0;
-	plane.crtc_w = mode->hdisplay;
-	plane.crtc_h = mode->vdisplay;
-	plane.crtc_id = crtc->obj;
-	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
-					    plane.crtc_w, plane.crtc_h,
-					    format, I915_TILING_NONE, &fb);
-
-	drmModeAtomicSetCursor(req, 0);
-	crtc_populate_req(crtc, req);
-	plane_populate_req(&plane, req);
-	ret = drmModeAtomicCommit(crtc->state->desc->fd, req,
-				  DRM_MODE_ATOMIC_TEST_ONLY, NULL);
-
-	igt_assert_eq(ret, 0);
-
-	/* go through dpms off/on cycle */
-	set_dpms(crtc->state->desc->fd, DRM_MODE_DPMS_OFF);
-	set_dpms(crtc->state->desc->fd, DRM_MODE_DPMS_ON);
-
-	/* check the state */
-	crtc_check_current_state(crtc, plane_old, ATOMIC_RELAX_NONE);
-	plane_check_current_state(plane_old, ATOMIC_RELAX_NONE);
-
-	/* Re-enable the plane through the legacy CRTC/primary-plane API, and
-	 * verify through atomic. */
-	crtc_commit_legacy(crtc, plane_old, CRTC_RELAX_MODE);
+	plane_get_current_state(primary, old_plane_values);
+	crtc_get_current_state(pipe_obj, old_crtc_values);
+
+	igt_assert(!old_crtc_values[IGT_CRTC_MODE_ID]);
+
+	igt_create_pattern_fb(pipe_obj->display->drm_fd,
+			     mode->hdisplay, mode->vdisplay,
+			     format, I915_TILING_NONE, &fb);
+	igt_plane_set_fb(primary, &fb);
+	igt_output_set_pipe(output, pipe_obj->pipe);
+
+	igt_display_commit_atomic(pipe_obj->display, DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+	/* check the state, should still be old state */
+	crtc_check_current_state(pipe_obj, old_crtc_values, old_plane_values, ATOMIC_RELAX_NONE);
+	plane_check_current_state(primary, old_plane_values, ATOMIC_RELAX_NONE);
+
+	/*
+	 * Enable the plane through the legacy CRTC/primary-plane API, and
+	 * verify through atomic.
+	 */
+	crtc_commit(pipe_obj, primary, COMMIT_LEGACY, CRTC_RELAX_MODE);
+
+	/* Same for disable.. */
+	plane_get_current_state(primary, old_plane_values);
+	crtc_get_current_state(pipe_obj, old_crtc_values);
+
+	igt_plane_set_fb(primary, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
 
-	drmModeAtomicFree(req);
+	igt_display_commit_atomic(pipe_obj->display, DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+	/* for extra stress, go through dpms off/on cycle */
+	set_dpms(output, DRM_MODE_DPMS_OFF);
+	set_dpms(output, DRM_MODE_DPMS_ON);
+
+	/* check the state, should still be old state */
+	crtc_check_current_state(pipe_obj, old_crtc_values, old_plane_values, ATOMIC_RELAX_NONE);
+	plane_check_current_state(primary, old_plane_values, ATOMIC_RELAX_NONE);
+
+	/* And disable the pipe and remove fb, test complete */
+	crtc_commit(pipe_obj, primary, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
+	igt_remove_fb(pipe_obj->display->drm_fd, &fb);
 }
 
-static void plane_cursor(struct kms_atomic_crtc_state *crtc,
-			 struct kms_atomic_plane_state *plane_old)
+static void plane_cursor(igt_pipe_t *pipe_obj,
+			 igt_output_t *output,
+			 igt_plane_t *cursor)
 {
-	struct drm_mode_modeinfo *mode = crtc->mode.data;
-	struct kms_atomic_plane_state plane = *plane_old;
-	drmModeAtomicReq *req = drmModeAtomicAlloc();
+	drmModeModeInfo *mode = igt_output_get_mode(output);
 	struct igt_fb fb;
 	uint64_t width, height;
-
-	igt_assert(req);
+	int x = mode->hdisplay / 2;
+	int y = mode->vdisplay / 2;
 
 	/* Any kernel new enough for atomic, also has the cursor size caps. */
-	do_or_die(drmGetCap(plane.state->desc->fd,
+	do_or_die(drmGetCap(pipe_obj->display->drm_fd,
 	                    DRM_CAP_CURSOR_WIDTH, &width));
-	do_or_die(drmGetCap(plane.state->desc->fd,
+	do_or_die(drmGetCap(pipe_obj->display->drm_fd,
 	                    DRM_CAP_CURSOR_HEIGHT, &height));
 
-	plane.src_x = 0;
-	plane.src_y = 0;
-	plane.src_w = width << 16;
-	plane.src_h = height << 16;
-	plane.crtc_x = mode->hdisplay / 2;
-	plane.crtc_y = mode->vdisplay / 2;
-	plane.crtc_w = width;
-	plane.crtc_h = height;
-	plane.crtc_id = crtc->obj;
-	plane.fb_id = igt_create_color_fb(plane.state->desc->fd,
-					  width, height,
-					  DRM_FORMAT_ARGB8888,
-					  LOCAL_DRM_FORMAT_MOD_NONE,
-					  0.0, 0.0, 0.0,
-					  &fb);
-	igt_assert_neq_u32(plane.fb_id, 0);
+	igt_create_color_fb(pipe_obj->display->drm_fd,
+			    width, height, DRM_FORMAT_ARGB8888,
+			    LOCAL_DRM_FORMAT_MOD_NONE,
+			    0.0, 0.0, 0.0, &fb);
 
 	/* Flip the cursor plane using the atomic API, and double-check
 	 * state is what we think it should be. */
-	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
+	igt_plane_set_fb(cursor, &fb);
+	igt_plane_set_position(cursor, x, y);
+	plane_commit(cursor, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
 	/* Restore the cursor plane and check the state matches the old. */
-	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
+	igt_plane_set_fb(cursor, NULL);
+	igt_plane_set_position(cursor, 0, 0);
+	plane_commit(cursor, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
 	/* Re-enable the plane through the legacy cursor API, and verify
 	 * through atomic. */
-	do_or_die(drmModeMoveCursor(plane.state->desc->fd, plane.crtc_id,
-				    plane.crtc_x, plane.crtc_y));
-	do_or_die(drmModeSetCursor(plane.state->desc->fd, plane.crtc_id,
-				   fb.gem_handle, width, height));
-	plane_check_current_state(&plane, PLANE_RELAX_FB);
+	igt_plane_set_fb(cursor, &fb);
+	igt_plane_set_position(cursor, x, y);
+	plane_commit(cursor, COMMIT_LEGACY, PLANE_RELAX_FB);
 
 	/* Wiggle. */
-	plane.crtc_x -= 16;
-	plane.crtc_y -= 16;
-	do_or_die(drmModeMoveCursor(plane.state->desc->fd, plane.crtc_id,
-				    plane.crtc_x, plane.crtc_y));
-	plane_check_current_state(&plane, PLANE_RELAX_FB);
+	igt_plane_set_position(cursor, x - 16, y - 16);
+	plane_commit(cursor, COMMIT_LEGACY, PLANE_RELAX_FB);
 
 	/* Restore the plane to its original settings through the legacy cursor
 	 * API, and verify through atomic. */
-	do_or_die(drmModeSetCursor2(plane.state->desc->fd, plane.crtc_id,
-				    0, 0, 0, 0, 0));
-	plane_check_current_state(plane_old, ATOMIC_RELAX_NONE);
-
-	/* Finally, restore to the original state. */
-	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
-
-	drmModeAtomicFree(req);
+	igt_plane_set_fb(cursor, NULL);
+	igt_plane_set_position(cursor, 0, 0);
+	plane_commit(cursor, COMMIT_LEGACY, ATOMIC_RELAX_NONE);
 }
 
-static void plane_invalid_params(struct kms_atomic_crtc_state *crtc,
-				 struct kms_atomic_plane_state *plane_old,
-				 struct kms_atomic_connector_state *conn)
+static void plane_invalid_params(igt_pipe_t *pipe,
+				 igt_output_t *output,
+				 igt_plane_t *plane,
+				 struct igt_fb *fb)
 {
-	struct drm_mode_modeinfo *mode = crtc->mode.data;
-	struct kms_atomic_plane_state plane = *plane_old;
-	uint32_t format = plane_get_igt_format(&plane);
-	drmModeAtomicReq *req = drmModeAtomicAlloc();
-	struct igt_fb fb;
+	struct igt_fb fb2;
 
 	/* Pass a series of invalid object IDs for the FB ID. */
-	plane.fb_id = plane.obj;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, plane->drm_plane->plane_id);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	plane.fb_id = crtc->obj;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, pipe->crtc_id);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	plane.fb_id = conn->obj;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, output->id);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	plane.fb_id = crtc->mode.id;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, pipe->values[IGT_CRTC_MODE_ID]);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	plane.fb_id = plane_old->fb_id;
-	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
+	igt_plane_set_fb(plane, fb);
+	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
 	/* Pass a series of invalid object IDs for the CRTC ID. */
-	plane.crtc_id = plane.obj;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, plane->drm_plane->plane_id);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	plane.crtc_id = plane.fb_id;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, fb->fb_id);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	plane.crtc_id = conn->obj;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, output->id);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	plane.crtc_id = crtc->mode.id;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, pipe->values[IGT_CRTC_MODE_ID]);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	plane.crtc_id = plane_old->crtc_id;
-	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
+	igt_plane_set_fb(plane, fb);
+	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
 	/* Create a framebuffer too small for the plane configuration. */
-	igt_require(format != 0);
+	igt_create_pattern_fb(pipe->display->drm_fd,
+			      fb->width - 1, fb->height - 1,
+			      fb->drm_format, I915_TILING_NONE, &fb2);
 
-	plane.src_x = 0;
-	plane.src_y = 0;
-	plane.src_w = mode->hdisplay << 16;
-	plane.src_h = mode->vdisplay << 16;
-	plane.crtc_x = 0;
-	plane.crtc_y = 0;
-	plane.crtc_w = mode->hdisplay;
-	plane.crtc_h = mode->vdisplay;
-	plane.crtc_id = crtc->obj;
-	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
-					    plane.crtc_w - 1, plane.crtc_h - 1,
-					    format, I915_TILING_NONE, &fb);
-
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, ENOSPC);
+	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, fb2.fb_id);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, ENOSPC);
 
 	/* Restore the primary plane and check the state matches the old. */
-	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
-
-	drmModeAtomicFree(req);
+	igt_plane_set_fb(plane, fb);
+	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 }
 
-static void plane_invalid_params_fence(struct kms_atomic_crtc_state *crtc,
-				struct kms_atomic_plane_state *plane_old,
-				struct kms_atomic_connector_state *conn)
+static void plane_invalid_params_fence(igt_pipe_t *pipe,
+				       igt_output_t *output,
+				       igt_plane_t *plane)
 {
-	struct kms_atomic_plane_state plane = *plane_old;
-	drmModeAtomicReq *req = drmModeAtomicAlloc();
 	int timeline, fence_fd;
 
 	igt_require_sw_sync();
 
+	timeline = sw_sync_timeline_create();
+
 	/* invalid fence fd */
-	plane.fence_fd = plane.state->desc->fd;
-	plane.crtc_id = plane_old->crtc_id;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	igt_plane_set_fence_fd(plane, pipe->display->drm_fd);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
 
 	/* Valid fence_fd but invalid CRTC */
-	timeline = sw_sync_timeline_create();
-	fence_fd =  sw_sync_timeline_create_fence(timeline, 1);
-	plane.fence_fd = fence_fd;
-	plane.crtc_id = ~0U;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	fence_fd = sw_sync_timeline_create_fence(timeline, 1);
+
+	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, ~0);
+	igt_plane_set_fence_fd(plane, fence_fd);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
+
+	sw_sync_timeline_inc(timeline, 1);
+	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, pipe->crtc_id);
+	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
-	plane.fence_fd = -1;
 	close(fence_fd);
 	close(timeline);
-
-	drmModeAtomicFree(req);
 }
 
-static void crtc_invalid_params(struct kms_atomic_crtc_state *crtc_old,
-				struct kms_atomic_plane_state *plane,
-				struct kms_atomic_connector_state *conn)
+static void crtc_invalid_params(igt_pipe_t *pipe,
+				igt_output_t *output,
+				igt_plane_t *plane,
+				struct igt_fb *fb)
 {
-	struct kms_atomic_crtc_state crtc = *crtc_old;
-	drmModeAtomicReq *req = drmModeAtomicAlloc();
-
-	igt_assert(req);
+	uint64_t old_mode_id = pipe->values[IGT_CRTC_MODE_ID];
+	drmModeModeInfo *mode = igt_output_get_mode(output);
 
 	/* Pass a series of invalid object IDs for the mode ID. */
-	crtc.mode.id = plane->obj;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-	                       ATOMIC_RELAX_NONE, EINVAL);
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, plane->drm_plane->plane_id);
+	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	crtc.mode.id = crtc.obj;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-	                       ATOMIC_RELAX_NONE, EINVAL);
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, pipe->crtc_id);
+	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	crtc.mode.id = conn->obj;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-	                       ATOMIC_RELAX_NONE, EINVAL);
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, output->id);
+	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	crtc.mode.id = plane->fb_id;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-	                       ATOMIC_RELAX_NONE, EINVAL);
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, fb->fb_id);
+	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	/* successful TEST_ONLY with fences set */
-	crtc.mode.id = crtc_old->mode.id;
-	crtc_commit_atomic(&crtc, plane, req, ATOMIC_RELAX_NONE,
-			   DRM_MODE_ATOMIC_TEST_ONLY);
+	/* Can we restore mode? */
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, old_mode_id);
+	crtc_commit_atomic_flags_err(pipe, plane, DRM_MODE_ATOMIC_TEST_ONLY, ATOMIC_RELAX_NONE, 0);
 
 	/*
 	 * TEST_ONLY cannot be combined with DRM_MODE_PAGE_FLIP_EVENT,
 	 * but DRM_MODE_PAGE_FLIP_EVENT will always generate EINVAL
 	 * without valid crtc, so test it here.
 	 */
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
-			       DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_PAGE_FLIP_EVENT,
-			       ATOMIC_RELAX_NONE, EINVAL);
+	crtc_commit_atomic_flags_err(pipe, plane,
+				     DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_PAGE_FLIP_EVENT,
+				     ATOMIC_RELAX_NONE, EINVAL);
 
 	/* Create a blob which is the wrong size to be a valid mode. */
-	do_or_die(drmModeCreatePropertyBlob(crtc.state->desc->fd,
-					    crtc.mode.data,
-					    sizeof(struct drm_mode_modeinfo) - 1,
-					    &crtc.mode.id));
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-	                       ATOMIC_RELAX_NONE, EINVAL);
-
+	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, mode, sizeof(*mode) - 1);
+	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	do_or_die(drmModeCreatePropertyBlob(crtc.state->desc->fd,
-					    crtc.mode.data,
-					    sizeof(struct drm_mode_modeinfo) + 1,
-					    &crtc.mode.id));
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-	                       ATOMIC_RELAX_NONE, EINVAL);
+	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, mode, sizeof(*mode) + 1);
+	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, EINVAL);
 
 
 	/* Restore the CRTC and check the state matches the old. */
-	crtc_commit_atomic(crtc_old, plane, req, ATOMIC_RELAX_NONE, 0);
-
-	drmModeAtomicFree(req);
+	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, mode, sizeof(*mode));
+	crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 }
 
-static void crtc_invalid_params_fence(struct kms_atomic_crtc_state *crtc_old,
-				struct kms_atomic_plane_state *plane,
-				struct kms_atomic_connector_state *conn)
+static void crtc_invalid_params_fence(igt_pipe_t *pipe,
+				      igt_output_t *output,
+				      igt_plane_t *plane,
+				      struct igt_fb *fb)
 {
-	struct kms_atomic_crtc_state crtc = *crtc_old;
-	drmModeAtomicReq *req = drmModeAtomicAlloc();
-	int timeline, fence_fd, *out_fence;
+	int timeline, fence_fd;
+	void *map;
+	const ptrdiff_t PAGE_SIZE = sysconf(_SC_PAGE_SIZE);
+	uint64_t old_mode_id = pipe->values[IGT_CRTC_MODE_ID];
 
 	igt_require_sw_sync();
 
+	timeline = sw_sync_timeline_create();
+
+	/* invalid out_fence_ptr */
+	map = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+	igt_assert(map != MAP_FAILED);
+
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)map);
+	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, EFAULT);
+	munmap(map, PAGE_SIZE);
+
 	/* invalid out_fence_ptr */
-	crtc.mode.id = crtc_old->mode.id;
-	crtc.out_fence_ptr = (int32_t *) crtc_invalid_params;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-	                       ATOMIC_RELAX_NONE, EFAULT);
+	map = mmap(NULL, PAGE_SIZE, PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+	igt_assert(map != MAP_FAILED);
+
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)map);
+	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, EFAULT);
+	munmap(map, PAGE_SIZE);
 
 	/* invalid out_fence_ptr */
-	crtc.mode.id = crtc_old->mode.id;
-	crtc.out_fence_ptr = (int32_t *) 0x8;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-	                       ATOMIC_RELAX_NONE, EFAULT);
-	crtc.out_fence_ptr = (int32_t *) 0;
+	map = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+	igt_assert(map != MAP_FAILED);
+
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)map);
+	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, EFAULT);
+	munmap(map, PAGE_SIZE);
 
 	/* valid in fence but not allowed prop on crtc */
-	timeline = sw_sync_timeline_create();
-	fence_fd =  sw_sync_timeline_create_fence(timeline, 1);
-	plane->fence_fd = fence_fd;
-	crtc.active = false;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-			       ATOMIC_RELAX_NONE, EINVAL);
+	fence_fd = sw_sync_timeline_create_fence(timeline, 1);
+	igt_plane_set_fence_fd(plane, fence_fd);
 
-	out_fence = malloc(sizeof(uint64_t));
-	igt_assert(out_fence);
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_ACTIVE, 0);
+	igt_pipe_obj_clear_prop_changed(pipe, IGT_CRTC_OUT_FENCE_PTR);
 
+	crtc_commit_atomic_flags_err(pipe, plane, 0, ATOMIC_RELAX_NONE, EINVAL);
 
 	/* valid out fence ptr and flip event but not allowed prop on crtc */
-	crtc.out_fence_ptr = (int32_t *) out_fence;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-			       ATOMIC_RELAX_NONE, EINVAL);
+	igt_pipe_request_out_fence(pipe);
+	crtc_commit_atomic_flags_err(pipe, plane, DRM_MODE_PAGE_FLIP_EVENT,
+				     ATOMIC_RELAX_NONE, EINVAL);
 
-	/* valid out fence ptr and flip event but not allowed prop on crtc */
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
-			       DRM_MODE_PAGE_FLIP_EVENT,
-			       ATOMIC_RELAX_NONE, EINVAL);
-
-	/* valid page flip event but not allowed prop on crtc */
-	crtc.out_fence_ptr = (int32_t *) 0;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
-			       DRM_MODE_PAGE_FLIP_EVENT,
-			       ATOMIC_RELAX_NONE, EINVAL);
-	crtc.active = true;
-
-	/* valid out fence  ptr and flip event but invalid prop on crtc */
-	crtc.out_fence_ptr = (int32_t *) out_fence;
-	crtc.mode.id = plane->fb_id;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-			       ATOMIC_RELAX_NONE, EINVAL);
+	/* valid flip event but not allowed prop on crtc */
+	igt_pipe_obj_clear_prop_changed(pipe, IGT_CRTC_OUT_FENCE_PTR);
+	crtc_commit_atomic_flags_err(pipe, plane, DRM_MODE_PAGE_FLIP_EVENT,
+				     ATOMIC_RELAX_NONE, EINVAL);
+
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_ACTIVE, 1);
+
+	/* Configuration should be valid again */
+	crtc_commit_atomic_flags_err(pipe, plane, DRM_MODE_ATOMIC_TEST_ONLY,
+				     ATOMIC_RELAX_NONE, 0);
+
+	/* Set invalid prop */
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, fb->fb_id);
+
+	/* valid out fence but invalid prop on crtc */
+	igt_pipe_request_out_fence(pipe);
+	crtc_commit_atomic_flags_err(pipe, plane, 0,
+				     ATOMIC_RELAX_NONE, EINVAL);
 
 	/* valid out fence ptr and flip event but invalid prop on crtc */
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
-			       DRM_MODE_PAGE_FLIP_EVENT,
-			       ATOMIC_RELAX_NONE, EINVAL);
+	crtc_commit_atomic_flags_err(pipe, plane, DRM_MODE_PAGE_FLIP_EVENT,
+				     ATOMIC_RELAX_NONE, EINVAL);
 
 	/* valid page flip event but invalid prop on crtc */
-	crtc.out_fence_ptr = (int32_t *) 0;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
-			       DRM_MODE_PAGE_FLIP_EVENT,
-			       ATOMIC_RELAX_NONE, EINVAL);
+	crtc_commit_atomic_flags_err(pipe, plane, DRM_MODE_PAGE_FLIP_EVENT,
+				     ATOMIC_RELAX_NONE, EINVAL);
 
 	/* successful TEST_ONLY with fences set */
-	plane->fence_fd = fence_fd;
-	crtc.mode.id = crtc_old->mode.id;
-	crtc_commit_atomic(&crtc, plane, req, ATOMIC_RELAX_NONE,
-			   DRM_MODE_ATOMIC_TEST_ONLY);
-	igt_assert(*out_fence == -1);
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, old_mode_id);
+	crtc_commit_atomic_flags_err(pipe, plane, DRM_MODE_ATOMIC_TEST_ONLY,
+				     ATOMIC_RELAX_NONE, 0);
+	igt_assert(pipe->out_fence_fd == -1);
 	close(fence_fd);
 	close(timeline);
 
 	/* reset fences */
-	plane->fence_fd = -1;
-	crtc.out_fence_ptr = (int32_t *) 0;
-	crtc_commit_atomic(&crtc, plane, req, ATOMIC_RELAX_NONE, 0);
+	igt_plane_set_fence_fd(plane, -1);
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, 0);
+	igt_pipe_obj_clear_prop_changed(pipe, IGT_CRTC_OUT_FENCE_PTR);
+	crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
 	/* out fence ptr but not page flip event */
-	crtc.out_fence_ptr = (int32_t *) out_fence;
-	crtc_commit_atomic(crtc_old, plane, req, ATOMIC_RELAX_NONE, 0);
+	igt_pipe_request_out_fence(pipe);
+	crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
-	close(*out_fence);
-	free(out_fence);
-	drmModeAtomicFree(req);
+	igt_assert(pipe->out_fence_fd != -1);
 }
 
 /* Abuse the atomic ioctl directly in order to test various invalid conditions,
  * which the libdrm wrapper won't allow us to create. */
-static void atomic_invalid_params(struct kms_atomic_crtc_state *crtc,
-				  struct kms_atomic_plane_state *plane,
-				  struct kms_atomic_connector_state *connector)
+static void atomic_invalid_params(igt_pipe_t *pipe,
+				  igt_plane_t *plane,
+				  igt_output_t *output,
+				  struct igt_fb *fb)
 {
-	struct kms_atomic_desc *desc = crtc->state->desc;
+	igt_display_t *display = pipe->display;
 	struct drm_mode_atomic ioc;
 	uint32_t obj_raw[16]; /* array of objects (sized by count_objs) */
 	uint32_t num_props_raw[16]; /* array of num props per obj (ditto) */
@@ -1346,7 +718,7 @@ static void atomic_invalid_params(struct kms_atomic_crtc_state *crtc,
 	memset(&ioc, 0, sizeof(ioc));
 
 	/* An empty request should do nothing. */
-	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
+	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
 
 	for (i = 0; i < ARRAY_SIZE(obj_raw); i++)
 		obj_raw[i] = 0;
@@ -1363,248 +735,228 @@ static void atomic_invalid_params(struct kms_atomic_crtc_state *crtc,
 	ioc.prop_values_ptr = (uintptr_t) values_raw;
 
 	/* Valid pointers, but still should copy nothing. */
-	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
+	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
 
 	/* Valid noop, but with event set should fail. */
 	ioc.flags = DRM_MODE_PAGE_FLIP_EVENT;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EINVAL);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EINVAL);
 
 	/* Nonsense flags. */
 	ioc.flags = 0xdeadbeef;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EINVAL);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EINVAL);
 
 	ioc.flags = 0;
 	/* Safety check that flags is reset properly. */
-	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
+	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
 
 	/* Reserved/MBZ. */
 	ioc.reserved = 1;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EINVAL);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EINVAL);
 	ioc.reserved = 0;
-	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
+	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
 
 	/* Zero is not a valid object ID. */
 	ioc.count_objs = ARRAY_SIZE(obj_raw);
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
 
 	/* Invalid object type (not a thing we can set properties on). */
 	ioc.count_objs = 1;
-	obj_raw[0] = crtc->mode.id;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
-	obj_raw[0] = plane->fb_id;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
+	obj_raw[0] = pipe->values[IGT_CRTC_MODE_ID];
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
+	obj_raw[0] = fb->fb_id;
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
 
 	/* Filled object but with no properties; no-op. */
 	for (i = 0; i < ARRAY_SIZE(obj_raw); i++)
-		obj_raw[i] = crtc->obj;
-	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
+		obj_raw[i] = pipe->crtc_id;
+	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
 
 	/* Pass in all sorts of things other than the property ID. */
 	num_props_raw[0] = 1;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
-	props_raw[0] = crtc->obj;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
-	props_raw[0] = plane->obj;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
-	props_raw[0] = connector->obj;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
-	props_raw[0] = crtc->mode.id;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
+	props_raw[0] = pipe->crtc_id;
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
+	props_raw[0] = plane->drm_plane->plane_id;
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
+	props_raw[0] = output->id;
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
+	props_raw[0] = pipe->values[IGT_CRTC_MODE_ID];
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
 
 	/* Valid property, valid value. */
 	for (i = 0; i < ARRAY_SIZE(props_raw); i++) {
-		props_raw[i] = desc->props_crtc[IGT_CRTC_MODE_ID];
-		values_raw[i] = crtc->mode.id;
+		props_raw[i] = pipe->props[IGT_CRTC_MODE_ID];
+		values_raw[i] = pipe->values[IGT_CRTC_MODE_ID];
 	}
-	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
+	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
 
 	/* Setting the same thing multiple times is OK. */
 	for (i = 0; i < ARRAY_SIZE(obj_raw); i++)
 		num_props_raw[i] = ARRAY_SIZE(props_raw) / ARRAY_SIZE(obj_raw);
-	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
+	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
 	ioc.count_objs = ARRAY_SIZE(obj_raw);
-	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
+	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
 
 	/* Pass a series of outlandish addresses. */
 	ioc.objs_ptr = 0;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
 
 	ioc.objs_ptr = (uintptr_t) obj_raw;
 	ioc.count_props_ptr = 0;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
 
 	ioc.count_props_ptr = (uintptr_t) num_props_raw;
 	ioc.props_ptr = 0;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
 
 	ioc.props_ptr = (uintptr_t) props_raw;
 	ioc.prop_values_ptr = 0;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
 
 	ioc.prop_values_ptr = (uintptr_t) values_raw;
-	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
+	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
 
 	/* Attempt to overflow and/or trip various boundary conditions. */
 	ioc.count_objs = UINT32_MAX / sizeof(uint32_t);
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
 
 	ioc.count_objs = ARRAY_SIZE(obj_raw);
 	ioc.objs_ptr = UINT64_MAX - sizeof(uint32_t);
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
 	ioc.count_objs = 1;
 	ioc.objs_ptr = UINT64_MAX - sizeof(uint32_t);
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
 
 	num_props_raw[0] = UINT32_MAX / sizeof(uint32_t);
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
 	num_props_raw[0] = UINT32_MAX - 1;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
 
 	for (i = 0; i < ARRAY_SIZE(obj_raw); i++)
 		num_props_raw[i] = (UINT32_MAX / ARRAY_SIZE(obj_raw)) + 1;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
 	for (i = 0; i < ARRAY_SIZE(obj_raw); i++)
 		num_props_raw[i] = ARRAY_SIZE(props_raw) / ARRAY_SIZE(obj_raw);
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+}
+
+static void atomic_setup(igt_display_t *display, enum pipe pipe, igt_output_t *output, igt_plane_t *primary, struct igt_fb *fb)
+{
+	igt_output_set_pipe(output, pipe);
+	igt_plane_set_fb(primary, fb);
+
+	crtc_commit(primary->pipe, primary, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
+}
+
+static void atomic_clear(igt_display_t *display, enum pipe pipe, igt_plane_t *primary, igt_output_t *output)
+{
+	igt_plane_t *plane;
+
+	for_each_plane_on_pipe(display, pipe, plane) {
+		igt_plane_set_fb(plane, NULL);
+		igt_plane_set_position(plane, 0, 0);
+	}
+
+	igt_output_set_pipe(output, PIPE_NONE);
+	crtc_commit(primary->pipe, primary, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 }
 
 igt_main
 {
-	struct kms_atomic_desc desc;
-	struct kms_atomic_state *current;
+	igt_display_t display;
+	enum pipe pipe = PIPE_NONE;
+	igt_pipe_t *pipe_obj;
+	igt_output_t *output = NULL;
+	igt_plane_t *primary = NULL;
+	drmModeModeInfo *mode;
+	struct igt_fb fb;
+
+	igt_fixture {
+		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
+
+		kmstest_set_vt_graphics_mode();
+
+		igt_display_init(&display, display.drm_fd);
+
+		igt_require(display.is_atomic);
+		igt_display_require_output(&display);
 
-	memset(&desc, 0, sizeof(desc));
+		for_each_pipe_with_valid_output(&display, pipe, output)
+			break;
+
+		pipe_obj = &display.pipes[pipe];
+		primary = igt_pipe_get_plane_type(pipe_obj, DRM_PLANE_TYPE_PRIMARY);
 
-	current = calloc(1, sizeof(*current));
-	igt_assert(current);
-	current->desc = &desc;
+		mode = igt_output_get_mode(output);
 
-	igt_fixture
-		atomic_setup(current);
+		igt_create_pattern_fb(display.drm_fd,
+				      mode->hdisplay, mode->vdisplay,
+				      plane_get_igt_format(primary),
+				      LOCAL_DRM_FORMAT_MOD_NONE, &fb);
+	}
 
 	igt_subtest("plane_overlay_legacy") {
-		struct kms_atomic_state *scratch = atomic_state_dup(current);
-		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
-		struct kms_atomic_plane_state *plane =
-			find_plane(scratch, PLANE_TYPE_OVERLAY, crtc);
-
-		igt_require(crtc);
-		igt_require(plane);
-		plane_overlay(crtc, plane);
-		atomic_state_free(scratch);
+		igt_plane_t *overlay =
+			igt_pipe_get_plane_type(pipe_obj, DRM_PLANE_TYPE_OVERLAY);
+
+		igt_require(overlay);
+
+		atomic_setup(&display, pipe, output, primary, &fb);
+		plane_overlay(pipe_obj, output, overlay);
 	}
 
 	igt_subtest("plane_primary_legacy") {
-		struct kms_atomic_state *scratch = atomic_state_dup(current);
-		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
-		struct kms_atomic_plane_state *plane =
-			find_plane(scratch, PLANE_TYPE_PRIMARY, crtc);
-
-		igt_require(crtc);
-		igt_require(plane);
-		plane_primary(crtc, plane);
-		atomic_state_free(scratch);
+		atomic_setup(&display, pipe, output, primary, &fb);
+
+		plane_primary(pipe_obj, primary, &fb);
 	}
 
 	igt_subtest("test_only") {
-		struct kms_atomic_state *scratch = atomic_state_dup(current);
-		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
-		struct kms_atomic_plane_state *plane =
-			find_plane(scratch, PLANE_TYPE_PRIMARY, crtc);
-
-		igt_require(crtc);
-		igt_require(plane);
-		test_only(crtc, plane);
-		atomic_state_free(scratch);
-	}
+		atomic_clear(&display, pipe, primary, output);
 
+		test_only(pipe_obj, primary, output);
+	}
 	igt_subtest("plane_cursor_legacy") {
-		struct kms_atomic_state *scratch = atomic_state_dup(current);
-		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
-		struct kms_atomic_plane_state *plane =
-			find_plane(scratch, PLANE_TYPE_CURSOR, crtc);
-
-		igt_require(crtc);
-		igt_require(plane);
-		plane_cursor(crtc, plane);
-		atomic_state_free(scratch);
+		igt_plane_t *cursor =
+			igt_pipe_get_plane_type(pipe_obj, DRM_PLANE_TYPE_CURSOR);
+
+		igt_require(cursor);
+
+		atomic_setup(&display, pipe, output, primary, &fb);
+		plane_cursor(pipe_obj, output, cursor);
 	}
 
 	igt_subtest("plane_invalid_params") {
-		struct kms_atomic_state *scratch = atomic_state_dup(current);
-		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
-		struct kms_atomic_plane_state *plane =
-			find_plane(current, PLANE_TYPE_PRIMARY, crtc);
-		struct kms_atomic_connector_state *conn =
-			find_connector(scratch, crtc);
-
-		igt_require(crtc);
-		igt_require(plane);
-		plane_invalid_params(crtc, plane, conn);
-		atomic_state_free(scratch);
+		atomic_setup(&display, pipe, output, primary, &fb);
+
+		plane_invalid_params(pipe_obj, output, primary, &fb);
 	}
 
 	igt_subtest("plane_invalid_params_fence") {
-		struct kms_atomic_state *scratch = atomic_state_dup(current);
-		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
-		struct kms_atomic_plane_state *plane =
-			find_plane(current, PLANE_TYPE_PRIMARY, crtc);
-		struct kms_atomic_connector_state *conn =
-			find_connector(scratch, crtc);
-
-		igt_require(crtc);
-		igt_require(plane);
-		plane_invalid_params_fence(crtc, plane, conn);
-		atomic_state_free(scratch);
+		atomic_setup(&display, pipe, output, primary, &fb);
+
+		plane_invalid_params_fence(pipe_obj, output, primary);
 	}
 
 	igt_subtest("crtc_invalid_params") {
-		struct kms_atomic_state *scratch = atomic_state_dup(current);
-		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
-		struct kms_atomic_plane_state *plane =
-			find_plane(scratch, NUM_PLANE_TYPE_PROPS, crtc);
-		struct kms_atomic_connector_state *conn =
-			find_connector(scratch, crtc);
-
-		igt_require(crtc);
-		igt_require(plane);
-		igt_require(conn);
-		crtc_invalid_params(crtc, plane, conn);
-		atomic_state_free(scratch);
+		atomic_setup(&display, pipe, output, primary, &fb);
+
+		crtc_invalid_params(pipe_obj, output, primary, &fb);
 	}
 
 	igt_subtest("crtc_invalid_params_fence") {
-		struct kms_atomic_state *scratch = atomic_state_dup(current);
-		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
-		struct kms_atomic_plane_state *plane =
-			find_plane(scratch, NUM_PLANE_TYPE_PROPS, crtc);
-		struct kms_atomic_connector_state *conn =
-			find_connector(scratch, crtc);
-
-		igt_require(crtc);
-		igt_require(plane);
-		igt_require(conn);
-		crtc_invalid_params_fence(crtc, plane, conn);
-		atomic_state_free(scratch);
-	}
+		atomic_setup(&display, pipe, output, primary, &fb);
 
-	igt_subtest("atomic_invalid_params") {
-		struct kms_atomic_state *scratch = atomic_state_dup(current);
-		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
-		struct kms_atomic_plane_state *plane =
-			find_plane(scratch, NUM_PLANE_TYPE_PROPS, crtc);
-		struct kms_atomic_connector_state *conn =
-			find_connector(scratch, crtc);
-
-		igt_require(crtc);
-		igt_require(plane);
-		igt_require(conn);
-		atomic_invalid_params(crtc, plane, conn);
-		atomic_state_free(scratch);
+		crtc_invalid_params_fence(pipe_obj, output, primary, &fb);
 	}
 
-	atomic_state_free(current);
+	igt_subtest("atomic_invalid_params")
+		atomic_invalid_params(pipe_obj, primary, output, &fb);
 
-	igt_fixture
-		close(desc.fd);
+	igt_fixture {
+		atomic_clear(&display, pipe, primary, output);
+		igt_remove_fb(display.drm_fd, &fb);
+
+		igt_display_fini(&display);
+	}
 }
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* ✓ Fi.CI.BAT: success for lib/igt_kms: Rewrite property handling to better match atomic. (rev4)
  2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
                   ` (13 preceding siblings ...)
  2017-10-12 11:54 ` [PATCH i-g-t v2 14/14] tests/kms_atomic: Convert/rewrite tests to use igt_kms framework Maarten Lankhorst
@ 2017-10-12 12:28 ` Patchwork
  2017-10-12 15:01 ` ✗ Fi.CI.IGT: failure " Patchwork
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 45+ messages in thread
From: Patchwork @ 2017-10-12 12:28 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: lib/igt_kms: Rewrite property handling to better match atomic. (rev4)
URL   : https://patchwork.freedesktop.org/series/31733/
State : success

== Summary ==

IGT patchset tested on top of latest successful build
f0bfbad1cf1d01e65112310e95ba5ecba15133d1 benchmark/gem_busy: Compare polling with syncobj_wait

with latest DRM-Tip kernel build CI_DRM_3222
a869721e93a5 drm-tip: 2017y-10m-12d-08h-30m-31s UTC integration manifest

No testlist changes.

fi-bdw-5557u     total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:451s
fi-bdw-gvtdvm    total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:475s
fi-blb-e6850     total:289  pass:223  dwarn:1   dfail:0   fail:0   skip:65  time:398s
fi-bsw-n3050     total:289  pass:243  dwarn:0   dfail:0   fail:0   skip:46  time:575s
fi-bwr-2160      total:289  pass:183  dwarn:0   dfail:0   fail:0   skip:106 time:290s
fi-bxt-dsi       total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:526s
fi-bxt-j4205     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:525s
fi-byt-j1900     total:289  pass:253  dwarn:1   dfail:0   fail:0   skip:35  time:541s
fi-byt-n2820     total:289  pass:249  dwarn:1   dfail:0   fail:0   skip:39  time:526s
fi-cfl-s         total:289  pass:253  dwarn:4   dfail:0   fail:0   skip:32  time:567s
fi-elk-e7500     total:289  pass:229  dwarn:0   dfail:0   fail:0   skip:60  time:429s
fi-gdg-551       total:289  pass:178  dwarn:1   dfail:0   fail:1   skip:109 time:277s
fi-glk-1         total:289  pass:261  dwarn:0   dfail:0   fail:0   skip:28  time:595s
fi-hsw-4770r     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:438s
fi-ilk-650       total:289  pass:228  dwarn:0   dfail:0   fail:0   skip:61  time:461s
fi-ivb-3520m     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:504s
fi-ivb-3770      total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:477s
fi-kbl-7500u     total:289  pass:264  dwarn:1   dfail:0   fail:0   skip:24  time:505s
fi-kbl-7567u     total:289  pass:265  dwarn:4   dfail:0   fail:0   skip:20  time:495s
fi-kbl-r         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:590s
fi-pnv-d510      total:289  pass:222  dwarn:1   dfail:0   fail:0   skip:66  time:664s
fi-skl-6260u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:468s
fi-skl-6700hq    total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:662s
fi-skl-6700k     total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:533s
fi-skl-6770hq    total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:512s
fi-skl-gvtdvm    total:289  pass:266  dwarn:0   dfail:0   fail:0   skip:23  time:473s
fi-snb-2520m     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:582s
fi-snb-2600      total:289  pass:249  dwarn:0   dfail:0   fail:0   skip:40  time:440s

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_337/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* ✗ Fi.CI.IGT: failure for lib/igt_kms: Rewrite property handling to better match atomic. (rev4)
  2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
                   ` (14 preceding siblings ...)
  2017-10-12 12:28 ` ✓ Fi.CI.BAT: success for lib/igt_kms: Rewrite property handling to better match atomic. (rev4) Patchwork
@ 2017-10-12 15:01 ` Patchwork
  2017-10-12 16:04 ` ✓ Fi.CI.BAT: success for lib/igt_kms: Rewrite property handling to better match atomic. (rev6) Patchwork
  2017-10-12 23:47 ` ✗ Fi.CI.IGT: failure " Patchwork
  17 siblings, 0 replies; 45+ messages in thread
From: Patchwork @ 2017-10-12 15:01 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: lib/igt_kms: Rewrite property handling to better match atomic. (rev4)
URL   : https://patchwork.freedesktop.org/series/31733/
State : failure

== Summary ==

Test perf:
        Subgroup polling:
                pass       -> FAIL       (shard-hsw) fdo#102252
Test prime_self_import:
        Subgroup reimport-vs-gem_close-race:
                fail       -> PASS       (shard-hsw) fdo#102655
Test kms_frontbuffer_tracking:
        Subgroup fbc-1p-rte:
                pass       -> SKIP       (shard-hsw)
        Subgroup fbc-farfromfence:
                pass       -> SKIP       (shard-hsw)
        Subgroup fbc-1p-primscrn-indfb-msflip-blt:
                pass       -> SKIP       (shard-hsw)
        Subgroup fbc-1p-offscren-pri-shrfb-draw-mmap-wc:
                dmesg-warn -> PASS       (shard-hsw) fdo#102614
Test kms_universal_plane:
        Subgroup cursor-fb-leak-pipe-A:
                pass       -> SKIP       (shard-hsw)
Test kms_crtc_background_color:
                skip       -> FAIL       (shard-hsw)
Test kms_atomic:
        Subgroup atomic_invalid_params:
                pass       -> FAIL       (shard-hsw)

fdo#102252 https://bugs.freedesktop.org/show_bug.cgi?id=102252
fdo#102655 https://bugs.freedesktop.org/show_bug.cgi?id=102655
fdo#102614 https://bugs.freedesktop.org/show_bug.cgi?id=102614

shard-hsw        total:2551 pass:1434 dwarn:0   dfail:0   fail:11  skip:1106 time:9555s

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_337/shards.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* [PATCH i-g-t v2] lib/igt_kms: Add igt_$obj_has_prop functions, v2.
  2017-10-12 11:54 ` [PATCH i-g-t v2 08/14] lib/igt_kms: Add igt_$obj_has_prop functions Maarten Lankhorst
@ 2017-10-12 15:33   ` Maarten Lankhorst
  2017-10-19 12:06     ` Mika Kahola
  0 siblings, 1 reply; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-12 15:33 UTC (permalink / raw)
  To: intel-gfx

This allows test to test whether a property is supported, in
a nice and clean way. It removes the need for special case
functions like igt_plane_supports_rotation.

Convert the users of igt_plane_supports_rotation and remove the
extra check in drm_plane_commit, this is already checked below
when setting plane properties.

Changes since v1:
- Use the correct has_prop in kms_crtc_background_color.c

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 lib/igt_kms.c                     |  4 ---
 lib/igt_kms.h                     | 62 ++++++++++++++++++++++++++++++++++++---
 tests/kms_crtc_background_color.c |  2 +-
 tests/kms_rotation_crc.c          |  6 ++--
 4 files changed, 62 insertions(+), 12 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index ad0855d0c8fa..339c11843154 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -2110,10 +2110,6 @@ static int igt_drm_plane_commit(igt_plane_t *plane,
 
 	igt_assert(plane->drm_plane);
 
-	/* it's an error to try an unsupported feature */
-	igt_assert(igt_plane_supports_rotation(plane) ||
-		   !igt_plane_is_prop_changed(plane, IGT_PLANE_ROTATION));
-
 	fb_id = igt_plane_get_fb_id(plane);
 	crtc_id = pipe->crtc_id;
 
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index b8a04af73e2f..916cd359519a 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -374,10 +374,6 @@ bool igt_pipe_get_property(igt_pipe_t *pipe, const char *name,
 			   uint32_t *prop_id, uint64_t *value,
 			   drmModePropertyPtr *prop);
 
-static inline bool igt_plane_supports_rotation(igt_plane_t *plane)
-{
-	return plane->props[IGT_PLANE_ROTATION] != 0;
-}
 void igt_pipe_request_out_fence(igt_pipe_t *pipe);
 
 void igt_plane_set_fb(igt_plane_t *plane, struct igt_fb *fb);
@@ -493,6 +489,20 @@ static inline bool igt_output_is_connected(igt_output_t *output)
 
 #define IGT_FIXED(i,f)	((i) << 16 | (f))
 
+/**
+ * igt_plane_has_prop - Check whether plane supports a given property.
+ *
+ * @plane: Plane to check.
+ * @prop: Property to check.
+ *
+ * Returns: True if the property is supported, otherwise false.
+ */
+static inline bool
+igt_plane_has_prop(igt_plane_t *plane, enum igt_atomic_plane_properties prop)
+{
+	return plane->props[prop];
+}
+
 #define igt_plane_is_prop_changed(plane, prop) \
 	(!!((plane)->changed & (1 << (prop))))
 
@@ -512,6 +522,20 @@ extern void igt_plane_replace_prop_blob(igt_plane_t *plane,
 					enum igt_atomic_plane_properties prop,
 					const void *ptr, size_t length);
 
+/**
+ * igt_output_has_prop - Check whether output supports a given property.
+ *
+ * @output: Output to check.
+ * @prop: Property to check.
+ *
+ * Returns: True if the property is supported, otherwise false.
+ */
+static inline bool
+igt_output_has_prop(igt_output_t *output, enum igt_atomic_connector_properties prop)
+{
+	return output->props[prop];
+}
+
 #define igt_output_is_prop_changed(output, prop) \
 	(!!((output)->changed & (1 << (prop))))
 #define igt_output_set_prop_changed(output, prop) \
@@ -530,6 +554,36 @@ extern void igt_output_replace_prop_blob(igt_output_t *output,
 					 enum igt_atomic_connector_properties prop,
 					 const void *ptr, size_t length);
 
+/**
+ * igt_pipe_obj_has_prop - Check whether pipe supports a given property.
+ *
+ * @pipe: Pipe to check.
+ * @prop: Property to check.
+ *
+ * Returns: True if the property is supported, otherwise false.
+ */
+static inline bool
+igt_pipe_obj_has_prop(igt_pipe_t *pipe, enum igt_atomic_crtc_properties prop)
+{
+	return pipe->props[prop];
+}
+
+/**
+ * igt_pipe_has_prop - Check whether pipe supports a given property.
+ *
+ * @display: Pointer to display.
+ * @pipe: Pipe to check.
+ * @prop: Property to check.
+ *
+ * Returns: True if the property is supported, otherwise false.
+ */
+static inline bool
+igt_pipe_has_prop(igt_display_t *display, enum pipe pipe,
+		  enum igt_atomic_connector_properties prop)
+{
+	return display->pipes[pipe].props[prop];
+}
+
 #define igt_pipe_obj_is_prop_changed(pipe_obj, prop) \
 	(!!((pipe_obj)->changed & (1 << (prop))))
 
diff --git a/tests/kms_crtc_background_color.c b/tests/kms_crtc_background_color.c
index 659a30b90219..ecd13a56712e 100644
--- a/tests/kms_crtc_background_color.c
+++ b/tests/kms_crtc_background_color.c
@@ -137,7 +137,7 @@ static void test_crtc_background(data_t *data)
 		igt_output_set_pipe(output, pipe);
 
 		plane = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
-		igt_require(plane->pipe->props[IGT_CRTC_BACKGROUND]);
+		igt_require(igt_pipe_has_prop(display, pipe, IGT_CRTC_BACKGROUND));
 
 		prepare_crtc(data, output, pipe, plane, 1, PURPLE, BLACK64);
 
diff --git a/tests/kms_rotation_crc.c b/tests/kms_rotation_crc.c
index b8327dfa0d83..27d1f8060234 100644
--- a/tests/kms_rotation_crc.c
+++ b/tests/kms_rotation_crc.c
@@ -351,7 +351,7 @@ static void test_plane_rotation(data_t *data, int plane_type)
 		igt_output_set_pipe(output, pipe);
 
 		plane = igt_output_get_plane_type(output, plane_type);
-		igt_require(igt_plane_supports_rotation(plane));
+		igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
 
 		prepare_crtc(data, output, pipe, plane, commit);
 
@@ -438,7 +438,7 @@ static void test_plane_rotation_ytiled_obj(data_t *data,
 	int ret;
 
 	plane = igt_output_get_plane_type(output, plane_type);
-	igt_require(igt_plane_supports_rotation(plane));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
 
 	if (plane_type == DRM_PLANE_TYPE_PRIMARY || plane_type == DRM_PLANE_TYPE_CURSOR)
 		commit = COMMIT_UNIVERSAL;
@@ -504,7 +504,7 @@ static void test_plane_rotation_exhaust_fences(data_t *data,
 	int i, ret;
 
 	plane = igt_output_get_plane_type(output, plane_type);
-	igt_require(igt_plane_supports_rotation(plane));
+	igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
 
 	if (plane_type == DRM_PLANE_TYPE_PRIMARY || plane_type == DRM_PLANE_TYPE_CURSOR)
 		commit = COMMIT_UNIVERSAL;
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH i-g-t v2] tests/kms_atomic: Convert/rewrite tests to use igt_kms framework, v2.
  2017-10-12 11:54 ` [PATCH i-g-t v2 14/14] tests/kms_atomic: Convert/rewrite tests to use igt_kms framework Maarten Lankhorst
@ 2017-10-12 15:33   ` Maarten Lankhorst
  2017-10-20 10:02     ` Mika Kahola
  0 siblings, 1 reply; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-12 15:33 UTC (permalink / raw)
  To: intel-gfx; +Cc: Daniel Stone

Now that we can set individual properties through the igt_kms api,
we no longer need to duplicate functionality from igt_kms. Set invalid
properties directly, and rewrite kms_atomic.c to use igt_display.
This will allow us to remove a lot of code in kms_atomic.c,
and benefit from how igt_kms can set up a valid configuration,
instead of having to inherit it from fbcon.

Changes since v1:
- Fix test failure when atomic_invalid_params is run standalone.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Daniel Stone <daniels@collabora.com>
---
 tests/kms_atomic.c | 1668 ++++++++++++++++------------------------------------
 1 file changed, 512 insertions(+), 1156 deletions(-)

diff --git a/tests/kms_atomic.c b/tests/kms_atomic.c
index 042a7c263aab..e0fc324eab61 100644
--- a/tests/kms_atomic.c
+++ b/tests/kms_atomic.c
@@ -46,10 +46,6 @@
 #include "igt_aux.h"
 #include "sw_sync.h"
 
-#ifndef DRM_CLIENT_CAP_ATOMIC
-#define DRM_CLIENT_CAP_ATOMIC 3
-#endif
-
 #ifndef DRM_CAP_CURSOR_WIDTH
 #define DRM_CAP_CURSOR_WIDTH 0x8
 #endif
@@ -58,23 +54,6 @@
 #define DRM_CAP_CURSOR_HEIGHT 0x9
 #endif
 
-#ifndef DRM_MODE_ATOMIC_TEST_ONLY
-#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
-#define DRM_MODE_ATOMIC_NONBLOCK 0x0200
-#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
-
-struct drm_mode_atomic {
-	__u32 flags;
-	__u32 count_objs;
-	__u64 objs_ptr;
-	__u64 count_props_ptr;
-	__u64 props_ptr;
-	__u64 prop_values_ptr;
-	__u64 reserved;
-	__u64 user_data;
-};
-#endif
-
 IGT_TEST_DESCRIPTION("Test atomic modesetting API");
 
 enum kms_atomic_check_relax {
@@ -83,1259 +62,652 @@ enum kms_atomic_check_relax {
 	PLANE_RELAX_FB = (1 << 1)
 };
 
-/**
- * KMS plane type enum
- *
- * KMS plane types are represented by enums, which do not have stable numeric
- * values, but must be looked up by their string value each time.
- *
- * To make the code more simple, we define a plane_type enum which maps to
- * each KMS enum value. These values must be looked up through the map, and
- * cannot be passed directly to KMS functions.
- */
-enum plane_type {
-	PLANE_TYPE_PRIMARY = 0,
-	PLANE_TYPE_OVERLAY,
-	PLANE_TYPE_CURSOR,
-	NUM_PLANE_TYPE_PROPS
-};
-
-static const char *plane_type_prop_names[NUM_PLANE_TYPE_PROPS] = {
-	"Primary",
-	"Overlay",
-	"Cursor"
-};
-
-struct kms_atomic_blob {
-	uint32_t id; /* 0 if not already allocated */
-	size_t len;
-	void *data;
-};
-
-struct kms_atomic_connector_state {
-	struct kms_atomic_state *state;
-	uint32_t obj;
-	uint32_t crtc_id;
-};
-
-struct kms_atomic_plane_state {
-	struct kms_atomic_state *state;
-	uint32_t obj;
-	enum plane_type type;
-	uint32_t crtc_mask;
-	uint32_t crtc_id; /* 0 to disable */
-	uint32_t fb_id; /* 0 to disable */
-	uint32_t src_x, src_y, src_w, src_h; /* 16.16 fixed-point */
-	uint32_t crtc_x, crtc_y, crtc_w, crtc_h; /* normal integers */
-	int32_t fence_fd;
-};
-
-struct kms_atomic_crtc_state {
-	struct kms_atomic_state *state;
-	uint32_t obj;
-	int idx;
-	bool active;
-	int32_t *out_fence_ptr;
-	struct kms_atomic_blob mode;
-};
-
-struct kms_atomic_state {
-	struct kms_atomic_connector_state *connectors;
-	int num_connectors;
-	struct kms_atomic_crtc_state *crtcs;
-	int num_crtcs;
-	struct kms_atomic_plane_state *planes;
-	int num_planes;
-	struct kms_atomic_desc *desc;
-};
-
-struct kms_atomic_desc {
-	int fd;
-	uint32_t props_connector[IGT_NUM_CONNECTOR_PROPS];
-	uint32_t props_crtc[IGT_NUM_CRTC_PROPS];
-	uint32_t props_plane[IGT_NUM_PLANE_PROPS];
-	uint64_t props_plane_type[NUM_PLANE_TYPE_PROPS];
-};
-
-static uint32_t blob_duplicate(int fd, uint32_t id_orig)
+static bool plane_filter(enum igt_atomic_plane_properties prop)
 {
-	drmModePropertyBlobPtr orig = drmModeGetPropertyBlob(fd, id_orig);
-	uint32_t id_new;
-
-	igt_assert(orig);
-	do_or_die(drmModeCreatePropertyBlob(fd, orig->data, orig->length,
-					    &id_new));
-	drmModeFreePropertyBlob(orig);
+	if ((1 << prop) & IGT_PLANE_COORD_CHANGED_MASK)
+		return false;
 
-	return id_new;
-}
-
-#define crtc_set_prop(req, crtc, prop, value) \
-	igt_assert_lt(0, drmModeAtomicAddProperty(req, crtc->obj, \
-						  crtc->state->desc->props_crtc[prop], \
-						  value));
-
-#define plane_set_prop(req, plane, prop, value) \
-	igt_assert_lt(0, drmModeAtomicAddProperty(req, plane->obj, \
-						  plane->state->desc->props_plane[prop], \
-						  value));
-
-#define do_atomic_commit(fd, req, flags) \
-	do_or_die(drmModeAtomicCommit(fd, req, flags, NULL));
+	if (prop == IGT_PLANE_CRTC_ID || prop == IGT_PLANE_FB_ID)
+		return false;
 
-#define do_atomic_commit_err(fd, req, flags, err) { \
-	igt_assert_neq(drmModeAtomicCommit(fd, req, flags, NULL), 0); \
-	igt_assert_eq(errno, err); \
-}
-
-#define crtc_commit_atomic(crtc, plane, req, relax, flags) { \
-	drmModeAtomicSetCursor(req, 0); \
-	crtc_populate_req(crtc, req); \
-	plane_populate_req(plane, req); \
-	do_atomic_commit((crtc)->state->desc->fd, req, flags); \
-	if (!(flags & DRM_MODE_ATOMIC_TEST_ONLY)) { \
-		crtc_check_current_state(crtc, plane, relax); \
-		plane_check_current_state(plane, relax); \
-	} \
-}
+	if (prop == IGT_PLANE_IN_FENCE_FD)
+		return false;
 
-#define crtc_commit_atomic_err(crtc, plane, crtc_old, plane_old, req, flags, relax, e) { \
-	drmModeAtomicSetCursor(req, 0); \
-	crtc_populate_req(crtc, req); \
-	plane_populate_req(plane, req); \
-	do_atomic_commit_err((crtc)->state->desc->fd, req, flags, e); \
-	crtc_check_current_state(crtc_old, plane_old, relax); \
-	plane_check_current_state(plane_old, relax); \
+	/* Don't care about other properties */
+	return true;
 }
 
-#define plane_commit_atomic(plane, req, relax) { \
-	drmModeAtomicSetCursor(req, 0); \
-	plane_populate_req(plane, req); \
-	do_atomic_commit((plane)->state->desc->fd, req, 0); \
-	plane_check_current_state(plane, relax); \
-}
-
-#define plane_commit_atomic_err(plane, plane_old, req, relax, e) { \
-	drmModeAtomicSetCursor(req, 0); \
-	plane_populate_req(plane, req); \
-	do_atomic_commit_err((plane)->state->desc->fd, req, 0, e); \
-	plane_check_current_state(plane_old, relax); \
-}
-
-static void
-connector_get_current_state(struct kms_atomic_connector_state *connector)
-{
-	drmModeObjectPropertiesPtr props;
-	int i;
-
-	props = drmModeObjectGetProperties(connector->state->desc->fd,
-					   connector->obj,
-					   DRM_MODE_OBJECT_CONNECTOR);
-	igt_assert(props);
-
-	for (i = 0; i < props->count_props; i++) {
-		uint32_t *prop_ids = connector->state->desc->props_connector;
-
-		if (props->props[i] == prop_ids[IGT_CONNECTOR_CRTC_ID])
-			connector->crtc_id = props->prop_values[i];
-	}
-	drmModeFreeObjectProperties(props);
-}
-
-#if 0
-/* XXX: Checking this repeatedly actually hangs the GPU. I have literally no
- *      idea why. */
-static void
-connector_check_current_state(struct kms_atomic_connector_state *connector)
-{
-	struct kms_atomic_connector_state connector_kernel;
-	drmModeConnectorPtr legacy;
-	uint32_t crtc_id;
-
-	legacy = drmModeGetConnectorCurrent(connector->state->desc->fd,
-					    connector->obj);
-	igt_assert(legacy);
-
-	if (legacy->encoder_id) {
-		drmModeEncoderPtr legacy_enc;
-
-		legacy_enc = drmModeGetEncoder(connector->state->desc->fd,
-					       legacy->encoder_id);
-		igt_assert(legacy_enc);
-
-		crtc_id = legacy_enc->crtc_id;
-		drmModeFreeEncoder(legacy_enc);
-	} else {
-		crtc_id = 0;
-	}
-
-	igt_assert_eq_u32(crtc_id, connector->crtc_id);
-
-	memcpy(&connector_kernel, connector, sizeof(connector_kernel));
-	connector_get_current_state(&connector_kernel);
-	do_or_die(memcmp(&connector_kernel, connector,
-			 sizeof(connector_kernel)));
-
-	drmModeFreeConnector(legacy);
-}
-#endif
-
-static struct kms_atomic_connector_state *
-find_connector(struct kms_atomic_state *state,
-	       struct kms_atomic_crtc_state *crtc)
+static void plane_get_current_state(igt_plane_t *plane, uint64_t *values)
 {
 	int i;
 
-	for (i = 0; i < state->num_connectors; i++) {
-		struct kms_atomic_connector_state *connector =
-			&state->connectors[i];
-
-		if (!connector->obj)
+	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++) {
+		if (plane_filter(i)) {
+			values[i] = 0;
 			continue;
-		if (crtc && connector->crtc_id != crtc->obj)
-			continue;
-
-		return connector;
-	}
-
-	return NULL;
-}
-
-static void plane_populate_req(struct kms_atomic_plane_state *plane,
-			       drmModeAtomicReq *req)
-{
-	if (plane->fence_fd)
-		plane_set_prop(req, plane, IGT_PLANE_IN_FENCE_FD, plane->fence_fd);
-
-	plane_set_prop(req, plane, IGT_PLANE_CRTC_ID, plane->crtc_id);
-	plane_set_prop(req, plane, IGT_PLANE_FB_ID, plane->fb_id);
-	plane_set_prop(req, plane, IGT_PLANE_SRC_X, plane->src_x);
-	plane_set_prop(req, plane, IGT_PLANE_SRC_Y, plane->src_y);
-	plane_set_prop(req, plane, IGT_PLANE_SRC_W, plane->src_w);
-	plane_set_prop(req, plane, IGT_PLANE_SRC_H, plane->src_h);
-	plane_set_prop(req, plane, IGT_PLANE_CRTC_X, plane->crtc_x);
-	plane_set_prop(req, plane, IGT_PLANE_CRTC_Y, plane->crtc_y);
-	plane_set_prop(req, plane, IGT_PLANE_CRTC_W, plane->crtc_w);
-	plane_set_prop(req, plane, IGT_PLANE_CRTC_H, plane->crtc_h);
-}
-
-static void plane_get_current_state(struct kms_atomic_plane_state *plane)
-{
-	struct kms_atomic_desc *desc = plane->state->desc;
-	drmModeObjectPropertiesPtr props;
-	int i;
-
-	props = drmModeObjectGetProperties(desc->fd, plane->obj,
-					   DRM_MODE_OBJECT_PLANE);
-	igt_assert(props);
-
-	for (i = 0; i < props->count_props; i++) {
-		uint32_t *prop_ids = desc->props_plane;
-
-		if (props->props[i] == prop_ids[IGT_PLANE_CRTC_ID])
-			plane->crtc_id = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_FB_ID])
-			plane->fb_id = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_CRTC_X])
-			plane->crtc_x = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_CRTC_Y])
-			plane->crtc_y = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_CRTC_W])
-			plane->crtc_w = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_CRTC_H])
-			plane->crtc_h = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_SRC_X])
-			plane->src_x = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_SRC_Y])
-			plane->src_y = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_SRC_W])
-			plane->src_w = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_SRC_H])
-			plane->src_h = props->prop_values[i];
-		else if (props->props[i] == prop_ids[IGT_PLANE_TYPE]) {
-			int j;
-
-			for (j = 0; j < ARRAY_SIZE(desc->props_plane_type); j++) {
-				if (props->prop_values[i] == desc->props_plane_type[j]) {
-					plane->type = j;
-					break;
-				}
-			}
 		}
-	}
 
-	drmModeFreeObjectProperties(props);
+		values[i] = igt_plane_get_prop(plane, i);
+	}
 }
 
-static void plane_check_current_state(struct kms_atomic_plane_state *plane,
+static void plane_check_current_state(igt_plane_t *plane, const uint64_t *values,
 				      enum kms_atomic_check_relax relax)
 {
 	drmModePlanePtr legacy;
-	struct kms_atomic_plane_state plane_kernel;
+	uint64_t current_values[IGT_NUM_PLANE_PROPS];
+	int i;
 
-	legacy = drmModeGetPlane(plane->state->desc->fd, plane->obj);
+	legacy = drmModeGetPlane(plane->pipe->display->drm_fd, plane->drm_plane->plane_id);
 	igt_assert(legacy);
 
-	igt_assert_eq_u32(legacy->crtc_id, plane->crtc_id);
+	igt_assert_eq_u32(legacy->crtc_id, values[IGT_PLANE_CRTC_ID]);
 
 	if (!(relax & PLANE_RELAX_FB))
-		igt_assert_eq_u32(legacy->fb_id, plane->fb_id);
+		igt_assert_eq_u32(legacy->fb_id, values[IGT_PLANE_FB_ID]);
 
-	memcpy(&plane_kernel, plane, sizeof(plane_kernel));
-	plane_get_current_state(&plane_kernel);
+	plane_get_current_state(plane, current_values);
 
 	/* Legacy cursor ioctls create their own, unknowable, internal
 	 * framebuffer which we can't reason about. */
 	if (relax & PLANE_RELAX_FB)
-		plane_kernel.fb_id = plane->fb_id;
-	do_or_die(memcmp(&plane_kernel, plane, sizeof(plane_kernel)));
+		current_values[IGT_PLANE_FB_ID] = values[IGT_PLANE_FB_ID];
+
+	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++)
+		if (!plane_filter(i))
+			igt_assert_eq_u64(current_values[i], values[i]);
 
 	drmModeFreePlane(legacy);
 }
 
-static void plane_commit_legacy(struct kms_atomic_plane_state *plane,
+static void plane_commit(igt_plane_t *plane, enum igt_commit_style s,
                                 enum kms_atomic_check_relax relax)
 {
-	do_or_die(drmModeSetPlane(plane->state->desc->fd, plane->obj,
-				  plane->crtc_id,
-				  plane->fb_id, 0,
-				  plane->crtc_x, plane->crtc_y,
-				  plane->crtc_w, plane->crtc_h,
-				  plane->src_x, plane->src_y,
-				  plane->src_w, plane->src_h));
-	plane_check_current_state(plane, relax);
+	igt_display_commit2(plane->pipe->display, s);
+	plane_check_current_state(plane, plane->values, relax);
 }
 
-static struct kms_atomic_plane_state *
-find_plane(struct kms_atomic_state *state, enum plane_type type,
-	   struct kms_atomic_crtc_state *crtc)
+static void plane_commit_atomic_err(igt_plane_t *plane,
+				    enum kms_atomic_check_relax relax,
+				    int err)
 {
-	struct kms_atomic_plane_state *ret = NULL;
-	int i;
-
-	for (i = 0; i < state->num_planes; i++) {
-		struct kms_atomic_plane_state *plane = &state->planes[i];
-
-		if (!plane->obj)
-			continue;
-		if (type != NUM_PLANE_TYPE_PROPS && plane->type != type)
-			continue;
-		if (crtc && !(plane->crtc_mask & (1 << crtc->idx)))
-			continue;
+	uint64_t current_values[IGT_NUM_PLANE_PROPS];
 
-		plane_get_current_state(plane);
+	plane_get_current_state(plane, current_values);
 
-		/* Try to find a plane that's already on this CRTC. In
-		 * particular, this ensures that for special (primary/cursor)
-		 * planes that can be on multiple CRTCs, we find the same
-		 * one that the legacy ioctls will. */
-		if (!crtc || plane->crtc_id == crtc->obj)
-			return plane;
-
-		ret = plane;
-	}
+	igt_assert_eq(-err, igt_display_try_commit2(plane->pipe->display, COMMIT_ATOMIC));
 
-	return ret;
+	plane_check_current_state(plane, current_values, relax);
 }
 
-static void crtc_populate_req(struct kms_atomic_crtc_state *crtc,
-			      drmModeAtomicReq *req)
+static bool crtc_filter(enum igt_atomic_crtc_properties prop)
 {
-	if (crtc->out_fence_ptr)
-		crtc_set_prop(req, crtc, IGT_CRTC_OUT_FENCE_PTR,
-			      to_user_pointer(crtc->out_fence_ptr));
+	if (prop == IGT_CRTC_MODE_ID || prop == IGT_CRTC_ACTIVE)
+		return false;
 
-	crtc_set_prop(req, crtc, IGT_CRTC_MODE_ID, crtc->mode.id);
-	crtc_set_prop(req, crtc, IGT_CRTC_ACTIVE, crtc->active);
+	return true;
 }
 
-static void crtc_get_current_state(struct kms_atomic_crtc_state *crtc)
+static void crtc_get_current_state(igt_pipe_t *pipe, uint64_t *values)
 {
-	drmModeObjectPropertiesPtr props;
 	int i;
 
-	props = drmModeObjectGetProperties(crtc->state->desc->fd, crtc->obj,
-					   DRM_MODE_OBJECT_CRTC);
-	igt_assert(props);
-
-	for (i = 0; i < props->count_props; i++) {
-		uint32_t *prop_ids = crtc->state->desc->props_crtc;
-
-		if (props->props[i] == prop_ids[IGT_CRTC_MODE_ID]) {
-			drmModePropertyBlobPtr blob;
-
-			crtc->mode.id = props->prop_values[i];
-			if (!crtc->mode.id) {
-				crtc->mode.len = 0;
-				continue;
-			}
-
-			blob = drmModeGetPropertyBlob(crtc->state->desc->fd,
-						      crtc->mode.id);
-			igt_assert(blob);
-			igt_assert_eq_u32(blob->length,
-					  sizeof(struct drm_mode_modeinfo));
-
-			if (!crtc->mode.data ||
-			    memcmp(crtc->mode.data, blob->data, blob->length) != 0)
-				crtc->mode.data = blob->data;
-			crtc->mode.len = blob->length;
-		}
-		else if (props->props[i] == prop_ids[IGT_CRTC_ACTIVE]) {
-			crtc->active = props->prop_values[i];
+	for (i = 0; i < IGT_NUM_CRTC_PROPS; i++) {
+		if (crtc_filter(i)) {
+			values[i] = 0;
+			continue;
 		}
-	}
 
-	drmModeFreeObjectProperties(props);
+		values[i] = igt_pipe_obj_get_prop(pipe, i);
+	}
 }
 
-static void crtc_check_current_state(struct kms_atomic_crtc_state *crtc,
-				     struct kms_atomic_plane_state *primary,
+static void crtc_check_current_state(igt_pipe_t *pipe,
+				     const uint64_t *pipe_values,
+				     const uint64_t *primary_values,
 				     enum kms_atomic_check_relax relax)
 {
-	struct kms_atomic_crtc_state crtc_kernel;
+	uint64_t current_pipe_values[IGT_NUM_CRTC_PROPS];
 	drmModeCrtcPtr legacy;
+	drmModePropertyBlobRes *mode_prop = NULL;
+	struct drm_mode_modeinfo *mode = NULL;
 
-	legacy = drmModeGetCrtc(crtc->state->desc->fd, crtc->obj);
-	igt_assert(legacy);
-
-	igt_assert_eq_u32(legacy->crtc_id, crtc->obj);
-	igt_assert_eq_u32(legacy->x, primary->src_x >> 16);
-	igt_assert_eq_u32(legacy->y, primary->src_y >> 16);
-
-	if (crtc->active)
-		igt_assert_eq_u32(legacy->buffer_id, primary->fb_id);
-	else
-		igt_assert_eq_u32(legacy->buffer_id, 0);
+	if (pipe_values[IGT_CRTC_MODE_ID]) {
+		mode_prop = drmModeGetPropertyBlob(pipe->display->drm_fd,
+						   pipe_values[IGT_CRTC_MODE_ID]);
 
-	if (legacy->mode_valid) {
-		igt_assert_neq(legacy->mode_valid, 0);
-		igt_assert_eq(crtc->mode.len,
-		              sizeof(struct drm_mode_modeinfo));
-		do_or_die(memcmp(&legacy->mode, crtc->mode.data,
-		                 crtc->mode.len));
-		igt_assert_eq(legacy->width, legacy->mode.hdisplay);
-		igt_assert_eq(legacy->height, legacy->mode.vdisplay);
-	} else {
-		igt_assert_eq(legacy->mode_valid, 0);
-	}
+		igt_assert(mode_prop);
 
-	memcpy(&crtc_kernel, crtc, sizeof(crtc_kernel));
-	crtc_get_current_state(&crtc_kernel);
-
-	if (crtc_kernel.mode.id != 0)
-		igt_assert_eq(crtc_kernel.mode.len,
+		igt_assert_eq(mode_prop->length,
 		              sizeof(struct drm_mode_modeinfo));
-
-	/* Optionally relax the check for MODE_ID: using the legacy SetCrtc
-	 * API can potentially change MODE_ID even if the mode itself remains
-	 * unchanged. */
-	if (((relax & CRTC_RELAX_MODE) &&
-	    (crtc_kernel.mode.id != crtc->mode.id &&
-	     crtc_kernel.mode.id != 0 && crtc->mode.id != 0)) &&
-	    memcmp(crtc_kernel.mode.data, crtc->mode.data,
-		   sizeof(struct drm_mode_modeinfo)) == 0) {
-		crtc_kernel.mode.id = crtc->mode.id;
-		crtc_kernel.mode.data = crtc->mode.data;
-	}
-
-	do_or_die(memcmp(&crtc_kernel, crtc, sizeof(crtc_kernel)));
-
-	drmModeFreeCrtc(legacy);
-}
-
-static void crtc_commit_legacy(struct kms_atomic_crtc_state *crtc,
-			       struct kms_atomic_plane_state *plane,
-			       enum kms_atomic_check_relax relax)
-{
-	drmModeObjectPropertiesPtr props;
-	uint32_t *connectors;
-	int num_connectors = 0;
-	int i;
-
-	if (!crtc->active) {
-		do_or_die(drmModeSetCrtc(crtc->state->desc->fd,
-					 crtc->obj, 0, 0, 0, NULL, 0, NULL));
-		return;
-	}
-
-	connectors = calloc(crtc->state->num_connectors,
-			    sizeof(*connectors));
-	igt_assert(connectors);
-
-	igt_assert_neq_u32(crtc->mode.id, 0);
-
-	for (i = 0; i < crtc->state->num_connectors; i++) {
-		struct kms_atomic_connector_state *connector =
-			&crtc->state->connectors[i];
-
-		if (connector->crtc_id != crtc->obj)
-			continue;
-
-		connectors[num_connectors++] = connector->obj;
+		mode = mode_prop->data;
 	}
 
-	do_or_die(drmModeSetCrtc(crtc->state->desc->fd, crtc->obj,
-	                         plane->fb_id,
-				 plane->src_x >> 16, plane->src_y >> 16,
-				 (num_connectors) ? connectors : NULL,
-				 num_connectors,
-				 crtc->mode.data));
-	/* When doing a legacy commit, the core may update MODE_ID to be a new
-	 * blob implicitly created by the legacy request. Hence we backfill
-	 * the value in the state object to ensure they match. */
-	props = drmModeObjectGetProperties(crtc->state->desc->fd, crtc->obj,
-					   DRM_MODE_OBJECT_CRTC);
-	igt_assert(props);
-
-	for (i = 0; i < props->count_props; i++) {
-		if (props->props[i] !=
-		    crtc->state->desc->props_crtc[IGT_CRTC_MODE_ID])
-			continue;
-		crtc->mode.id = props->prop_values[i];
-		break;
-	}
+	legacy = drmModeGetCrtc(pipe->display->drm_fd, pipe->crtc_id);
+	igt_assert(legacy);
 
-	drmModeFreeObjectProperties(props);
+	igt_assert_eq_u32(legacy->crtc_id, pipe->crtc_id);
+	igt_assert_eq_u32(legacy->x, primary_values[IGT_PLANE_SRC_X] >> 16);
+	igt_assert_eq_u32(legacy->y, primary_values[IGT_PLANE_SRC_Y] >> 16);
 
-	crtc_check_current_state(crtc, plane, relax);
-	plane_check_current_state(plane, relax);
-}
+	igt_assert_eq_u32(legacy->buffer_id, primary_values[IGT_PLANE_FB_ID]);
 
-static struct kms_atomic_crtc_state *find_crtc(struct kms_atomic_state *state,
-					       bool must_be_enabled)
-{
-	int i;
+	if (legacy->mode_valid) {
+		igt_assert(mode_prop);
 
-	for (i = 0; i < state->num_crtcs; i++) {
-		struct kms_atomic_crtc_state *crtc = &state->crtcs[i];
+		do_or_die(memcmp(&legacy->mode, mode, sizeof(*mode)));
 
-		if (!crtc->obj)
-			continue;
-		if (must_be_enabled && !crtc->active)
-			continue;
+		igt_assert_eq(legacy->width, legacy->mode.hdisplay);
+		igt_assert_eq(legacy->height, legacy->mode.vdisplay);
 
-		crtc_get_current_state(crtc);
-		return crtc;
+		igt_assert_neq(pipe_values[IGT_CRTC_MODE_ID], 0);
+	} else {
+		igt_assert(!mode_prop);
 	}
 
-	return NULL;
-}
+	crtc_get_current_state(pipe, current_pipe_values);
 
-static void fill_obj_props(int fd, uint32_t id, int type, int num_props,
-			   const char **prop_names, uint32_t *prop_ids)
-{
-	drmModeObjectPropertiesPtr props;
-	int i, j;
-
-	props = drmModeObjectGetProperties(fd, id, type);
-	igt_assert(props);
+	/* Optionally relax the check for MODE_ID: using the legacy SetCrtc
+	 * API can potentially change MODE_ID even if the mode itself remains
+	 * unchanged. */
+	if (relax & CRTC_RELAX_MODE && mode && current_pipe_values[IGT_CRTC_MODE_ID] &&
+	    current_pipe_values[IGT_CRTC_MODE_ID] != pipe_values[IGT_CRTC_MODE_ID]) {
+		drmModePropertyBlobRes *cur_prop =
+			drmModeGetPropertyBlob(pipe->display->drm_fd,
+					       current_pipe_values[IGT_CRTC_MODE_ID]);
 
-	for (i = 0; i < props->count_props; i++) {
-		drmModePropertyPtr prop =
-			drmModeGetProperty(fd, props->props[i]);
+		igt_assert(cur_prop);
+		igt_assert_eq(cur_prop->length, sizeof(struct drm_mode_modeinfo));
 
-		for (j = 0; j < num_props; j++) {
-			if (strcmp(prop->name, prop_names[j]) != 0)
-				continue;
-			prop_ids[j] = props->props[i];
-			break;
-		}
+		if (!memcmp(cur_prop->data, mode, sizeof(*mode)))
+			current_pipe_values[IGT_CRTC_MODE_ID] = pipe_values[IGT_CRTC_MODE_ID];
 
-		drmModeFreeProperty(prop);
+		drmModeFreePropertyBlob(cur_prop);
 	}
 
-	drmModeFreeObjectProperties(props);
-}
+	do_or_die(memcmp(pipe_values, current_pipe_values, sizeof(current_pipe_values)));
 
-static void fill_obj_prop_map(int fd, uint32_t id, int type, const char *name,
-			      int num_enums, const char **enum_names,
-			      uint64_t *enum_ids)
-{
-	drmModeObjectPropertiesPtr props;
-	int i, j, k;
-
-	props = drmModeObjectGetProperties(fd, id, type);
-	igt_assert(props);
-
-	for (i = 0; i < props->count_props; i++) {
-		drmModePropertyPtr prop =
-			drmModeGetProperty(fd, props->props[i]);
-
-		igt_assert(prop);
-
-		if (strcmp(prop->name, name) != 0) {
-			drmModeFreeProperty(prop);
-			continue;
-		}
-
-		for (j = 0; j < prop->count_enums; j++) {
-			struct drm_mode_property_enum *e = &prop->enums[j];
-
-			for (k = 0; k < num_enums; k++) {
-				if (strcmp(e->name, enum_names[k]) != 0)
-					continue;
-
-				enum_ids[k] = e->value;
-				break;
-			}
-		}
-
-		drmModeFreeProperty(prop);
-	}
+	drmModeFreeCrtc(legacy);
+	drmModeFreePropertyBlob(mode_prop);
 }
 
-static void atomic_setup(struct kms_atomic_state *state)
+static void crtc_commit(igt_pipe_t *pipe, igt_plane_t *plane,
+			enum igt_commit_style s,
+			enum kms_atomic_check_relax relax)
 {
-	struct kms_atomic_desc *desc = state->desc;
-	drmModeResPtr res;
-	drmModePlaneResPtr res_plane;
-	int i;
-
-	desc->fd = drm_open_driver_master(DRIVER_ANY);
-	igt_assert_fd(desc->fd);
-
-	igt_skip_on(drmSetClientCap(desc->fd, DRM_CLIENT_CAP_ATOMIC, 1));
-
-	res = drmModeGetResources(desc->fd);
-	res_plane = drmModeGetPlaneResources(desc->fd);
-	igt_assert(res);
-	igt_assert(res_plane);
-
-	igt_assert_lt(0, res->count_crtcs);
-	state->num_crtcs = res->count_crtcs;
-	state->crtcs = calloc(state->num_crtcs, sizeof(*state->crtcs));
-	igt_assert(state->crtcs);
-
-	igt_assert_lt(0, res_plane->count_planes);
-	state->num_planes = res_plane->count_planes;
-	state->planes = calloc(state->num_planes, sizeof(*state->planes));
-	igt_assert(state->planes);
-
-	igt_assert_lt(0, res->count_connectors);
-	state->num_connectors = res->count_connectors;
-	state->connectors = calloc(state->num_connectors,
-				   sizeof(*state->connectors));
-	igt_assert(state->connectors);
-
-	fill_obj_props(desc->fd, res->crtcs[0],
-		       DRM_MODE_OBJECT_CRTC, IGT_NUM_CRTC_PROPS,
-		       igt_crtc_prop_names, desc->props_crtc);
-
-	fill_obj_props(desc->fd, res_plane->planes[0],
-		       DRM_MODE_OBJECT_PLANE, IGT_NUM_PLANE_PROPS,
-		       igt_plane_prop_names, desc->props_plane);
-	fill_obj_prop_map(desc->fd, res_plane->planes[0],
-			  DRM_MODE_OBJECT_PLANE, "type",
-			  NUM_PLANE_TYPE_PROPS, plane_type_prop_names,
-			  desc->props_plane_type);
-
-	fill_obj_props(desc->fd, res->connectors[0],
-		       DRM_MODE_OBJECT_CONNECTOR, IGT_NUM_CONNECTOR_PROPS,
-		       igt_connector_prop_names, desc->props_connector);
-
-	for (i = 0; i < state->num_crtcs; i++) {
-		struct kms_atomic_crtc_state *crtc = &state->crtcs[i];
-
-		crtc->state = state;
-		crtc->obj = res->crtcs[i];
-		crtc->idx = i;
-		crtc_get_current_state(crtc);
-
-		/* The blob pointed to by MODE_ID could well be transient,
-		 * and lose its last reference as we switch away from it.
-		 * Duplicate the blob here so we have a reference we know we
-		 * own. */
-		if (crtc->mode.id != 0)
-		    crtc->mode.id = blob_duplicate(desc->fd, crtc->mode.id);
-	}
+	igt_display_commit2(pipe->display, s);
 
-	for (i = 0; i < state->num_planes; i++) {
-		drmModePlanePtr plane =
-			drmModeGetPlane(desc->fd, res_plane->planes[i]);
-		igt_assert(plane);
-
-		state->planes[i].state = state;
-		state->planes[i].obj = res_plane->planes[i];
-		state->planes[i].crtc_mask = plane->possible_crtcs;
-		plane_get_current_state(&state->planes[i]);
-	}
-
-	for (i = 0; i < state->num_connectors; i++) {
-		state->connectors[i].state = state;
-		state->connectors[i].obj = res->connectors[i];
-		connector_get_current_state(&state->connectors[i]);
-	}
-
-	drmModeFreePlaneResources(res_plane);
-	drmModeFreeResources(res);
+	crtc_check_current_state(pipe, pipe->values, plane->values, relax);
+	plane_check_current_state(plane, plane->values, relax);
 }
 
-static struct kms_atomic_state *
-atomic_state_dup(const struct kms_atomic_state *state)
+static void crtc_commit_atomic_flags_err(igt_pipe_t *pipe, igt_plane_t *plane,
+					 unsigned flags,
+					 enum kms_atomic_check_relax relax,
+					 int err)
 {
-	struct kms_atomic_state *ret = calloc(1, sizeof(*ret));
-
-	igt_assert(ret);
-	*ret = *state;
+	uint64_t current_pipe_values[IGT_NUM_CRTC_PROPS];
+	uint64_t current_plane_values[IGT_NUM_PLANE_PROPS];
 
-	ret->crtcs = calloc(ret->num_crtcs, sizeof(*ret->crtcs));
-	igt_assert(ret->crtcs);
-	memcpy(ret->crtcs, state->crtcs, ret->num_crtcs * sizeof(*ret->crtcs));
+	crtc_get_current_state(pipe, current_pipe_values);
+	plane_get_current_state(plane, current_plane_values);
 
-	ret->planes = calloc(ret->num_planes, sizeof(*ret->planes));
-	igt_assert(ret->planes);
-	memcpy(ret->planes, state->planes,
-	       ret->num_planes * sizeof(*ret->planes));
+	igt_assert_eq(-err, igt_display_try_commit_atomic(pipe->display, flags, NULL));
 
-	ret->connectors = calloc(ret->num_connectors, sizeof(*ret->connectors));
-	igt_assert(ret->connectors);
-	memcpy(ret->connectors, state->connectors,
-	       ret->num_connectors * sizeof(*ret->connectors));
-
-	return ret;
+	crtc_check_current_state(pipe, current_pipe_values, current_plane_values, relax);
+	plane_check_current_state(plane, current_plane_values, relax);
 }
 
-static void atomic_state_free(struct kms_atomic_state *state)
-{
-	free(state->crtcs);
-	free(state->planes);
-	free(state->connectors);
-	free(state);
-}
+#define crtc_commit_atomic_err(pipe, plane, relax, err) \
+	crtc_commit_atomic_flags_err(pipe, plane, DRM_MODE_ATOMIC_ALLOW_MODESET, relax, err)
 
-static uint32_t plane_get_igt_format(struct kms_atomic_plane_state *plane)
+static uint32_t plane_get_igt_format(igt_plane_t *plane)
 {
 	drmModePlanePtr plane_kms;
 	const uint32_t *igt_formats;
-	uint32_t ret = 0;
 	int num_igt_formats;
 	int i;
 
-	plane_kms = drmModeGetPlane(plane->state->desc->fd, plane->obj);
-	igt_assert(plane_kms);
+	plane_kms = plane->drm_plane;
 
 	igt_get_all_cairo_formats(&igt_formats, &num_igt_formats);
 	for (i = 0; i < num_igt_formats; i++) {
 		int j;
 
 		for (j = 0; j < plane_kms->count_formats; j++) {
-			if (plane_kms->formats[j] == igt_formats[i]) {
-				ret = plane_kms->formats[j];
-				break;
-			}
+			if (plane_kms->formats[j] == igt_formats[i])
+				return plane_kms->formats[j];
 		}
 	}
 
-	drmModeFreePlane(plane_kms);
-	return ret;
+	return 0;
 }
 
 static void
-set_dpms(int fd, int mode)
+set_dpms(igt_output_t *output, int mode)
 {
-	int i;
-	drmModeConnector *connector;
-	uint32_t id;
-	drmModeRes *resources = drmModeGetResources(fd);
-
-	for (i = 0; i < resources->count_connectors; i++) {
-		id = resources->connectors[i];
-
-		connector = drmModeGetConnectorCurrent(fd, id);
-
-		kmstest_set_connector_dpms(fd, connector, mode);
-
-		drmModeFreeConnector(connector);
-	}
+	do_or_die(drmModeConnectorSetProperty(output->display->drm_fd, output->id,
+					      output->props[IGT_CONNECTOR_DPMS], mode));
 }
 
-static void plane_overlay(struct kms_atomic_crtc_state *crtc,
-			  struct kms_atomic_plane_state *plane_old)
+static void plane_overlay(igt_pipe_t *pipe, igt_output_t *output, igt_plane_t *plane)
 {
-	struct drm_mode_modeinfo *mode = crtc->mode.data;
-	struct kms_atomic_plane_state plane = *plane_old;
-	uint32_t format = plane_get_igt_format(&plane);
-	drmModeAtomicReq *req = drmModeAtomicAlloc();
+	drmModeModeInfo *mode = igt_output_get_mode(output);
+	uint32_t format = plane_get_igt_format(plane);
 	struct igt_fb fb;
+	uint32_t w = mode->hdisplay / 2;
+	uint32_t h = mode->vdisplay / 2;
 
-	igt_require(req);
 	igt_require(format != 0);
 
-	plane.src_x = 0;
-	plane.src_y = 0;
-	plane.src_w = (mode->hdisplay / 2) << 16;
-	plane.src_h = (mode->vdisplay / 2) << 16;
-	plane.crtc_x = mode->hdisplay / 4;
-	plane.crtc_y = mode->vdisplay / 4;
-	plane.crtc_w = mode->hdisplay / 2;
-	plane.crtc_h = mode->vdisplay / 2;
-	plane.crtc_id = crtc->obj;
-	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
-					    plane.crtc_w, plane.crtc_h,
-					    format, I915_TILING_NONE, &fb);
+	igt_create_pattern_fb(pipe->display->drm_fd, w, h,
+			      format, I915_TILING_NONE, &fb);
+
+	igt_plane_set_fb(plane, &fb);
+	igt_plane_set_position(plane, w/2, h/2);
 
 	/* Enable the overlay plane using the atomic API, and double-check
 	 * state is what we think it should be. */
-	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
+	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
 	/* Disable the plane and check the state matches the old. */
-	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
+	igt_plane_set_fb(plane, NULL);
+	igt_plane_set_position(plane, 0, 0);
+	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
 	/* Re-enable the plane through the legacy plane API, and verify through
 	 * atomic. */
-	plane_commit_legacy(&plane, ATOMIC_RELAX_NONE);
+	igt_plane_set_fb(plane, &fb);
+	igt_plane_set_position(plane, w/2, h/2);
+	plane_commit(plane, COMMIT_LEGACY, ATOMIC_RELAX_NONE);
 
 	/* Restore the plane to its original settings through the legacy plane
 	 * API, and verify through atomic. */
-	plane_commit_legacy(plane_old, ATOMIC_RELAX_NONE);
+	igt_plane_set_fb(plane, NULL);
+	igt_plane_set_position(plane, 0, 0);
+	plane_commit(plane, COMMIT_LEGACY, ATOMIC_RELAX_NONE);
 
-	drmModeAtomicFree(req);
+	igt_remove_fb(pipe->display->drm_fd, &fb);
 }
 
-static void plane_primary(struct kms_atomic_crtc_state *crtc,
-			  struct kms_atomic_plane_state *plane_old)
+static void plane_primary(igt_pipe_t *pipe, igt_plane_t *plane, struct igt_fb *fb)
 {
-	struct drm_mode_modeinfo *mode = crtc->mode.data;
-	struct kms_atomic_plane_state plane = *plane_old;
-	uint32_t format = plane_get_igt_format(&plane);
-	drmModeAtomicReq *req = drmModeAtomicAlloc();
-	struct igt_fb fb;
-	uint32_t flags = 0;
-	int ret;
-
-	igt_require(format != 0);
+	struct igt_fb fb2;
 
-	plane.src_x = 0;
-	plane.src_y = 0;
-	plane.src_w = mode->hdisplay << 16;
-	plane.src_h = mode->vdisplay << 16;
-	plane.crtc_x = 0;
-	plane.crtc_y = 0;
-	plane.crtc_w = mode->hdisplay;
-	plane.crtc_h = mode->vdisplay;
-	plane.crtc_id = crtc->obj;
-	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
-					    plane.crtc_w, plane.crtc_h,
-					    format, I915_TILING_NONE, &fb);
-
-	drmModeAtomicSetCursor(req, 0);
-	crtc_populate_req(crtc, req);
-	plane_populate_req(&plane, req);
-	ret = drmModeAtomicCommit(crtc->state->desc->fd, req,
-				  DRM_MODE_ATOMIC_TEST_ONLY, NULL);
-	/* Try harder in case the failure is caused by disallowing modeset. */
-	if (ret == -EINVAL)
-		flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
+	igt_create_color_pattern_fb(pipe->display->drm_fd,
+				    fb->width, fb->height,
+				    fb->drm_format, I915_TILING_NONE,
+				    0.2, 0.2, 0.2, &fb2);
 
 	/* Flip the primary plane using the atomic API, and double-check
 	 * state is what we think it should be. */
-	crtc_commit_atomic(crtc, &plane, req, ATOMIC_RELAX_NONE, flags);
+	igt_plane_set_fb(plane, &fb2);
+	crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
 	/* Restore the primary plane and check the state matches the old. */
-	crtc_commit_atomic(crtc, plane_old, req, ATOMIC_RELAX_NONE, flags);
+	igt_plane_set_fb(plane, fb);
+	crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
-	/* Re-enable the plane through the legacy CRTC/primary-plane API, and
+	/* Set the plane through the legacy CRTC/primary-plane API, and
 	 * verify through atomic. */
-	crtc_commit_legacy(crtc, &plane, CRTC_RELAX_MODE);
+	igt_plane_set_fb(plane, &fb2);
+	crtc_commit(pipe, plane, COMMIT_LEGACY, CRTC_RELAX_MODE);
 
 	/* Restore the plane to its original settings through the legacy CRTC
 	 * API, and verify through atomic. */
-	crtc_commit_legacy(crtc, plane_old, CRTC_RELAX_MODE);
-
-	/* Finally, restore to the original state. */
-	crtc_commit_atomic(crtc, plane_old, req, ATOMIC_RELAX_NONE, flags);
+	igt_plane_set_fb(plane, fb);
+	crtc_commit(pipe, plane, COMMIT_LEGACY, CRTC_RELAX_MODE);
 
-	drmModeAtomicFree(req);
+	/* Set the plane through the universal setplane API, and
+	 * verify through atomic. */
+	igt_plane_set_fb(plane, &fb2);
+	plane_commit(plane, COMMIT_UNIVERSAL, ATOMIC_RELAX_NONE);
 }
 
 /* test to ensure that DRM_MODE_ATOMIC_TEST_ONLY really only touches the
  * free-standing state objects and nothing else.
  */
-static void test_only(struct kms_atomic_crtc_state *crtc,
-		      struct kms_atomic_plane_state *plane_old)
+static void test_only(igt_pipe_t *pipe_obj,
+		      igt_plane_t *primary,
+		      igt_output_t *output)
 {
-	struct drm_mode_modeinfo *mode = crtc->mode.data;
-	struct kms_atomic_plane_state plane = *plane_old;
-	uint32_t format = plane_get_igt_format(&plane);
-	drmModeAtomicReq *req = drmModeAtomicAlloc();
+	drmModeModeInfo *mode = igt_output_get_mode(output);
+	uint32_t format = plane_get_igt_format(primary);
 	struct igt_fb fb;
-	int ret;
+	uint64_t old_plane_values[IGT_NUM_PLANE_PROPS], old_crtc_values[IGT_NUM_CRTC_PROPS];
 
 	igt_require(format != 0);
 
-	plane.src_x = 0;
-	plane.src_y = 0;
-	plane.src_w = mode->hdisplay << 16;
-	plane.src_h = mode->vdisplay << 16;
-	plane.crtc_x = 0;
-	plane.crtc_y = 0;
-	plane.crtc_w = mode->hdisplay;
-	plane.crtc_h = mode->vdisplay;
-	plane.crtc_id = crtc->obj;
-	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
-					    plane.crtc_w, plane.crtc_h,
-					    format, I915_TILING_NONE, &fb);
-
-	drmModeAtomicSetCursor(req, 0);
-	crtc_populate_req(crtc, req);
-	plane_populate_req(&plane, req);
-	ret = drmModeAtomicCommit(crtc->state->desc->fd, req,
-				  DRM_MODE_ATOMIC_TEST_ONLY, NULL);
-
-	igt_assert_eq(ret, 0);
-
-	/* go through dpms off/on cycle */
-	set_dpms(crtc->state->desc->fd, DRM_MODE_DPMS_OFF);
-	set_dpms(crtc->state->desc->fd, DRM_MODE_DPMS_ON);
-
-	/* check the state */
-	crtc_check_current_state(crtc, plane_old, ATOMIC_RELAX_NONE);
-	plane_check_current_state(plane_old, ATOMIC_RELAX_NONE);
-
-	/* Re-enable the plane through the legacy CRTC/primary-plane API, and
-	 * verify through atomic. */
-	crtc_commit_legacy(crtc, plane_old, CRTC_RELAX_MODE);
+	plane_get_current_state(primary, old_plane_values);
+	crtc_get_current_state(pipe_obj, old_crtc_values);
+
+	igt_assert(!old_crtc_values[IGT_CRTC_MODE_ID]);
+
+	igt_create_pattern_fb(pipe_obj->display->drm_fd,
+			     mode->hdisplay, mode->vdisplay,
+			     format, I915_TILING_NONE, &fb);
+	igt_plane_set_fb(primary, &fb);
+	igt_output_set_pipe(output, pipe_obj->pipe);
+
+	igt_display_commit_atomic(pipe_obj->display, DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+	/* check the state, should still be old state */
+	crtc_check_current_state(pipe_obj, old_crtc_values, old_plane_values, ATOMIC_RELAX_NONE);
+	plane_check_current_state(primary, old_plane_values, ATOMIC_RELAX_NONE);
+
+	/*
+	 * Enable the plane through the legacy CRTC/primary-plane API, and
+	 * verify through atomic.
+	 */
+	crtc_commit(pipe_obj, primary, COMMIT_LEGACY, CRTC_RELAX_MODE);
+
+	/* Same for disable.. */
+	plane_get_current_state(primary, old_plane_values);
+	crtc_get_current_state(pipe_obj, old_crtc_values);
+
+	igt_plane_set_fb(primary, NULL);
+	igt_output_set_pipe(output, PIPE_NONE);
+
+	igt_display_commit_atomic(pipe_obj->display, DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
 
-	drmModeAtomicFree(req);
+	/* for extra stress, go through dpms off/on cycle */
+	set_dpms(output, DRM_MODE_DPMS_OFF);
+	set_dpms(output, DRM_MODE_DPMS_ON);
+
+	/* check the state, should still be old state */
+	crtc_check_current_state(pipe_obj, old_crtc_values, old_plane_values, ATOMIC_RELAX_NONE);
+	plane_check_current_state(primary, old_plane_values, ATOMIC_RELAX_NONE);
+
+	/* And disable the pipe and remove fb, test complete */
+	crtc_commit(pipe_obj, primary, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
+	igt_remove_fb(pipe_obj->display->drm_fd, &fb);
 }
 
-static void plane_cursor(struct kms_atomic_crtc_state *crtc,
-			 struct kms_atomic_plane_state *plane_old)
+static void plane_cursor(igt_pipe_t *pipe_obj,
+			 igt_output_t *output,
+			 igt_plane_t *cursor)
 {
-	struct drm_mode_modeinfo *mode = crtc->mode.data;
-	struct kms_atomic_plane_state plane = *plane_old;
-	drmModeAtomicReq *req = drmModeAtomicAlloc();
+	drmModeModeInfo *mode = igt_output_get_mode(output);
 	struct igt_fb fb;
 	uint64_t width, height;
-
-	igt_assert(req);
+	int x = mode->hdisplay / 2;
+	int y = mode->vdisplay / 2;
 
 	/* Any kernel new enough for atomic, also has the cursor size caps. */
-	do_or_die(drmGetCap(plane.state->desc->fd,
+	do_or_die(drmGetCap(pipe_obj->display->drm_fd,
 	                    DRM_CAP_CURSOR_WIDTH, &width));
-	do_or_die(drmGetCap(plane.state->desc->fd,
+	do_or_die(drmGetCap(pipe_obj->display->drm_fd,
 	                    DRM_CAP_CURSOR_HEIGHT, &height));
 
-	plane.src_x = 0;
-	plane.src_y = 0;
-	plane.src_w = width << 16;
-	plane.src_h = height << 16;
-	plane.crtc_x = mode->hdisplay / 2;
-	plane.crtc_y = mode->vdisplay / 2;
-	plane.crtc_w = width;
-	plane.crtc_h = height;
-	plane.crtc_id = crtc->obj;
-	plane.fb_id = igt_create_color_fb(plane.state->desc->fd,
-					  width, height,
-					  DRM_FORMAT_ARGB8888,
-					  LOCAL_DRM_FORMAT_MOD_NONE,
-					  0.0, 0.0, 0.0,
-					  &fb);
-	igt_assert_neq_u32(plane.fb_id, 0);
+	igt_create_color_fb(pipe_obj->display->drm_fd,
+			    width, height, DRM_FORMAT_ARGB8888,
+			    LOCAL_DRM_FORMAT_MOD_NONE,
+			    0.0, 0.0, 0.0, &fb);
 
 	/* Flip the cursor plane using the atomic API, and double-check
 	 * state is what we think it should be. */
-	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
+	igt_plane_set_fb(cursor, &fb);
+	igt_plane_set_position(cursor, x, y);
+	plane_commit(cursor, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
 	/* Restore the cursor plane and check the state matches the old. */
-	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
+	igt_plane_set_fb(cursor, NULL);
+	igt_plane_set_position(cursor, 0, 0);
+	plane_commit(cursor, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
 	/* Re-enable the plane through the legacy cursor API, and verify
 	 * through atomic. */
-	do_or_die(drmModeMoveCursor(plane.state->desc->fd, plane.crtc_id,
-				    plane.crtc_x, plane.crtc_y));
-	do_or_die(drmModeSetCursor(plane.state->desc->fd, plane.crtc_id,
-				   fb.gem_handle, width, height));
-	plane_check_current_state(&plane, PLANE_RELAX_FB);
+	igt_plane_set_fb(cursor, &fb);
+	igt_plane_set_position(cursor, x, y);
+	plane_commit(cursor, COMMIT_LEGACY, PLANE_RELAX_FB);
 
 	/* Wiggle. */
-	plane.crtc_x -= 16;
-	plane.crtc_y -= 16;
-	do_or_die(drmModeMoveCursor(plane.state->desc->fd, plane.crtc_id,
-				    plane.crtc_x, plane.crtc_y));
-	plane_check_current_state(&plane, PLANE_RELAX_FB);
+	igt_plane_set_position(cursor, x - 16, y - 16);
+	plane_commit(cursor, COMMIT_LEGACY, PLANE_RELAX_FB);
 
 	/* Restore the plane to its original settings through the legacy cursor
 	 * API, and verify through atomic. */
-	do_or_die(drmModeSetCursor2(plane.state->desc->fd, plane.crtc_id,
-				    0, 0, 0, 0, 0));
-	plane_check_current_state(plane_old, ATOMIC_RELAX_NONE);
-
-	/* Finally, restore to the original state. */
-	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
-
-	drmModeAtomicFree(req);
+	igt_plane_set_fb(cursor, NULL);
+	igt_plane_set_position(cursor, 0, 0);
+	plane_commit(cursor, COMMIT_LEGACY, ATOMIC_RELAX_NONE);
 }
 
-static void plane_invalid_params(struct kms_atomic_crtc_state *crtc,
-				 struct kms_atomic_plane_state *plane_old,
-				 struct kms_atomic_connector_state *conn)
+static void plane_invalid_params(igt_pipe_t *pipe,
+				 igt_output_t *output,
+				 igt_plane_t *plane,
+				 struct igt_fb *fb)
 {
-	struct drm_mode_modeinfo *mode = crtc->mode.data;
-	struct kms_atomic_plane_state plane = *plane_old;
-	uint32_t format = plane_get_igt_format(&plane);
-	drmModeAtomicReq *req = drmModeAtomicAlloc();
-	struct igt_fb fb;
+	struct igt_fb fb2;
 
 	/* Pass a series of invalid object IDs for the FB ID. */
-	plane.fb_id = plane.obj;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, plane->drm_plane->plane_id);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	plane.fb_id = crtc->obj;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, pipe->crtc_id);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	plane.fb_id = conn->obj;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, output->id);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	plane.fb_id = crtc->mode.id;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, pipe->values[IGT_CRTC_MODE_ID]);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	plane.fb_id = plane_old->fb_id;
-	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
+	igt_plane_set_fb(plane, fb);
+	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
 	/* Pass a series of invalid object IDs for the CRTC ID. */
-	plane.crtc_id = plane.obj;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, plane->drm_plane->plane_id);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	plane.crtc_id = plane.fb_id;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, fb->fb_id);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	plane.crtc_id = conn->obj;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, output->id);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	plane.crtc_id = crtc->mode.id;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, pipe->values[IGT_CRTC_MODE_ID]);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	plane.crtc_id = plane_old->crtc_id;
-	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
+	igt_plane_set_fb(plane, fb);
+	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
 	/* Create a framebuffer too small for the plane configuration. */
-	igt_require(format != 0);
+	igt_create_pattern_fb(pipe->display->drm_fd,
+			      fb->width - 1, fb->height - 1,
+			      fb->drm_format, I915_TILING_NONE, &fb2);
 
-	plane.src_x = 0;
-	plane.src_y = 0;
-	plane.src_w = mode->hdisplay << 16;
-	plane.src_h = mode->vdisplay << 16;
-	plane.crtc_x = 0;
-	plane.crtc_y = 0;
-	plane.crtc_w = mode->hdisplay;
-	plane.crtc_h = mode->vdisplay;
-	plane.crtc_id = crtc->obj;
-	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
-					    plane.crtc_w - 1, plane.crtc_h - 1,
-					    format, I915_TILING_NONE, &fb);
-
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, ENOSPC);
+	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, fb2.fb_id);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, ENOSPC);
 
 	/* Restore the primary plane and check the state matches the old. */
-	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
-
-	drmModeAtomicFree(req);
+	igt_plane_set_fb(plane, fb);
+	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 }
 
-static void plane_invalid_params_fence(struct kms_atomic_crtc_state *crtc,
-				struct kms_atomic_plane_state *plane_old,
-				struct kms_atomic_connector_state *conn)
+static void plane_invalid_params_fence(igt_pipe_t *pipe,
+				       igt_output_t *output,
+				       igt_plane_t *plane)
 {
-	struct kms_atomic_plane_state plane = *plane_old;
-	drmModeAtomicReq *req = drmModeAtomicAlloc();
 	int timeline, fence_fd;
 
 	igt_require_sw_sync();
 
+	timeline = sw_sync_timeline_create();
+
 	/* invalid fence fd */
-	plane.fence_fd = plane.state->desc->fd;
-	plane.crtc_id = plane_old->crtc_id;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	igt_plane_set_fence_fd(plane, pipe->display->drm_fd);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
 
 	/* Valid fence_fd but invalid CRTC */
-	timeline = sw_sync_timeline_create();
-	fence_fd =  sw_sync_timeline_create_fence(timeline, 1);
-	plane.fence_fd = fence_fd;
-	plane.crtc_id = ~0U;
-	plane_commit_atomic_err(&plane, plane_old, req,
-	                        ATOMIC_RELAX_NONE, EINVAL);
+	fence_fd = sw_sync_timeline_create_fence(timeline, 1);
+
+	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, ~0);
+	igt_plane_set_fence_fd(plane, fence_fd);
+	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
+
+	sw_sync_timeline_inc(timeline, 1);
+	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, pipe->crtc_id);
+	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
-	plane.fence_fd = -1;
 	close(fence_fd);
 	close(timeline);
-
-	drmModeAtomicFree(req);
 }
 
-static void crtc_invalid_params(struct kms_atomic_crtc_state *crtc_old,
-				struct kms_atomic_plane_state *plane,
-				struct kms_atomic_connector_state *conn)
+static void crtc_invalid_params(igt_pipe_t *pipe,
+				igt_output_t *output,
+				igt_plane_t *plane,
+				struct igt_fb *fb)
 {
-	struct kms_atomic_crtc_state crtc = *crtc_old;
-	drmModeAtomicReq *req = drmModeAtomicAlloc();
-
-	igt_assert(req);
+	uint64_t old_mode_id = pipe->values[IGT_CRTC_MODE_ID];
+	drmModeModeInfo *mode = igt_output_get_mode(output);
 
 	/* Pass a series of invalid object IDs for the mode ID. */
-	crtc.mode.id = plane->obj;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-	                       ATOMIC_RELAX_NONE, EINVAL);
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, plane->drm_plane->plane_id);
+	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	crtc.mode.id = crtc.obj;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-	                       ATOMIC_RELAX_NONE, EINVAL);
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, pipe->crtc_id);
+	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	crtc.mode.id = conn->obj;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-	                       ATOMIC_RELAX_NONE, EINVAL);
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, output->id);
+	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	crtc.mode.id = plane->fb_id;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-	                       ATOMIC_RELAX_NONE, EINVAL);
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, fb->fb_id);
+	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, EINVAL);
 
-	/* successful TEST_ONLY with fences set */
-	crtc.mode.id = crtc_old->mode.id;
-	crtc_commit_atomic(&crtc, plane, req, ATOMIC_RELAX_NONE,
-			   DRM_MODE_ATOMIC_TEST_ONLY);
+	/* Can we restore mode? */
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, old_mode_id);
+	crtc_commit_atomic_flags_err(pipe, plane, DRM_MODE_ATOMIC_TEST_ONLY, ATOMIC_RELAX_NONE, 0);
 
 	/*
 	 * TEST_ONLY cannot be combined with DRM_MODE_PAGE_FLIP_EVENT,
 	 * but DRM_MODE_PAGE_FLIP_EVENT will always generate EINVAL
 	 * without valid crtc, so test it here.
 	 */
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
-			       DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_PAGE_FLIP_EVENT,
-			       ATOMIC_RELAX_NONE, EINVAL);
+	crtc_commit_atomic_flags_err(pipe, plane,
+				     DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_PAGE_FLIP_EVENT,
+				     ATOMIC_RELAX_NONE, EINVAL);
 
 	/* Create a blob which is the wrong size to be a valid mode. */
-	do_or_die(drmModeCreatePropertyBlob(crtc.state->desc->fd,
-					    crtc.mode.data,
-					    sizeof(struct drm_mode_modeinfo) - 1,
-					    &crtc.mode.id));
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-	                       ATOMIC_RELAX_NONE, EINVAL);
+	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, mode, sizeof(*mode) - 1);
+	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, EINVAL);
 
-
-	do_or_die(drmModeCreatePropertyBlob(crtc.state->desc->fd,
-					    crtc.mode.data,
-					    sizeof(struct drm_mode_modeinfo) + 1,
-					    &crtc.mode.id));
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-	                       ATOMIC_RELAX_NONE, EINVAL);
+	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, mode, sizeof(*mode) + 1);
+	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, EINVAL);
 
 
 	/* Restore the CRTC and check the state matches the old. */
-	crtc_commit_atomic(crtc_old, plane, req, ATOMIC_RELAX_NONE, 0);
-
-	drmModeAtomicFree(req);
+	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, mode, sizeof(*mode));
+	crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 }
 
-static void crtc_invalid_params_fence(struct kms_atomic_crtc_state *crtc_old,
-				struct kms_atomic_plane_state *plane,
-				struct kms_atomic_connector_state *conn)
+static void crtc_invalid_params_fence(igt_pipe_t *pipe,
+				      igt_output_t *output,
+				      igt_plane_t *plane,
+				      struct igt_fb *fb)
 {
-	struct kms_atomic_crtc_state crtc = *crtc_old;
-	drmModeAtomicReq *req = drmModeAtomicAlloc();
-	int timeline, fence_fd, *out_fence;
+	int timeline, fence_fd;
+	void *map;
+	const ptrdiff_t PAGE_SIZE = sysconf(_SC_PAGE_SIZE);
+	uint64_t old_mode_id = pipe->values[IGT_CRTC_MODE_ID];
 
 	igt_require_sw_sync();
 
+	timeline = sw_sync_timeline_create();
+
+	/* invalid out_fence_ptr */
+	map = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+	igt_assert(map != MAP_FAILED);
+
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)map);
+	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, EFAULT);
+	munmap(map, PAGE_SIZE);
+
 	/* invalid out_fence_ptr */
-	crtc.mode.id = crtc_old->mode.id;
-	crtc.out_fence_ptr = (int32_t *) crtc_invalid_params;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-	                       ATOMIC_RELAX_NONE, EFAULT);
+	map = mmap(NULL, PAGE_SIZE, PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+	igt_assert(map != MAP_FAILED);
+
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)map);
+	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, EFAULT);
+	munmap(map, PAGE_SIZE);
 
 	/* invalid out_fence_ptr */
-	crtc.mode.id = crtc_old->mode.id;
-	crtc.out_fence_ptr = (int32_t *) 0x8;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-	                       ATOMIC_RELAX_NONE, EFAULT);
-	crtc.out_fence_ptr = (int32_t *) 0;
+	map = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+	igt_assert(map != MAP_FAILED);
+
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, (ptrdiff_t)map);
+	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE, EFAULT);
+	munmap(map, PAGE_SIZE);
 
 	/* valid in fence but not allowed prop on crtc */
-	timeline = sw_sync_timeline_create();
-	fence_fd =  sw_sync_timeline_create_fence(timeline, 1);
-	plane->fence_fd = fence_fd;
-	crtc.active = false;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-			       ATOMIC_RELAX_NONE, EINVAL);
+	fence_fd = sw_sync_timeline_create_fence(timeline, 1);
+	igt_plane_set_fence_fd(plane, fence_fd);
 
-	out_fence = malloc(sizeof(uint64_t));
-	igt_assert(out_fence);
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_ACTIVE, 0);
+	igt_pipe_obj_clear_prop_changed(pipe, IGT_CRTC_OUT_FENCE_PTR);
 
+	crtc_commit_atomic_flags_err(pipe, plane, 0, ATOMIC_RELAX_NONE, EINVAL);
 
 	/* valid out fence ptr and flip event but not allowed prop on crtc */
-	crtc.out_fence_ptr = (int32_t *) out_fence;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-			       ATOMIC_RELAX_NONE, EINVAL);
+	igt_pipe_request_out_fence(pipe);
+	crtc_commit_atomic_flags_err(pipe, plane, DRM_MODE_PAGE_FLIP_EVENT,
+				     ATOMIC_RELAX_NONE, EINVAL);
 
-	/* valid out fence ptr and flip event but not allowed prop on crtc */
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
-			       DRM_MODE_PAGE_FLIP_EVENT,
-			       ATOMIC_RELAX_NONE, EINVAL);
-
-	/* valid page flip event but not allowed prop on crtc */
-	crtc.out_fence_ptr = (int32_t *) 0;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
-			       DRM_MODE_PAGE_FLIP_EVENT,
-			       ATOMIC_RELAX_NONE, EINVAL);
-	crtc.active = true;
-
-	/* valid out fence  ptr and flip event but invalid prop on crtc */
-	crtc.out_fence_ptr = (int32_t *) out_fence;
-	crtc.mode.id = plane->fb_id;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req, 0,
-			       ATOMIC_RELAX_NONE, EINVAL);
+	/* valid flip event but not allowed prop on crtc */
+	igt_pipe_obj_clear_prop_changed(pipe, IGT_CRTC_OUT_FENCE_PTR);
+	crtc_commit_atomic_flags_err(pipe, plane, DRM_MODE_PAGE_FLIP_EVENT,
+				     ATOMIC_RELAX_NONE, EINVAL);
+
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_ACTIVE, 1);
+
+	/* Configuration should be valid again */
+	crtc_commit_atomic_flags_err(pipe, plane, DRM_MODE_ATOMIC_TEST_ONLY,
+				     ATOMIC_RELAX_NONE, 0);
+
+	/* Set invalid prop */
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, fb->fb_id);
+
+	/* valid out fence but invalid prop on crtc */
+	igt_pipe_request_out_fence(pipe);
+	crtc_commit_atomic_flags_err(pipe, plane, 0,
+				     ATOMIC_RELAX_NONE, EINVAL);
 
 	/* valid out fence ptr and flip event but invalid prop on crtc */
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
-			       DRM_MODE_PAGE_FLIP_EVENT,
-			       ATOMIC_RELAX_NONE, EINVAL);
+	crtc_commit_atomic_flags_err(pipe, plane, DRM_MODE_PAGE_FLIP_EVENT,
+				     ATOMIC_RELAX_NONE, EINVAL);
 
 	/* valid page flip event but invalid prop on crtc */
-	crtc.out_fence_ptr = (int32_t *) 0;
-	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
-			       DRM_MODE_PAGE_FLIP_EVENT,
-			       ATOMIC_RELAX_NONE, EINVAL);
+	crtc_commit_atomic_flags_err(pipe, plane, DRM_MODE_PAGE_FLIP_EVENT,
+				     ATOMIC_RELAX_NONE, EINVAL);
 
 	/* successful TEST_ONLY with fences set */
-	plane->fence_fd = fence_fd;
-	crtc.mode.id = crtc_old->mode.id;
-	crtc_commit_atomic(&crtc, plane, req, ATOMIC_RELAX_NONE,
-			   DRM_MODE_ATOMIC_TEST_ONLY);
-	igt_assert(*out_fence == -1);
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, old_mode_id);
+	crtc_commit_atomic_flags_err(pipe, plane, DRM_MODE_ATOMIC_TEST_ONLY,
+				     ATOMIC_RELAX_NONE, 0);
+	igt_assert(pipe->out_fence_fd == -1);
 	close(fence_fd);
 	close(timeline);
 
 	/* reset fences */
-	plane->fence_fd = -1;
-	crtc.out_fence_ptr = (int32_t *) 0;
-	crtc_commit_atomic(&crtc, plane, req, ATOMIC_RELAX_NONE, 0);
+	igt_plane_set_fence_fd(plane, -1);
+	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR, 0);
+	igt_pipe_obj_clear_prop_changed(pipe, IGT_CRTC_OUT_FENCE_PTR);
+	crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
 	/* out fence ptr but not page flip event */
-	crtc.out_fence_ptr = (int32_t *) out_fence;
-	crtc_commit_atomic(crtc_old, plane, req, ATOMIC_RELAX_NONE, 0);
+	igt_pipe_request_out_fence(pipe);
+	crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 
-	close(*out_fence);
-	free(out_fence);
-	drmModeAtomicFree(req);
+	igt_assert(pipe->out_fence_fd != -1);
 }
 
 /* Abuse the atomic ioctl directly in order to test various invalid conditions,
  * which the libdrm wrapper won't allow us to create. */
-static void atomic_invalid_params(struct kms_atomic_crtc_state *crtc,
-				  struct kms_atomic_plane_state *plane,
-				  struct kms_atomic_connector_state *connector)
+static void atomic_invalid_params(igt_pipe_t *pipe,
+				  igt_plane_t *plane,
+				  igt_output_t *output,
+				  struct igt_fb *fb)
 {
-	struct kms_atomic_desc *desc = crtc->state->desc;
+	igt_display_t *display = pipe->display;
 	struct drm_mode_atomic ioc;
 	uint32_t obj_raw[16]; /* array of objects (sized by count_objs) */
 	uint32_t num_props_raw[16]; /* array of num props per obj (ditto) */
@@ -1346,7 +718,7 @@ static void atomic_invalid_params(struct kms_atomic_crtc_state *crtc,
 	memset(&ioc, 0, sizeof(ioc));
 
 	/* An empty request should do nothing. */
-	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
+	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
 
 	for (i = 0; i < ARRAY_SIZE(obj_raw); i++)
 		obj_raw[i] = 0;
@@ -1363,248 +735,232 @@ static void atomic_invalid_params(struct kms_atomic_crtc_state *crtc,
 	ioc.prop_values_ptr = (uintptr_t) values_raw;
 
 	/* Valid pointers, but still should copy nothing. */
-	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
+	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
 
 	/* Valid noop, but with event set should fail. */
 	ioc.flags = DRM_MODE_PAGE_FLIP_EVENT;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EINVAL);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EINVAL);
 
 	/* Nonsense flags. */
 	ioc.flags = 0xdeadbeef;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EINVAL);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EINVAL);
 
 	ioc.flags = 0;
 	/* Safety check that flags is reset properly. */
-	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
+	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
 
 	/* Reserved/MBZ. */
 	ioc.reserved = 1;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EINVAL);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EINVAL);
 	ioc.reserved = 0;
-	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
+	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
 
 	/* Zero is not a valid object ID. */
 	ioc.count_objs = ARRAY_SIZE(obj_raw);
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
 
 	/* Invalid object type (not a thing we can set properties on). */
 	ioc.count_objs = 1;
-	obj_raw[0] = crtc->mode.id;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
-	obj_raw[0] = plane->fb_id;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
+	obj_raw[0] = pipe->values[IGT_CRTC_MODE_ID];
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
+	obj_raw[0] = fb->fb_id;
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
 
 	/* Filled object but with no properties; no-op. */
 	for (i = 0; i < ARRAY_SIZE(obj_raw); i++)
-		obj_raw[i] = crtc->obj;
-	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
+		obj_raw[i] = pipe->crtc_id;
+	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
 
 	/* Pass in all sorts of things other than the property ID. */
 	num_props_raw[0] = 1;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
-	props_raw[0] = crtc->obj;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
-	props_raw[0] = plane->obj;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
-	props_raw[0] = connector->obj;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
-	props_raw[0] = crtc->mode.id;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
+	props_raw[0] = pipe->crtc_id;
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
+	props_raw[0] = plane->drm_plane->plane_id;
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
+	props_raw[0] = output->id;
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
+	props_raw[0] = pipe->values[IGT_CRTC_MODE_ID];
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
 
 	/* Valid property, valid value. */
+
 	for (i = 0; i < ARRAY_SIZE(props_raw); i++) {
-		props_raw[i] = desc->props_crtc[IGT_CRTC_MODE_ID];
-		values_raw[i] = crtc->mode.id;
+		props_raw[i] = pipe->props[IGT_CRTC_MODE_ID];
+		values_raw[i] = pipe->values[IGT_CRTC_MODE_ID];
 	}
-	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
+	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
 
 	/* Setting the same thing multiple times is OK. */
 	for (i = 0; i < ARRAY_SIZE(obj_raw); i++)
 		num_props_raw[i] = ARRAY_SIZE(props_raw) / ARRAY_SIZE(obj_raw);
-	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
+	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
 	ioc.count_objs = ARRAY_SIZE(obj_raw);
-	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
+	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
 
 	/* Pass a series of outlandish addresses. */
 	ioc.objs_ptr = 0;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
 
 	ioc.objs_ptr = (uintptr_t) obj_raw;
 	ioc.count_props_ptr = 0;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
 
 	ioc.count_props_ptr = (uintptr_t) num_props_raw;
 	ioc.props_ptr = 0;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
 
 	ioc.props_ptr = (uintptr_t) props_raw;
 	ioc.prop_values_ptr = 0;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
 
 	ioc.prop_values_ptr = (uintptr_t) values_raw;
-	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
+	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
 
 	/* Attempt to overflow and/or trip various boundary conditions. */
 	ioc.count_objs = UINT32_MAX / sizeof(uint32_t);
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
 
 	ioc.count_objs = ARRAY_SIZE(obj_raw);
 	ioc.objs_ptr = UINT64_MAX - sizeof(uint32_t);
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
 	ioc.count_objs = 1;
 	ioc.objs_ptr = UINT64_MAX - sizeof(uint32_t);
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
 
 	num_props_raw[0] = UINT32_MAX / sizeof(uint32_t);
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
 	num_props_raw[0] = UINT32_MAX - 1;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
 
 	for (i = 0; i < ARRAY_SIZE(obj_raw); i++)
 		num_props_raw[i] = (UINT32_MAX / ARRAY_SIZE(obj_raw)) + 1;
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
 	for (i = 0; i < ARRAY_SIZE(obj_raw); i++)
 		num_props_raw[i] = ARRAY_SIZE(props_raw) / ARRAY_SIZE(obj_raw);
-	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
+}
+
+static void atomic_setup(igt_display_t *display, enum pipe pipe, igt_output_t *output, igt_plane_t *primary, struct igt_fb *fb)
+{
+	igt_output_set_pipe(output, pipe);
+	igt_plane_set_fb(primary, fb);
+
+	crtc_commit(primary->pipe, primary, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
+}
+
+static void atomic_clear(igt_display_t *display, enum pipe pipe, igt_plane_t *primary, igt_output_t *output)
+{
+	igt_plane_t *plane;
+
+	for_each_plane_on_pipe(display, pipe, plane) {
+		igt_plane_set_fb(plane, NULL);
+		igt_plane_set_position(plane, 0, 0);
+	}
+
+	igt_output_set_pipe(output, PIPE_NONE);
+	crtc_commit(primary->pipe, primary, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
 }
 
 igt_main
 {
-	struct kms_atomic_desc desc;
-	struct kms_atomic_state *current;
+	igt_display_t display;
+	enum pipe pipe = PIPE_NONE;
+	igt_pipe_t *pipe_obj;
+	igt_output_t *output = NULL;
+	igt_plane_t *primary = NULL;
+	drmModeModeInfo *mode;
+	struct igt_fb fb;
+
+	igt_fixture {
+		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
+
+		kmstest_set_vt_graphics_mode();
+
+		igt_display_init(&display, display.drm_fd);
+
+		igt_require(display.is_atomic);
+		igt_display_require_output(&display);
 
-	memset(&desc, 0, sizeof(desc));
+		for_each_pipe_with_valid_output(&display, pipe, output)
+			break;
+
+		pipe_obj = &display.pipes[pipe];
+		primary = igt_pipe_get_plane_type(pipe_obj, DRM_PLANE_TYPE_PRIMARY);
 
-	current = calloc(1, sizeof(*current));
-	igt_assert(current);
-	current->desc = &desc;
+		mode = igt_output_get_mode(output);
 
-	igt_fixture
-		atomic_setup(current);
+		igt_create_pattern_fb(display.drm_fd,
+				      mode->hdisplay, mode->vdisplay,
+				      plane_get_igt_format(primary),
+				      LOCAL_DRM_FORMAT_MOD_NONE, &fb);
+	}
 
 	igt_subtest("plane_overlay_legacy") {
-		struct kms_atomic_state *scratch = atomic_state_dup(current);
-		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
-		struct kms_atomic_plane_state *plane =
-			find_plane(scratch, PLANE_TYPE_OVERLAY, crtc);
-
-		igt_require(crtc);
-		igt_require(plane);
-		plane_overlay(crtc, plane);
-		atomic_state_free(scratch);
+		igt_plane_t *overlay =
+			igt_pipe_get_plane_type(pipe_obj, DRM_PLANE_TYPE_OVERLAY);
+
+		igt_require(overlay);
+
+		atomic_setup(&display, pipe, output, primary, &fb);
+		plane_overlay(pipe_obj, output, overlay);
 	}
 
 	igt_subtest("plane_primary_legacy") {
-		struct kms_atomic_state *scratch = atomic_state_dup(current);
-		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
-		struct kms_atomic_plane_state *plane =
-			find_plane(scratch, PLANE_TYPE_PRIMARY, crtc);
-
-		igt_require(crtc);
-		igt_require(plane);
-		plane_primary(crtc, plane);
-		atomic_state_free(scratch);
+		atomic_setup(&display, pipe, output, primary, &fb);
+
+		plane_primary(pipe_obj, primary, &fb);
 	}
 
 	igt_subtest("test_only") {
-		struct kms_atomic_state *scratch = atomic_state_dup(current);
-		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
-		struct kms_atomic_plane_state *plane =
-			find_plane(scratch, PLANE_TYPE_PRIMARY, crtc);
-
-		igt_require(crtc);
-		igt_require(plane);
-		test_only(crtc, plane);
-		atomic_state_free(scratch);
-	}
+		atomic_clear(&display, pipe, primary, output);
 
+		test_only(pipe_obj, primary, output);
+	}
 	igt_subtest("plane_cursor_legacy") {
-		struct kms_atomic_state *scratch = atomic_state_dup(current);
-		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
-		struct kms_atomic_plane_state *plane =
-			find_plane(scratch, PLANE_TYPE_CURSOR, crtc);
-
-		igt_require(crtc);
-		igt_require(plane);
-		plane_cursor(crtc, plane);
-		atomic_state_free(scratch);
+		igt_plane_t *cursor =
+			igt_pipe_get_plane_type(pipe_obj, DRM_PLANE_TYPE_CURSOR);
+
+		igt_require(cursor);
+
+		atomic_setup(&display, pipe, output, primary, &fb);
+		plane_cursor(pipe_obj, output, cursor);
 	}
 
 	igt_subtest("plane_invalid_params") {
-		struct kms_atomic_state *scratch = atomic_state_dup(current);
-		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
-		struct kms_atomic_plane_state *plane =
-			find_plane(current, PLANE_TYPE_PRIMARY, crtc);
-		struct kms_atomic_connector_state *conn =
-			find_connector(scratch, crtc);
-
-		igt_require(crtc);
-		igt_require(plane);
-		plane_invalid_params(crtc, plane, conn);
-		atomic_state_free(scratch);
+		atomic_setup(&display, pipe, output, primary, &fb);
+
+		plane_invalid_params(pipe_obj, output, primary, &fb);
 	}
 
 	igt_subtest("plane_invalid_params_fence") {
-		struct kms_atomic_state *scratch = atomic_state_dup(current);
-		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
-		struct kms_atomic_plane_state *plane =
-			find_plane(current, PLANE_TYPE_PRIMARY, crtc);
-		struct kms_atomic_connector_state *conn =
-			find_connector(scratch, crtc);
-
-		igt_require(crtc);
-		igt_require(plane);
-		plane_invalid_params_fence(crtc, plane, conn);
-		atomic_state_free(scratch);
+		atomic_setup(&display, pipe, output, primary, &fb);
+
+		plane_invalid_params_fence(pipe_obj, output, primary);
 	}
 
 	igt_subtest("crtc_invalid_params") {
-		struct kms_atomic_state *scratch = atomic_state_dup(current);
-		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
-		struct kms_atomic_plane_state *plane =
-			find_plane(scratch, NUM_PLANE_TYPE_PROPS, crtc);
-		struct kms_atomic_connector_state *conn =
-			find_connector(scratch, crtc);
-
-		igt_require(crtc);
-		igt_require(plane);
-		igt_require(conn);
-		crtc_invalid_params(crtc, plane, conn);
-		atomic_state_free(scratch);
+		atomic_setup(&display, pipe, output, primary, &fb);
+
+		crtc_invalid_params(pipe_obj, output, primary, &fb);
 	}
 
 	igt_subtest("crtc_invalid_params_fence") {
-		struct kms_atomic_state *scratch = atomic_state_dup(current);
-		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
-		struct kms_atomic_plane_state *plane =
-			find_plane(scratch, NUM_PLANE_TYPE_PROPS, crtc);
-		struct kms_atomic_connector_state *conn =
-			find_connector(scratch, crtc);
-
-		igt_require(crtc);
-		igt_require(plane);
-		igt_require(conn);
-		crtc_invalid_params_fence(crtc, plane, conn);
-		atomic_state_free(scratch);
+		atomic_setup(&display, pipe, output, primary, &fb);
+
+		crtc_invalid_params_fence(pipe_obj, output, primary, &fb);
 	}
 
 	igt_subtest("atomic_invalid_params") {
-		struct kms_atomic_state *scratch = atomic_state_dup(current);
-		struct kms_atomic_crtc_state *crtc = find_crtc(scratch, true);
-		struct kms_atomic_plane_state *plane =
-			find_plane(scratch, NUM_PLANE_TYPE_PROPS, crtc);
-		struct kms_atomic_connector_state *conn =
-			find_connector(scratch, crtc);
-
-		igt_require(crtc);
-		igt_require(plane);
-		igt_require(conn);
-		atomic_invalid_params(crtc, plane, conn);
-		atomic_state_free(scratch);
+		atomic_setup(&display, pipe, output, primary, &fb);
+
+		atomic_invalid_params(pipe_obj, primary, output, &fb);
 	}
 
-	atomic_state_free(current);
+	igt_fixture {
+		atomic_clear(&display, pipe, primary, output);
+		igt_remove_fb(display.drm_fd, &fb);
 
-	igt_fixture
-		close(desc.fd);
+		igt_display_fini(&display);
+	}
 }
-- 
2.14.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* ✓ Fi.CI.BAT: success for lib/igt_kms: Rewrite property handling to better match atomic. (rev6)
  2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
                   ` (15 preceding siblings ...)
  2017-10-12 15:01 ` ✗ Fi.CI.IGT: failure " Patchwork
@ 2017-10-12 16:04 ` Patchwork
  2017-10-12 23:47 ` ✗ Fi.CI.IGT: failure " Patchwork
  17 siblings, 0 replies; 45+ messages in thread
From: Patchwork @ 2017-10-12 16:04 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: lib/igt_kms: Rewrite property handling to better match atomic. (rev6)
URL   : https://patchwork.freedesktop.org/series/31733/
State : success

== Summary ==

IGT patchset tested on top of latest successful build
69fbd44e269bd5e7e751a34e4d846e6cf3fa3eb3 tests/pm_backlight: Enable connected output to allow tests to succeed, v4.

with latest DRM-Tip kernel build CI_DRM_3223
e8024950de9e drm-tip: 2017y-10m-12d-15h-17m-52s UTC integration manifest

No testlist changes.

Test gem_exec_reloc:
        Subgroup basic-cpu-gtt-active:
                fail       -> PASS       (fi-gdg-551) fdo#102582

fdo#102582 https://bugs.freedesktop.org/show_bug.cgi?id=102582

fi-bdw-5557u     total:289  pass:268  dwarn:0   dfail:0   fail:0   skip:21  time:453s
fi-bdw-gvtdvm    total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:471s
fi-blb-e6850     total:289  pass:223  dwarn:1   dfail:0   fail:0   skip:65  time:391s
fi-bsw-n3050     total:289  pass:243  dwarn:0   dfail:0   fail:0   skip:46  time:577s
fi-bwr-2160      total:289  pass:183  dwarn:0   dfail:0   fail:0   skip:106 time:288s
fi-bxt-dsi       total:289  pass:259  dwarn:0   dfail:0   fail:0   skip:30  time:526s
fi-bxt-j4205     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:525s
fi-byt-j1900     total:289  pass:253  dwarn:1   dfail:0   fail:0   skip:35  time:547s
fi-cfl-s         total:289  pass:253  dwarn:4   dfail:0   fail:0   skip:32  time:565s
fi-cnl-y         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:634s
fi-elk-e7500     total:289  pass:229  dwarn:0   dfail:0   fail:0   skip:60  time:440s
fi-gdg-551       total:289  pass:178  dwarn:1   dfail:0   fail:1   skip:109 time:276s
fi-glk-1         total:289  pass:261  dwarn:0   dfail:0   fail:0   skip:28  time:602s
fi-hsw-4770r     total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:441s
fi-ilk-650       total:289  pass:228  dwarn:0   dfail:0   fail:0   skip:61  time:461s
fi-ivb-3520m     total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:508s
fi-ivb-3770      total:289  pass:260  dwarn:0   dfail:0   fail:0   skip:29  time:480s
fi-kbl-7500u     total:289  pass:264  dwarn:1   dfail:0   fail:0   skip:24  time:509s
fi-kbl-7567u     total:289  pass:265  dwarn:4   dfail:0   fail:0   skip:20  time:489s
fi-kbl-r         total:289  pass:262  dwarn:0   dfail:0   fail:0   skip:27  time:598s
fi-pnv-d510      total:289  pass:222  dwarn:1   dfail:0   fail:0   skip:66  time:662s
fi-skl-6260u     total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:478s
fi-skl-6700hq    total:289  pass:263  dwarn:0   dfail:0   fail:0   skip:26  time:668s
fi-skl-6700k     total:289  pass:265  dwarn:0   dfail:0   fail:0   skip:24  time:536s
fi-skl-6770hq    total:289  pass:269  dwarn:0   dfail:0   fail:0   skip:20  time:520s
fi-skl-gvtdvm    total:289  pass:266  dwarn:0   dfail:0   fail:0   skip:23  time:472s
fi-snb-2520m     total:289  pass:250  dwarn:0   dfail:0   fail:0   skip:39  time:590s
fi-snb-2600      total:289  pass:249  dwarn:0   dfail:0   fail:0   skip:40  time:439s

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_340/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* ✗ Fi.CI.IGT: failure for lib/igt_kms: Rewrite property handling to better match atomic. (rev6)
  2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
                   ` (16 preceding siblings ...)
  2017-10-12 16:04 ` ✓ Fi.CI.BAT: success for lib/igt_kms: Rewrite property handling to better match atomic. (rev6) Patchwork
@ 2017-10-12 23:47 ` Patchwork
  17 siblings, 0 replies; 45+ messages in thread
From: Patchwork @ 2017-10-12 23:47 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: lib/igt_kms: Rewrite property handling to better match atomic. (rev6)
URL   : https://patchwork.freedesktop.org/series/31733/
State : failure

== Summary ==

Test kms_atomic:
        Subgroup test_only:
                skip       -> PASS       (shard-hsw)
Test perf:
        Subgroup polling:
                fail       -> PASS       (shard-hsw) fdo#102252
        Subgroup oa-exponents:
                pass       -> FAIL       (shard-hsw)
Test kms_busy:
        Subgroup extended-modeset-hang-oldfb-with-reset-render-C:
                dmesg-warn -> PASS       (shard-hsw)
Test prime_self_import:
        Subgroup export-vs-gem_close-race:
                fail       -> PASS       (shard-hsw)

fdo#102252 https://bugs.freedesktop.org/show_bug.cgi?id=102252

shard-hsw        total:2552 pass:1439 dwarn:0   dfail:0   fail:10  skip:1103 time:9639s

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_340/shards.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2 02/14] lib/igt_kms: Rework plane properties to be more atomic, v5.
  2017-10-12 11:54 ` [PATCH i-g-t v2 02/14] lib/igt_kms: Rework plane properties to be more atomic, v5 Maarten Lankhorst
@ 2017-10-19  9:08   ` Mika Kahola
  2017-10-19  9:44     ` Maarten Lankhorst
  0 siblings, 1 reply; 45+ messages in thread
From: Mika Kahola @ 2017-10-19  9:08 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx

On Thu, 2017-10-12 at 13:54 +0200, Maarten Lankhorst wrote:
> In the future I want to allow tests to commit more properties,
> but for this to work I have to fix all properties to work better
> with atomic commit. Instead of special casing each
> property make a bitmask for all property changed flags, and try to
> commit all properties.
> 
> Changes since v1:
> - Remove special dumping of src and crtc coordinates.
> - Dump all modified coordinates.
> Changes since v2:
> - Move igt_plane_set_prop_changed up slightly.
> Changes since v3:
> - Fix wrong ordering of set_position in kms_plane_lowres causing a
> test failure.
> Changes since v4:
> - Back out resetting crtc position in igt_plane_set_fb() and
>   document it during init. Tests appear to rely on it being
> preserved.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  lib/igt_kms.c                    | 299 +++++++++++++++++----------
> ------------
>  lib/igt_kms.h                    |  59 ++++----
>  tests/kms_atomic_interruptible.c |  12 +-
>  tests/kms_rotation_crc.c         |   4 +-
>  4 files changed, 165 insertions(+), 209 deletions(-)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index e6fa8f4af455..e77ae5d696da 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -192,11 +192,11 @@ const char
> *igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
>  
>  /*
>   * Retrieve all the properies specified in props_name and store them
> into
> - * plane->atomic_props_plane.
> + * plane->props.
>   */
>  static void
> -igt_atomic_fill_plane_props(igt_display_t *display, igt_plane_t
> *plane,
> -			int num_props, const char **prop_names)
> +igt_fill_plane_props(igt_display_t *display, igt_plane_t *plane,
> +		     int num_props, const char **prop_names)
>  {
>  	drmModeObjectPropertiesPtr props;
>  	int i, j, fd;
> @@ -214,7 +214,7 @@ igt_atomic_fill_plane_props(igt_display_t
> *display, igt_plane_t *plane,
>  			if (strcmp(prop->name, prop_names[j]) != 0)
>  				continue;
>  
> -			plane->atomic_props_plane[j] = props-
> >props[i];
> +			plane->props[j] = props->props[i];
>  			break;
>  		}
>  
> @@ -1659,7 +1659,6 @@ void igt_display_init(igt_display_t *display,
> int drm_fd)
>  	drmModeRes *resources;
>  	drmModePlaneRes *plane_resources;
>  	int i;
> -	int is_atomic = 0;
>  
>  	memset(display, 0, sizeof(igt_display_t));
>  
> @@ -1679,7 +1678,9 @@ void igt_display_init(igt_display_t *display,
> int drm_fd)
>  	igt_assert_f(display->pipes, "Failed to allocate memory for
> %d pipes\n", display->n_pipes);
>  
>  	drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
> -	is_atomic = drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC,
> 1);
> +	if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1) == 0)
> +		display->is_atomic = 1;
> +
>  	plane_resources = drmModeGetPlaneResources(display->drm_fd);
>  	igt_assert(plane_resources);
>  
> @@ -1776,19 +1777,27 @@ void igt_display_init(igt_display_t *display,
> int drm_fd)
>  			plane->type = type;
>  			plane->pipe = pipe;
>  			plane->drm_plane = drm_plane;
> -			plane->fence_fd = -1;
> +			plane->values[IGT_PLANE_IN_FENCE_FD] =
> ~0ULL;
>  
> -			if (is_atomic == 0) {
> -				display->is_atomic = 1;
> -				igt_atomic_fill_plane_props(display,
> plane, IGT_NUM_PLANE_PROPS, igt_plane_prop_names);
> -			}
> +			igt_fill_plane_props(display, plane,
> IGT_NUM_PLANE_PROPS, igt_plane_prop_names);
>  
>  			get_plane_property(display->drm_fd,
> drm_plane->plane_id,
>  					   "rotation",
> -					   &plane-
> >rotation_property,
> -					   &prop_value,
> +					   &plane-
> >props[IGT_PLANE_ROTATION],
> +					   &plane-
> >values[IGT_PLANE_ROTATION],
>  					   NULL);
> -			plane->rotation =
> (igt_rotation_t)prop_value;
> +
> +			/* Clear any residual framebuffer info on
> first commit. */
> +			igt_plane_set_prop_changed(plane,
> IGT_PLANE_FB_ID);
> +			igt_plane_set_prop_changed(plane,
> IGT_PLANE_CRTC_ID);
> +
> +			/*
> +			 * CRTC_X/Y are not changed in
> igt_plane_set_fb, so
> +			 * force them to be sanitized in case they
> contain
> +			 * garbage.
> +			 */
> +			igt_plane_set_prop_changed(plane,
> IGT_PLANE_CRTC_X);
> +			igt_plane_set_prop_changed(plane,
> IGT_PLANE_CRTC_Y);
>  		}
>  
>  		/*
> @@ -1805,9 +1814,6 @@ void igt_display_init(igt_display_t *display,
> int drm_fd)
>  
>  		pipe->n_planes = n_planes;
>  
> -		for_each_plane_on_pipe(display, i, plane)
> -			plane->fb_changed = true;
> -
>  		pipe->mode_changed = true;
>  	}
>  
> @@ -2070,18 +2076,7 @@ bool igt_pipe_get_property(igt_pipe_t *pipe,
> const char *name,
>  
>  static uint32_t igt_plane_get_fb_id(igt_plane_t *plane)
>  {
> -	if (plane->fb)
> -		return plane->fb->fb_id;
> -	else
> -		return 0;
> -}
> -
> -static uint32_t igt_plane_get_fb_gem_handle(igt_plane_t *plane)
> -{
> -	if (plane->fb)
> -		return plane->fb->gem_handle;
> -	else
> -		return 0;
> +	return plane->values[IGT_PLANE_FB_ID];
>  }
>  
>  #define CHECK_RETURN(r, fail) {	\
> @@ -2090,9 +2085,6 @@ static uint32_t
> igt_plane_get_fb_gem_handle(igt_plane_t *plane)
>  	igt_assert_eq(r, 0);	\
>  }
>  
> -
> -
> -
>  /*
>   * Add position and fb changes of a plane to the atomic property set
>   */
> @@ -2101,63 +2093,31 @@ igt_atomic_prepare_plane_commit(igt_plane_t
> *plane, igt_pipe_t *pipe,
>  	drmModeAtomicReq *req)
>  {
>  	igt_display_t *display = pipe->display;
> -	uint32_t fb_id, crtc_id;
> +	int i;
>  
>  	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 = pipe->crtc_id;
> -
>  	LOG(display,
>  	    "populating plane data: %s.%d, fb %u\n",
>  	    kmstest_pipe_name(pipe->pipe),
>  	    plane->index,
> -	    fb_id);
> -
> -	if (plane->fence_fd >= 0) {
> -		uint64_t fence_fd = (int64_t) plane->fence_fd;
> -		igt_atomic_populate_plane_req(req, plane,
> IGT_PLANE_IN_FENCE_FD, fence_fd);
> -	}
> +	    igt_plane_get_fb_id(plane));
>  
> -	if (plane->fb_changed) {
> -		igt_atomic_populate_plane_req(req, plane,
> IGT_PLANE_CRTC_ID, fb_id ? crtc_id : 0);
> -		igt_atomic_populate_plane_req(req, plane,
> IGT_PLANE_FB_ID, fb_id);
> -	}
> -
> -	if (plane->position_changed || plane->size_changed) {
> -		uint32_t src_x = IGT_FIXED(plane->src_x, 0); /*
> src_x */
> -		uint32_t src_y = IGT_FIXED(plane->src_y, 0); /*
> src_y */
> -		uint32_t src_w = IGT_FIXED(plane->src_w, 0); /*
> src_w */
> -		uint32_t src_h = IGT_FIXED(plane->src_h, 0); /*
> src_h */
> -		int32_t crtc_x = plane->crtc_x;
> -		int32_t crtc_y = plane->crtc_y;
> -		uint32_t crtc_w = plane->crtc_w;
> -		uint32_t crtc_h = plane->crtc_h;
> +	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++) {
> +		if (!igt_plane_is_prop_changed(plane, i))
> +			continue;
Could we add a macro here too? Like 'for_each_prop_on_plane()' or
similar?

>  
> -		LOG(display,
> -		"src = (%d, %d) %u x %u "
> -		"dst = (%d, %d) %u x %u\n",
> -		src_x >> 16, src_y >> 16, src_w >> 16, src_h >> 16,
> -		crtc_x, crtc_y, crtc_w, crtc_h);
> +		/* it's an error to try an unsupported feature */
> +		igt_assert(plane->props[i]);
>  
> -		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_debug("plane %s.%d: Setting property \"%s\" to
> 0x%"PRIx64"/%"PRIi64"\n",
> +			kmstest_pipe_name(pipe->pipe), plane->index, 
> igt_plane_prop_names[i],
> +			plane->values[i], plane->values[i]);
>  
> -		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);
> +		igt_assert_lt(0, drmModeAtomicAddProperty(req,
> plane->drm_plane->plane_id,
> +						  plane->props[i],
> +						  plane-
> >values[i]));
>  	}
> -
> -	if (plane->rotation_changed)
> -		igt_atomic_populate_plane_req(req, plane,
> -			IGT_PLANE_ROTATION, plane->rotation);
>  }
>  
>  
> @@ -2183,17 +2143,20 @@ static int igt_drm_plane_commit(igt_plane_t
> *plane,
>  	int32_t crtc_y;
>  	uint32_t crtc_w;
>  	uint32_t crtc_h;
> +	bool setplane =
> +		igt_plane_is_prop_changed(plane, IGT_PLANE_FB_ID) ||
> +		plane->changed & IGT_PLANE_COORD_CHANGED_MASK;
>  
>  	igt_assert(plane->drm_plane);
>  
>  	/* it's an error to try an unsupported feature */
>  	igt_assert(igt_plane_supports_rotation(plane) ||
> -		   !plane->rotation_changed);
> +		   !igt_plane_is_prop_changed(plane,
> IGT_PLANE_ROTATION));
>  
>  	fb_id = igt_plane_get_fb_id(plane);
>  	crtc_id = pipe->crtc_id;
>  
> -	if ((plane->fb_changed || plane->size_changed) && fb_id ==
> 0) {
> +	if (setplane && fb_id == 0) {
>  		LOG(display,
>  		    "SetPlane pipe %s, plane %d, disabling\n",
>  		    kmstest_pipe_name(pipe->pipe),
> @@ -2212,16 +2175,15 @@ static int igt_drm_plane_commit(igt_plane_t
> *plane,
>  				      IGT_FIXED(0,0) /* src_h */);
>  
>  		CHECK_RETURN(ret, fail_on_error);
> -	} else if (plane->fb_changed || plane->position_changed ||
> -		plane->size_changed) {
> -		src_x = IGT_FIXED(plane->src_x,0); /* src_x */
> -		src_y = IGT_FIXED(plane->src_y,0); /* src_y */
> -		src_w = IGT_FIXED(plane->src_w,0); /* src_w */
> -		src_h = IGT_FIXED(plane->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;
> +	} else if (setplane) {
> +		src_x = plane->values[IGT_PLANE_SRC_X];
> +		src_y = plane->values[IGT_PLANE_SRC_Y];
> +		src_w = plane->values[IGT_PLANE_SRC_W];
> +		src_h = plane->values[IGT_PLANE_SRC_H];
> +		crtc_x = plane->values[IGT_PLANE_CRTC_X];
> +		crtc_y = plane->values[IGT_PLANE_CRTC_Y];
> +		crtc_w = plane->values[IGT_PLANE_CRTC_W];
> +		crtc_h = plane->values[IGT_PLANE_CRTC_H];
>  
>  		LOG(display,
>  		    "SetPlane %s.%d, fb %u, src = (%d, %d) "
> @@ -2245,9 +2207,10 @@ static int igt_drm_plane_commit(igt_plane_t
> *plane,
>  		CHECK_RETURN(ret, fail_on_error);
>  	}
>  
> -	if (plane->rotation_changed) {
> -		ret = igt_plane_set_property(plane, plane-
> >rotation_property,
> -				       plane->rotation);
> +	if (igt_plane_is_prop_changed(plane, IGT_PLANE_ROTATION)) {
> +		ret = igt_plane_set_property(plane,
> +					     plane-
> >props[IGT_PLANE_ROTATION],
> +					     plane-
> >values[IGT_PLANE_ROTATION]);
>  
>  		CHECK_RETURN(ret, fail_on_error);
>  	}
> @@ -2269,35 +2232,30 @@ static int
> igt_cursor_commit_legacy(igt_plane_t *cursor,
>  	uint32_t crtc_id = pipe->crtc_id;
>  	int ret;
>  
> -	if (cursor->fb_changed) {
> -		uint32_t gem_handle =
> igt_plane_get_fb_gem_handle(cursor);
> -
> -		if (gem_handle) {
> +	if (igt_plane_is_prop_changed(cursor, IGT_PLANE_FB_ID)) {
> +		if (cursor->gem_handle)
>  			LOG(display,
>  			    "SetCursor pipe %s, fb %u %dx%d\n",
>  			    kmstest_pipe_name(pipe->pipe),
> -			    gem_handle,
> -			    cursor->crtc_w, cursor->crtc_h);
> -
> -			ret = drmModeSetCursor(display->drm_fd,
> crtc_id,
> -					       gem_handle,
> -					       cursor->crtc_w,
> -					       cursor->crtc_h);
> -		} else {
> +			    cursor->gem_handle,
> +			    (unsigned)cursor-
> >values[IGT_PLANE_CRTC_W],
> +			    (unsigned)cursor-
> >values[IGT_PLANE_CRTC_H]);
> +		else
>  			LOG(display,
>  			    "SetCursor pipe %s, disabling\n",
>  			    kmstest_pipe_name(pipe->pipe));
>  
> -			ret = drmModeSetCursor(display->drm_fd,
> crtc_id,
> -					       0, 0, 0);
> -		}
> -
> +		ret = drmModeSetCursor(display->drm_fd, crtc_id,
> +				       cursor->gem_handle,
> +				       cursor-
> >values[IGT_PLANE_CRTC_W],
> +				       cursor-
> >values[IGT_PLANE_CRTC_H]);
>  		CHECK_RETURN(ret, fail_on_error);
>  	}
>  
> -	if (cursor->position_changed) {
> -		int x = cursor->crtc_x;
> -		int y = cursor->crtc_y;
> +	if (igt_plane_is_prop_changed(cursor, IGT_PLANE_CRTC_X) ||
> +	    igt_plane_is_prop_changed(cursor, IGT_PLANE_CRTC_Y)) {
> +		int x = cursor->values[IGT_PLANE_CRTC_X];
> +		int y = cursor->values[IGT_PLANE_CRTC_Y];
>  
>  		LOG(display,
>  		    "MoveCursor pipe %s, (%d, %d)\n",
> @@ -2326,13 +2284,14 @@ static int
> igt_primary_plane_commit_legacy(igt_plane_t *primary,
>  	int ret;
>  
>  	/* Primary planes can't be windowed when using a legacy
> commit */
> -	igt_assert((primary->crtc_x == 0 && primary->crtc_y == 0));
> +	igt_assert((primary->values[IGT_PLANE_CRTC_X] == 0 &&
> primary->values[IGT_PLANE_CRTC_Y] == 0));
>  
>  	/* nor rotated */
> -	igt_assert(!primary->rotation_changed);
> +	igt_assert(!igt_plane_is_prop_changed(primary,
> IGT_PLANE_ROTATION));
>  
> -	if (!primary->fb_changed && !primary->position_changed &&
> -	    !primary->size_changed && !primary->pipe->mode_changed)
> +	if (!igt_plane_is_prop_changed(primary, IGT_PLANE_FB_ID) &&
> +	    !(primary->changed & IGT_PLANE_COORD_CHANGED_MASK) &&
> +	    !primary->pipe->mode_changed)
>  		return 0;
>  
>  	crtc_id = pipe->crtc_id;
> @@ -2343,19 +2302,22 @@ static int
> igt_primary_plane_commit_legacy(igt_plane_t *primary,
>  		mode = NULL;
>  
>  	if (fb_id) {
> +		uint32_t src_x = primary->values[IGT_PLANE_SRC_X] >>
> 16;
> +		uint32_t src_y = primary->values[IGT_PLANE_SRC_Y] >>
> 16;
> +
>  		LOG(display,
>  		    "%s: SetCrtc pipe %s, fb %u, src (%d, %d), "
>  		    "mode %dx%d\n",
>  		    igt_output_name(output),
>  		    kmstest_pipe_name(pipe->pipe),
>  		    fb_id,
> -		    primary->src_x, primary->src_y,
> +		    src_x, src_y,
>  		    mode->hdisplay, mode->vdisplay);
>  
>  		ret = drmModeSetCrtc(display->drm_fd,
>  				     crtc_id,
>  				     fb_id,
> -				     primary->src_x, primary->src_y,
> +				     src_x, src_y,
>  				     &output->id,
>  				     1,
>  				     mode);
> @@ -2608,18 +2570,27 @@ display_commit_changed(igt_display_t
> *display, enum igt_commit_style s)
>  		}
>  
>  		for_each_plane_on_pipe(display, pipe, plane) {
> -			plane->fb_changed = false;
> -			plane->position_changed = false;
> -			plane->size_changed = false;
> +			if (s == COMMIT_ATOMIC) {
> +				int fd;
> +				plane->changed = 0;
>  
> -			if (s != COMMIT_LEGACY ||
> -			    !(plane->type == DRM_PLANE_TYPE_PRIMARY
> ||
> -			      plane->type == DRM_PLANE_TYPE_CURSOR))
> -				plane->rotation_changed = false;
> +				fd = plane-
> >values[IGT_PLANE_IN_FENCE_FD];
> +				if (fd != -1)
> +					close(fd);
>  
> -			if (s == COMMIT_ATOMIC)
>  				/* reset fence_fd to prevent it from
> being set for the next commit */
> -				igt_plane_set_fence_fd(plane, -1);
> +				plane->values[IGT_PLANE_IN_FENCE_FD] 
> = -1;
> +			} else {
> +				plane->changed &=
> ~IGT_PLANE_COORD_CHANGED_MASK;
> +
> +				igt_plane_clear_prop_changed(plane,
> IGT_PLANE_CRTC_ID);
> +				igt_plane_clear_prop_changed(plane,
> IGT_PLANE_FB_ID);
> +
> +				if (s != COMMIT_LEGACY ||
> +				    !(plane->type ==
> DRM_PLANE_TYPE_PRIMARY ||
> +				      plane->type ==
> DRM_PLANE_TYPE_CURSOR))
> +					igt_plane_clear_prop_changed
> (plane, IGT_PLANE_ROTATION);
> +			}
>  		}
>  	}
>  
> @@ -2913,30 +2884,29 @@ void igt_plane_set_fb(igt_plane_t *plane,
> struct igt_fb *fb)
>  	LOG(display, "%s.%d: plane_set_fb(%d)\n",
> kmstest_pipe_name(pipe->pipe),
>  	    plane->index, fb ? fb->fb_id : 0);
>  
> -	plane->fb = fb;
> +	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, fb ?
> pipe->crtc_id : 0);
> +	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, fb ? fb-
> >fb_id : 0);
> +
> +	if (plane->type == DRM_PLANE_TYPE_CURSOR && fb)
> +		plane->gem_handle = fb->gem_handle;
> +	else
> +		plane->gem_handle = 0;
> +
>  	/* hack to keep tests working that don't call
> igt_plane_set_size() */
>  	if (fb) {
>  		/* set default plane size as fb size */
> -		plane->crtc_w = fb->width;
> -		plane->crtc_h = fb->height;
> +		igt_plane_set_size(plane, fb->width, fb->height);
>  
>  		/* set default src pos/size as fb size */
> -		plane->src_x = 0;
> -		plane->src_y = 0;
> -		plane->src_w = fb->width;
> -		plane->src_h = fb->height;
> +		igt_fb_set_position(fb, plane, 0, 0);
> +		igt_fb_set_size(fb, plane, fb->width, fb->height);
>  	} else {
> -		plane->src_x = 0;
> -		plane->src_y = 0;
> -		plane->src_w = 0;
> -		plane->src_h = 0;
> +		igt_plane_set_size(plane, 0, 0);
>  
> -		plane->crtc_w = 0;
> -		plane->crtc_h = 0;
> +		/* set default src pos/size as fb size */
> +		igt_fb_set_position(fb, plane, 0, 0);
> +		igt_fb_set_size(fb, plane, 0, 0);
>  	}
> -
> -	plane->fb_changed = true;
> -	plane->size_changed = true;
>  }
>  
>  /**
> @@ -2949,12 +2919,19 @@ void igt_plane_set_fb(igt_plane_t *plane,
> struct igt_fb *fb)
>   */
>  void igt_plane_set_fence_fd(igt_plane_t *plane, int fence_fd)
>  {
> -	close(plane->fence_fd);
> +	int64_t fd;
>  
> -	if (fcntl(fence_fd, F_GETFD) != -1)
> -		plane->fence_fd = dup(fence_fd);
> -	else
> -		plane->fence_fd = -1;
> +	fd = plane->values[IGT_PLANE_IN_FENCE_FD];
> +	if (fd != -1)
> +		close(fd);
> +
> +	if (fence_fd != -1) {
> +		fd = dup(fence_fd);
> +		igt_fail_on(fd == -1);
> +	} else
> +		fd = -1;
> +
> +	igt_plane_set_prop_value(plane, IGT_PLANE_IN_FENCE_FD, fd);
>  }
>  
>  void igt_plane_set_position(igt_plane_t *plane, int x, int y)
> @@ -2965,10 +2942,8 @@ void igt_plane_set_position(igt_plane_t
> *plane, int x, int y)
>  	LOG(display, "%s.%d: plane_set_position(%d,%d)\n",
>  	    kmstest_pipe_name(pipe->pipe), plane->index, x, y);
>  
> -	plane->crtc_x = x;
> -	plane->crtc_y = y;
> -
> -	plane->position_changed = true;
> +	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_X, x);
> +	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_Y, y);
>  }
>  
>  /**
> @@ -2989,10 +2964,8 @@ void igt_plane_set_size(igt_plane_t *plane,
> int w, int h)
>  	LOG(display, "%s.%d: plane_set_size (%dx%d)\n",
>  	    kmstest_pipe_name(pipe->pipe), plane->index, w, h);
>  
> -	plane->crtc_w = w;
> -	plane->crtc_h = h;
> -
> -	plane->size_changed = true;
> +	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_W, w);
> +	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_H, h);
>  }
>  
>  /**
> @@ -3014,10 +2987,8 @@ void igt_fb_set_position(struct igt_fb *fb,
> igt_plane_t *plane,
>  	LOG(display, "%s.%d: fb_set_position(%d,%d)\n",
>  	    kmstest_pipe_name(pipe->pipe), plane->index, x, y);
>  
> -	plane->src_x = x;
> -	plane->src_y = y;
> -
> -	plane->fb_changed = true;
> +	igt_plane_set_prop_value(plane, IGT_PLANE_SRC_X,
> IGT_FIXED(x, 0));
> +	igt_plane_set_prop_value(plane, IGT_PLANE_SRC_Y,
> IGT_FIXED(y, 0));
>  }
>  
>  /**
> @@ -3040,10 +3011,8 @@ void igt_fb_set_size(struct igt_fb *fb,
> igt_plane_t *plane,
>  	LOG(display, "%s.%d: fb_set_size(%dx%d)\n",
>  	    kmstest_pipe_name(pipe->pipe), plane->index, w, h);
>  
> -	plane->src_w = w;
> -	plane->src_h = h;
> -
> -	plane->fb_changed = true;
> +	igt_plane_set_prop_value(plane, IGT_PLANE_SRC_W,
> IGT_FIXED(w, 0));
> +	igt_plane_set_prop_value(plane, IGT_PLANE_SRC_H,
> IGT_FIXED(h, 0));
>  }
>  
>  static const char *rotation_name(igt_rotation_t rotation)
> @@ -3071,9 +3040,7 @@ void igt_plane_set_rotation(igt_plane_t *plane,
> igt_rotation_t rotation)
>  	    kmstest_pipe_name(pipe->pipe),
>  	    plane->index, rotation_name(rotation));
>  
> -	plane->rotation = rotation;
> -
> -	plane->rotation_changed = true;
> +	igt_plane_set_prop_value(plane, IGT_PLANE_ROTATION,
> rotation);
>  }
>  
>  /**
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index 1ef10e7d525c..f87f8be31421 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -252,6 +252,9 @@ enum igt_atomic_plane_properties {
>         IGT_PLANE_CRTC_W,
>         IGT_PLANE_CRTC_H,
>  
> +/* Append new properties after IGT_PLANE_COORD_CHANGED_MASK */
> +#define IGT_PLANE_COORD_CHANGED_MASK 0xff
> +
>         IGT_PLANE_FB_ID,
>         IGT_PLANE_CRTC_ID,
>         IGT_PLANE_IN_FENCE_FD,
> @@ -286,37 +289,19 @@ typedef struct {
>  	int index;
>  	/* capabilities */
>  	int type;
> -	/* state tracking */
> -	unsigned int fb_changed       : 1;
> -	unsigned int position_changed : 1;
> -	unsigned int rotation_changed : 1;
> -	unsigned int size_changed     : 1;
> +
>  	/*
>  	 * drm_plane can be NULL for primary and cursor planes (when
> not
>  	 * using the atomic modeset API)
>  	 */
>  	drmModePlane *drm_plane;
> -	struct igt_fb *fb;
> -
> -	uint32_t rotation_property;
> -
> -	/* position within pipe_src_w x pipe_src_h */
> -	int crtc_x, crtc_y;
> -	/* size within pipe_src_w x pipe_src_h */
> -	int crtc_w, crtc_h;
>  
> -	/* position within the framebuffer */
> -	uint32_t src_x;
> -	uint32_t src_y;
> -	/* size within the framebuffer*/
> -	uint32_t src_w;
> -	uint32_t src_h;
> +	/* gem handle for fb */
> +	uint32_t gem_handle;
>  
> -	igt_rotation_t rotation;
> -
> -	/* in fence fd */
> -	int fence_fd;
> -	uint32_t atomic_props_plane[IGT_NUM_PLANE_PROPS];
> +	uint64_t changed;
> +	uint32_t props[IGT_NUM_PLANE_PROPS];
> +	uint64_t values[IGT_NUM_PLANE_PROPS];
>  } igt_plane_t;
>  
>  struct igt_pipe {
> @@ -407,7 +392,7 @@ bool igt_pipe_get_property(igt_pipe_t *pipe,
> const char *name,
>  
>  static inline bool igt_plane_supports_rotation(igt_plane_t *plane)
>  {
> -	return plane->rotation_property != 0;
> +	return plane->props[IGT_PLANE_ROTATION] != 0;
>  }
>  void igt_pipe_request_out_fence(igt_pipe_t *pipe);
>  void igt_pipe_set_degamma_lut(igt_pipe_t *pipe, void *ptr, size_t
> length);
> @@ -527,16 +512,20 @@ static inline bool
> igt_output_is_connected(igt_output_t *output)
>  
>  #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))
> +#define igt_plane_is_prop_changed(plane, prop) \
> +	(!!((plane)->changed & (1 << (prop))))
> +
> +#define igt_plane_set_prop_changed(plane, prop) \
> +	(plane)->changed |= 1 << (prop)
> +
> +#define igt_plane_clear_prop_changed(plane, prop) \
> +	(plane)->changed &= ~(1 << (prop))
> +
> +#define igt_plane_set_prop_value(plane, prop, value) \
> +	do { \
> +		plane->values[prop] = value; \
> +		igt_plane_set_prop_changed(plane, prop); \
> +	} while (0)
>  
>  /**
>   * igt_atomic_populate_crtc_req:
> diff --git a/tests/kms_atomic_interruptible.c
> b/tests/kms_atomic_interruptible.c
> index dcdbc267d3ef..4a2a577412cc 100644
> --- a/tests/kms_atomic_interruptible.c
> +++ b/tests/kms_atomic_interruptible.c
> @@ -163,12 +163,12 @@ static void run_plane_test(igt_display_t
> *display, enum pipe pipe, igt_output_t
>  					/* connector: 1 prop */
>  					output-
> >props[IGT_CONNECTOR_CRTC_ID],
>  					/* plane: remainder props */
> -					plane-
> >atomic_props_plane[IGT_PLANE_CRTC_ID],
> -					plane-
> >atomic_props_plane[IGT_PLANE_FB_ID],
> -					plane-
> >atomic_props_plane[IGT_PLANE_SRC_W],
> -					plane-
> >atomic_props_plane[IGT_PLANE_SRC_H],
> -					plane-
> >atomic_props_plane[IGT_PLANE_CRTC_W],
> -					plane-
> >atomic_props_plane[IGT_PLANE_CRTC_H]
> +					plane-
> >props[IGT_PLANE_CRTC_ID],
> +					plane-
> >props[IGT_PLANE_FB_ID],
> +					plane-
> >props[IGT_PLANE_SRC_W],
> +					plane-
> >props[IGT_PLANE_SRC_H],
> +					plane-
> >props[IGT_PLANE_CRTC_W],
> +					plane-
> >props[IGT_PLANE_CRTC_H]
>  				};
>  				uint64_t prop_vals[] = {
>  					/* crtc */
> diff --git a/tests/kms_rotation_crc.c b/tests/kms_rotation_crc.c
> index 5aec8fa39671..b8327dfa0d83 100644
> --- a/tests/kms_rotation_crc.c
> +++ b/tests/kms_rotation_crc.c
> @@ -122,11 +122,11 @@ static void prepare_crtc(data_t *data,
> igt_output_t *output, enum pipe pipe,
>  	igt_plane_set_fb(primary, &data->fb_modeset);
>  
>  	if (commit < COMMIT_ATOMIC) {
> -		primary->rotation_changed = false;
> +		igt_plane_clear_prop_changed(primary,
> IGT_PLANE_ROTATION);
>  		igt_display_commit(display);
>  
>  		if (plane->type == DRM_PLANE_TYPE_PRIMARY)
> -			primary->rotation_changed = true;
> +			igt_plane_set_prop_changed(primary,
> IGT_PLANE_ROTATION);
>  	}
>  
>  	igt_plane_set_fb(plane, NULL);
-- 
Mika Kahola - Intel OTC

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2 02/14] lib/igt_kms: Rework plane properties to be more atomic, v5.
  2017-10-19  9:08   ` Mika Kahola
@ 2017-10-19  9:44     ` Maarten Lankhorst
  2017-10-20  8:03       ` Mika Kahola
  0 siblings, 1 reply; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-19  9:44 UTC (permalink / raw)
  To: mika.kahola, intel-gfx

Op 19-10-17 om 11:08 schreef Mika Kahola:
> On Thu, 2017-10-12 at 13:54 +0200, Maarten Lankhorst wrote:
>> In the future I want to allow tests to commit more properties,
>> but for this to work I have to fix all properties to work better
>> with atomic commit. Instead of special casing each
>> property make a bitmask for all property changed flags, and try to
>> commit all properties.
>>
>> Changes since v1:
>> - Remove special dumping of src and crtc coordinates.
>> - Dump all modified coordinates.
>> Changes since v2:
>> - Move igt_plane_set_prop_changed up slightly.
>> Changes since v3:
>> - Fix wrong ordering of set_position in kms_plane_lowres causing a
>> test failure.
>> Changes since v4:
>> - Back out resetting crtc position in igt_plane_set_fb() and
>>   document it during init. Tests appear to rely on it being
>> preserved.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  lib/igt_kms.c                    | 299 +++++++++++++++++----------
>> ------------
>>  lib/igt_kms.h                    |  59 ++++----
>>  tests/kms_atomic_interruptible.c |  12 +-
>>  tests/kms_rotation_crc.c         |   4 +-
>>  4 files changed, 165 insertions(+), 209 deletions(-)
>>
>> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
>> index e6fa8f4af455..e77ae5d696da 100644
>> --- a/lib/igt_kms.c
>> +++ b/lib/igt_kms.c
>> @@ -192,11 +192,11 @@ const char
>> *igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
>>  
>>  /*
>>   * Retrieve all the properies specified in props_name and store them
>> into
>> - * plane->atomic_props_plane.
>> + * plane->props.
>>   */
>>  static void
>> -igt_atomic_fill_plane_props(igt_display_t *display, igt_plane_t
>> *plane,
>> -			int num_props, const char **prop_names)
>> +igt_fill_plane_props(igt_display_t *display, igt_plane_t *plane,
>> +		     int num_props, const char **prop_names)
>>  {
>>  	drmModeObjectPropertiesPtr props;
>>  	int i, j, fd;
>> @@ -214,7 +214,7 @@ igt_atomic_fill_plane_props(igt_display_t
>> *display, igt_plane_t *plane,
>>  			if (strcmp(prop->name, prop_names[j]) != 0)
>>  				continue;
>>  
>> -			plane->atomic_props_plane[j] = props-
>>> props[i];
>> +			plane->props[j] = props->props[i];
>>  			break;
>>  		}
>>  
>> @@ -1659,7 +1659,6 @@ void igt_display_init(igt_display_t *display,
>> int drm_fd)
>>  	drmModeRes *resources;
>>  	drmModePlaneRes *plane_resources;
>>  	int i;
>> -	int is_atomic = 0;
>>  
>>  	memset(display, 0, sizeof(igt_display_t));
>>  
>> @@ -1679,7 +1678,9 @@ void igt_display_init(igt_display_t *display,
>> int drm_fd)
>>  	igt_assert_f(display->pipes, "Failed to allocate memory for
>> %d pipes\n", display->n_pipes);
>>  
>>  	drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
>> -	is_atomic = drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC,
>> 1);
>> +	if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1) == 0)
>> +		display->is_atomic = 1;
>> +
>>  	plane_resources = drmModeGetPlaneResources(display->drm_fd);
>>  	igt_assert(plane_resources);
>>  
>> @@ -1776,19 +1777,27 @@ void igt_display_init(igt_display_t *display,
>> int drm_fd)
>>  			plane->type = type;
>>  			plane->pipe = pipe;
>>  			plane->drm_plane = drm_plane;
>> -			plane->fence_fd = -1;
>> +			plane->values[IGT_PLANE_IN_FENCE_FD] =
>> ~0ULL;
>>  
>> -			if (is_atomic == 0) {
>> -				display->is_atomic = 1;
>> -				igt_atomic_fill_plane_props(display,
>> plane, IGT_NUM_PLANE_PROPS, igt_plane_prop_names);
>> -			}
>> +			igt_fill_plane_props(display, plane,
>> IGT_NUM_PLANE_PROPS, igt_plane_prop_names);
>>  
>>  			get_plane_property(display->drm_fd,
>> drm_plane->plane_id,
>>  					   "rotation",
>> -					   &plane-
>>> rotation_property,
>> -					   &prop_value,
>> +					   &plane-
>>> props[IGT_PLANE_ROTATION],
>> +					   &plane-
>>> values[IGT_PLANE_ROTATION],
>>  					   NULL);
>> -			plane->rotation =
>> (igt_rotation_t)prop_value;
>> +
>> +			/* Clear any residual framebuffer info on
>> first commit. */
>> +			igt_plane_set_prop_changed(plane,
>> IGT_PLANE_FB_ID);
>> +			igt_plane_set_prop_changed(plane,
>> IGT_PLANE_CRTC_ID);
>> +
>> +			/*
>> +			 * CRTC_X/Y are not changed in
>> igt_plane_set_fb, so
>> +			 * force them to be sanitized in case they
>> contain
>> +			 * garbage.
>> +			 */
>> +			igt_plane_set_prop_changed(plane,
>> IGT_PLANE_CRTC_X);
>> +			igt_plane_set_prop_changed(plane,
>> IGT_PLANE_CRTC_Y);
>>  		}
>>  
>>  		/*
>> @@ -1805,9 +1814,6 @@ void igt_display_init(igt_display_t *display,
>> int drm_fd)
>>  
>>  		pipe->n_planes = n_planes;
>>  
>> -		for_each_plane_on_pipe(display, i, plane)
>> -			plane->fb_changed = true;
>> -
>>  		pipe->mode_changed = true;
>>  	}
>>  
>> @@ -2070,18 +2076,7 @@ bool igt_pipe_get_property(igt_pipe_t *pipe,
>> const char *name,
>>  
>>  static uint32_t igt_plane_get_fb_id(igt_plane_t *plane)
>>  {
>> -	if (plane->fb)
>> -		return plane->fb->fb_id;
>> -	else
>> -		return 0;
>> -}
>> -
>> -static uint32_t igt_plane_get_fb_gem_handle(igt_plane_t *plane)
>> -{
>> -	if (plane->fb)
>> -		return plane->fb->gem_handle;
>> -	else
>> -		return 0;
>> +	return plane->values[IGT_PLANE_FB_ID];
>>  }
>>  
>>  #define CHECK_RETURN(r, fail) {	\
>> @@ -2090,9 +2085,6 @@ static uint32_t
>> igt_plane_get_fb_gem_handle(igt_plane_t *plane)
>>  	igt_assert_eq(r, 0);	\
>>  }
>>  
>> -
>> -
>> -
>>  /*
>>   * Add position and fb changes of a plane to the atomic property set
>>   */
>> @@ -2101,63 +2093,31 @@ igt_atomic_prepare_plane_commit(igt_plane_t
>> *plane, igt_pipe_t *pipe,
>>  	drmModeAtomicReq *req)
>>  {
>>  	igt_display_t *display = pipe->display;
>> -	uint32_t fb_id, crtc_id;
>> +	int i;
>>  
>>  	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 = pipe->crtc_id;
>> -
>>  	LOG(display,
>>  	    "populating plane data: %s.%d, fb %u\n",
>>  	    kmstest_pipe_name(pipe->pipe),
>>  	    plane->index,
>> -	    fb_id);
>> -
>> -	if (plane->fence_fd >= 0) {
>> -		uint64_t fence_fd = (int64_t) plane->fence_fd;
>> -		igt_atomic_populate_plane_req(req, plane,
>> IGT_PLANE_IN_FENCE_FD, fence_fd);
>> -	}
>> +	    igt_plane_get_fb_id(plane));
>>  
>> -	if (plane->fb_changed) {
>> -		igt_atomic_populate_plane_req(req, plane,
>> IGT_PLANE_CRTC_ID, fb_id ? crtc_id : 0);
>> -		igt_atomic_populate_plane_req(req, plane,
>> IGT_PLANE_FB_ID, fb_id);
>> -	}
>> -
>> -	if (plane->position_changed || plane->size_changed) {
>> -		uint32_t src_x = IGT_FIXED(plane->src_x, 0); /*
>> src_x */
>> -		uint32_t src_y = IGT_FIXED(plane->src_y, 0); /*
>> src_y */
>> -		uint32_t src_w = IGT_FIXED(plane->src_w, 0); /*
>> src_w */
>> -		uint32_t src_h = IGT_FIXED(plane->src_h, 0); /*
>> src_h */
>> -		int32_t crtc_x = plane->crtc_x;
>> -		int32_t crtc_y = plane->crtc_y;
>> -		uint32_t crtc_w = plane->crtc_w;
>> -		uint32_t crtc_h = plane->crtc_h;
>> +	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++) {
>> +		if (!igt_plane_is_prop_changed(plane, i))
>> +			continue;
> Could we add a macro here too? Like 'for_each_prop_on_plane()' or
> similar?

Outside of commit it doesn't make much sense to iterate over the properties.
The only test that enumerates over the array is the reworked kms_atomic, to
see if the value committed is the same as the value returned by getprop.

And the only reason the test does so is because it was easier to store in an
array to memcmp plane->values against kernel_values.

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2 03/14] lib/igt_kms: Rework pipe properties to be more atomic, v7.
  2017-10-12 11:54 ` [PATCH i-g-t v2 03/14] lib/igt_kms: Rework pipe properties to be more atomic, v7 Maarten Lankhorst
@ 2017-10-19 10:28   ` Mika Kahola
  2018-03-05 14:37     ` [igt-dev] [Intel-gfx] " Maxime Ripard
  1 sibling, 0 replies; 45+ messages in thread
From: Mika Kahola @ 2017-10-19 10:28 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx

Reviewed-by: Mika Kahola <mika.kahola@intel.com>

On Thu, 2017-10-12 at 13:54 +0200, Maarten Lankhorst wrote:
> In the future I want to allow tests to commit more properties,
> but for this to work I have to fix all properties to work better
> with atomic commit. Instead of special casing each
> property make a bitmask for all property changed flags, and try to
> commit all properties.
> 
> This has been the most involved one, since legacy pipe commit still
> handles a lot of the properties differently from the rest.
> 
> Changes since v1:
> - Dump all changed properties on commit.
> - Fix bug in igt_pipe_refresh().
> Changes since v2:
> - Set pipe ACTIVE property changed flag on init.
> Changes since v3:
> - Add a missing igt_pipe_refresh() to kms_atomic_interruptible.
> Changes since v4:
> - Perform error handling when setting custom crtc properties.
> Changes since v5:
> - Only attempt to commit changes properties.
> Changes since v6:
> - Clear OUT_FENCE_PTR on succesful commit.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  lib/igt_kms.c                     | 231 ++++++++++++++++++++------
> ------------
>  lib/igt_kms.h                     |  77 +++++--------
>  tests/kms_atomic_interruptible.c  |   8 +-
>  tests/kms_atomic_transition.c     |   2 +-
>  tests/kms_crtc_background_color.c |   2 +-
>  5 files changed, 159 insertions(+), 161 deletions(-)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index e77ae5d696da..02de39b8fc7f 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -259,8 +259,8 @@ igt_atomic_fill_connector_props(igt_display_t
> *display, igt_output_t *output,
>  }
>  
>  static void
> -igt_atomic_fill_pipe_props(igt_display_t *display, igt_pipe_t *pipe,
> -			int num_crtc_props, const char
> **crtc_prop_names)
> +igt_fill_pipe_props(igt_display_t *display, igt_pipe_t *pipe,
> +		    int num_crtc_props, const char
> **crtc_prop_names)
>  {
>  	drmModeObjectPropertiesPtr props;
>  	int i, j, fd;
> @@ -278,7 +278,7 @@ igt_atomic_fill_pipe_props(igt_display_t
> *display, igt_pipe_t *pipe,
>  			if (strcmp(prop->name, crtc_prop_names[j])
> != 0)
>  				continue;
>  
> -			pipe->atomic_props_crtc[j] = props-
> >props[i];
> +			pipe->props[j] = props->props[i];
>  			break;
>  		}
>  
> @@ -1620,13 +1620,6 @@ get_crtc_property(int drm_fd, uint32_t
> crtc_id, const char *name,
>  				    name, prop_id, value, prop);
>  }
>  
> -static void
> -igt_crtc_set_property(igt_pipe_t *pipe, uint32_t prop_id, uint64_t
> value)
> -{
> -	drmModeObjectSetProperty(pipe->display->drm_fd,
> -		pipe->crtc_id, DRM_MODE_OBJECT_CRTC, prop_id,
> value);
> -}
> -
>  /*
>   * Walk a plane's property list to determine its type.  If we don't
>   * find a type property, then the kernel doesn't support universal
> @@ -1690,7 +1683,6 @@ void igt_display_init(igt_display_t *display,
> int drm_fd)
>  		int p = 1;
>  		int j, type;
>  		uint8_t last_plane = 0, n_planes = 0;
> -		uint64_t prop_value;
>  
>  		pipe->crtc_id = resources->crtcs[i];
>  		pipe->display = display;
> @@ -1700,29 +1692,16 @@ void igt_display_init(igt_display_t *display,
> int drm_fd)
>  		pipe->planes = NULL;
>  		pipe->out_fence_fd = -1;
>  
> +		igt_fill_pipe_props(display, pipe,
> IGT_NUM_CRTC_PROPS, igt_crtc_prop_names);
> +
> +		/* Force modeset disable on first commit */
> +		igt_pipe_obj_set_prop_changed(pipe,
> IGT_CRTC_MODE_ID);
> +		igt_pipe_obj_set_prop_changed(pipe,
> IGT_CRTC_ACTIVE);
> +
>  		get_crtc_property(display->drm_fd, pipe->crtc_id,
> -				    "background_color",
> -				    &pipe->background_property,
> -				    &prop_value,
> +				    "background_color", NULL,
> +				    &pipe-
> >values[IGT_CRTC_BACKGROUND],
>  				    NULL);
> -		pipe->background = (uint32_t)prop_value;
> -		get_crtc_property(display->drm_fd, pipe->crtc_id,
> -				  "DEGAMMA_LUT",
> -				  &pipe->degamma_property,
> -				  NULL,
> -				  NULL);
> -		get_crtc_property(display->drm_fd, pipe->crtc_id,
> -				  "CTM",
> -				  &pipe->ctm_property,
> -				  NULL,
> -				  NULL);
> -		get_crtc_property(display->drm_fd, pipe->crtc_id,
> -				  "GAMMA_LUT",
> -				  &pipe->gamma_property,
> -				  NULL,
> -				  NULL);
> -
> -		igt_atomic_fill_pipe_props(display, pipe,
> IGT_NUM_CRTC_PROPS, igt_crtc_prop_names);
>  
>  		/* count number of valid planes */
>  		for (j = 0; j < plane_resources->count_planes; j++)
> {
> @@ -1813,8 +1792,6 @@ void igt_display_init(igt_display_t *display,
> int drm_fd)
>  			igt_assert_eq(p, n_planes);
>  
>  		pipe->n_planes = n_planes;
> -
> -		pipe->mode_changed = true;
>  	}
>  
>  	/*
> @@ -2291,7 +2268,7 @@ static int
> igt_primary_plane_commit_legacy(igt_plane_t *primary,
>  
>  	if (!igt_plane_is_prop_changed(primary, IGT_PLANE_FB_ID) &&
>  	    !(primary->changed & IGT_PLANE_COORD_CHANGED_MASK) &&
> -	    !primary->pipe->mode_changed)
> +	    !igt_pipe_obj_is_prop_changed(primary->pipe,
> IGT_CRTC_MODE_ID))
>  		return 0;
>  
>  	crtc_id = pipe->crtc_id;
> @@ -2360,6 +2337,16 @@ static int igt_plane_commit(igt_plane_t
> *plane,
>  	}
>  }
>  
> +static bool is_atomic_prop(enum igt_atomic_crtc_properties prop)
> +{
> +       if (prop == IGT_CRTC_MODE_ID ||
> +	   prop == IGT_CRTC_ACTIVE ||
> +	   prop == IGT_CRTC_OUT_FENCE_PTR)
> +		return true;
> +
> +	return false;
> +}
> +
>  /*
>   * Commit all plane changes to an output.  Note that if @s is
> COMMIT_LEGACY,
>   * enabling/disabling the primary plane will also enable/disable the
> CRTC.
> @@ -2377,19 +2364,17 @@ static int igt_pipe_commit(igt_pipe_t *pipe,
>  	int i;
>  	int ret;
>  
> -	if (pipe->background_changed) {
> -		igt_crtc_set_property(pipe, pipe-
> >background_property,
> -			pipe->background);
> -	}
> +	for (i = 0; i < IGT_NUM_CRTC_PROPS; i++)
> +		if (igt_pipe_obj_is_prop_changed(pipe, i) &&
> +		    !is_atomic_prop(i)) {
> +			igt_assert(pipe->props[i]);
>  
> -	if (pipe->color_mgmt_changed) {
> -		igt_crtc_set_property(pipe, pipe->degamma_property,
> -				      pipe->degamma_blob);
> -		igt_crtc_set_property(pipe, pipe->ctm_property,
> -				      pipe->ctm_blob);
> -		igt_crtc_set_property(pipe, pipe->gamma_property,
> -				      pipe->gamma_blob);
> -	}
> +			ret = drmModeObjectSetProperty(pipe-
> >display->drm_fd,
> +				pipe->crtc_id, DRM_MODE_OBJECT_CRTC,
> +				pipe->props[i], pipe->values[i]);
> +
> +			CHECK_RETURN(ret, fail_on_error);
> +		}
>  
>  	for (i = 0; i < pipe->n_planes; i++) {
>  		igt_plane_t *plane = &pipe->planes[i];
> @@ -2402,9 +2387,10 @@ static int igt_pipe_commit(igt_pipe_t *pipe,
>  }
>  
>  static void
> -igt_pipe_replace_blob(igt_pipe_t *pipe, uint64_t *blob, void *ptr,
> size_t length)
> +igt_pipe_replace_blob(igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop, void *ptr, size_t length)
>  {
>  	igt_display_t *display = pipe->display;
> +	uint64_t *blob = &pipe->values[prop];
>  	uint32_t blob_id = 0;
>  
>  	if (*blob != 0)
> @@ -2416,6 +2402,7 @@ igt_pipe_replace_blob(igt_pipe_t *pipe,
> uint64_t *blob, void *ptr, size_t length
>  						     ptr, length,
> &blob_id) == 0);
>  
>  	*blob = blob_id;
> +	igt_pipe_obj_set_prop_changed(pipe, prop);
>  }
>  
>  /*
> @@ -2423,51 +2410,23 @@ igt_pipe_replace_blob(igt_pipe_t *pipe,
> uint64_t *blob, void *ptr, size_t length
>   */
>  static void igt_atomic_prepare_crtc_commit(igt_pipe_t *pipe_obj,
> drmModeAtomicReq *req)
>  {
> -	if (pipe_obj->background_changed)
> -		igt_atomic_populate_crtc_req(req, pipe_obj,
> IGT_CRTC_BACKGROUND, pipe_obj->background);
> -
> -	if (pipe_obj->color_mgmt_changed) {
> -		igt_atomic_populate_crtc_req(req, pipe_obj,
> IGT_CRTC_DEGAMMA_LUT, pipe_obj->degamma_blob);
> -		igt_atomic_populate_crtc_req(req, pipe_obj,
> IGT_CRTC_CTM, pipe_obj->ctm_blob);
> -		igt_atomic_populate_crtc_req(req, pipe_obj,
> IGT_CRTC_GAMMA_LUT, pipe_obj->gamma_blob);
> -	}
> -
> -	if (pipe_obj->mode_changed) {
> -		igt_output_t *output =
> igt_pipe_get_output(pipe_obj);
> -
> -		if (!output) {
> -			igt_pipe_replace_blob(pipe_obj, &pipe_obj-
> >mode_blob, NULL, 0);
> -
> -			LOG(pipe_obj->display, "%s: Setting NULL
> mode\n",
> -			    kmstest_pipe_name(pipe_obj->pipe));
> -		} else {
> -			drmModeModeInfo *mode =
> igt_output_get_mode(output);
> +	int i;
>  
> -			igt_pipe_replace_blob(pipe_obj, &pipe_obj-
> >mode_blob, mode, sizeof(*mode));
> +	for (i = 0; i < IGT_NUM_CRTC_PROPS; i++) {
> +		if (!igt_pipe_obj_is_prop_changed(pipe_obj, i))
> +			continue;
>  
> -			LOG(pipe_obj->display, "%s: Setting mode %s
> from %s\n",
> -			    kmstest_pipe_name(pipe_obj->pipe),
> -			    mode->name, igt_output_name(output));
> -		}
> +		igt_debug("Pipe %s: Setting property \"%s\" to
> 0x%"PRIx64"/%"PRIi64"\n",
> +			kmstest_pipe_name(pipe_obj->pipe),
> igt_crtc_prop_names[i],
> +			pipe_obj->values[i], pipe_obj->values[i]);
>  
> -		igt_atomic_populate_crtc_req(req, pipe_obj,
> IGT_CRTC_MODE_ID, pipe_obj->mode_blob);
> -		igt_atomic_populate_crtc_req(req, pipe_obj,
> IGT_CRTC_ACTIVE, !!output);
> +		igt_assert_lt(0, drmModeAtomicAddProperty(req,
> pipe_obj->crtc_id, pipe_obj->props[i], pipe_obj->values[i]));
>  	}
>  
>  	if (pipe_obj->out_fence_fd != -1) {
>  		close(pipe_obj->out_fence_fd);
>  		pipe_obj->out_fence_fd = -1;
>  	}
> -
> -	if (pipe_obj->out_fence_requested)
> -	{
> -		igt_atomic_populate_crtc_req(req, pipe_obj,
> IGT_CRTC_OUT_FENCE_PTR,
> -		    (uint64_t)(uintptr_t) &pipe_obj->out_fence_fd);
> -	}
> -
> -	/*
> -	 *	TODO: Add all crtc level properties here
> -	 */
>  }
>  
>  /*
> @@ -2558,15 +2517,22 @@ display_commit_changed(igt_display_t
> *display, enum igt_commit_style s)
>  		igt_pipe_t *pipe_obj = &display->pipes[pipe];
>  		igt_plane_t *plane;
>  
> -		pipe_obj->color_mgmt_changed = false;
> -		pipe_obj->background_changed = false;
> +		if (s == COMMIT_ATOMIC) {
> +			if (igt_pipe_obj_is_prop_changed(pipe_obj,
> IGT_CRTC_OUT_FENCE_PTR))
> +				igt_assert(pipe_obj->out_fence_fd >=
> 0);
>  
> -		if (s != COMMIT_UNIVERSAL)
> -			pipe_obj->mode_changed = false;
> -
> -		if (s == COMMIT_ATOMIC && pipe_obj-
> >out_fence_requested) {
> -			pipe_obj->out_fence_requested = false;
> -			igt_assert(pipe_obj->out_fence_fd >= 0);
> +			pipe_obj->values[IGT_CRTC_OUT_FENCE_PTR] =
> 0;
> +			pipe_obj->changed = 0;
> +		} else {
> +			igt_pipe_obj_clear_prop_changed(pipe_obj,
> IGT_CRTC_BACKGROUND);
> +			igt_pipe_obj_clear_prop_changed(pipe_obj,
> IGT_CRTC_CTM);
> +			igt_pipe_obj_clear_prop_changed(pipe_obj,
> IGT_CRTC_DEGAMMA_LUT);
> +			igt_pipe_obj_clear_prop_changed(pipe_obj,
> IGT_CRTC_GAMMA_LUT);
> +
> +			if (s != COMMIT_UNIVERSAL) {
> +				igt_pipe_obj_clear_prop_changed(pipe
> _obj, IGT_CRTC_MODE_ID);
> +				igt_pipe_obj_clear_prop_changed(pipe
> _obj, IGT_CRTC_ACTIVE);
> +			}
>  		}
>  
>  		for_each_plane_on_pipe(display, pipe, plane) {
> @@ -2820,33 +2786,83 @@ void igt_output_override_mode(igt_output_t
> *output, drmModeModeInfo *mode)
>  
>  	output->use_override_mode = !!mode;
>  
> -	if (pipe)
> -		pipe->mode_changed = true;
> +	if (pipe) {
> +		if (output->display->is_atomic)
> +			igt_pipe_replace_blob(pipe,
> IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(*mode));
> +		else
> +			igt_pipe_obj_set_prop_changed(pipe,
> IGT_CRTC_MODE_ID);
> +	}
>  }
>  
>  void igt_output_set_pipe(igt_output_t *output, enum pipe pipe)
>  {
>  	igt_display_t *display = output->display;
> -	igt_pipe_t *old_pipe;
> +	igt_pipe_t *old_pipe = NULL, *pipe_obj = NULL;;
>  
>  	igt_assert(output->name);
>  
> -	if (output->pending_pipe != PIPE_NONE) {
> +	if (output->pending_pipe != PIPE_NONE)
>  		old_pipe = igt_output_get_driving_pipe(output);
>  
> -		old_pipe->mode_changed = true;
> -	}
> +	if (pipe != PIPE_NONE)
> +		pipe_obj = &display->pipes[pipe];
>  
>  	LOG(display, "%s: set_pipe(%s)\n", igt_output_name(output),
>  	    kmstest_pipe_name(pipe));
>  	output->pending_pipe = pipe;
>  
> -	if (pipe != PIPE_NONE)
> -		display->pipes[pipe].mode_changed = true;
> +	if (old_pipe) {
> +		igt_output_t *old_output;
> +
> +		old_output = igt_pipe_get_output(old_pipe);
> +		if (!old_output) {
> +			if (display->is_atomic)
> +				igt_pipe_replace_blob(old_pipe,
> IGT_CRTC_MODE_ID, NULL, 0);
> +			else
> +				igt_pipe_obj_set_prop_changed(old_pi
> pe, IGT_CRTC_MODE_ID);
> +
> +			igt_pipe_obj_set_prop_value(old_pipe,
> IGT_CRTC_ACTIVE, 0);
> +		}
> +	}
>  
>  	igt_output_set_prop_value(output, IGT_CONNECTOR_CRTC_ID,
> pipe == PIPE_NONE ? 0 : display->pipes[pipe].crtc_id);
>  
>  	igt_output_refresh(output);
> +
> +	if (pipe_obj) {
> +		if (display->is_atomic)
> +			igt_pipe_replace_blob(pipe_obj,
> IGT_CRTC_MODE_ID, igt_output_get_mode(output),
> sizeof(drmModeModeInfo));
> +		else
> +			igt_pipe_obj_set_prop_changed(pipe_obj,
> IGT_CRTC_MODE_ID);
> +
> +		igt_pipe_obj_set_prop_value(pipe_obj,
> IGT_CRTC_ACTIVE, 1);
> +	}
> +}
> +
> +/*
> + * igt_pipe_refresh:
> + * @display: a pointer to an #igt_display_t structure
> + * @pipe: Pipe to refresh
> + * @force: Should be set to true if mode_blob is no longer
> considered
> + * to be valid, for example after doing an atomic commit during fork
> or closing display fd.
> + *
> + * Requests the pipe to be part of the state on next update.
> + * This is useful when state may have been out of sync after
> + * a fork, or we just want to be sure the pipe is included
> + * in the next commit.
> + */
> +void igt_pipe_refresh(igt_display_t *display, enum pipe pipe, bool
> force)
> +{
> +	igt_pipe_t *pipe_obj = &display->pipes[pipe];
> +
> +	if (force && display->is_atomic) {
> +		igt_output_t *output =
> igt_pipe_get_output(pipe_obj);
> +
> +		pipe_obj->values[IGT_CRTC_MODE_ID] = 0;
> +		if (output)
> +			igt_pipe_replace_blob(pipe_obj,
> IGT_CRTC_MODE_ID, igt_output_get_mode(output),
> sizeof(drmModeModeInfo));
> +	} else
> +		igt_pipe_obj_set_prop_changed(pipe_obj,
> IGT_CRTC_MODE_ID);
>  }
>  
>  void igt_output_set_scaling_mode(igt_output_t *output, uint64_t
> scaling_mode)
> @@ -3052,28 +3068,25 @@ void igt_plane_set_rotation(igt_plane_t
> *plane, igt_rotation_t rotation)
>   */
>  void igt_pipe_request_out_fence(igt_pipe_t *pipe)
>  {
> -	pipe->out_fence_requested = true;
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR,
> (ptrdiff_t)&pipe->out_fence_fd);
>  }
>  
>  void
>  igt_pipe_set_degamma_lut(igt_pipe_t *pipe, void *ptr, size_t length)
>  {
> -	igt_pipe_replace_blob(pipe, &pipe->degamma_blob, ptr,
> length);
> -	pipe->color_mgmt_changed = 1;
> +	igt_pipe_replace_blob(pipe, IGT_CRTC_DEGAMMA_LUT, ptr,
> length);
>  }
>  
>  void
>  igt_pipe_set_ctm_matrix(igt_pipe_t *pipe, void *ptr, size_t length)
>  {
> -	igt_pipe_replace_blob(pipe, &pipe->ctm_blob, ptr, length);
> -	pipe->color_mgmt_changed = 1;
> +	igt_pipe_replace_blob(pipe, IGT_CRTC_CTM, ptr, length);
>  }
>  
>  void
>  igt_pipe_set_gamma_lut(igt_pipe_t *pipe, void *ptr, size_t length)
>  {
> -	igt_pipe_replace_blob(pipe, &pipe->gamma_blob, ptr, length);
> -	pipe->color_mgmt_changed = 1;
> +	igt_pipe_replace_blob(pipe, IGT_CRTC_GAMMA_LUT, ptr,
> length);
>  }
>  
>  /**
> @@ -3094,9 +3107,7 @@ void igt_crtc_set_background(igt_pipe_t *pipe,
> uint64_t background)
>  	    kmstest_pipe_name(pipe->pipe),
>  	    pipe->pipe, background);
>  
> -	pipe->background = background;
> -
> -	pipe->background_changed = true;
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_BACKGROUND,
> background);
>  }
>  
>  void igt_wait_for_vblank_count(int drm_fd, enum pipe pipe, int
> count)
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index f87f8be31421..b53127ffef5f 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -313,27 +313,13 @@ struct igt_pipe {
>  	int plane_primary;
>  	igt_plane_t *planes;
>  
> -	uint32_t atomic_props_crtc[IGT_NUM_CRTC_PROPS];
> -
> -	uint64_t background; /* Background color MSB BGR 16bpc LSB
> */
> -	uint32_t background_changed : 1;
> -	uint32_t background_property;
> -
> -	uint64_t degamma_blob;
> -	uint32_t degamma_property;
> -	uint64_t ctm_blob;
> -	uint32_t ctm_property;
> -	uint64_t gamma_blob;
> -	uint32_t gamma_property;
> -	uint32_t color_mgmt_changed : 1;
> +	uint64_t changed;
> +	uint32_t props[IGT_NUM_CRTC_PROPS];
> +	uint64_t values[IGT_NUM_CRTC_PROPS];
>  
>  	uint32_t crtc_id;
>  
> -	uint64_t mode_blob;
> -	bool mode_changed;
> -
>  	int32_t out_fence_fd;
> -	bool out_fence_requested;
>  };
>  
>  typedef struct {
> @@ -527,17 +513,6 @@ static inline bool
> igt_output_is_connected(igt_output_t *output)
>  		igt_plane_set_prop_changed(plane, prop); \
>  	} while (0)
>  
> -/**
> - * igt_atomic_populate_crtc_req:
> - * @req: A pointer to drmModeAtomicReq
> - * @pipe: A pointer igt_pipe_t
> - * @prop: one of igt_atomic_crtc_properties
> - * @value: the value to add
> - */
> -#define igt_atomic_populate_crtc_req(req, pipe, prop, value) \
> -	igt_assert_lt(0, drmModeAtomicAddProperty(req, pipe-
> >crtc_id,\
> -						  pipe-
> >atomic_props_crtc[prop], value))
> -
>  #define igt_output_is_prop_changed(output, prop) \
>  	(!!((output)->changed & (1 << (prop))))
>  #define igt_output_set_prop_changed(output, prop) \
> @@ -552,26 +527,34 @@ static inline bool
> igt_output_is_connected(igt_output_t *output)
>  		igt_output_set_prop_changed(output, prop); \
>  	} while (0)
>  
> -/*
> - * igt_pipe_refresh:
> - * @display: a pointer to an #igt_display_t structure
> - * @pipe: Pipe to refresh
> - * @force: Should be set to true if mode_blob is no longer
> considered
> - * to be valid, for example after doing an atomic commit during fork
> or closing display fd.
> - *
> - * Requests the pipe to be part of the state on next update.
> - * This is useful when state may have been out of sync after
> - * a fork, or we just want to be sure the pipe is included
> - * in the next commit.
> - */
> -static inline void
> -igt_pipe_refresh(igt_display_t *display, enum pipe pipe, bool force)
> -{
> -	if (force)
> -		display->pipes[pipe].mode_blob = 0;
> +#define igt_pipe_obj_is_prop_changed(pipe_obj, prop) \
> +	(!!((pipe_obj)->changed & (1 << (prop))))
>  
> -	display->pipes[pipe].mode_changed = true;
> -}
> +#define igt_pipe_is_prop_changed(display, pipe, prop) \
> +	igt_pipe_obj_is_prop_changed(&(display)->pipes[(pipe)],
> prop)
> +
> +#define igt_pipe_obj_set_prop_changed(pipe_obj, prop) \
> +	(pipe_obj)->changed |= 1 << (prop)
> +
> +#define igt_pipe_set_prop_changed(display, pipe, prop) \
> +	igt_pipe_obj_set_prop_changed(&(display)->pipes[(pipe)],
> prop)
> +
> +#define igt_pipe_obj_clear_prop_changed(pipe_obj, prop) \
> +	(pipe_obj)->changed &= ~(1 << (prop))
> +
> +#define igt_pipe_clear_prop_changed(display, pipe, prop) \
> +	igt_pipe_obj_clear_prop_changed(&(display)->pipes[(pipe)],
> prop)
> +
> +#define igt_pipe_obj_set_prop_value(pipe_obj, prop, value) \
> +	do { \
> +		(pipe_obj)->values[prop] = (value); \
> +		igt_pipe_obj_set_prop_changed(pipe_obj, prop); \
> +	} while (0)
> +
> +#define igt_pipe_set_prop_value(display, pipe, prop, value) \
> +	igt_pipe_obj_set_prop_value(&(display)->pipes[(pipe)], prop,
> value)
> +
> +void igt_pipe_refresh(igt_display_t *display, enum pipe pipe, bool
> force);
>  
>  void igt_enable_connectors(void);
>  void igt_reset_connectors(void);
> diff --git a/tests/kms_atomic_interruptible.c
> b/tests/kms_atomic_interruptible.c
> index 4a2a577412cc..64a005597a21 100644
> --- a/tests/kms_atomic_interruptible.c
> +++ b/tests/kms_atomic_interruptible.c
> @@ -158,8 +158,8 @@ static void run_plane_test(igt_display_t
> *display, enum pipe pipe, igt_output_t
>  				uint32_t count_props[3] = { 2, 1, 6
> };
>  				uint32_t props[] = {
>  					/* crtc: 2 props */
> -					plane->pipe-
> >atomic_props_crtc[IGT_CRTC_MODE_ID],
> -					plane->pipe-
> >atomic_props_crtc[IGT_CRTC_ACTIVE],
> +					plane->pipe-
> >props[IGT_CRTC_MODE_ID],
> +					plane->pipe-
> >props[IGT_CRTC_ACTIVE],
>  					/* connector: 1 prop */
>  					output-
> >props[IGT_CONNECTOR_CRTC_ID],
>  					/* plane: remainder props */
> @@ -255,6 +255,10 @@ static void run_plane_test(igt_display_t
> *display, enum pipe pipe, igt_output_t
>  
>  	igt_waitchildren();
>  
> +	/* The mode is unset by the forked helper, force a refresh
> here */
> +	if (test_type == test_legacy_modeset || test_type ==
> test_atomic_modeset)
> +		igt_pipe_refresh(display, pipe, true);
> +
>  	igt_plane_set_fb(plane, NULL);
>  	igt_plane_set_fb(primary, NULL);
>  	igt_output_set_pipe(output, PIPE_NONE);
> diff --git a/tests/kms_atomic_transition.c
> b/tests/kms_atomic_transition.c
> index 2ae75f2d6630..7ddb65cea183 100644
> --- a/tests/kms_atomic_transition.c
> +++ b/tests/kms_atomic_transition.c
> @@ -633,7 +633,7 @@ static unsigned set_combinations(igt_display_t
> *display, unsigned mask, struct i
>  		drmModeModeInfo *mode = NULL;
>  
>  		if (!(mask & (1 << pipe))) {
> -			if (display->pipes[pipe].mode_blob) {
> +			if (igt_pipe_is_prop_changed(display, pipe,
> IGT_CRTC_ACTIVE)) {
>  				event_mask |= 1 << pipe;
>  				igt_plane_set_fb(plane, NULL);
>  			}
> diff --git a/tests/kms_crtc_background_color.c
> b/tests/kms_crtc_background_color.c
> index e12e163449f8..659a30b90219 100644
> --- a/tests/kms_crtc_background_color.c
> +++ b/tests/kms_crtc_background_color.c
> @@ -137,7 +137,7 @@ static void test_crtc_background(data_t *data)
>  		igt_output_set_pipe(output, pipe);
>  
>  		plane = igt_output_get_plane_type(output,
> DRM_PLANE_TYPE_PRIMARY);
> -		igt_require(plane->pipe->background_property);
> +		igt_require(plane->pipe-
> >props[IGT_CRTC_BACKGROUND]);
>  
>  		prepare_crtc(data, output, pipe, plane, 1, PURPLE,
> BLACK64);
>  
-- 
Mika Kahola - Intel OTC

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2 04/14] lib/igt_kms: Allow setting any plane property through the universal path
  2017-10-12 11:54 ` [PATCH i-g-t v2 04/14] lib/igt_kms: Allow setting any plane property through the universal path Maarten Lankhorst
@ 2017-10-19 11:04   ` Mika Kahola
  0 siblings, 0 replies; 45+ messages in thread
From: Mika Kahola @ 2017-10-19 11:04 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx

Reviewed-by: Mika Kahola <mika.kahola@intel.com>

On Thu, 2017-10-12 at 13:54 +0200, Maarten Lankhorst wrote:
> Blacklist some explicit atomic properties. We could theoretically set
> them but that's not what the legacy path is for. :)
> 
> When adding new properties, this means we could test those through
> the legacy commit.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  lib/igt_kms.c | 39 +++++++++++++++++++++++++++++++++------
>  1 file changed, 33 insertions(+), 6 deletions(-)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index 02de39b8fc7f..be89632547e5 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -2097,7 +2097,22 @@ igt_atomic_prepare_plane_commit(igt_plane_t
> *plane, igt_pipe_t *pipe,
>  	}
>  }
>  
> -
> +/*
> + * Properties that can be changed through legacy SetProperty:
> + * - Obviously not the XYWH SRC/CRTC coordinates.
> + * - Not CRTC_ID or FENCE_ID, done through SetPlane.
> + * - Can't set IN_FENCE_FD, that would be silly.
> + *
> + * Theoretically the above can all be set through the legacy path
> + * with the atomic cap set, but that's not how our legacy plane
> + * commit behaves, so blacklist it by default.
> + */
> +#define LEGACY_PLANE_COMMIT_MASK \
> +	(((1ULL << IGT_NUM_PLANE_PROPS) - 1) & \
> +	 ~(IGT_PLANE_COORD_CHANGED_MASK | \
> +	   (1ULL << IGT_PLANE_FB_ID) | \
> +	   (1ULL << IGT_PLANE_CRTC_ID) | \
> +	   (1ULL << IGT_PLANE_IN_FENCE_FD)))
>  
>  /*
>   * Commit position and fb changes to a DRM plane via the SetPlane
> ioctl; if the
> @@ -2111,7 +2126,7 @@ static int igt_drm_plane_commit(igt_plane_t
> *plane,
>  {
>  	igt_display_t *display = pipe->display;
>  	uint32_t fb_id, crtc_id;
> -	int ret;
> +	int ret, i;
>  	uint32_t src_x;
>  	uint32_t src_y;
>  	uint32_t src_w;
> @@ -2120,6 +2135,7 @@ static int igt_drm_plane_commit(igt_plane_t
> *plane,
>  	int32_t crtc_y;
>  	uint32_t crtc_w;
>  	uint32_t crtc_h;
> +	uint64_t changed_mask;
>  	bool setplane =
>  		igt_plane_is_prop_changed(plane, IGT_PLANE_FB_ID) ||
>  		plane->changed & IGT_PLANE_COORD_CHANGED_MASK;
> @@ -2184,10 +2200,21 @@ static int igt_drm_plane_commit(igt_plane_t
> *plane,
>  		CHECK_RETURN(ret, fail_on_error);
>  	}
>  
> -	if (igt_plane_is_prop_changed(plane, IGT_PLANE_ROTATION)) {
> +	changed_mask = plane->changed & LEGACY_PLANE_COMMIT_MASK;
> +
> +	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++) {
> +		if (!(changed_mask & (1 << i)))
> +			continue;
> +
> +		LOG(display, "SetProp plane %s.%d \"%s\" to
> 0x%"PRIx64"/%"PRIi64"\n",
> +			kmstest_pipe_name(pipe->pipe), plane->index, 
> igt_plane_prop_names[i],
> +			plane->values[i], plane->values[i]);
> +
> +		igt_assert(plane->props[i]);
> +
>  		ret = igt_plane_set_property(plane,
> -					     plane-
> >props[IGT_PLANE_ROTATION],
> -					     plane-
> >values[IGT_PLANE_ROTATION]);
> +					     plane->props[i],
> +					     plane->values[i]);
>  
>  		CHECK_RETURN(ret, fail_on_error);
>  	}
> @@ -2555,7 +2582,7 @@ display_commit_changed(igt_display_t *display,
> enum igt_commit_style s)
>  				if (s != COMMIT_LEGACY ||
>  				    !(plane->type ==
> DRM_PLANE_TYPE_PRIMARY ||
>  				      plane->type ==
> DRM_PLANE_TYPE_CURSOR))
> -					igt_plane_clear_prop_changed
> (plane, IGT_PLANE_ROTATION);
> +					plane->changed &=
> ~LEGACY_PLANE_COMMIT_MASK;
>  			}
>  		}
>  	}
-- 
Mika Kahola - Intel OTC

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2 06/14] lib/igt_kms: Export property blob functions for output/pipe/plane, v2.
  2017-10-12 11:54 ` [PATCH i-g-t v2 06/14] lib/igt_kms: Export property blob functions for output/pipe/plane, v2 Maarten Lankhorst
@ 2017-10-19 11:24   ` Mika Kahola
  0 siblings, 0 replies; 45+ messages in thread
From: Mika Kahola @ 2017-10-19 11:24 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx

Reviewed-by: Mika Kahola <mika.kahola@intel.com>

On Thu, 2017-10-12 at 13:54 +0200, Maarten Lankhorst wrote:
> With the replace_prop_blob functions we can safely replace the blob
> for
> any property, without having to care about error handling ourselves.
> 
> This will for example allow overriding color management blobs, or for
> kms_atomic set invalid mode blobs.
> 
> The color management blob functions are removed, they can now be
> replaced by direct calls to replace the properties.
> 
> Changes since v1:
> - Fix chamelium tests.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  lib/igt_kms.c     | 117 +++++++++++++++++++++++++++++++++++++++-----
> ----------
>  lib/igt_kms.h     |  19 +++++++--
>  tests/chamelium.c |   6 +--
>  tests/kms_color.c |  12 +++---
>  4 files changed, 110 insertions(+), 44 deletions(-)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index e7b9fbaba709..5f54021350ac 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -2443,8 +2443,88 @@ static int igt_output_commit(igt_output_t
> *output,
>  	return 0;
>  }
>  
> -static void
> -igt_pipe_replace_blob(igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop, void *ptr, size_t length)
> +/**
> + * igt_plane_replace_prop_blob:
> + * @plane: plane to set property on.
> + * @prop: property for which the blob will be replaced.
> + * @ptr: Pointer to contents for the property.
> + * @length: Length of contents.
> + *
> + * This function will destroy the old property blob for the given
> property,
> + * and will create a new property blob with the values passed to
> this function.
> + *
> + * The new property blob will be committed when you call
> igt_display_commit(),
> + * igt_display_commit2() or igt_display_commit_atomic().
> + */
> +void
> +igt_plane_replace_prop_blob(igt_plane_t *plane, enum
> igt_atomic_plane_properties prop, const void *ptr, size_t length)
> +{
> +	igt_display_t *display = plane->pipe->display;
> +	uint64_t *blob = &plane->values[prop];
> +	uint32_t blob_id = 0;
> +
> +	if (*blob != 0)
> +		igt_assert(drmModeDestroyPropertyBlob(display-
> >drm_fd,
> +						      *blob) == 0);
> +
> +	if (length > 0)
> +		igt_assert(drmModeCreatePropertyBlob(display-
> >drm_fd,
> +						     ptr, length,
> &blob_id) == 0);
> +
> +	*blob = blob_id;
> +	igt_plane_set_prop_changed(plane, prop);
> +}
> +
> +/**
> + * igt_output_replace_prop_blob:
> + * @output: output to set property on.
> + * @prop: property for which the blob will be replaced.
> + * @ptr: Pointer to contents for the property.
> + * @length: Length of contents.
> + *
> + * This function will destroy the old property blob for the given
> property,
> + * and will create a new property blob with the values passed to
> this function.
> + *
> + * The new property blob will be committed when you call
> igt_display_commit(),
> + * igt_display_commit2() or igt_display_commit_atomic().
> + */
> +void
> +igt_output_replace_prop_blob(igt_output_t *output, enum
> igt_atomic_connector_properties prop, const void *ptr, size_t length)
> +{
> +	igt_display_t *display = output->display;
> +	uint64_t *blob = &output->values[prop];
> +	uint32_t blob_id = 0;
> +
> +	if (*blob != 0)
> +		igt_assert(drmModeDestroyPropertyBlob(display-
> >drm_fd,
> +						      *blob) == 0);
> +
> +	if (length > 0)
> +		igt_assert(drmModeCreatePropertyBlob(display-
> >drm_fd,
> +						     ptr, length,
> &blob_id) == 0);
> +
> +	*blob = blob_id;
> +	igt_output_set_prop_changed(output, prop);
> +}
> +
> +/**
> + * igt_pipe_obj_replace_prop_blob:
> + * @pipe: pipe to set property on.
> + * @prop: property for which the blob will be replaced.
> + * @ptr: Pointer to contents for the property.
> + * @length: Length of contents.
> + *
> + * This function will destroy the old property blob for the given
> property,
> + * and will create a new property blob with the values passed to
> this function.
> + *
> + * The new property blob will be committed when you call
> igt_display_commit(),
> + * igt_display_commit2() or igt_display_commit_atomic().
> + *
> + * Please use igt_output_override_mode() if you want to set
> #IGT_CRTC_MODE_ID,
> + * it works better with legacy commit.
> + */
> +void
> +igt_pipe_obj_replace_prop_blob(igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop, const void *ptr, size_t length)
>  {
>  	igt_display_t *display = pipe->display;
>  	uint64_t *blob = &pipe->values[prop];
> @@ -2836,7 +2916,7 @@ void igt_output_override_mode(igt_output_t
> *output, drmModeModeInfo *mode)
>  
>  	if (pipe) {
>  		if (output->display->is_atomic)
> -			igt_pipe_replace_blob(pipe,
> IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(*mode));
> +			igt_pipe_obj_replace_prop_blob(pipe,
> IGT_CRTC_MODE_ID, igt_output_get_mode(output), sizeof(*mode));
>  		else
>  			igt_pipe_obj_set_prop_changed(pipe,
> IGT_CRTC_MODE_ID);
>  	}
> @@ -2865,7 +2945,7 @@ void igt_output_set_pipe(igt_output_t *output,
> enum pipe pipe)
>  		old_output = igt_pipe_get_output(old_pipe);
>  		if (!old_output) {
>  			if (display->is_atomic)
> -				igt_pipe_replace_blob(old_pipe,
> IGT_CRTC_MODE_ID, NULL, 0);
> +				igt_pipe_obj_replace_prop_blob(old_p
> ipe, IGT_CRTC_MODE_ID, NULL, 0);
>  			else
>  				igt_pipe_obj_set_prop_changed(old_pi
> pe, IGT_CRTC_MODE_ID);
>  
> @@ -2879,7 +2959,7 @@ void igt_output_set_pipe(igt_output_t *output,
> enum pipe pipe)
>  
>  	if (pipe_obj) {
>  		if (display->is_atomic)
> -			igt_pipe_replace_blob(pipe_obj,
> IGT_CRTC_MODE_ID, igt_output_get_mode(output),
> sizeof(drmModeModeInfo));
> +			igt_pipe_obj_replace_prop_blob(pipe_obj,
> IGT_CRTC_MODE_ID, igt_output_get_mode(output),
> sizeof(drmModeModeInfo));
>  		else
>  			igt_pipe_obj_set_prop_changed(pipe_obj,
> IGT_CRTC_MODE_ID);
>  
> @@ -2908,18 +2988,11 @@ void igt_pipe_refresh(igt_display_t *display,
> enum pipe pipe, bool force)
>  
>  		pipe_obj->values[IGT_CRTC_MODE_ID] = 0;
>  		if (output)
> -			igt_pipe_replace_blob(pipe_obj,
> IGT_CRTC_MODE_ID, igt_output_get_mode(output),
> sizeof(drmModeModeInfo));
> +			igt_pipe_obj_replace_prop_blob(pipe_obj,
> IGT_CRTC_MODE_ID, igt_output_get_mode(output),
> sizeof(drmModeModeInfo));
>  	} else
>  		igt_pipe_obj_set_prop_changed(pipe_obj,
> IGT_CRTC_MODE_ID);
>  }
>  
> -void igt_output_set_scaling_mode(igt_output_t *output, uint64_t
> scaling_mode)
> -{
> -	igt_output_set_prop_value(output,
> IGT_CONNECTOR_SCALING_MODE, scaling_mode);
> -
> -	igt_require(output->props[IGT_CONNECTOR_SCALING_MODE]);
> -}
> -
>  igt_plane_t *igt_output_get_plane(igt_output_t *output, int
> plane_idx)
>  {
>  	igt_pipe_t *pipe;
> @@ -3119,24 +3192,6 @@ void igt_pipe_request_out_fence(igt_pipe_t
> *pipe)
>  	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR,
> (ptrdiff_t)&pipe->out_fence_fd);
>  }
>  
> -void
> -igt_pipe_set_degamma_lut(igt_pipe_t *pipe, void *ptr, size_t length)
> -{
> -	igt_pipe_replace_blob(pipe, IGT_CRTC_DEGAMMA_LUT, ptr,
> length);
> -}
> -
> -void
> -igt_pipe_set_ctm_matrix(igt_pipe_t *pipe, void *ptr, size_t length)
> -{
> -	igt_pipe_replace_blob(pipe, IGT_CRTC_CTM, ptr, length);
> -}
> -
> -void
> -igt_pipe_set_gamma_lut(igt_pipe_t *pipe, void *ptr, size_t length)
> -{
> -	igt_pipe_replace_blob(pipe, IGT_CRTC_GAMMA_LUT, ptr,
> length);
> -}
> -
>  /**
>   * igt_crtc_set_background:
>   * @pipe: pipe pointer to which background color to be set
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index b53127ffef5f..2e4c23437f4e 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -366,7 +366,6 @@ const char *igt_output_name(igt_output_t
> *output);
>  drmModeModeInfo *igt_output_get_mode(igt_output_t *output);
>  void igt_output_override_mode(igt_output_t *output, drmModeModeInfo
> *mode);
>  void igt_output_set_pipe(igt_output_t *output, enum pipe pipe);
> -void igt_output_set_scaling_mode(igt_output_t *output, uint64_t
> scaling_mode);
>  igt_plane_t *igt_output_get_plane(igt_output_t *output, int
> plane_idx);
>  igt_plane_t *igt_output_get_plane_type(igt_output_t *output, int
> plane_type);
>  igt_output_t *igt_output_from_connector(igt_display_t *display,
> @@ -381,9 +380,6 @@ static inline bool
> igt_plane_supports_rotation(igt_plane_t *plane)
>  	return plane->props[IGT_PLANE_ROTATION] != 0;
>  }
>  void igt_pipe_request_out_fence(igt_pipe_t *pipe);
> -void igt_pipe_set_degamma_lut(igt_pipe_t *pipe, void *ptr, size_t
> length);
> -void igt_pipe_set_ctm_matrix(igt_pipe_t *pipe, void *ptr, size_t
> length);
> -void igt_pipe_set_gamma_lut(igt_pipe_t *pipe, void *ptr, size_t
> length);
>  
>  void igt_plane_set_fb(igt_plane_t *plane, struct igt_fb *fb);
>  void igt_plane_set_fence_fd(igt_plane_t *plane, int fence_fd);
> @@ -513,6 +509,10 @@ static inline bool
> igt_output_is_connected(igt_output_t *output)
>  		igt_plane_set_prop_changed(plane, prop); \
>  	} while (0)
>  
> +extern void igt_plane_replace_prop_blob(igt_plane_t *plane,
> +					enum
> igt_atomic_plane_properties prop,
> +					const void *ptr, size_t
> length);
> +
>  #define igt_output_is_prop_changed(output, prop) \
>  	(!!((output)->changed & (1 << (prop))))
>  #define igt_output_set_prop_changed(output, prop) \
> @@ -527,6 +527,10 @@ static inline bool
> igt_output_is_connected(igt_output_t *output)
>  		igt_output_set_prop_changed(output, prop); \
>  	} while (0)
>  
> +extern void igt_output_replace_prop_blob(igt_output_t *output,
> +					 enum
> igt_atomic_connector_properties prop,
> +					 const void *ptr, size_t
> length);
> +
>  #define igt_pipe_obj_is_prop_changed(pipe_obj, prop) \
>  	(!!((pipe_obj)->changed & (1 << (prop))))
>  
> @@ -554,6 +558,13 @@ static inline bool
> igt_output_is_connected(igt_output_t *output)
>  #define igt_pipe_set_prop_value(display, pipe, prop, value) \
>  	igt_pipe_obj_set_prop_value(&(display)->pipes[(pipe)], prop,
> value)
>  
> +extern void igt_pipe_obj_replace_prop_blob(igt_pipe_t *pipe_obj,
> +					   enum
> igt_atomic_crtc_properties prop,
> +					   const void *ptr, size_t
> length);
> +
> +#define igt_pipe_replace_prop_blob(display, pipe, prop, ptr, length)
> \
> +	igt_pipe_obj_replace_prop_blob(&(display)->pipes[(pipe)],
> prop, ptr, length)
> +
>  void igt_pipe_refresh(igt_display_t *display, enum pipe pipe, bool
> force);
>  
>  void igt_enable_connectors(void);
> diff --git a/tests/chamelium.c b/tests/chamelium.c
> index e3d81357b32b..ae164920e86e 100644
> --- a/tests/chamelium.c
> +++ b/tests/chamelium.c
> @@ -462,9 +462,9 @@ enable_output(data_t *data,
>  	igt_output_set_pipe(output, output->config.pipe);
>  
>  	/* Clear any color correction values that might be enabled
> */
> -	igt_pipe_set_degamma_lut(primary->pipe, NULL, 0);
> -	igt_pipe_set_gamma_lut(primary->pipe, NULL, 0);
> -	igt_pipe_set_ctm_matrix(primary->pipe, NULL, 0);
> +	igt_pipe_obj_replace_prop_blob(primary->pipe,
> IGT_CRTC_DEGAMMA_LUT, NULL, 0);
> +	igt_pipe_obj_replace_prop_blob(primary->pipe,
> IGT_CRTC_GAMMA_LUT, NULL, 0);
> +	igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_CTM,
> NULL, 0);
>  
>  	kmstest_set_connector_broadcast_rgb(display->drm_fd,
> connector,
>  					    BROADCAST_RGB_FULL);
> diff --git a/tests/kms_color.c b/tests/kms_color.c
> index bcd48d89875c..e30e6bf4e409 100644
> --- a/tests/kms_color.c
> +++ b/tests/kms_color.c
> @@ -189,7 +189,7 @@ static void set_degamma(data_t *data,
>  						   data-
> >degamma_lut_size,
>  						   data-
> >color_depth, 0);
>  
> -	igt_pipe_set_degamma_lut(pipe, lut, size);
> +	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_DEGAMMA_LUT,
> lut, size);
>  
>  	free(lut);
>  }
> @@ -204,7 +204,7 @@ static void set_gamma(data_t *data,
>  						   data-
> >gamma_lut_size,
>  						   data-
> >color_depth, 0);
>  
> -	igt_pipe_set_gamma_lut(pipe, lut, size);
> +		igt_pipe_obj_replace_prop_blob(pipe,
> IGT_CRTC_GAMMA_LUT, lut, size);
>  
>  	free(lut);
>  }
> @@ -224,12 +224,12 @@ static void set_ctm(igt_pipe_t *pipe, const
> double *coefficients)
>  				(int64_t) (coefficients[i] *
> ((int64_t) 1L << 32));
>  	}
>  
> -	igt_pipe_set_ctm_matrix(pipe, &ctm, sizeof(ctm));
> +	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_CTM, &ctm,
> sizeof(ctm));
>  }
>  
> -#define disable_degamma(pipe) igt_pipe_set_degamma_lut(pipe, NULL,
> 0)
> -#define disable_gamma(pipe) igt_pipe_set_gamma_lut(pipe, NULL, 0)
> -#define disable_ctm(pipe) igt_pipe_set_ctm_matrix(pipe, NULL, 0)
> +#define disable_degamma(pipe) igt_pipe_obj_replace_prop_blob(pipe,
> IGT_CRTC_DEGAMMA_LUT, NULL, 0)
> +#define disable_gamma(pipe) igt_pipe_obj_replace_prop_blob(pipe,
> IGT_CRTC_GAMMA_LUT, NULL, 0)
> +#define disable_ctm(pipe) igt_pipe_obj_replace_prop_blob(pipe,
> IGT_CRTC_CTM, NULL, 0)
>  
>  static void output_set_property_enum(igt_output_t *output,
>  				     const char *property,
-- 
Mika Kahola - Intel OTC

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2 07/14] lib/igt_kms: Unexport broadcast rgb API.
  2017-10-12 11:54 ` [PATCH i-g-t v2 07/14] lib/igt_kms: Unexport broadcast rgb API Maarten Lankhorst
@ 2017-10-19 11:28   ` Mika Kahola
  0 siblings, 0 replies; 45+ messages in thread
From: Mika Kahola @ 2017-10-19 11:28 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx

Reviewed-by: Mika Kahola <mika.kahola@intel.com>

On Thu, 2017-10-12 at 13:54 +0200, Maarten Lankhorst wrote:
> Setting broadcast rgb was only used by chamelium, but is now handled
> in igt_display by default. This means that chamelium doesn't need to
> set it, and this can be hidden. The broadcast RGB property is intel
> connector specific, so rename the enum to intel_broadcast_rgb_mode.
> 
> Keep the property and enum public in case someone wants to test the
> property later.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  lib/igt_kms.c     | 44 ++++++--------------------------------------
>  lib/igt_kms.h     |  7 +++----
>  tests/chamelium.c |  3 ---
>  3 files changed, 9 insertions(+), 45 deletions(-)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index 5f54021350ac..ad0855d0c8fa 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -187,7 +187,8 @@ const char
> *igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
>  const char *igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
>  	"scaling mode",
>  	"CRTC_ID",
> -	"DPMS"
> +	"DPMS",
> +	"Broadcast RGB"
>  };
>  
>  /*
> @@ -1037,40 +1038,6 @@ void kmstest_set_connector_dpms(int fd,
> drmModeConnector *connector, int mode)
>  					       dpms, mode) == 0);
>  }
>  
> -/**
> - * kmstest_set_connector_broadcast_rgb:
> - * @fd: DRM fd
> - * @connector: libdrm connector
> - * @mode: Broadcast RGB mode
> - *
> - * This function sets the Broadcast RGB prop of @connector to @mode,
> if there
> - * is one.
> - *
> - * Returns: true if we found and set the Broadcast RGB prop, false
> otherwise
> - */
> -bool kmstest_set_connector_broadcast_rgb(int fd, drmModeConnector
> *connector,
> -					 enum
> kmstest_broadcast_rgb_mode mode)
> -{
> -	uint32_t prop_id;
> -	int ret;
> -
> -	ret = kmstest_get_property(fd, connector->connector_id,
> -				   DRM_MODE_OBJECT_CONNECTOR,
> "Broadcast RGB",
> -				   &prop_id, NULL, NULL);
> -	if (!ret) {
> -		igt_debug("Broadcast RGB property not found on
> %d\n",
> -			  connector->connector_id);
> -		return false;
> -	}
> -
> -	igt_debug("Setting Broadcast RGB mode on connector %d to
> %d\n",
> -		  connector->connector_id, mode);
> -	ret = drmModeConnectorSetProperty(fd, connector-
> >connector_id, prop_id,
> -					  mode);
> -
> -	return ret == 0;
> -}
> -
>  /**
>   * kmstest_get_property:
>   * @drm_fd: drm file descriptor
> @@ -1583,9 +1550,10 @@ static void igt_output_refresh(igt_output_t
> *output)
>  		igt_atomic_fill_connector_props(display, output,
>  			IGT_NUM_CONNECTOR_PROPS,
> igt_connector_prop_names);
>  
> -		kmstest_set_connector_broadcast_rgb(display->drm_fd,
> -						    output-
> >config.connector,
> -						    BROADCAST_RGB_FU
> LL);
> +		if (output->props[IGT_CONNECTOR_BROADCAST_RGB])
> +			igt_output_set_prop_value(output,
> +						  IGT_CONNECTOR_BROA
> DCAST_RGB,
> +						  BROADCAST_RGB_FULL
> );
>  	}
>  
>  	LOG(display, "%s: Selecting pipe %s\n", output->name,
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index 2e4c23437f4e..b8a04af73e2f 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -115,6 +115,7 @@ enum igt_atomic_connector_properties {
>         IGT_CONNECTOR_SCALING_MODE = 0,
>         IGT_CONNECTOR_CRTC_ID,
>         IGT_CONNECTOR_DPMS,
> +       IGT_CONNECTOR_BROADCAST_RGB,
>         IGT_NUM_CONNECTOR_PROPS
>  };
>  
> @@ -171,13 +172,13 @@ enum kmstest_force_connector_state {
>  };
>  
>  /**
> - * kmstest_broadcast_rgb_mode:
> + * intel_broadcast_rgb_mode:
>   * @BROADCAST_RGB_AUTO: Choose the color range to use automatically
>   * @BROADCAST_RGB_FULL: Force the connector to use full color range
>   * @BROADCAST_RGB_16_235: Force the connector to use a limited
> 16:235 color
>   * range
>   */
> -enum kmstest_broadcast_rgb_mode {
> +enum intel_broadcast_rgb_mode {
>  	BROADCAST_RGB_AUTO = 0,
>  	BROADCAST_RGB_FULL,
>  	BROADCAST_RGB_16_235
> @@ -203,8 +204,6 @@ bool kmstest_probe_connector_config(int drm_fd,
> uint32_t connector_id,
>  void kmstest_free_connector_config(struct kmstest_connector_config
> *config);
>  
>  void kmstest_set_connector_dpms(int fd, drmModeConnector *connector,
> int mode);
> -bool kmstest_set_connector_broadcast_rgb(int fd, drmModeConnector
> *connector,
> -					 enum
> kmstest_broadcast_rgb_mode mode);
>  bool kmstest_get_property(int drm_fd, uint32_t object_id, uint32_t
> object_type,
>  			  const char *name, uint32_t *prop_id,
> uint64_t *value,
>  			  drmModePropertyPtr *prop);
> diff --git a/tests/chamelium.c b/tests/chamelium.c
> index ae164920e86e..4ad29f9d178a 100644
> --- a/tests/chamelium.c
> +++ b/tests/chamelium.c
> @@ -466,9 +466,6 @@ enable_output(data_t *data,
>  	igt_pipe_obj_replace_prop_blob(primary->pipe,
> IGT_CRTC_GAMMA_LUT, NULL, 0);
>  	igt_pipe_obj_replace_prop_blob(primary->pipe, IGT_CRTC_CTM,
> NULL, 0);
>  
> -	kmstest_set_connector_broadcast_rgb(display->drm_fd,
> connector,
> -					    BROADCAST_RGB_FULL);
> -
>  	igt_display_commit(display);
>  
>  	if (chamelium_port_get_type(port) == DRM_MODE_CONNECTOR_VGA)
-- 
Mika Kahola - Intel OTC

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2] lib/igt_kms: Add igt_$obj_has_prop functions, v2.
  2017-10-12 15:33   ` [PATCH i-g-t v2] lib/igt_kms: Add igt_$obj_has_prop functions, v2 Maarten Lankhorst
@ 2017-10-19 12:06     ` Mika Kahola
  0 siblings, 0 replies; 45+ messages in thread
From: Mika Kahola @ 2017-10-19 12:06 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx

Reviewed-by: Mika Kahola <mika.kahola@intel.com>

On Thu, 2017-10-12 at 17:33 +0200, Maarten Lankhorst wrote:
> This allows test to test whether a property is supported, in
> a nice and clean way. It removes the need for special case
> functions like igt_plane_supports_rotation.
> 
> Convert the users of igt_plane_supports_rotation and remove the
> extra check in drm_plane_commit, this is already checked below
> when setting plane properties.
> 
> Changes since v1:
> - Use the correct has_prop in kms_crtc_background_color.c
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  lib/igt_kms.c                     |  4 ---
>  lib/igt_kms.h                     | 62
> ++++++++++++++++++++++++++++++++++++---
>  tests/kms_crtc_background_color.c |  2 +-
>  tests/kms_rotation_crc.c          |  6 ++--
>  4 files changed, 62 insertions(+), 12 deletions(-)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index ad0855d0c8fa..339c11843154 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -2110,10 +2110,6 @@ static int igt_drm_plane_commit(igt_plane_t
> *plane,
>  
>  	igt_assert(plane->drm_plane);
>  
> -	/* it's an error to try an unsupported feature */
> -	igt_assert(igt_plane_supports_rotation(plane) ||
> -		   !igt_plane_is_prop_changed(plane,
> IGT_PLANE_ROTATION));
> -
>  	fb_id = igt_plane_get_fb_id(plane);
>  	crtc_id = pipe->crtc_id;
>  
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index b8a04af73e2f..916cd359519a 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -374,10 +374,6 @@ bool igt_pipe_get_property(igt_pipe_t *pipe,
> const char *name,
>  			   uint32_t *prop_id, uint64_t *value,
>  			   drmModePropertyPtr *prop);
>  
> -static inline bool igt_plane_supports_rotation(igt_plane_t *plane)
> -{
> -	return plane->props[IGT_PLANE_ROTATION] != 0;
> -}
>  void igt_pipe_request_out_fence(igt_pipe_t *pipe);
>  
>  void igt_plane_set_fb(igt_plane_t *plane, struct igt_fb *fb);
> @@ -493,6 +489,20 @@ static inline bool
> igt_output_is_connected(igt_output_t *output)
>  
>  #define IGT_FIXED(i,f)	((i) << 16 | (f))
>  
> +/**
> + * igt_plane_has_prop - Check whether plane supports a given
> property.
> + *
> + * @plane: Plane to check.
> + * @prop: Property to check.
> + *
> + * Returns: True if the property is supported, otherwise false.
> + */
> +static inline bool
> +igt_plane_has_prop(igt_plane_t *plane, enum
> igt_atomic_plane_properties prop)
> +{
> +	return plane->props[prop];
> +}
> +
>  #define igt_plane_is_prop_changed(plane, prop) \
>  	(!!((plane)->changed & (1 << (prop))))
>  
> @@ -512,6 +522,20 @@ extern void
> igt_plane_replace_prop_blob(igt_plane_t *plane,
>  					enum
> igt_atomic_plane_properties prop,
>  					const void *ptr, size_t
> length);
>  
> +/**
> + * igt_output_has_prop - Check whether output supports a given
> property.
> + *
> + * @output: Output to check.
> + * @prop: Property to check.
> + *
> + * Returns: True if the property is supported, otherwise false.
> + */
> +static inline bool
> +igt_output_has_prop(igt_output_t *output, enum
> igt_atomic_connector_properties prop)
> +{
> +	return output->props[prop];
> +}
> +
>  #define igt_output_is_prop_changed(output, prop) \
>  	(!!((output)->changed & (1 << (prop))))
>  #define igt_output_set_prop_changed(output, prop) \
> @@ -530,6 +554,36 @@ extern void
> igt_output_replace_prop_blob(igt_output_t *output,
>  					 enum
> igt_atomic_connector_properties prop,
>  					 const void *ptr, size_t
> length);
>  
> +/**
> + * igt_pipe_obj_has_prop - Check whether pipe supports a given
> property.
> + *
> + * @pipe: Pipe to check.
> + * @prop: Property to check.
> + *
> + * Returns: True if the property is supported, otherwise false.
> + */
> +static inline bool
> +igt_pipe_obj_has_prop(igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop)
> +{
> +	return pipe->props[prop];
> +}
> +
> +/**
> + * igt_pipe_has_prop - Check whether pipe supports a given property.
> + *
> + * @display: Pointer to display.
> + * @pipe: Pipe to check.
> + * @prop: Property to check.
> + *
> + * Returns: True if the property is supported, otherwise false.
> + */
> +static inline bool
> +igt_pipe_has_prop(igt_display_t *display, enum pipe pipe,
> +		  enum igt_atomic_connector_properties prop)
> +{
> +	return display->pipes[pipe].props[prop];
> +}
> +
>  #define igt_pipe_obj_is_prop_changed(pipe_obj, prop) \
>  	(!!((pipe_obj)->changed & (1 << (prop))))
>  
> diff --git a/tests/kms_crtc_background_color.c
> b/tests/kms_crtc_background_color.c
> index 659a30b90219..ecd13a56712e 100644
> --- a/tests/kms_crtc_background_color.c
> +++ b/tests/kms_crtc_background_color.c
> @@ -137,7 +137,7 @@ static void test_crtc_background(data_t *data)
>  		igt_output_set_pipe(output, pipe);
>  
>  		plane = igt_output_get_plane_type(output,
> DRM_PLANE_TYPE_PRIMARY);
> -		igt_require(plane->pipe-
> >props[IGT_CRTC_BACKGROUND]);
> +		igt_require(igt_pipe_has_prop(display, pipe,
> IGT_CRTC_BACKGROUND));
>  
>  		prepare_crtc(data, output, pipe, plane, 1, PURPLE,
> BLACK64);
>  
> diff --git a/tests/kms_rotation_crc.c b/tests/kms_rotation_crc.c
> index b8327dfa0d83..27d1f8060234 100644
> --- a/tests/kms_rotation_crc.c
> +++ b/tests/kms_rotation_crc.c
> @@ -351,7 +351,7 @@ static void test_plane_rotation(data_t *data, int
> plane_type)
>  		igt_output_set_pipe(output, pipe);
>  
>  		plane = igt_output_get_plane_type(output,
> plane_type);
> -		igt_require(igt_plane_supports_rotation(plane));
> +		igt_require(igt_plane_has_prop(plane,
> IGT_PLANE_ROTATION));
>  
>  		prepare_crtc(data, output, pipe, plane, commit);
>  
> @@ -438,7 +438,7 @@ static void test_plane_rotation_ytiled_obj(data_t
> *data,
>  	int ret;
>  
>  	plane = igt_output_get_plane_type(output, plane_type);
> -	igt_require(igt_plane_supports_rotation(plane));
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
>  
>  	if (plane_type == DRM_PLANE_TYPE_PRIMARY || plane_type ==
> DRM_PLANE_TYPE_CURSOR)
>  		commit = COMMIT_UNIVERSAL;
> @@ -504,7 +504,7 @@ static void
> test_plane_rotation_exhaust_fences(data_t *data,
>  	int i, ret;
>  
>  	plane = igt_output_get_plane_type(output, plane_type);
> -	igt_require(igt_plane_supports_rotation(plane));
> +	igt_require(igt_plane_has_prop(plane, IGT_PLANE_ROTATION));
>  
>  	if (plane_type == DRM_PLANE_TYPE_PRIMARY || plane_type ==
> DRM_PLANE_TYPE_CURSOR)
>  		commit = COMMIT_UNIVERSAL;
-- 
Mika Kahola - Intel OTC

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2 09/14] lib/igt_kms: Add igt_$obj_get_prop functions
  2017-10-12 11:54 ` [PATCH i-g-t v2 09/14] lib/igt_kms: Add igt_$obj_get_prop functions Maarten Lankhorst
@ 2017-10-19 12:58   ` Mika Kahola
  0 siblings, 0 replies; 45+ messages in thread
From: Mika Kahola @ 2017-10-19 12:58 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx

Reviewed-by: Mika Kahola <mika.kahola@intel.com>

On Thu, 2017-10-12 at 13:54 +0200, Maarten Lankhorst wrote:
> Some tests need to get the current kernel value for properties
> as part of the test. Add get_prop functions that will retrieve
> the current kernel value.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  lib/igt_kms.c | 81
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/igt_kms.h | 24 ++++++++++++++++++
>  2 files changed, 105 insertions(+)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index 339c11843154..176e6825a492 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -2407,6 +2407,51 @@ static int igt_output_commit(igt_output_t
> *output,
>  	return 0;
>  }
>  
> +static uint64_t igt_mode_object_get_prop(igt_display_t *display,
> +					 uint32_t object_type,
> +					 uint32_t object_id,
> +					 uint32_t prop)
> +{
> +	drmModeObjectPropertiesPtr proplist;
> +	bool found = false;
> +	int i;
> +	uint64_t ret;
> +
> +	proplist = drmModeObjectGetProperties(display->drm_fd,
> object_id, object_type);
> +	for (i = 0; i < proplist->count_props; i++) {
> +		if (proplist->props[i] != prop)
> +			continue;
> +
> +		found = true;
> +		break;
> +	}
> +
> +	igt_assert(found);
> +
> +	ret = proplist->prop_values[i];
> +
> +	drmModeFreeObjectProperties(proplist);
> +	return ret;
> +}
> +
> +/**
> + * igt_plane_get_prop - Return current value on a plane for a given
> property.
> + *
> + * @plane: Target plane.
> + * @prop: Property to check.
> + *
> + * Returns: The value the property is set to, if this
> + * is a blob, the blob id is returned. This can be passed
> + * to drmModeGetPropertyBlob() to get the contents of the blob.
> + */
> +uint64_t igt_plane_get_prop(igt_plane_t *plane, enum
> igt_atomic_plane_properties prop)
> +{
> +	igt_assert(igt_plane_has_prop(plane, prop));
> +
> +	return igt_mode_object_get_prop(plane->pipe->display,
> DRM_MODE_OBJECT_PLANE,
> +					plane->drm_plane->plane_id,
> plane->props[prop]);
> +}
> +
>  /**
>   * igt_plane_replace_prop_blob:
>   * @plane: plane to set property on.
> @@ -2439,6 +2484,24 @@ igt_plane_replace_prop_blob(igt_plane_t
> *plane, enum igt_atomic_plane_properties
>  	igt_plane_set_prop_changed(plane, prop);
>  }
>  
> +/**
> + * igt_output_get_prop - Return current value on an output for a
> given property.
> + *
> + * @output: Target output.
> + * @prop: Property to return.
> + *
> + * Returns: The value the property is set to, if this
> + * is a blob, the blob id is returned. This can be passed
> + * to drmModeGetPropertyBlob() to get the contents of the blob.
> + */
> +uint64_t igt_output_get_prop(igt_output_t *output, enum
> igt_atomic_connector_properties prop)
> +{
> +	igt_assert(igt_output_has_prop(output, prop));
> +
> +	return igt_mode_object_get_prop(output->display,
> DRM_MODE_OBJECT_CONNECTOR,
> +					output->id, output-
> >props[prop]);
> +}
> +
>  /**
>   * igt_output_replace_prop_blob:
>   * @output: output to set property on.
> @@ -2471,6 +2534,24 @@ igt_output_replace_prop_blob(igt_output_t
> *output, enum igt_atomic_connector_pro
>  	igt_output_set_prop_changed(output, prop);
>  }
>  
> +/**
> + * igt_pipe_obj_get_prop - Return current value on a pipe for a
> given property.
> + *
> + * @pipe: Target pipe.
> + * @prop: Property to return.
> + *
> + * Returns: The value the property is set to, if this
> + * is a blob, the blob id is returned. This can be passed
> + * to drmModeGetPropertyBlob() to get the contents of the blob.
> + */
> +uint64_t igt_pipe_obj_get_prop(igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop)
> +{
> +	igt_assert(igt_pipe_obj_has_prop(pipe, prop));
> +
> +	return igt_mode_object_get_prop(pipe->display,
> DRM_MODE_OBJECT_CRTC,
> +					pipe->crtc_id, pipe-
> >props[prop]);
> +}
> +
>  /**
>   * igt_pipe_obj_replace_prop_blob:
>   * @pipe: pipe to set property on.
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index 916cd359519a..fda94cb640de 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -503,6 +503,8 @@ igt_plane_has_prop(igt_plane_t *plane, enum
> igt_atomic_plane_properties prop)
>  	return plane->props[prop];
>  }
>  
> +uint64_t igt_plane_get_prop(igt_plane_t *plane, enum
> igt_atomic_plane_properties prop);
> +
>  #define igt_plane_is_prop_changed(plane, prop) \
>  	(!!((plane)->changed & (1 << (prop))))
>  
> @@ -536,6 +538,8 @@ igt_output_has_prop(igt_output_t *output, enum
> igt_atomic_connector_properties p
>  	return output->props[prop];
>  }
>  
> +uint64_t igt_output_get_prop(igt_output_t *output, enum
> igt_atomic_connector_properties prop);
> +
>  #define igt_output_is_prop_changed(output, prop) \
>  	(!!((output)->changed & (1 << (prop))))
>  #define igt_output_set_prop_changed(output, prop) \
> @@ -568,6 +572,26 @@ igt_pipe_obj_has_prop(igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop)
>  	return pipe->props[prop];
>  }
>  
> +uint64_t igt_pipe_obj_get_prop(igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop);
> +
> +/**
> + * igt_pipe_get_prop - Return current value on a pipe for a given
> property.
> + *
> + * @display: Pointer to display.
> + * @pipe: Target pipe.
> + * @prop: Property to return.
> + *
> + * Returns: The value the property is set to, if this
> + * is a blob, the blob id is returned. This can be passed
> + * to drmModeGetPropertyBlob() to get the contents of the blob.
> + */
> +static inline uint64_t
> +igt_pipe_get_prop(igt_display_t *display, enum pipe pipe,
> +		  enum igt_atomic_crtc_properties prop)
> +{
> +	return igt_pipe_obj_get_prop(&display->pipes[pipe], prop);
> +}
> +
>  /**
>   * igt_pipe_has_prop - Check whether pipe supports a given property.
>   *
-- 
Mika Kahola - Intel OTC

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2 10/14] lib/igt_kms: Remove igt_pipe_get_property
  2017-10-12 11:54 ` [PATCH i-g-t v2 10/14] lib/igt_kms: Remove igt_pipe_get_property Maarten Lankhorst
@ 2017-10-19 13:18   ` Mika Kahola
  0 siblings, 0 replies; 45+ messages in thread
From: Mika Kahola @ 2017-10-19 13:18 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx

Reviewed-by: Mika Kahola <mika.kahola@intel.com>

On Thu, 2017-10-12 at 13:54 +0200, Maarten Lankhorst wrote:
> igt_pipe_get_property has been replaced by igt_pipe_obj_get_prop.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  lib/igt_kms.c | 10 ----------
>  lib/igt_kms.h |  3 ---
>  2 files changed, 13 deletions(-)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index 176e6825a492..70b104b24f8d 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -2009,16 +2009,6 @@ static igt_output_t
> *igt_pipe_get_output(igt_pipe_t *pipe)
>  	return NULL;
>  }
>  
> -bool igt_pipe_get_property(igt_pipe_t *pipe, const char *name,
> -			   uint32_t *prop_id, uint64_t *value,
> -			   drmModePropertyPtr *prop)
> -{
> -	return get_crtc_property(pipe->display->drm_fd,
> -				 pipe->crtc_id,
> -				 name,
> -				 prop_id, value, prop);
> -}
> -
>  static uint32_t igt_plane_get_fb_id(igt_plane_t *plane)
>  {
>  	return plane->values[IGT_PLANE_FB_ID];
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index fda94cb640de..dbba0cd53a25 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -370,9 +370,6 @@ igt_plane_t
> *igt_output_get_plane_type(igt_output_t *output, int plane_type);
>  igt_output_t *igt_output_from_connector(igt_display_t *display,
>      drmModeConnector *connector);
>  igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int
> plane_type);
> -bool igt_pipe_get_property(igt_pipe_t *pipe, const char *name,
> -			   uint32_t *prop_id, uint64_t *value,
> -			   drmModePropertyPtr *prop);
>  
>  void igt_pipe_request_out_fence(igt_pipe_t *pipe);
>  
-- 
Mika Kahola - Intel OTC

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2 11/14] lib/igt_kms: Remove igt_crtc_set_background()
  2017-10-12 11:54 ` [PATCH i-g-t v2 11/14] lib/igt_kms: Remove igt_crtc_set_background() Maarten Lankhorst
@ 2017-10-20  6:33   ` Mika Kahola
  0 siblings, 0 replies; 45+ messages in thread
From: Mika Kahola @ 2017-10-20  6:33 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx

Reviewed-by: Mika Kahola <mika.kahola@intel.com>

On Thu, 2017-10-12 at 13:54 +0200, Maarten Lankhorst wrote:
> This can be handled by generic properties.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  lib/igt_kms.c                     | 21 ---------------------
>  lib/igt_kms.h                     |  1 -
>  tests/kms_crtc_background_color.c | 18 +++++++++---------
>  3 files changed, 9 insertions(+), 31 deletions(-)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index 70b104b24f8d..9cf4b68f4191 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -3227,27 +3227,6 @@ void igt_pipe_request_out_fence(igt_pipe_t
> *pipe)
>  	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR,
> (ptrdiff_t)&pipe->out_fence_fd);
>  }
>  
> -/**
> - * igt_crtc_set_background:
> - * @pipe: pipe pointer to which background color to be set
> - * @background: background color value in BGR 16bpc
> - *
> - * Sets background color for requested pipe. Color value provided
> here
> - * will be actually submitted at output commit time via
> "background_color"
> - * property.
> - * For example to get red as background, set background =
> 0x00000000FFFF.
> - */
> -void igt_crtc_set_background(igt_pipe_t *pipe, uint64_t background)
> -{
> -	igt_display_t *display = pipe->display;
> -
> -	LOG(display, "%s.%d: crtc_set_background(%"PRIx64")\n",
> -	    kmstest_pipe_name(pipe->pipe),
> -	    pipe->pipe, background);
> -
> -	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_BACKGROUND,
> background);
> -}
> -
>  void igt_wait_for_vblank_count(int drm_fd, enum pipe pipe, int
> count)
>  {
>  	drmVBlank wait_vbl;
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index dbba0cd53a25..e722f0be3757 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -378,7 +378,6 @@ void igt_plane_set_fence_fd(igt_plane_t *plane,
> int fence_fd);
>  void igt_plane_set_position(igt_plane_t *plane, int x, int y);
>  void igt_plane_set_size(igt_plane_t *plane, int w, int h);
>  void igt_plane_set_rotation(igt_plane_t *plane, igt_rotation_t
> rotation);
> -void igt_crtc_set_background(igt_pipe_t *pipe, uint64_t background);
>  void igt_fb_set_position(struct igt_fb *fb, igt_plane_t *plane,
>  	uint32_t x, uint32_t y);
>  void igt_fb_set_size(struct igt_fb *fb, igt_plane_t *plane,
> diff --git a/tests/kms_crtc_background_color.c
> b/tests/kms_crtc_background_color.c
> index 414cc82f3e8b..6edb8de3bb24 100644
> --- a/tests/kms_crtc_background_color.c
> +++ b/tests/kms_crtc_background_color.c
> @@ -97,7 +97,7 @@ static void prepare_crtc(data_t *data, igt_output_t
> *output, enum pipe pipe,
>  	igt_assert(fb_id);
>  
>  	/* To make FB pixel win with background color, set alpha as
> full opaque */
> -	igt_crtc_set_background(plane->pipe, pipe_background_color);
> +	igt_pipe_set_prop_value(display, pipe, IGT_CRTC_BACKGROUND,
> pipe_background_color);
>  	if (opaque_buffer)
>  		alpha = 1.0;    /* alpha 1 is fully opque */
>  	else
> @@ -117,7 +117,7 @@ static void cleanup_crtc(data_t *data,
> igt_output_t *output, igt_plane_t *plane)
>  
>  	igt_remove_fb(data->gfx_fd, &data->fb);
>  
> -	igt_crtc_set_background(plane->pipe, BLACK64);
> +	igt_pipe_obj_set_prop_value(plane->pipe,
> IGT_CRTC_BACKGROUND, BLACK64);
>  	igt_plane_set_fb(plane, NULL);
>  	igt_output_set_pipe(output, PIPE_ANY);
>  
> @@ -144,26 +144,26 @@ static void test_crtc_background(data_t *data)
>  		/* Now set background without using a plane, i.e.,
>  		 * Disable the plane to let hw background color win
> blend. */
>  		igt_plane_set_fb(plane, NULL);
> -		igt_crtc_set_background(plane->pipe, PURPLE64);
> +		igt_pipe_set_prop_value(display, pipe,
> IGT_CRTC_BACKGROUND, PURPLE64);
>  		igt_display_commit2(display, COMMIT_UNIVERSAL);
>  
>  		/* Try few other background colors */
> -		igt_crtc_set_background(plane->pipe, CYAN64);
> +		igt_pipe_set_prop_value(display, pipe,
> IGT_CRTC_BACKGROUND, CYAN64);
>  		igt_display_commit2(display, COMMIT_UNIVERSAL);
>  
> -		igt_crtc_set_background(plane->pipe, YELLOW64);
> +		igt_pipe_set_prop_value(display, pipe,
> IGT_CRTC_BACKGROUND, YELLOW64);
>  		igt_display_commit2(display, COMMIT_UNIVERSAL);
>  
> -		igt_crtc_set_background(plane->pipe, RED64);
> +		igt_pipe_set_prop_value(display, pipe,
> IGT_CRTC_BACKGROUND, RED64);
>  		igt_display_commit2(display, COMMIT_UNIVERSAL);
>  
> -		igt_crtc_set_background(plane->pipe, GREEN64);
> +		igt_pipe_set_prop_value(display, pipe,
> IGT_CRTC_BACKGROUND, GREEN64);
>  		igt_display_commit2(display, COMMIT_UNIVERSAL);
>  
> -		igt_crtc_set_background(plane->pipe, BLUE64);
> +		igt_pipe_set_prop_value(display, pipe,
> IGT_CRTC_BACKGROUND, BLUE64);
>  		igt_display_commit2(display, COMMIT_UNIVERSAL);
>  
> -		igt_crtc_set_background(plane->pipe, WHITE64);
> +		igt_pipe_set_prop_value(display, pipe,
> IGT_CRTC_BACKGROUND, WHITE64);
>  		igt_display_commit2(display, COMMIT_UNIVERSAL);
>  
>  		valid_tests++;
-- 
Mika Kahola - Intel OTC

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2 12/14] tests/kms_color: Rework tests slightly to work better with new atomic api
  2017-10-12 11:54 ` [PATCH i-g-t v2 12/14] tests/kms_color: Rework tests slightly to work better with new atomic api Maarten Lankhorst
@ 2017-10-20  7:14   ` Mika Kahola
  0 siblings, 0 replies; 45+ messages in thread
From: Mika Kahola @ 2017-10-20  7:14 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx

Reviewed-by: Mika Kahola <mika.kahola@intel.com>

On Thu, 2017-10-12 at 13:54 +0200, Maarten Lankhorst wrote:
> igt_pipe_get_property is about to be removed, so use
> igt_pipe_obj_get_prop instead. This requires adding 2 more properties
> to the crtc property list. Also get rid of the Broadcast RGB call,
> this is already handled in igt_kms.
> 
> Change order for DEGAMMA_LUT and GAMMA_LUT around, else this test
> will
> fail if legacy gamma is set. In the legacy path, this will update
> GAMMA_LUT to the new size before DEGAMMA_LUT is set.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  lib/igt_kms.c     |   4 +-
>  lib/igt_kms.h     |   4 +-
>  tests/kms_color.c | 217 +++++++++++++++++++-------------------------
> ----------
>  3 files changed, 83 insertions(+), 142 deletions(-)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index 9cf4b68f4191..cb2bc2b8df98 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -177,8 +177,10 @@ const char
> *igt_plane_prop_names[IGT_NUM_PLANE_PROPS] = {
>  const char *igt_crtc_prop_names[IGT_NUM_CRTC_PROPS] = {
>  	"background_color",
>  	"CTM",
> -	"DEGAMMA_LUT",
>  	"GAMMA_LUT",
> +	"GAMMA_LUT_SIZE",
> +	"DEGAMMA_LUT",
> +	"DEGAMMA_LUT_SIZE",
>  	"MODE_ID",
>  	"ACTIVE",
>  	"OUT_FENCE_PTR"
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index e722f0be3757..200f35e63308 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -95,8 +95,10 @@ void kmstest_restore_vt_mode(void);
>  enum igt_atomic_crtc_properties {
>         IGT_CRTC_BACKGROUND = 0,
>         IGT_CRTC_CTM,
> -       IGT_CRTC_DEGAMMA_LUT,
>         IGT_CRTC_GAMMA_LUT,
> +       IGT_CRTC_GAMMA_LUT_SIZE,
> +       IGT_CRTC_DEGAMMA_LUT,
> +       IGT_CRTC_DEGAMMA_LUT_SIZE,
>         IGT_CRTC_MODE_ID,
>         IGT_CRTC_ACTIVE,
>         IGT_CRTC_OUT_FENCE_PTR,
> diff --git a/tests/kms_color.c b/tests/kms_color.c
> index e30e6bf4e409..dcda12de3a39 100644
> --- a/tests/kms_color.c
> +++ b/tests/kms_color.c
> @@ -231,41 +231,6 @@ static void set_ctm(igt_pipe_t *pipe, const
> double *coefficients)
>  #define disable_gamma(pipe) igt_pipe_obj_replace_prop_blob(pipe,
> IGT_CRTC_GAMMA_LUT, NULL, 0)
>  #define disable_ctm(pipe) igt_pipe_obj_replace_prop_blob(pipe,
> IGT_CRTC_CTM, NULL, 0)
>  
> -static void output_set_property_enum(igt_output_t *output,
> -				     const char *property,
> -				     const char *enum_value)
> -{
> -	int i;
> -	int32_t value = -1;
> -	uint32_t prop_id;
> -	drmModePropertyPtr prop;
> -
> -	if (!kmstest_get_property(output->display->drm_fd,
> -				  output->id,
> -				  DRM_MODE_OBJECT_CONNECTOR,
> -				  property,
> -				  &prop_id, NULL, &prop))
> -		return;
> -
> -	igt_assert(prop->flags & DRM_MODE_PROP_ENUM);
> -
> -	for (i = 0; i < prop->count_enums; i++) {
> -		if (!strcmp(prop->enums[i].name, enum_value)) {
> -			value = prop->enums[i].value;
> -			break;
> -		}
> -	}
> -	igt_assert_neq(value, -1);
> -
> -	igt_assert_eq(drmModeObjectSetProperty(output->display-
> >drm_fd,
> -					       output->id,
> -					       DRM_MODE_OBJECT_CONNE
> CTOR,
> -					       prop_id, value), 0);
> -
> -
> -	drmModeFreeProperty(prop);
> -}
> -
>  /*
>   * Draw 3 gradient rectangles in red, green and blue, with a maxed
> out
>   * degamma LUT and verify we have the same CRC as drawing solid
> color
> @@ -531,23 +496,16 @@ static void test_pipe_legacy_gamma(data_t
> *data,
>  }
>  
>  static drmModePropertyBlobPtr
> -get_blob(data_t *data, igt_pipe_t *pipe, const char *property_name)
> +get_blob(data_t *data, igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop)
>  {
>  	uint64_t prop_value;
> -	drmModePropertyPtr prop;
> -	drmModePropertyBlobPtr blob;
>  
> -	igt_assert(igt_pipe_get_property(pipe, property_name,
> -					 NULL, &prop_value, &prop));
> +	prop_value = igt_pipe_obj_get_prop(pipe, prop);
>  
>  	if (prop_value == 0)
>  		return NULL;
>  
> -	igt_assert(prop->flags & DRM_MODE_PROP_BLOB);
> -	blob = drmModeGetPropertyBlob(data->drm_fd, prop_value);
> -	drmModeFreeProperty(prop);
> -
> -	return blob;
> +	return drmModeGetPropertyBlob(data->drm_fd, prop_value);
>  }
>  
>  /*
> @@ -590,18 +548,18 @@ static void test_pipe_legacy_gamma_reset(data_t
> *data,
>  		set_gamma(data, primary->pipe, gamma_zero);
>  		igt_display_commit(&data->display);
>  
> -		blob = get_blob(data, primary->pipe, "DEGAMMA_LUT");
> +		blob = get_blob(data, primary->pipe,
> IGT_CRTC_DEGAMMA_LUT);
>  		igt_assert(blob &&
>  			   blob->length == (sizeof(struct
> _drm_color_lut) *
>  					    data-
> >degamma_lut_size));
>  		drmModeFreePropertyBlob(blob);
>  
> -		blob = get_blob(data, primary->pipe, "CTM");
> +		blob = get_blob(data, primary->pipe, IGT_CRTC_CTM);
>  		igt_assert(blob &&
>  			   blob->length == sizeof(struct
> _drm_color_ctm));
>  		drmModeFreePropertyBlob(blob);
>  
> -		blob = get_blob(data, primary->pipe, "GAMMA_LUT");
> +		blob = get_blob(data, primary->pipe,
> IGT_CRTC_GAMMA_LUT);
>  		igt_assert(blob &&
>  			   blob->length == (sizeof(struct
> _drm_color_lut) *
>  					    data->gamma_lut_size));
> @@ -634,10 +592,10 @@ static void test_pipe_legacy_gamma_reset(data_t
> *data,
>  		igt_display_commit(&data->display);
>  
>  		igt_assert(get_blob(data, primary->pipe,
> -				    "DEGAMMA_LUT") == NULL);
> -		igt_assert(get_blob(data, primary->pipe, "CTM") ==
> NULL);
> +				    IGT_CRTC_DEGAMMA_LUT) == NULL);
> +		igt_assert(get_blob(data, primary->pipe,
> IGT_CRTC_CTM) == NULL);
>  
> -		blob = get_blob(data, primary->pipe, "GAMMA_LUT");
> +		blob = get_blob(data, primary->pipe,
> IGT_CRTC_GAMMA_LUT);
>  		igt_assert(blob &&
>  			   blob->length == (sizeof(struct
> _drm_color_lut) *
>  					    legacy_lut_size));
> @@ -777,6 +735,7 @@ static void test_pipe_limited_range_ctm(data_t
> *data,
>  			0.0, 0.0, 1.0 };
>  	double *degamma_linear, *gamma_linear;
>  	igt_output_t *output;
> +	bool has_broadcast_rgb_output = false;
>  
>  	degamma_linear = generate_table(data->degamma_lut_size,
> 1.0);
>  	gamma_linear = generate_table(data->gamma_lut_size, 1.0);
> @@ -787,6 +746,11 @@ static void test_pipe_limited_range_ctm(data_t
> *data,
>  		igt_crc_t crc_full, crc_limited;
>  		int fb_id, fb_modeset_id;
>  
> +		if (!igt_output_has_prop(output,
> IGT_CONNECTOR_BROADCAST_RGB))
> +			continue;
> +
> +		has_broadcast_rgb_output = true;
> +
>  		igt_output_set_pipe(output, primary->pipe->pipe);
>  		mode = igt_output_get_mode(output);
>  
> @@ -812,7 +776,7 @@ static void test_pipe_limited_range_ctm(data_t
> *data,
>  		set_gamma(data, primary->pipe, gamma_linear);
>  		set_ctm(primary->pipe, ctm);
>  
> -		output_set_property_enum(output, "Broadcast RGB",
> "Full");
> +		igt_output_set_prop_value(output,
> IGT_CONNECTOR_BROADCAST_RGB, BROADCAST_RGB_FULL);
>  		paint_rectangles(data, mode, red_green_blue_limited,
> &fb);
>  		igt_plane_set_fb(primary, &fb);
>  		igt_display_commit(&data->display);
> @@ -820,31 +784,34 @@ static void test_pipe_limited_range_ctm(data_t
> *data,
>  		igt_pipe_crc_collect_crc(data->pipe_crc, &crc_full);
>  
>  		/* Set the output into limited range. */
> -		output_set_property_enum(output, "Broadcast RGB",
> "Limited 16:235");
> +		igt_output_set_prop_value(output,
> IGT_CONNECTOR_BROADCAST_RGB, BROADCAST_RGB_16_235);
>  		paint_rectangles(data, mode, red_green_blue_full,
> &fb);
>  		igt_plane_set_fb(primary, &fb);
>  		igt_display_commit(&data->display);
>  		igt_wait_for_vblank(data->drm_fd, primary->pipe-
> >pipe);
>  		igt_pipe_crc_collect_crc(data->pipe_crc,
> &crc_limited);
>  
> +		/* And reset.. */
> +		igt_output_set_prop_value(output,
> IGT_CONNECTOR_BROADCAST_RGB, BROADCAST_RGB_FULL);
> +		igt_plane_set_fb(primary, NULL);
> +		igt_output_set_pipe(output, PIPE_NONE);
> +
>  		/* Verify that the CRC of the software computed
> output is
>  		 * equal to the CRC of the CTM matrix transformation
> output.
>  		 */
>  		igt_assert_crc_equal(&crc_full, &crc_limited);
> -
> -		igt_plane_set_fb(primary, NULL);
> -		igt_output_set_pipe(output, PIPE_NONE);
>  	}
>  
>  	free(gamma_linear);
>  	free(degamma_linear);
> +
> +	igt_require(has_broadcast_rgb_output);
>  }
>  #endif
>  
>  static void
>  run_tests_for_pipe(data_t *data, enum pipe p)
>  {
> -	igt_output_t *output;
>  	igt_pipe_t *pipe;
>  	igt_plane_t *primary;
>  	double delta;
> @@ -856,8 +823,6 @@ run_tests_for_pipe(data_t *data, enum pipe p)
>  	};
>  
>  	igt_fixture {
> -		int valid_tests = 0;
> -
>  		igt_require_pipe_crc(data->drm_fd);
>  
>  		igt_require(p < data->display.n_pipes);
> @@ -871,23 +836,18 @@ run_tests_for_pipe(data_t *data, enum pipe p)
>  						  primary->pipe-
> >pipe,
>  						  INTEL_PIPE_CRC_SOU
> RCE_AUTO);
>  
> -		igt_require(igt_pipe_get_property(&data-
> >display.pipes[p],
> -						  "DEGAMMA_LUT_SIZE"
> ,
> -						  NULL,
> -						  &data-
> >degamma_lut_size,
> -						  NULL));
> -		igt_require(igt_pipe_get_property(&data-
> >display.pipes[p],
> -						  "GAMMA_LUT_SIZE",
> -						  NULL,
> -						  &data-
> >gamma_lut_size,
> -						  NULL));
> -
> -		for_each_valid_output_on_pipe(&data->display, p,
> output) {
> -			output_set_property_enum(output, "Broadcast
> RGB", "Full");
> -
> -			valid_tests++;
> -		}
> -		igt_require_f(valid_tests, "no valid crtc/connector
> combinations found\n");
> +		igt_require(igt_pipe_obj_has_prop(&data-
> >display.pipes[p], IGT_CRTC_DEGAMMA_LUT_SIZE));
> +		igt_require(igt_pipe_obj_has_prop(&data-
> >display.pipes[p], IGT_CRTC_GAMMA_LUT_SIZE));
> +
> +		data->degamma_lut_size =
> +			igt_pipe_obj_get_prop(&data-
> >display.pipes[p],
> +					      IGT_CRTC_DEGAMMA_LUT_S
> IZE);
> +
> +		data->gamma_lut_size =
> +			igt_pipe_obj_get_prop(&data-
> >display.pipes[p],
> +					      IGT_CRTC_GAMMA_LUT_SIZ
> E);
> +
> +		igt_display_require_output_on_pipe(&data->display,
> p);
>  	}
>  
>  	/* We assume an 8bits depth per color for degamma/gamma LUTs
> @@ -1050,9 +1010,6 @@ run_tests_for_pipe(data_t *data, enum pipe p)
>  		test_pipe_legacy_gamma_reset(data, primary);
>  
>  	igt_fixture {
> -		for_each_connected_output(&data->display, output)
> -			output_set_property_enum(output, "Broadcast
> RGB", "Full");
> -
>  		disable_degamma(primary->pipe);
>  		disable_gamma(primary->pipe);
>  		disable_ctm(primary->pipe);
> @@ -1064,93 +1021,76 @@ run_tests_for_pipe(data_t *data, enum pipe p)
>  }
>  
>  static int
> -pipe_set_property_blob_id(igt_pipe_t *pipe, const char *property,
> uint32_t blob_id)
> +pipe_set_property_blob_id(igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop, uint32_t blob_id)
>  {
> -	uint32_t prop_id;
> -
> -	igt_assert(kmstest_get_property(pipe->display->drm_fd,
> -					pipe->crtc_id,
> -					DRM_MODE_OBJECT_CRTC,
> -					property,
> -					&prop_id, NULL, NULL));
> -
> -	return drmModeObjectSetProperty(pipe->display->drm_fd,
> -					pipe->crtc_id,
> -					DRM_MODE_OBJECT_CRTC,
> -					prop_id, blob_id);
> -}
> +	int ret;
>  
> -static int
> -pipe_set_property_blob(igt_pipe_t *pipe, const char *property, void
> *ptr, size_t length)
> -{
> -	int ret = 0;
> -	uint32_t blob_id = 0;
> +	igt_pipe_obj_replace_prop_blob(pipe, prop, NULL, 0);
>  
> -	if (length > 0)
> -		igt_assert_eq(drmModeCreatePropertyBlob(pipe-
> >display->drm_fd,
> -							ptr, length,
> -							&blob_id),
> 0);
> +	igt_pipe_obj_set_prop_value(pipe, prop, blob_id);
>  
> -	ret = pipe_set_property_blob_id(pipe, property, blob_id);
> +	ret = igt_display_try_commit2(pipe->display, pipe->display-
> >is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
>  
> -	if (blob_id != 0)
> -		igt_assert_eq(drmModeDestroyPropertyBlob(pipe-
> >display->drm_fd, blob_id), 0);
> +	igt_pipe_obj_set_prop_value(pipe, prop, 0);
>  
>  	return ret;
>  }
>  
> +static int
> +pipe_set_property_blob(igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop, void *ptr, size_t length)
> +{
> +	igt_pipe_obj_replace_prop_blob(pipe, prop, ptr, length);
> +
> +	return igt_display_try_commit2(pipe->display, pipe->display-
> >is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY);
> +}
> +
>  static void
>  invalid_lut_sizes(data_t *data)
>  {
> -	igt_pipe_t *pipe = &data->display.pipes[0];
> +	igt_display_t *display = &data->display;
> +	igt_pipe_t *pipe = &display->pipes[0];
>  	size_t degamma_lut_size = data->degamma_lut_size *
> sizeof(struct _drm_color_lut);
>  	size_t gamma_lut_size = data->gamma_lut_size * sizeof(struct
> _drm_color_lut);
>  
>  	struct _drm_color_lut *degamma_lut = malloc(data-
> >degamma_lut_size * sizeof(struct _drm_color_lut) * 2);
>  	struct _drm_color_lut *gamma_lut = malloc(data-
> >gamma_lut_size * sizeof(struct _drm_color_lut) * 2);
>  
> -	if (kmstest_get_property(pipe->display->drm_fd,
> -				 pipe->crtc_id,
> -				 DRM_MODE_OBJECT_CRTC,
> -				 "DEGAMMA_LUT",
> -				 NULL, NULL, NULL)) {
> -		igt_assert_eq(pipe_set_property_blob(pipe,
> "DEGAMMA_LUT",
> +	igt_display_commit2(display, display->is_atomic ?
> COMMIT_ATOMIC : COMMIT_LEGACY);
> +
> +	if (igt_pipe_obj_has_prop(pipe, IGT_CRTC_DEGAMMA_LUT)) {
> +		igt_assert_eq(pipe_set_property_blob(pipe,
> IGT_CRTC_DEGAMMA_LUT,
>  						     degamma_lut,
> 1), -EINVAL);
> -		igt_assert_eq(pipe_set_property_blob(pipe,
> "DEGAMMA_LUT",
> +		igt_assert_eq(pipe_set_property_blob(pipe,
> IGT_CRTC_DEGAMMA_LUT,
>  						     degamma_lut,
> degamma_lut_size + 1),
>  			      -EINVAL);
> -		igt_assert_eq(pipe_set_property_blob(pipe,
> "DEGAMMA_LUT",
> +		igt_assert_eq(pipe_set_property_blob(pipe,
> IGT_CRTC_DEGAMMA_LUT,
>  						     degamma_lut,
> degamma_lut_size - 1),
>  			      -EINVAL);
> -		igt_assert_eq(pipe_set_property_blob(pipe,
> "DEGAMMA_LUT",
> +		igt_assert_eq(pipe_set_property_blob(pipe,
> IGT_CRTC_DEGAMMA_LUT,
>  						     degamma_lut,
> degamma_lut_size + sizeof(struct _drm_color_lut)),
>  			      -EINVAL);
> -		igt_assert_eq(pipe_set_property_blob_id(pipe,
> "DEGAMMA_LUT", pipe->crtc_id),
> +		igt_assert_eq(pipe_set_property_blob_id(pipe,
> IGT_CRTC_DEGAMMA_LUT, pipe->crtc_id),
>  			      -EINVAL);
> -		igt_assert_eq(pipe_set_property_blob_id(pipe,
> "DEGAMMA_LUT", 4096 * 4096),
> +		igt_assert_eq(pipe_set_property_blob_id(pipe,
> IGT_CRTC_DEGAMMA_LUT, 4096 * 4096),
>  			      -EINVAL);
>  	}
>  
> -	if (kmstest_get_property(pipe->display->drm_fd,
> -				 pipe->crtc_id,
> -				 DRM_MODE_OBJECT_CRTC,
> -				 "GAMMA_LUT",
> -				 NULL, NULL, NULL)) {
> -		igt_assert_eq(pipe_set_property_blob(pipe,
> "GAMMA_LUT",
> +	if (igt_pipe_obj_has_prop(pipe, IGT_CRTC_GAMMA_LUT)) {
> +		igt_assert_eq(pipe_set_property_blob(pipe,
> IGT_CRTC_GAMMA_LUT,
>  						     gamma_lut, 1),
>  			      -EINVAL);
> -		igt_assert_eq(pipe_set_property_blob(pipe,
> "GAMMA_LUT",
> +		igt_assert_eq(pipe_set_property_blob(pipe,
> IGT_CRTC_GAMMA_LUT,
>  						     gamma_lut,
> gamma_lut_size + 1),
>  			      -EINVAL);
> -		igt_assert_eq(pipe_set_property_blob(pipe,
> "GAMMA_LUT",
> +		igt_assert_eq(pipe_set_property_blob(pipe,
> IGT_CRTC_GAMMA_LUT,
>  						     gamma_lut,
> gamma_lut_size - 1),
>  			      -EINVAL);
> -		igt_assert_eq(pipe_set_property_blob(pipe,
> "GAMMA_LUT",
> +		igt_assert_eq(pipe_set_property_blob(pipe,
> IGT_CRTC_GAMMA_LUT,
>  						     gamma_lut,
> gamma_lut_size + sizeof(struct _drm_color_lut)),
>  			      -EINVAL);
> -		igt_assert_eq(pipe_set_property_blob_id(pipe,
> "GAMMA_LUT", pipe->crtc_id),
> +		igt_assert_eq(pipe_set_property_blob_id(pipe,
> IGT_CRTC_GAMMA_LUT, pipe->crtc_id),
>  			      -EINVAL);
> -		igt_assert_eq(pipe_set_property_blob_id(pipe,
> "GAMMA_LUT", 4096 * 4096),
> +		igt_assert_eq(pipe_set_property_blob_id(pipe,
> IGT_CRTC_GAMMA_LUT, 4096 * 4096),
>  			      -EINVAL);
>  	}
>  
> @@ -1161,32 +1101,29 @@ invalid_lut_sizes(data_t *data)
>  static void
>  invalid_ctm_matrix_sizes(data_t *data)
>  {
> -	igt_pipe_t *pipe = &data->display.pipes[0];
> +	igt_display_t *display = &data->display;
> +	igt_pipe_t *pipe = &display->pipes[0];
>  	void *ptr;
>  
> -	if (!kmstest_get_property(pipe->display->drm_fd,
> -				  pipe->crtc_id,
> -				  DRM_MODE_OBJECT_CRTC,
> -				  "CTM",
> -				  NULL, NULL, NULL))
> +	if (!igt_pipe_obj_has_prop(pipe, IGT_CRTC_CTM))
>  		return;
>  
>  	ptr = malloc(sizeof(struct _drm_color_ctm) * 4);
>  
> -	igt_assert_eq(pipe_set_property_blob(pipe, "CTM", ptr, 1),
> +	igt_assert_eq(pipe_set_property_blob(pipe, IGT_CRTC_CTM,
> ptr, 1),
>  		      -EINVAL);
> -	igt_assert_eq(pipe_set_property_blob(pipe, "CTM", ptr,
> +	igt_assert_eq(pipe_set_property_blob(pipe, IGT_CRTC_CTM,
> ptr,
>  					     sizeof(struct
> _drm_color_ctm) + 1),
>  		      -EINVAL);
> -	igt_assert_eq(pipe_set_property_blob(pipe, "CTM", ptr,
> +	igt_assert_eq(pipe_set_property_blob(pipe, IGT_CRTC_CTM,
> ptr,
>  					     sizeof(struct
> _drm_color_ctm) - 1),
>  		      -EINVAL);
> -	igt_assert_eq(pipe_set_property_blob(pipe, "CTM", ptr,
> +	igt_assert_eq(pipe_set_property_blob(pipe, IGT_CRTC_CTM,
> ptr,
>  					     sizeof(struct
> _drm_color_ctm) * 2),
>  		      -EINVAL);
> -	igt_assert_eq(pipe_set_property_blob_id(pipe, "CTM", pipe-
> >crtc_id),
> +	igt_assert_eq(pipe_set_property_blob_id(pipe, IGT_CRTC_CTM,
> pipe->crtc_id),
>  		      -EINVAL);
> -	igt_assert_eq(pipe_set_property_blob_id(pipe, "CTM", 4096 *
> 4096),
> +	igt_assert_eq(pipe_set_property_blob_id(pipe, IGT_CRTC_CTM,
> 4096 * 4096),
>  		      -EINVAL);
>  
>  	free(ptr);
-- 
Mika Kahola - Intel OTC

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2 13/14] tests/chamelium: Remove reliance on output->config.pipe
  2017-10-12 11:54 ` [PATCH i-g-t v2 13/14] tests/chamelium: Remove reliance on output->config.pipe Maarten Lankhorst
@ 2017-10-20  7:15   ` Mika Kahola
  0 siblings, 0 replies; 45+ messages in thread
From: Mika Kahola @ 2017-10-20  7:15 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx

Reviewed-by: Mika Kahola <mika.kahola@intel.com>

On Thu, 2017-10-12 at 13:54 +0200, Maarten Lankhorst wrote:
> IGT has an api that can find a matching pipe for a given connector,
> so use that.
> 
> igt_output_override_mode already forces a modeset on an affected pipe
> since an earlier commit, so the second call to igt_output_set_pipe
> can be removed.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  tests/chamelium.c | 17 ++++++++++++++---
>  1 file changed, 14 insertions(+), 3 deletions(-)
> 
> diff --git a/tests/chamelium.c b/tests/chamelium.c
> index 4ad29f9d178a..d4a185e76873 100644
> --- a/tests/chamelium.c
> +++ b/tests/chamelium.c
> @@ -416,6 +416,8 @@ prepare_output(data_t *data,
>  	drmModeRes *res;
>  	drmModeConnector *connector =
>  		chamelium_port_get_connector(data->chamelium, port,
> false);
> +	enum pipe pipe;
> +	bool found = false;
>  
>  	igt_assert(res = drmModeGetResources(data->drm_fd));
>  	kmstest_unset_all_crtcs(data->drm_fd, res);
> @@ -433,7 +435,18 @@ prepare_output(data_t *data,
>  
>  	igt_assert(kmstest_probe_connector_config(
>  		data->drm_fd, connector->connector_id, ~0, &output-
> >config));
> -	igt_output_set_pipe(output, output->config.pipe);
> +
> +	for_each_pipe(display, pipe) {
> +		if (!igt_pipe_connector_valid(pipe, output))
> +			continue;
> +
> +		found = true;
> +		break;
> +	}
> +
> +	igt_assert_f(found, "No pipe found for output %s\n",
> igt_output_name(output));
> +
> +	igt_output_set_pipe(output, pipe);
>  
>  	drmModeFreeConnector(connector);
>  	drmModeFreeResources(res);
> @@ -459,8 +472,6 @@ enable_output(data_t *data,
>  	igt_plane_set_fb(primary, fb);
>  	igt_output_override_mode(output, mode);
>  
> -	igt_output_set_pipe(output, output->config.pipe);
> -
>  	/* Clear any color correction values that might be enabled
> */
>  	igt_pipe_obj_replace_prop_blob(primary->pipe,
> IGT_CRTC_DEGAMMA_LUT, NULL, 0);
>  	igt_pipe_obj_replace_prop_blob(primary->pipe,
> IGT_CRTC_GAMMA_LUT, NULL, 0);
-- 
Mika Kahola - Intel OTC

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2 02/14] lib/igt_kms: Rework plane properties to be more atomic, v5.
  2017-10-19  9:44     ` Maarten Lankhorst
@ 2017-10-20  8:03       ` Mika Kahola
  0 siblings, 0 replies; 45+ messages in thread
From: Mika Kahola @ 2017-10-20  8:03 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx

On Thu, 2017-10-19 at 11:44 +0200, Maarten Lankhorst wrote:
> Op 19-10-17 om 11:08 schreef Mika Kahola:
> > 
> > On Thu, 2017-10-12 at 13:54 +0200, Maarten Lankhorst wrote:
> > > 
> > > In the future I want to allow tests to commit more properties,
> > > but for this to work I have to fix all properties to work better
> > > with atomic commit. Instead of special casing each
> > > property make a bitmask for all property changed flags, and try
> > > to
> > > commit all properties.
> > > 
> > > Changes since v1:
> > > - Remove special dumping of src and crtc coordinates.
> > > - Dump all modified coordinates.
> > > Changes since v2:
> > > - Move igt_plane_set_prop_changed up slightly.
> > > Changes since v3:
> > > - Fix wrong ordering of set_position in kms_plane_lowres causing
> > > a
> > > test failure.
> > > Changes since v4:
> > > - Back out resetting crtc position in igt_plane_set_fb() and
> > >   document it during init. Tests appear to rely on it being
> > > preserved.
> > > 
> > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.c
> > > om>
> > > ---
> > >  lib/igt_kms.c                    | 299 +++++++++++++++++------
> > > ----
> > > ------------
> > >  lib/igt_kms.h                    |  59 ++++----
> > >  tests/kms_atomic_interruptible.c |  12 +-
> > >  tests/kms_rotation_crc.c         |   4 +-
> > >  4 files changed, 165 insertions(+), 209 deletions(-)
> > > 
> > > diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> > > index e6fa8f4af455..e77ae5d696da 100644
> > > --- a/lib/igt_kms.c
> > > +++ b/lib/igt_kms.c
> > > @@ -192,11 +192,11 @@ const char
> > > *igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
> > >  
> > >  /*
> > >   * Retrieve all the properies specified in props_name and store
> > > them
> > > into
> > > - * plane->atomic_props_plane.
> > > + * plane->props.
> > >   */
> > >  static void
> > > -igt_atomic_fill_plane_props(igt_display_t *display, igt_plane_t
> > > *plane,
> > > -			int num_props, const char **prop_names)
> > > +igt_fill_plane_props(igt_display_t *display, igt_plane_t *plane,
> > > +		     int num_props, const char **prop_names)
> > >  {
> > >  	drmModeObjectPropertiesPtr props;
> > >  	int i, j, fd;
> > > @@ -214,7 +214,7 @@ igt_atomic_fill_plane_props(igt_display_t
> > > *display, igt_plane_t *plane,
> > >  			if (strcmp(prop->name, prop_names[j]) !=
> > > 0)
> > >  				continue;
> > >  
> > > -			plane->atomic_props_plane[j] = props-
> > > > 
> > > > props[i];
> > > +			plane->props[j] = props->props[i];
> > >  			break;
> > >  		}
> > >  
> > > @@ -1659,7 +1659,6 @@ void igt_display_init(igt_display_t
> > > *display,
> > > int drm_fd)
> > >  	drmModeRes *resources;
> > >  	drmModePlaneRes *plane_resources;
> > >  	int i;
> > > -	int is_atomic = 0;
> > >  
> > >  	memset(display, 0, sizeof(igt_display_t));
> > >  
> > > @@ -1679,7 +1678,9 @@ void igt_display_init(igt_display_t
> > > *display,
> > > int drm_fd)
> > >  	igt_assert_f(display->pipes, "Failed to allocate memory
> > > for
> > > %d pipes\n", display->n_pipes);
> > >  
> > >  	drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES,
> > > 1);
> > > -	is_atomic = drmSetClientCap(drm_fd,
> > > DRM_CLIENT_CAP_ATOMIC,
> > > 1);
> > > +	if (drmSetClientCap(drm_fd, DRM_CLIENT_CAP_ATOMIC, 1) ==
> > > 0)
> > > +		display->is_atomic = 1;
> > > +
> > >  	plane_resources = drmModeGetPlaneResources(display-
> > > >drm_fd);
> > >  	igt_assert(plane_resources);
> > >  
> > > @@ -1776,19 +1777,27 @@ void igt_display_init(igt_display_t
> > > *display,
> > > int drm_fd)
> > >  			plane->type = type;
> > >  			plane->pipe = pipe;
> > >  			plane->drm_plane = drm_plane;
> > > -			plane->fence_fd = -1;
> > > +			plane->values[IGT_PLANE_IN_FENCE_FD] =
> > > ~0ULL;
> > >  
> > > -			if (is_atomic == 0) {
> > > -				display->is_atomic = 1;
> > > -				igt_atomic_fill_plane_props(disp
> > > lay,
> > > plane, IGT_NUM_PLANE_PROPS, igt_plane_prop_names);
> > > -			}
> > > +			igt_fill_plane_props(display, plane,
> > > IGT_NUM_PLANE_PROPS, igt_plane_prop_names);
> > >  
> > >  			get_plane_property(display->drm_fd,
> > > drm_plane->plane_id,
> > >  					   "rotation",
> > > -					   &plane-
> > > > 
> > > > rotation_property,
> > > -					   &prop_value,
> > > +					   &plane-
> > > > 
> > > > props[IGT_PLANE_ROTATION],
> > > +					   &plane-
> > > > 
> > > > values[IGT_PLANE_ROTATION],
> > >  					   NULL);
> > > -			plane->rotation =
> > > (igt_rotation_t)prop_value;
> > > +
> > > +			/* Clear any residual framebuffer info
> > > on
> > > first commit. */
> > > +			igt_plane_set_prop_changed(plane,
> > > IGT_PLANE_FB_ID);
> > > +			igt_plane_set_prop_changed(plane,
> > > IGT_PLANE_CRTC_ID);
> > > +
> > > +			/*
> > > +			 * CRTC_X/Y are not changed in
> > > igt_plane_set_fb, so
> > > +			 * force them to be sanitized in case
> > > they
> > > contain
> > > +			 * garbage.
> > > +			 */
> > > +			igt_plane_set_prop_changed(plane,
> > > IGT_PLANE_CRTC_X);
> > > +			igt_plane_set_prop_changed(plane,
> > > IGT_PLANE_CRTC_Y);
> > >  		}
> > >  
> > >  		/*
> > > @@ -1805,9 +1814,6 @@ void igt_display_init(igt_display_t
> > > *display,
> > > int drm_fd)
> > >  
> > >  		pipe->n_planes = n_planes;
> > >  
> > > -		for_each_plane_on_pipe(display, i, plane)
> > > -			plane->fb_changed = true;
> > > -
> > >  		pipe->mode_changed = true;
> > >  	}
> > >  
> > > @@ -2070,18 +2076,7 @@ bool igt_pipe_get_property(igt_pipe_t
> > > *pipe,
> > > const char *name,
> > >  
> > >  static uint32_t igt_plane_get_fb_id(igt_plane_t *plane)
> > >  {
> > > -	if (plane->fb)
> > > -		return plane->fb->fb_id;
> > > -	else
> > > -		return 0;
> > > -}
> > > -
> > > -static uint32_t igt_plane_get_fb_gem_handle(igt_plane_t *plane)
> > > -{
> > > -	if (plane->fb)
> > > -		return plane->fb->gem_handle;
> > > -	else
> > > -		return 0;
> > > +	return plane->values[IGT_PLANE_FB_ID];
> > >  }
> > >  
> > >  #define CHECK_RETURN(r, fail) {	\
> > > @@ -2090,9 +2085,6 @@ static uint32_t
> > > igt_plane_get_fb_gem_handle(igt_plane_t *plane)
> > >  	igt_assert_eq(r, 0);	\
> > >  }
> > >  
> > > -
> > > -
> > > -
> > >  /*
> > >   * Add position and fb changes of a plane to the atomic property
> > > set
> > >   */
> > > @@ -2101,63 +2093,31 @@
> > > igt_atomic_prepare_plane_commit(igt_plane_t
> > > *plane, igt_pipe_t *pipe,
> > >  	drmModeAtomicReq *req)
> > >  {
> > >  	igt_display_t *display = pipe->display;
> > > -	uint32_t fb_id, crtc_id;
> > > +	int i;
> > >  
> > >  	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 = pipe->crtc_id;
> > > -
> > >  	LOG(display,
> > >  	    "populating plane data: %s.%d, fb %u\n",
> > >  	    kmstest_pipe_name(pipe->pipe),
> > >  	    plane->index,
> > > -	    fb_id);
> > > -
> > > -	if (plane->fence_fd >= 0) {
> > > -		uint64_t fence_fd = (int64_t) plane->fence_fd;
> > > -		igt_atomic_populate_plane_req(req, plane,
> > > IGT_PLANE_IN_FENCE_FD, fence_fd);
> > > -	}
> > > +	    igt_plane_get_fb_id(plane));
> > >  
> > > -	if (plane->fb_changed) {
> > > -		igt_atomic_populate_plane_req(req, plane,
> > > IGT_PLANE_CRTC_ID, fb_id ? crtc_id : 0);
> > > -		igt_atomic_populate_plane_req(req, plane,
> > > IGT_PLANE_FB_ID, fb_id);
> > > -	}
> > > -
> > > -	if (plane->position_changed || plane->size_changed) {
> > > -		uint32_t src_x = IGT_FIXED(plane->src_x, 0); /*
> > > src_x */
> > > -		uint32_t src_y = IGT_FIXED(plane->src_y, 0); /*
> > > src_y */
> > > -		uint32_t src_w = IGT_FIXED(plane->src_w, 0); /*
> > > src_w */
> > > -		uint32_t src_h = IGT_FIXED(plane->src_h, 0); /*
> > > src_h */
> > > -		int32_t crtc_x = plane->crtc_x;
> > > -		int32_t crtc_y = plane->crtc_y;
> > > -		uint32_t crtc_w = plane->crtc_w;
> > > -		uint32_t crtc_h = plane->crtc_h;
> > > +	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++) {
> > > +		if (!igt_plane_is_prop_changed(plane, i))
> > > +			continue;
> > Could we add a macro here too? Like 'for_each_prop_on_plane()' or
> > similar?
> Outside of commit it doesn't make much sense to iterate over the
> properties.
> The only test that enumerates over the array is the reworked
> kms_atomic, to
> see if the value committed is the same as the value returned by
> getprop.
> 
> And the only reason the test does so is because it was easier to
> store in an
> array to memcmp plane->values against kernel_values.
Ok. We'll keep it as it is.

Reviewed-by: Mika Kahola <mika.kahola@intel.com>

> 
-- 
Mika Kahola - Intel OTC

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2 05/14] lib/igt_kms: Allow setting any output property through the !atomic paths
  2017-10-12 11:54 ` [PATCH i-g-t v2 05/14] lib/igt_kms: Allow setting any output property through the !atomic paths Maarten Lankhorst
@ 2017-10-20  9:38   ` Mika Kahola
  0 siblings, 0 replies; 45+ messages in thread
From: Mika Kahola @ 2017-10-20  9:38 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx

Reviewed-by: Mika Kahola <mika.kahola@intel.com>

On Thu, 2017-10-12 at 13:54 +0200, Maarten Lankhorst wrote:
> Everything except CRTC_ID can be set in the legacy paths,
> we even have 2, the legacy and universal path. Excercise both. :D
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  lib/igt_kms.c | 53 +++++++++++++++++++++++++++++++++++++----------
> ------
>  1 file changed, 37 insertions(+), 16 deletions(-)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index be89632547e5..e7b9fbaba709 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -2413,6 +2413,36 @@ static int igt_pipe_commit(igt_pipe_t *pipe,
>  	return 0;
>  }
>  
> +static int igt_output_commit(igt_output_t *output,
> +			     enum igt_commit_style s,
> +			     bool fail_on_error)
> +{
> +	int i, ret;
> +
> +	for (i = 0; i < IGT_NUM_CONNECTOR_PROPS; i++) {
> +		if (!igt_output_is_prop_changed(output, i))
> +			continue;
> +
> +		/* CRTC_ID is set by calling drmModeSetCrtc in the
> legacy path. */
> +		if (i == IGT_CONNECTOR_CRTC_ID)
> +			continue;
> +
> +		igt_assert(output->props[i]);
> +
> +		if (s == COMMIT_LEGACY)
> +			ret = drmModeConnectorSetProperty(output-
> >display->drm_fd, output->id,
> +							  output-
> >props[i], output->values[i]);
> +		else
> +			ret = drmModeObjectSetProperty(output-
> >display->drm_fd, output->id,
> +						       DRM_MODE_OBJE
> CT_CONNECTOR,
> +						       output-
> >props[i], output->values[i]);
> +
> +		CHECK_RETURN(ret, fail_on_error);
> +	}
> +
> +	return 0;
> +}
> +
>  static void
>  igt_pipe_replace_blob(igt_pipe_t *pipe, enum
> igt_atomic_crtc_properties prop, void *ptr, size_t length)
>  {
> @@ -2590,10 +2620,11 @@ display_commit_changed(igt_display_t
> *display, enum igt_commit_style s)
>  	for (i = 0; i < display->n_outputs; i++) {
>  		igt_output_t *output = &display->outputs[i];
>  
> -		if (s == COMMIT_ATOMIC)
> +		if (s != COMMIT_UNIVERSAL)
>  			output->changed = 0;
> -		else if (s != COMMIT_UNIVERSAL)
> -			igt_output_clear_prop_changed(output,
> IGT_CONNECTOR_CRTC_ID);
> +		else
> +			/* no modeset in universal commit, no change
> to crtc. */
> +			output->changed &= 1 <<
> IGT_CONNECTOR_CRTC_ID;
>  	}
>  }
>  
> @@ -2610,7 +2641,7 @@ static int do_display_commit(igt_display_t
> *display,
>  			     enum igt_commit_style s,
>  			     bool fail_on_error)
>  {
> -	int ret;
> +	int i, ret = 0;
>  	enum pipe pipe;
>  	LOG_INDENT(display, "commit");
>  
> @@ -2619,28 +2650,18 @@ static int do_display_commit(igt_display_t
> *display,
>  	if (s == COMMIT_ATOMIC) {
>  		ret = igt_atomic_commit(display,
> DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
>  	} else {
> -		int valid_outs = 0;
> -
>  		for_each_pipe(display, pipe) {
>  			igt_pipe_t *pipe_obj = &display-
> >pipes[pipe];
> -			igt_output_t *output =
> igt_pipe_get_output(pipe_obj);
> -
> -			if (output)
> -				valid_outs++;
>  
>  			ret = igt_pipe_commit(pipe_obj, s,
> fail_on_error);
>  			if (ret)
>  				break;
>  		}
>  
> -		if (valid_outs == 0) {
> -			LOG_UNINDENT(display);
> -
> -			return -1;
> -		}
> +		for (i = 0; !ret && i < display->n_outputs; i++)
> +			ret = igt_output_commit(&display-
> >outputs[i], s, fail_on_error);
>  	}
>  
> -
>  	LOG_UNINDENT(display);
>  	CHECK_RETURN(ret, fail_on_error);
>  
-- 
Mika Kahola - Intel OTC

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2] tests/kms_atomic: Convert/rewrite tests to use igt_kms framework, v2.
  2017-10-12 15:33   ` [PATCH i-g-t v2] tests/kms_atomic: Convert/rewrite tests to use igt_kms framework, v2 Maarten Lankhorst
@ 2017-10-20 10:02     ` Mika Kahola
  2017-10-20 10:08       ` Maarten Lankhorst
  0 siblings, 1 reply; 45+ messages in thread
From: Mika Kahola @ 2017-10-20 10:02 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx; +Cc: Daniel Stone

On Thu, 2017-10-12 at 17:33 +0200, Maarten Lankhorst wrote:
> Now that we can set individual properties through the igt_kms api,
> we no longer need to duplicate functionality from igt_kms. Set
> invalid
> properties directly, and rewrite kms_atomic.c to use igt_display.
> This will allow us to remove a lot of code in kms_atomic.c,
> and benefit from how igt_kms can set up a valid configuration,
> instead of having to inherit it from fbcon.
> 
> Changes since v1:
> - Fix test failure when atomic_invalid_params is run standalone.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Daniel Stone <daniels@collabora.com>
> ---
>  tests/kms_atomic.c | 1668 ++++++++++++++++------------------------
> ------------
>  1 file changed, 512 insertions(+), 1156 deletions(-)
> 
> diff --git a/tests/kms_atomic.c b/tests/kms_atomic.c
> index 042a7c263aab..e0fc324eab61 100644
> --- a/tests/kms_atomic.c
> +++ b/tests/kms_atomic.c
> @@ -46,10 +46,6 @@
>  #include "igt_aux.h"
>  #include "sw_sync.h"
>  
> -#ifndef DRM_CLIENT_CAP_ATOMIC
> -#define DRM_CLIENT_CAP_ATOMIC 3
> -#endif
> -
>  #ifndef DRM_CAP_CURSOR_WIDTH
>  #define DRM_CAP_CURSOR_WIDTH 0x8
>  #endif
> @@ -58,23 +54,6 @@
>  #define DRM_CAP_CURSOR_HEIGHT 0x9
>  #endif
>  
> -#ifndef DRM_MODE_ATOMIC_TEST_ONLY
> -#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
> -#define DRM_MODE_ATOMIC_NONBLOCK 0x0200
> -#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
> -
> -struct drm_mode_atomic {
> -	__u32 flags;
> -	__u32 count_objs;
> -	__u64 objs_ptr;
> -	__u64 count_props_ptr;
> -	__u64 props_ptr;
> -	__u64 prop_values_ptr;
> -	__u64 reserved;
> -	__u64 user_data;
> -};
> -#endif
> -
>  IGT_TEST_DESCRIPTION("Test atomic modesetting API");
>  
>  enum kms_atomic_check_relax {
> @@ -83,1259 +62,652 @@ enum kms_atomic_check_relax {
>  	PLANE_RELAX_FB = (1 << 1)
>  };
>  
> -/**
> - * KMS plane type enum
> - *
> - * KMS plane types are represented by enums, which do not have
> stable numeric
> - * values, but must be looked up by their string value each time.
> - *
> - * To make the code more simple, we define a plane_type enum which
> maps to
> - * each KMS enum value. These values must be looked up through the
> map, and
> - * cannot be passed directly to KMS functions.
> - */
> -enum plane_type {
> -	PLANE_TYPE_PRIMARY = 0,
> -	PLANE_TYPE_OVERLAY,
> -	PLANE_TYPE_CURSOR,
> -	NUM_PLANE_TYPE_PROPS
> -};
> -
> -static const char *plane_type_prop_names[NUM_PLANE_TYPE_PROPS] = {
> -	"Primary",
> -	"Overlay",
> -	"Cursor"
> -};
> -
> -struct kms_atomic_blob {
> -	uint32_t id; /* 0 if not already allocated */
> -	size_t len;
> -	void *data;
> -};
> -
> -struct kms_atomic_connector_state {
> -	struct kms_atomic_state *state;
> -	uint32_t obj;
> -	uint32_t crtc_id;
> -};
> -
> -struct kms_atomic_plane_state {
> -	struct kms_atomic_state *state;
> -	uint32_t obj;
> -	enum plane_type type;
> -	uint32_t crtc_mask;
> -	uint32_t crtc_id; /* 0 to disable */
> -	uint32_t fb_id; /* 0 to disable */
> -	uint32_t src_x, src_y, src_w, src_h; /* 16.16 fixed-point */
> -	uint32_t crtc_x, crtc_y, crtc_w, crtc_h; /* normal integers
> */
> -	int32_t fence_fd;
> -};
> -
> -struct kms_atomic_crtc_state {
> -	struct kms_atomic_state *state;
> -	uint32_t obj;
> -	int idx;
> -	bool active;
> -	int32_t *out_fence_ptr;
> -	struct kms_atomic_blob mode;
> -};
> -
> -struct kms_atomic_state {
> -	struct kms_atomic_connector_state *connectors;
> -	int num_connectors;
> -	struct kms_atomic_crtc_state *crtcs;
> -	int num_crtcs;
> -	struct kms_atomic_plane_state *planes;
> -	int num_planes;
> -	struct kms_atomic_desc *desc;
> -};
> -
> -struct kms_atomic_desc {
> -	int fd;
> -	uint32_t props_connector[IGT_NUM_CONNECTOR_PROPS];
> -	uint32_t props_crtc[IGT_NUM_CRTC_PROPS];
> -	uint32_t props_plane[IGT_NUM_PLANE_PROPS];
> -	uint64_t props_plane_type[NUM_PLANE_TYPE_PROPS];
> -};
> -
> -static uint32_t blob_duplicate(int fd, uint32_t id_orig)
> +static bool plane_filter(enum igt_atomic_plane_properties prop)
>  {
> -	drmModePropertyBlobPtr orig = drmModeGetPropertyBlob(fd,
> id_orig);
> -	uint32_t id_new;
> -
> -	igt_assert(orig);
> -	do_or_die(drmModeCreatePropertyBlob(fd, orig->data, orig-
> >length,
> -					    &id_new));
> -	drmModeFreePropertyBlob(orig);
> +	if ((1 << prop) & IGT_PLANE_COORD_CHANGED_MASK)
> +		return false;
>  
> -	return id_new;
> -}
> -
> -#define crtc_set_prop(req, crtc, prop, value) \
> -	igt_assert_lt(0, drmModeAtomicAddProperty(req, crtc->obj, \
> -						  crtc->state->desc-
> >props_crtc[prop], \
> -						  value));
> -
> -#define plane_set_prop(req, plane, prop, value) \
> -	igt_assert_lt(0, drmModeAtomicAddProperty(req, plane->obj, \
> -						  plane->state-
> >desc->props_plane[prop], \
> -						  value));
> -
> -#define do_atomic_commit(fd, req, flags) \
> -	do_or_die(drmModeAtomicCommit(fd, req, flags, NULL));
> +	if (prop == IGT_PLANE_CRTC_ID || prop == IGT_PLANE_FB_ID)
> +		return false;
>  
> -#define do_atomic_commit_err(fd, req, flags, err) { \
> -	igt_assert_neq(drmModeAtomicCommit(fd, req, flags, NULL),
> 0); \
> -	igt_assert_eq(errno, err); \
> -}
> -
> -#define crtc_commit_atomic(crtc, plane, req, relax, flags) { \
> -	drmModeAtomicSetCursor(req, 0); \
> -	crtc_populate_req(crtc, req); \
> -	plane_populate_req(plane, req); \
> -	do_atomic_commit((crtc)->state->desc->fd, req, flags); \
> -	if (!(flags & DRM_MODE_ATOMIC_TEST_ONLY)) { \
> -		crtc_check_current_state(crtc, plane, relax); \
> -		plane_check_current_state(plane, relax); \
> -	} \
> -}
> +	if (prop == IGT_PLANE_IN_FENCE_FD)
> +		return false;
>  
> -#define crtc_commit_atomic_err(crtc, plane, crtc_old, plane_old,
> req, flags, relax, e) { \
> -	drmModeAtomicSetCursor(req, 0); \
> -	crtc_populate_req(crtc, req); \
> -	plane_populate_req(plane, req); \
> -	do_atomic_commit_err((crtc)->state->desc->fd, req, flags,
> e); \
> -	crtc_check_current_state(crtc_old, plane_old, relax); \
> -	plane_check_current_state(plane_old, relax); \
> +	/* Don't care about other properties */
> +	return true;
>  }
>  
> -#define plane_commit_atomic(plane, req, relax) { \
> -	drmModeAtomicSetCursor(req, 0); \
> -	plane_populate_req(plane, req); \
> -	do_atomic_commit((plane)->state->desc->fd, req, 0); \
> -	plane_check_current_state(plane, relax); \
> -}
> -
> -#define plane_commit_atomic_err(plane, plane_old, req, relax, e) { \
> -	drmModeAtomicSetCursor(req, 0); \
> -	plane_populate_req(plane, req); \
> -	do_atomic_commit_err((plane)->state->desc->fd, req, 0, e); \
> -	plane_check_current_state(plane_old, relax); \
> -}
> -
> -static void
> -connector_get_current_state(struct kms_atomic_connector_state
> *connector)
> -{
> -	drmModeObjectPropertiesPtr props;
> -	int i;
> -
> -	props = drmModeObjectGetProperties(connector->state->desc-
> >fd,
> -					   connector->obj,
> -					   DRM_MODE_OBJECT_CONNECTOR
> );
> -	igt_assert(props);
> -
> -	for (i = 0; i < props->count_props; i++) {
> -		uint32_t *prop_ids = connector->state->desc-
> >props_connector;
> -
> -		if (props->props[i] ==
> prop_ids[IGT_CONNECTOR_CRTC_ID])
> -			connector->crtc_id = props->prop_values[i];
> -	}
> -	drmModeFreeObjectProperties(props);
> -}
> -
> -#if 0
> -/* XXX: Checking this repeatedly actually hangs the GPU. I have
> literally no
> - *      idea why. */
> -static void
> -connector_check_current_state(struct kms_atomic_connector_state
> *connector)
> -{
> -	struct kms_atomic_connector_state connector_kernel;
> -	drmModeConnectorPtr legacy;
> -	uint32_t crtc_id;
> -
> -	legacy = drmModeGetConnectorCurrent(connector->state->desc-
> >fd,
> -					    connector->obj);
> -	igt_assert(legacy);
> -
> -	if (legacy->encoder_id) {
> -		drmModeEncoderPtr legacy_enc;
> -
> -		legacy_enc = drmModeGetEncoder(connector->state-
> >desc->fd,
> -					       legacy->encoder_id);
> -		igt_assert(legacy_enc);
> -
> -		crtc_id = legacy_enc->crtc_id;
> -		drmModeFreeEncoder(legacy_enc);
> -	} else {
> -		crtc_id = 0;
> -	}
> -
> -	igt_assert_eq_u32(crtc_id, connector->crtc_id);
> -
> -	memcpy(&connector_kernel, connector,
> sizeof(connector_kernel));
> -	connector_get_current_state(&connector_kernel);
> -	do_or_die(memcmp(&connector_kernel, connector,
> -			 sizeof(connector_kernel)));
> -
> -	drmModeFreeConnector(legacy);
> -}
> -#endif
> -
> -static struct kms_atomic_connector_state *
> -find_connector(struct kms_atomic_state *state,
> -	       struct kms_atomic_crtc_state *crtc)
> +static void plane_get_current_state(igt_plane_t *plane, uint64_t
> *values)
>  {
>  	int i;
>  
> -	for (i = 0; i < state->num_connectors; i++) {
> -		struct kms_atomic_connector_state *connector =
> -			&state->connectors[i];
> -
> -		if (!connector->obj)
> +	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++) {
> +		if (plane_filter(i)) {
> +			values[i] = 0;
>  			continue;
> -		if (crtc && connector->crtc_id != crtc->obj)
> -			continue;
> -
> -		return connector;
> -	}
> -
> -	return NULL;
> -}
> -
> -static void plane_populate_req(struct kms_atomic_plane_state *plane,
> -			       drmModeAtomicReq *req)
> -{
> -	if (plane->fence_fd)
> -		plane_set_prop(req, plane, IGT_PLANE_IN_FENCE_FD,
> plane->fence_fd);
> -
> -	plane_set_prop(req, plane, IGT_PLANE_CRTC_ID, plane-
> >crtc_id);
> -	plane_set_prop(req, plane, IGT_PLANE_FB_ID, plane->fb_id);
> -	plane_set_prop(req, plane, IGT_PLANE_SRC_X, plane->src_x);
> -	plane_set_prop(req, plane, IGT_PLANE_SRC_Y, plane->src_y);
> -	plane_set_prop(req, plane, IGT_PLANE_SRC_W, plane->src_w);
> -	plane_set_prop(req, plane, IGT_PLANE_SRC_H, plane->src_h);
> -	plane_set_prop(req, plane, IGT_PLANE_CRTC_X, plane->crtc_x);
> -	plane_set_prop(req, plane, IGT_PLANE_CRTC_Y, plane->crtc_y);
> -	plane_set_prop(req, plane, IGT_PLANE_CRTC_W, plane->crtc_w);
> -	plane_set_prop(req, plane, IGT_PLANE_CRTC_H, plane->crtc_h);
> -}
> -
> -static void plane_get_current_state(struct kms_atomic_plane_state
> *plane)
> -{
> -	struct kms_atomic_desc *desc = plane->state->desc;
> -	drmModeObjectPropertiesPtr props;
> -	int i;
> -
> -	props = drmModeObjectGetProperties(desc->fd, plane->obj,
> -					   DRM_MODE_OBJECT_PLANE);
> -	igt_assert(props);
> -
> -	for (i = 0; i < props->count_props; i++) {
> -		uint32_t *prop_ids = desc->props_plane;
> -
> -		if (props->props[i] == prop_ids[IGT_PLANE_CRTC_ID])
> -			plane->crtc_id = props->prop_values[i];
> -		else if (props->props[i] ==
> prop_ids[IGT_PLANE_FB_ID])
> -			plane->fb_id = props->prop_values[i];
> -		else if (props->props[i] ==
> prop_ids[IGT_PLANE_CRTC_X])
> -			plane->crtc_x = props->prop_values[i];
> -		else if (props->props[i] ==
> prop_ids[IGT_PLANE_CRTC_Y])
> -			plane->crtc_y = props->prop_values[i];
> -		else if (props->props[i] ==
> prop_ids[IGT_PLANE_CRTC_W])
> -			plane->crtc_w = props->prop_values[i];
> -		else if (props->props[i] ==
> prop_ids[IGT_PLANE_CRTC_H])
> -			plane->crtc_h = props->prop_values[i];
> -		else if (props->props[i] ==
> prop_ids[IGT_PLANE_SRC_X])
> -			plane->src_x = props->prop_values[i];
> -		else if (props->props[i] ==
> prop_ids[IGT_PLANE_SRC_Y])
> -			plane->src_y = props->prop_values[i];
> -		else if (props->props[i] ==
> prop_ids[IGT_PLANE_SRC_W])
> -			plane->src_w = props->prop_values[i];
> -		else if (props->props[i] ==
> prop_ids[IGT_PLANE_SRC_H])
> -			plane->src_h = props->prop_values[i];
> -		else if (props->props[i] ==
> prop_ids[IGT_PLANE_TYPE]) {
> -			int j;
> -
> -			for (j = 0; j < ARRAY_SIZE(desc-
> >props_plane_type); j++) {
> -				if (props->prop_values[i] == desc-
> >props_plane_type[j]) {
> -					plane->type = j;
> -					break;
> -				}
> -			}
>  		}
> -	}
>  
> -	drmModeFreeObjectProperties(props);
> +		values[i] = igt_plane_get_prop(plane, i);
> +	}
>  }
>  
> -static void plane_check_current_state(struct kms_atomic_plane_state
> *plane,
> +static void plane_check_current_state(igt_plane_t *plane, const
> uint64_t *values,
>  				      enum kms_atomic_check_relax
> relax)
>  {
>  	drmModePlanePtr legacy;
> -	struct kms_atomic_plane_state plane_kernel;
> +	uint64_t current_values[IGT_NUM_PLANE_PROPS];
> +	int i;
>  
> -	legacy = drmModeGetPlane(plane->state->desc->fd, plane-
> >obj);
> +	legacy = drmModeGetPlane(plane->pipe->display->drm_fd,
> plane->drm_plane->plane_id);
>  	igt_assert(legacy);
>  
> -	igt_assert_eq_u32(legacy->crtc_id, plane->crtc_id);
> +	igt_assert_eq_u32(legacy->crtc_id,
> values[IGT_PLANE_CRTC_ID]);
>  
>  	if (!(relax & PLANE_RELAX_FB))
> -		igt_assert_eq_u32(legacy->fb_id, plane->fb_id);
> +		igt_assert_eq_u32(legacy->fb_id,
> values[IGT_PLANE_FB_ID]);
>  
> -	memcpy(&plane_kernel, plane, sizeof(plane_kernel));
> -	plane_get_current_state(&plane_kernel);
> +	plane_get_current_state(plane, current_values);
>  
>  	/* Legacy cursor ioctls create their own, unknowable,
> internal
>  	 * framebuffer which we can't reason about. */
>  	if (relax & PLANE_RELAX_FB)
> -		plane_kernel.fb_id = plane->fb_id;
> -	do_or_die(memcmp(&plane_kernel, plane,
> sizeof(plane_kernel)));
> +		current_values[IGT_PLANE_FB_ID] =
> values[IGT_PLANE_FB_ID];
> +
> +	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++)
> +		if (!plane_filter(i))
> +			igt_assert_eq_u64(current_values[i],
> values[i]);
>  
>  	drmModeFreePlane(legacy);
>  }
>  
> -static void plane_commit_legacy(struct kms_atomic_plane_state
> *plane,
> +static void plane_commit(igt_plane_t *plane, enum igt_commit_style
> s,
>                                  enum kms_atomic_check_relax relax)
>  {
> -	do_or_die(drmModeSetPlane(plane->state->desc->fd, plane-
> >obj,
> -				  plane->crtc_id,
> -				  plane->fb_id, 0,
> -				  plane->crtc_x, plane->crtc_y,
> -				  plane->crtc_w, plane->crtc_h,
> -				  plane->src_x, plane->src_y,
> -				  plane->src_w, plane->src_h));
> -	plane_check_current_state(plane, relax);
> +	igt_display_commit2(plane->pipe->display, s);
> +	plane_check_current_state(plane, plane->values, relax);
>  }
>  
> -static struct kms_atomic_plane_state *
> -find_plane(struct kms_atomic_state *state, enum plane_type type,
> -	   struct kms_atomic_crtc_state *crtc)
> +static void plane_commit_atomic_err(igt_plane_t *plane,
> +				    enum kms_atomic_check_relax
> relax,
> +				    int err)
>  {
> -	struct kms_atomic_plane_state *ret = NULL;
> -	int i;
> -
> -	for (i = 0; i < state->num_planes; i++) {
> -		struct kms_atomic_plane_state *plane = &state-
> >planes[i];
> -
> -		if (!plane->obj)
> -			continue;
> -		if (type != NUM_PLANE_TYPE_PROPS && plane->type !=
> type)
> -			continue;
> -		if (crtc && !(plane->crtc_mask & (1 << crtc->idx)))
> -			continue;
> +	uint64_t current_values[IGT_NUM_PLANE_PROPS];
>  
> -		plane_get_current_state(plane);
> +	plane_get_current_state(plane, current_values);
>  
> -		/* Try to find a plane that's already on this CRTC.
> In
> -		 * particular, this ensures that for special
> (primary/cursor)
> -		 * planes that can be on multiple CRTCs, we find the
> same
> -		 * one that the legacy ioctls will. */
> -		if (!crtc || plane->crtc_id == crtc->obj)
> -			return plane;
> -
> -		ret = plane;
> -	}
> +	igt_assert_eq(-err, igt_display_try_commit2(plane->pipe-
> >display, COMMIT_ATOMIC));
>  
> -	return ret;
> +	plane_check_current_state(plane, current_values, relax);
>  }
>  
> -static void crtc_populate_req(struct kms_atomic_crtc_state *crtc,
> -			      drmModeAtomicReq *req)
> +static bool crtc_filter(enum igt_atomic_crtc_properties prop)
>  {
> -	if (crtc->out_fence_ptr)
> -		crtc_set_prop(req, crtc, IGT_CRTC_OUT_FENCE_PTR,
> -			      to_user_pointer(crtc->out_fence_ptr));
> +	if (prop == IGT_CRTC_MODE_ID || prop == IGT_CRTC_ACTIVE)
> +		return false;
>  
> -	crtc_set_prop(req, crtc, IGT_CRTC_MODE_ID, crtc->mode.id);
> -	crtc_set_prop(req, crtc, IGT_CRTC_ACTIVE, crtc->active);
> +	return true;
>  }
>  
> -static void crtc_get_current_state(struct kms_atomic_crtc_state
> *crtc)
> +static void crtc_get_current_state(igt_pipe_t *pipe, uint64_t
> *values)
>  {
> -	drmModeObjectPropertiesPtr props;
>  	int i;
>  
> -	props = drmModeObjectGetProperties(crtc->state->desc->fd,
> crtc->obj,
> -					   DRM_MODE_OBJECT_CRTC);
> -	igt_assert(props);
> -
> -	for (i = 0; i < props->count_props; i++) {
> -		uint32_t *prop_ids = crtc->state->desc->props_crtc;
> -
> -		if (props->props[i] == prop_ids[IGT_CRTC_MODE_ID]) {
> -			drmModePropertyBlobPtr blob;
> -
> -			crtc->mode.id = props->prop_values[i];
> -			if (!crtc->mode.id) {
> -				crtc->mode.len = 0;
> -				continue;
> -			}
> -
> -			blob = drmModeGetPropertyBlob(crtc->state-
> >desc->fd,
> -						      crtc-
> >mode.id);
> -			igt_assert(blob);
> -			igt_assert_eq_u32(blob->length,
> -					  sizeof(struct
> drm_mode_modeinfo));
> -
> -			if (!crtc->mode.data ||
> -			    memcmp(crtc->mode.data, blob->data,
> blob->length) != 0)
> -				crtc->mode.data = blob->data;
> -			crtc->mode.len = blob->length;
> -		}
> -		else if (props->props[i] ==
> prop_ids[IGT_CRTC_ACTIVE]) {
> -			crtc->active = props->prop_values[i];
> +	for (i = 0; i < IGT_NUM_CRTC_PROPS; i++) {
> +		if (crtc_filter(i)) {
> +			values[i] = 0;
> +			continue;
>  		}
> -	}
>  
> -	drmModeFreeObjectProperties(props);
> +		values[i] = igt_pipe_obj_get_prop(pipe, i);
> +	}
>  }
>  
> -static void crtc_check_current_state(struct kms_atomic_crtc_state
> *crtc,
> -				     struct kms_atomic_plane_state
> *primary,
> +static void crtc_check_current_state(igt_pipe_t *pipe,
> +				     const uint64_t *pipe_values,
> +				     const uint64_t *primary_values,
>  				     enum kms_atomic_check_relax
> relax)
>  {
> -	struct kms_atomic_crtc_state crtc_kernel;
> +	uint64_t current_pipe_values[IGT_NUM_CRTC_PROPS];
>  	drmModeCrtcPtr legacy;
> +	drmModePropertyBlobRes *mode_prop = NULL;
> +	struct drm_mode_modeinfo *mode = NULL;
>  
> -	legacy = drmModeGetCrtc(crtc->state->desc->fd, crtc->obj);
> -	igt_assert(legacy);
> -
> -	igt_assert_eq_u32(legacy->crtc_id, crtc->obj);
> -	igt_assert_eq_u32(legacy->x, primary->src_x >> 16);
> -	igt_assert_eq_u32(legacy->y, primary->src_y >> 16);
> -
> -	if (crtc->active)
> -		igt_assert_eq_u32(legacy->buffer_id, primary-
> >fb_id);
> -	else
> -		igt_assert_eq_u32(legacy->buffer_id, 0);
> +	if (pipe_values[IGT_CRTC_MODE_ID]) {
> +		mode_prop = drmModeGetPropertyBlob(pipe->display-
> >drm_fd,
> +						   pipe_values[IGT_C
> RTC_MODE_ID]);
>  
> -	if (legacy->mode_valid) {
> -		igt_assert_neq(legacy->mode_valid, 0);
> -		igt_assert_eq(crtc->mode.len,
> -		              sizeof(struct drm_mode_modeinfo));
> -		do_or_die(memcmp(&legacy->mode, crtc->mode.data,
> -		                 crtc->mode.len));
> -		igt_assert_eq(legacy->width, legacy->mode.hdisplay);
> -		igt_assert_eq(legacy->height, legacy-
> >mode.vdisplay);
> -	} else {
> -		igt_assert_eq(legacy->mode_valid, 0);
> -	}
> +		igt_assert(mode_prop);
>  
> -	memcpy(&crtc_kernel, crtc, sizeof(crtc_kernel));
> -	crtc_get_current_state(&crtc_kernel);
> -
> -	if (crtc_kernel.mode.id != 0)
> -		igt_assert_eq(crtc_kernel.mode.len,
> +		igt_assert_eq(mode_prop->length,
>  		              sizeof(struct drm_mode_modeinfo));
> -
> -	/* Optionally relax the check for MODE_ID: using the legacy
> SetCrtc
> -	 * API can potentially change MODE_ID even if the mode
> itself remains
> -	 * unchanged. */
> -	if (((relax & CRTC_RELAX_MODE) &&
> -	    (crtc_kernel.mode.id != crtc->mode.id &&
> -	     crtc_kernel.mode.id != 0 && crtc->mode.id != 0)) &&
> -	    memcmp(crtc_kernel.mode.data, crtc->mode.data,
> -		   sizeof(struct drm_mode_modeinfo)) == 0) {
> -		crtc_kernel.mode.id = crtc->mode.id;
> -		crtc_kernel.mode.data = crtc->mode.data;
> -	}
> -
> -	do_or_die(memcmp(&crtc_kernel, crtc, sizeof(crtc_kernel)));
> -
> -	drmModeFreeCrtc(legacy);
> -}
> -
> -static void crtc_commit_legacy(struct kms_atomic_crtc_state *crtc,
> -			       struct kms_atomic_plane_state *plane,
> -			       enum kms_atomic_check_relax relax)
> -{
> -	drmModeObjectPropertiesPtr props;
> -	uint32_t *connectors;
> -	int num_connectors = 0;
> -	int i;
> -
> -	if (!crtc->active) {
> -		do_or_die(drmModeSetCrtc(crtc->state->desc->fd,
> -					 crtc->obj, 0, 0, 0, NULL,
> 0, NULL));
> -		return;
> -	}
> -
> -	connectors = calloc(crtc->state->num_connectors,
> -			    sizeof(*connectors));
> -	igt_assert(connectors);
> -
> -	igt_assert_neq_u32(crtc->mode.id, 0);
> -
> -	for (i = 0; i < crtc->state->num_connectors; i++) {
> -		struct kms_atomic_connector_state *connector =
> -			&crtc->state->connectors[i];
> -
> -		if (connector->crtc_id != crtc->obj)
> -			continue;
> -
> -		connectors[num_connectors++] = connector->obj;
> +		mode = mode_prop->data;
>  	}
>  
> -	do_or_die(drmModeSetCrtc(crtc->state->desc->fd, crtc->obj,
> -	                         plane->fb_id,
> -				 plane->src_x >> 16, plane->src_y >>
> 16,
> -				 (num_connectors) ? connectors :
> NULL,
> -				 num_connectors,
> -				 crtc->mode.data));
> -	/* When doing a legacy commit, the core may update MODE_ID
> to be a new
> -	 * blob implicitly created by the legacy request. Hence we
> backfill
> -	 * the value in the state object to ensure they match. */
> -	props = drmModeObjectGetProperties(crtc->state->desc->fd,
> crtc->obj,
> -					   DRM_MODE_OBJECT_CRTC);
> -	igt_assert(props);
> -
> -	for (i = 0; i < props->count_props; i++) {
> -		if (props->props[i] !=
> -		    crtc->state->desc->props_crtc[IGT_CRTC_MODE_ID])
> -			continue;
> -		crtc->mode.id = props->prop_values[i];
> -		break;
> -	}
> +	legacy = drmModeGetCrtc(pipe->display->drm_fd, pipe-
> >crtc_id);
> +	igt_assert(legacy);
>  
> -	drmModeFreeObjectProperties(props);
> +	igt_assert_eq_u32(legacy->crtc_id, pipe->crtc_id);
> +	igt_assert_eq_u32(legacy->x, primary_values[IGT_PLANE_SRC_X]
> >> 16);
> +	igt_assert_eq_u32(legacy->y, primary_values[IGT_PLANE_SRC_Y]
> >> 16);
>  
> -	crtc_check_current_state(crtc, plane, relax);
> -	plane_check_current_state(plane, relax);
> -}
> +	igt_assert_eq_u32(legacy->buffer_id,
> primary_values[IGT_PLANE_FB_ID]);
>  
> -static struct kms_atomic_crtc_state *find_crtc(struct
> kms_atomic_state *state,
> -					       bool must_be_enabled)
> -{
> -	int i;
> +	if (legacy->mode_valid) {
> +		igt_assert(mode_prop);
>  
> -	for (i = 0; i < state->num_crtcs; i++) {
> -		struct kms_atomic_crtc_state *crtc = &state-
> >crtcs[i];
> +		do_or_die(memcmp(&legacy->mode, mode,
> sizeof(*mode)));
>  
> -		if (!crtc->obj)
> -			continue;
> -		if (must_be_enabled && !crtc->active)
> -			continue;
> +		igt_assert_eq(legacy->width, legacy->mode.hdisplay);
> +		igt_assert_eq(legacy->height, legacy-
> >mode.vdisplay);
>  
> -		crtc_get_current_state(crtc);
> -		return crtc;
> +		igt_assert_neq(pipe_values[IGT_CRTC_MODE_ID], 0);
> +	} else {
> +		igt_assert(!mode_prop);
>  	}
>  
> -	return NULL;
> -}
> +	crtc_get_current_state(pipe, current_pipe_values);
>  
> -static void fill_obj_props(int fd, uint32_t id, int type, int
> num_props,
> -			   const char **prop_names, uint32_t
> *prop_ids)
> -{
> -	drmModeObjectPropertiesPtr props;
> -	int i, j;
> -
> -	props = drmModeObjectGetProperties(fd, id, type);
> -	igt_assert(props);
> +	/* Optionally relax the check for MODE_ID: using the legacy
> SetCrtc
> +	 * API can potentially change MODE_ID even if the mode
> itself remains
> +	 * unchanged. */
> +	if (relax & CRTC_RELAX_MODE && mode &&
> current_pipe_values[IGT_CRTC_MODE_ID] &&
> +	    current_pipe_values[IGT_CRTC_MODE_ID] !=
> pipe_values[IGT_CRTC_MODE_ID]) {
> +		drmModePropertyBlobRes *cur_prop =
> +			drmModeGetPropertyBlob(pipe->display-
> >drm_fd,
> +					       current_pipe_values[I
> GT_CRTC_MODE_ID]);
>  
> -	for (i = 0; i < props->count_props; i++) {
> -		drmModePropertyPtr prop =
> -			drmModeGetProperty(fd, props->props[i]);
> +		igt_assert(cur_prop);
> +		igt_assert_eq(cur_prop->length, sizeof(struct
> drm_mode_modeinfo));
>  
> -		for (j = 0; j < num_props; j++) {
> -			if (strcmp(prop->name, prop_names[j]) != 0)
> -				continue;
> -			prop_ids[j] = props->props[i];
> -			break;
> -		}
> +		if (!memcmp(cur_prop->data, mode, sizeof(*mode)))
> +			current_pipe_values[IGT_CRTC_MODE_ID] =
> pipe_values[IGT_CRTC_MODE_ID];
>  
> -		drmModeFreeProperty(prop);
> +		drmModeFreePropertyBlob(cur_prop);
>  	}
>  
> -	drmModeFreeObjectProperties(props);
> -}
> +	do_or_die(memcmp(pipe_values, current_pipe_values,
> sizeof(current_pipe_values)));
>  
> -static void fill_obj_prop_map(int fd, uint32_t id, int type, const
> char *name,
> -			      int num_enums, const char
> **enum_names,
> -			      uint64_t *enum_ids)
> -{
> -	drmModeObjectPropertiesPtr props;
> -	int i, j, k;
> -
> -	props = drmModeObjectGetProperties(fd, id, type);
> -	igt_assert(props);
> -
> -	for (i = 0; i < props->count_props; i++) {
> -		drmModePropertyPtr prop =
> -			drmModeGetProperty(fd, props->props[i]);
> -
> -		igt_assert(prop);
> -
> -		if (strcmp(prop->name, name) != 0) {
> -			drmModeFreeProperty(prop);
> -			continue;
> -		}
> -
> -		for (j = 0; j < prop->count_enums; j++) {
> -			struct drm_mode_property_enum *e = &prop-
> >enums[j];
> -
> -			for (k = 0; k < num_enums; k++) {
> -				if (strcmp(e->name, enum_names[k])
> != 0)
> -					continue;
> -
> -				enum_ids[k] = e->value;
> -				break;
> -			}
> -		}
> -
> -		drmModeFreeProperty(prop);
> -	}
> +	drmModeFreeCrtc(legacy);
> +	drmModeFreePropertyBlob(mode_prop);
>  }
>  
> -static void atomic_setup(struct kms_atomic_state *state)
> +static void crtc_commit(igt_pipe_t *pipe, igt_plane_t *plane,
> +			enum igt_commit_style s,
> +			enum kms_atomic_check_relax relax)
>  {
> -	struct kms_atomic_desc *desc = state->desc;
> -	drmModeResPtr res;
> -	drmModePlaneResPtr res_plane;
> -	int i;
> -
> -	desc->fd = drm_open_driver_master(DRIVER_ANY);
> -	igt_assert_fd(desc->fd);
> -
> -	igt_skip_on(drmSetClientCap(desc->fd, DRM_CLIENT_CAP_ATOMIC,
> 1));
> -
> -	res = drmModeGetResources(desc->fd);
> -	res_plane = drmModeGetPlaneResources(desc->fd);
> -	igt_assert(res);
> -	igt_assert(res_plane);
> -
> -	igt_assert_lt(0, res->count_crtcs);
> -	state->num_crtcs = res->count_crtcs;
> -	state->crtcs = calloc(state->num_crtcs, sizeof(*state-
> >crtcs));
> -	igt_assert(state->crtcs);
> -
> -	igt_assert_lt(0, res_plane->count_planes);
> -	state->num_planes = res_plane->count_planes;
> -	state->planes = calloc(state->num_planes, sizeof(*state-
> >planes));
> -	igt_assert(state->planes);
> -
> -	igt_assert_lt(0, res->count_connectors);
> -	state->num_connectors = res->count_connectors;
> -	state->connectors = calloc(state->num_connectors,
> -				   sizeof(*state->connectors));
> -	igt_assert(state->connectors);
> -
> -	fill_obj_props(desc->fd, res->crtcs[0],
> -		       DRM_MODE_OBJECT_CRTC, IGT_NUM_CRTC_PROPS,
> -		       igt_crtc_prop_names, desc->props_crtc);
> -
> -	fill_obj_props(desc->fd, res_plane->planes[0],
> -		       DRM_MODE_OBJECT_PLANE, IGT_NUM_PLANE_PROPS,
> -		       igt_plane_prop_names, desc->props_plane);
> -	fill_obj_prop_map(desc->fd, res_plane->planes[0],
> -			  DRM_MODE_OBJECT_PLANE, "type",
> -			  NUM_PLANE_TYPE_PROPS,
> plane_type_prop_names,
> -			  desc->props_plane_type);
> -
> -	fill_obj_props(desc->fd, res->connectors[0],
> -		       DRM_MODE_OBJECT_CONNECTOR,
> IGT_NUM_CONNECTOR_PROPS,
> -		       igt_connector_prop_names, desc-
> >props_connector);
> -
> -	for (i = 0; i < state->num_crtcs; i++) {
> -		struct kms_atomic_crtc_state *crtc = &state-
> >crtcs[i];
> -
> -		crtc->state = state;
> -		crtc->obj = res->crtcs[i];
> -		crtc->idx = i;
> -		crtc_get_current_state(crtc);
> -
> -		/* The blob pointed to by MODE_ID could well be
> transient,
> -		 * and lose its last reference as we switch away
> from it.
> -		 * Duplicate the blob here so we have a reference we
> know we
> -		 * own. */
> -		if (crtc->mode.id != 0)
> -		    crtc->mode.id = blob_duplicate(desc->fd, crtc-
> >mode.id);
> -	}
> +	igt_display_commit2(pipe->display, s);
>  
> -	for (i = 0; i < state->num_planes; i++) {
> -		drmModePlanePtr plane =
> -			drmModeGetPlane(desc->fd, res_plane-
> >planes[i]);
> -		igt_assert(plane);
> -
> -		state->planes[i].state = state;
> -		state->planes[i].obj = res_plane->planes[i];
> -		state->planes[i].crtc_mask = plane->possible_crtcs;
> -		plane_get_current_state(&state->planes[i]);
> -	}
> -
> -	for (i = 0; i < state->num_connectors; i++) {
> -		state->connectors[i].state = state;
> -		state->connectors[i].obj = res->connectors[i];
> -		connector_get_current_state(&state->connectors[i]);
> -	}
> -
> -	drmModeFreePlaneResources(res_plane);
> -	drmModeFreeResources(res);
> +	crtc_check_current_state(pipe, pipe->values, plane->values,
> relax);
> +	plane_check_current_state(plane, plane->values, relax);
>  }
>  
> -static struct kms_atomic_state *
> -atomic_state_dup(const struct kms_atomic_state *state)
> +static void crtc_commit_atomic_flags_err(igt_pipe_t *pipe,
> igt_plane_t *plane,
> +					 unsigned flags,
> +					 enum kms_atomic_check_relax
> relax,
> +					 int err)
>  {
> -	struct kms_atomic_state *ret = calloc(1, sizeof(*ret));
> -
> -	igt_assert(ret);
> -	*ret = *state;
> +	uint64_t current_pipe_values[IGT_NUM_CRTC_PROPS];
> +	uint64_t current_plane_values[IGT_NUM_PLANE_PROPS];
>  
> -	ret->crtcs = calloc(ret->num_crtcs, sizeof(*ret->crtcs));
> -	igt_assert(ret->crtcs);
> -	memcpy(ret->crtcs, state->crtcs, ret->num_crtcs *
> sizeof(*ret->crtcs));
> +	crtc_get_current_state(pipe, current_pipe_values);
> +	plane_get_current_state(plane, current_plane_values);
>  
> -	ret->planes = calloc(ret->num_planes, sizeof(*ret->planes));
> -	igt_assert(ret->planes);
> -	memcpy(ret->planes, state->planes,
> -	       ret->num_planes * sizeof(*ret->planes));
> +	igt_assert_eq(-err, igt_display_try_commit_atomic(pipe-
> >display, flags, NULL));
>  
> -	ret->connectors = calloc(ret->num_connectors, sizeof(*ret-
> >connectors));
> -	igt_assert(ret->connectors);
> -	memcpy(ret->connectors, state->connectors,
> -	       ret->num_connectors * sizeof(*ret->connectors));
> -
> -	return ret;
> +	crtc_check_current_state(pipe, current_pipe_values,
> current_plane_values, relax);
> +	plane_check_current_state(plane, current_plane_values,
> relax);
>  }
>  
> -static void atomic_state_free(struct kms_atomic_state *state)
> -{
> -	free(state->crtcs);
> -	free(state->planes);
> -	free(state->connectors);
> -	free(state);
> -}
> +#define crtc_commit_atomic_err(pipe, plane, relax, err) \
> +	crtc_commit_atomic_flags_err(pipe, plane,
> DRM_MODE_ATOMIC_ALLOW_MODESET, relax, err)
>  
> -static uint32_t plane_get_igt_format(struct kms_atomic_plane_state
> *plane)
> +static uint32_t plane_get_igt_format(igt_plane_t *plane)
>  {
>  	drmModePlanePtr plane_kms;
>  	const uint32_t *igt_formats;
> -	uint32_t ret = 0;
>  	int num_igt_formats;
>  	int i;
>  
> -	plane_kms = drmModeGetPlane(plane->state->desc->fd, plane-
> >obj);
> -	igt_assert(plane_kms);
> +	plane_kms = plane->drm_plane;
>  
>  	igt_get_all_cairo_formats(&igt_formats, &num_igt_formats);
>  	for (i = 0; i < num_igt_formats; i++) {
>  		int j;
>  
>  		for (j = 0; j < plane_kms->count_formats; j++) {
> -			if (plane_kms->formats[j] == igt_formats[i])
> {
> -				ret = plane_kms->formats[j];
> -				break;
> -			}
> +			if (plane_kms->formats[j] == igt_formats[i])
> +				return plane_kms->formats[j];
>  		}
>  	}
>  
> -	drmModeFreePlane(plane_kms);
> -	return ret;
> +	return 0;
>  }
>  
>  static void
> -set_dpms(int fd, int mode)
> +set_dpms(igt_output_t *output, int mode)
>  {
> -	int i;
> -	drmModeConnector *connector;
> -	uint32_t id;
> -	drmModeRes *resources = drmModeGetResources(fd);
> -
> -	for (i = 0; i < resources->count_connectors; i++) {
> -		id = resources->connectors[i];
> -
> -		connector = drmModeGetConnectorCurrent(fd, id);
> -
> -		kmstest_set_connector_dpms(fd, connector, mode);
> -
> -		drmModeFreeConnector(connector);
> -	}
> +	do_or_die(drmModeConnectorSetProperty(output->display-
> >drm_fd, output->id,
> +					      output-
> >props[IGT_CONNECTOR_DPMS], mode));
>  }
>  
> -static void plane_overlay(struct kms_atomic_crtc_state *crtc,
> -			  struct kms_atomic_plane_state *plane_old)
> +static void plane_overlay(igt_pipe_t *pipe, igt_output_t *output,
> igt_plane_t *plane)
>  {
> -	struct drm_mode_modeinfo *mode = crtc->mode.data;
> -	struct kms_atomic_plane_state plane = *plane_old;
> -	uint32_t format = plane_get_igt_format(&plane);
> -	drmModeAtomicReq *req = drmModeAtomicAlloc();
> +	drmModeModeInfo *mode = igt_output_get_mode(output);
> +	uint32_t format = plane_get_igt_format(plane);
>  	struct igt_fb fb;
> +	uint32_t w = mode->hdisplay / 2;
> +	uint32_t h = mode->vdisplay / 2;
>  
> -	igt_require(req);
>  	igt_require(format != 0);
>  
> -	plane.src_x = 0;
> -	plane.src_y = 0;
> -	plane.src_w = (mode->hdisplay / 2) << 16;
> -	plane.src_h = (mode->vdisplay / 2) << 16;
> -	plane.crtc_x = mode->hdisplay / 4;
> -	plane.crtc_y = mode->vdisplay / 4;
> -	plane.crtc_w = mode->hdisplay / 2;
> -	plane.crtc_h = mode->vdisplay / 2;
> -	plane.crtc_id = crtc->obj;
> -	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
> -					    plane.crtc_w,
> plane.crtc_h,
> -					    format,
> I915_TILING_NONE, &fb);
> +	igt_create_pattern_fb(pipe->display->drm_fd, w, h,
> +			      format, I915_TILING_NONE, &fb);
> +
> +	igt_plane_set_fb(plane, &fb);
> +	igt_plane_set_position(plane, w/2, h/2);
>  
>  	/* Enable the overlay plane using the atomic API, and
> double-check
>  	 * state is what we think it should be. */
> -	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
> +	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>  
>  	/* Disable the plane and check the state matches the old. */
> -	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
> +	igt_plane_set_fb(plane, NULL);
> +	igt_plane_set_position(plane, 0, 0);
> +	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>  
>  	/* Re-enable the plane through the legacy plane API, and
> verify through
>  	 * atomic. */
> -	plane_commit_legacy(&plane, ATOMIC_RELAX_NONE);
> +	igt_plane_set_fb(plane, &fb);
> +	igt_plane_set_position(plane, w/2, h/2);
> +	plane_commit(plane, COMMIT_LEGACY, ATOMIC_RELAX_NONE);
>  
>  	/* Restore the plane to its original settings through the
> legacy plane
>  	 * API, and verify through atomic. */
> -	plane_commit_legacy(plane_old, ATOMIC_RELAX_NONE);
> +	igt_plane_set_fb(plane, NULL);
> +	igt_plane_set_position(plane, 0, 0);
> +	plane_commit(plane, COMMIT_LEGACY, ATOMIC_RELAX_NONE);
>  
> -	drmModeAtomicFree(req);
> +	igt_remove_fb(pipe->display->drm_fd, &fb);
>  }
>  
> -static void plane_primary(struct kms_atomic_crtc_state *crtc,
> -			  struct kms_atomic_plane_state *plane_old)
> +static void plane_primary(igt_pipe_t *pipe, igt_plane_t *plane,
> struct igt_fb *fb)
>  {
> -	struct drm_mode_modeinfo *mode = crtc->mode.data;
> -	struct kms_atomic_plane_state plane = *plane_old;
> -	uint32_t format = plane_get_igt_format(&plane);
> -	drmModeAtomicReq *req = drmModeAtomicAlloc();
> -	struct igt_fb fb;
> -	uint32_t flags = 0;
> -	int ret;
> -
> -	igt_require(format != 0);
> +	struct igt_fb fb2;
>  
> -	plane.src_x = 0;
> -	plane.src_y = 0;
> -	plane.src_w = mode->hdisplay << 16;
> -	plane.src_h = mode->vdisplay << 16;
> -	plane.crtc_x = 0;
> -	plane.crtc_y = 0;
> -	plane.crtc_w = mode->hdisplay;
> -	plane.crtc_h = mode->vdisplay;
> -	plane.crtc_id = crtc->obj;
> -	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
> -					    plane.crtc_w,
> plane.crtc_h,
> -					    format,
> I915_TILING_NONE, &fb);
> -
> -	drmModeAtomicSetCursor(req, 0);
> -	crtc_populate_req(crtc, req);
> -	plane_populate_req(&plane, req);
> -	ret = drmModeAtomicCommit(crtc->state->desc->fd, req,
> -				  DRM_MODE_ATOMIC_TEST_ONLY, NULL);
> -	/* Try harder in case the failure is caused by disallowing
> modeset. */
> -	if (ret == -EINVAL)
> -		flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
> +	igt_create_color_pattern_fb(pipe->display->drm_fd,
> +				    fb->width, fb->height,
> +				    fb->drm_format,
> I915_TILING_NONE,
> +				    0.2, 0.2, 0.2, &fb2);
>  
>  	/* Flip the primary plane using the atomic API, and double-
> check
>  	 * state is what we think it should be. */
> -	crtc_commit_atomic(crtc, &plane, req, ATOMIC_RELAX_NONE,
> flags);
> +	igt_plane_set_fb(plane, &fb2);
> +	crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>  
>  	/* Restore the primary plane and check the state matches the
> old. */
> -	crtc_commit_atomic(crtc, plane_old, req, ATOMIC_RELAX_NONE,
> flags);
> +	igt_plane_set_fb(plane, fb);
> +	crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>  
> -	/* Re-enable the plane through the legacy CRTC/primary-plane 
> API, and
> +	/* Set the plane through the legacy CRTC/primary-plane API,
> and
>  	 * verify through atomic. */
> -	crtc_commit_legacy(crtc, &plane, CRTC_RELAX_MODE);
> +	igt_plane_set_fb(plane, &fb2);
> +	crtc_commit(pipe, plane, COMMIT_LEGACY, CRTC_RELAX_MODE);
>  
>  	/* Restore the plane to its original settings through the
> legacy CRTC
>  	 * API, and verify through atomic. */
> -	crtc_commit_legacy(crtc, plane_old, CRTC_RELAX_MODE);
> -
> -	/* Finally, restore to the original state. */
> -	crtc_commit_atomic(crtc, plane_old, req, ATOMIC_RELAX_NONE,
> flags);
> +	igt_plane_set_fb(plane, fb);
> +	crtc_commit(pipe, plane, COMMIT_LEGACY, CRTC_RELAX_MODE);
>  
> -	drmModeAtomicFree(req);
> +	/* Set the plane through the universal setplane API, and
> +	 * verify through atomic. */
> +	igt_plane_set_fb(plane, &fb2);
> +	plane_commit(plane, COMMIT_UNIVERSAL, ATOMIC_RELAX_NONE);
>  }
>  
>  /* test to ensure that DRM_MODE_ATOMIC_TEST_ONLY really only touches
> the
>   * free-standing state objects and nothing else.
>   */
> -static void test_only(struct kms_atomic_crtc_state *crtc,
> -		      struct kms_atomic_plane_state *plane_old)
> +static void test_only(igt_pipe_t *pipe_obj,
> +		      igt_plane_t *primary,
> +		      igt_output_t *output)
>  {
> -	struct drm_mode_modeinfo *mode = crtc->mode.data;
> -	struct kms_atomic_plane_state plane = *plane_old;
> -	uint32_t format = plane_get_igt_format(&plane);
> -	drmModeAtomicReq *req = drmModeAtomicAlloc();
> +	drmModeModeInfo *mode = igt_output_get_mode(output);
> +	uint32_t format = plane_get_igt_format(primary);
>  	struct igt_fb fb;
> -	int ret;
> +	uint64_t old_plane_values[IGT_NUM_PLANE_PROPS],
> old_crtc_values[IGT_NUM_CRTC_PROPS];
>  
>  	igt_require(format != 0);
>  
> -	plane.src_x = 0;
> -	plane.src_y = 0;
> -	plane.src_w = mode->hdisplay << 16;
> -	plane.src_h = mode->vdisplay << 16;
> -	plane.crtc_x = 0;
> -	plane.crtc_y = 0;
> -	plane.crtc_w = mode->hdisplay;
> -	plane.crtc_h = mode->vdisplay;
> -	plane.crtc_id = crtc->obj;
> -	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
> -					    plane.crtc_w,
> plane.crtc_h,
> -					    format,
> I915_TILING_NONE, &fb);
> -
> -	drmModeAtomicSetCursor(req, 0);
> -	crtc_populate_req(crtc, req);
> -	plane_populate_req(&plane, req);
> -	ret = drmModeAtomicCommit(crtc->state->desc->fd, req,
> -				  DRM_MODE_ATOMIC_TEST_ONLY, NULL);
> -
> -	igt_assert_eq(ret, 0);
> -
> -	/* go through dpms off/on cycle */
> -	set_dpms(crtc->state->desc->fd, DRM_MODE_DPMS_OFF);
> -	set_dpms(crtc->state->desc->fd, DRM_MODE_DPMS_ON);
> -
> -	/* check the state */
> -	crtc_check_current_state(crtc, plane_old,
> ATOMIC_RELAX_NONE);
> -	plane_check_current_state(plane_old, ATOMIC_RELAX_NONE);
> -
> -	/* Re-enable the plane through the legacy CRTC/primary-plane 
> API, and
> -	 * verify through atomic. */
> -	crtc_commit_legacy(crtc, plane_old, CRTC_RELAX_MODE);
> +	plane_get_current_state(primary, old_plane_values);
> +	crtc_get_current_state(pipe_obj, old_crtc_values);
> +
> +	igt_assert(!old_crtc_values[IGT_CRTC_MODE_ID]);
> +
> +	igt_create_pattern_fb(pipe_obj->display->drm_fd,
> +			     mode->hdisplay, mode->vdisplay,
> +			     format, I915_TILING_NONE, &fb);
> +	igt_plane_set_fb(primary, &fb);
> +	igt_output_set_pipe(output, pipe_obj->pipe);
> +
> +	igt_display_commit_atomic(pipe_obj->display,
> DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
> +
> +	/* check the state, should still be old state */
> +	crtc_check_current_state(pipe_obj, old_crtc_values,
> old_plane_values, ATOMIC_RELAX_NONE);
> +	plane_check_current_state(primary, old_plane_values,
> ATOMIC_RELAX_NONE);
> +
> +	/*
> +	 * Enable the plane through the legacy CRTC/primary-plane
> API, and
> +	 * verify through atomic.
> +	 */
> +	crtc_commit(pipe_obj, primary, COMMIT_LEGACY,
> CRTC_RELAX_MODE);
> +
> +	/* Same for disable.. */
> +	plane_get_current_state(primary, old_plane_values);
> +	crtc_get_current_state(pipe_obj, old_crtc_values);
> +
> +	igt_plane_set_fb(primary, NULL);
> +	igt_output_set_pipe(output, PIPE_NONE);
> +
> +	igt_display_commit_atomic(pipe_obj->display,
> DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
>  
> -	drmModeAtomicFree(req);
> +	/* for extra stress, go through dpms off/on cycle */
> +	set_dpms(output, DRM_MODE_DPMS_OFF);
> +	set_dpms(output, DRM_MODE_DPMS_ON);
There is this library function 'kmstest_set_connector_dpms()'. Could we
utilize this function here instead?

> +
> +	/* check the state, should still be old state */
> +	crtc_check_current_state(pipe_obj, old_crtc_values,
> old_plane_values, ATOMIC_RELAX_NONE);
> +	plane_check_current_state(primary, old_plane_values,
> ATOMIC_RELAX_NONE);
> +
> +	/* And disable the pipe and remove fb, test complete */
> +	crtc_commit(pipe_obj, primary, COMMIT_ATOMIC,
> ATOMIC_RELAX_NONE);
> +	igt_remove_fb(pipe_obj->display->drm_fd, &fb);
>  }
>  
> -static void plane_cursor(struct kms_atomic_crtc_state *crtc,
> -			 struct kms_atomic_plane_state *plane_old)
> +static void plane_cursor(igt_pipe_t *pipe_obj,
> +			 igt_output_t *output,
> +			 igt_plane_t *cursor)
>  {
> -	struct drm_mode_modeinfo *mode = crtc->mode.data;
> -	struct kms_atomic_plane_state plane = *plane_old;
> -	drmModeAtomicReq *req = drmModeAtomicAlloc();
> +	drmModeModeInfo *mode = igt_output_get_mode(output);
>  	struct igt_fb fb;
>  	uint64_t width, height;
> -
> -	igt_assert(req);
> +	int x = mode->hdisplay / 2;
> +	int y = mode->vdisplay / 2;
>  
>  	/* Any kernel new enough for atomic, also has the cursor
> size caps. */
> -	do_or_die(drmGetCap(plane.state->desc->fd,
> +	do_or_die(drmGetCap(pipe_obj->display->drm_fd,
>  	                    DRM_CAP_CURSOR_WIDTH, &width));
> -	do_or_die(drmGetCap(plane.state->desc->fd,
> +	do_or_die(drmGetCap(pipe_obj->display->drm_fd,
>  	                    DRM_CAP_CURSOR_HEIGHT, &height));
>  
> -	plane.src_x = 0;
> -	plane.src_y = 0;
> -	plane.src_w = width << 16;
> -	plane.src_h = height << 16;
> -	plane.crtc_x = mode->hdisplay / 2;
> -	plane.crtc_y = mode->vdisplay / 2;
> -	plane.crtc_w = width;
> -	plane.crtc_h = height;
> -	plane.crtc_id = crtc->obj;
> -	plane.fb_id = igt_create_color_fb(plane.state->desc->fd,
> -					  width, height,
> -					  DRM_FORMAT_ARGB8888,
> -					  LOCAL_DRM_FORMAT_MOD_NONE,
> -					  0.0, 0.0, 0.0,
> -					  &fb);
> -	igt_assert_neq_u32(plane.fb_id, 0);
> +	igt_create_color_fb(pipe_obj->display->drm_fd,
> +			    width, height, DRM_FORMAT_ARGB8888,
> +			    LOCAL_DRM_FORMAT_MOD_NONE,
> +			    0.0, 0.0, 0.0, &fb);
>  
>  	/* Flip the cursor plane using the atomic API, and double-
> check
>  	 * state is what we think it should be. */
> -	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
> +	igt_plane_set_fb(cursor, &fb);
> +	igt_plane_set_position(cursor, x, y);
> +	plane_commit(cursor, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>  
>  	/* Restore the cursor plane and check the state matches the
> old. */
> -	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
> +	igt_plane_set_fb(cursor, NULL);
> +	igt_plane_set_position(cursor, 0, 0);
> +	plane_commit(cursor, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>  
>  	/* Re-enable the plane through the legacy cursor API, and
> verify
>  	 * through atomic. */
> -	do_or_die(drmModeMoveCursor(plane.state->desc->fd,
> plane.crtc_id,
> -				    plane.crtc_x, plane.crtc_y));
> -	do_or_die(drmModeSetCursor(plane.state->desc->fd,
> plane.crtc_id,
> -				   fb.gem_handle, width, height));
> -	plane_check_current_state(&plane, PLANE_RELAX_FB);
> +	igt_plane_set_fb(cursor, &fb);
> +	igt_plane_set_position(cursor, x, y);
> +	plane_commit(cursor, COMMIT_LEGACY, PLANE_RELAX_FB);
>  
>  	/* Wiggle. */
> -	plane.crtc_x -= 16;
> -	plane.crtc_y -= 16;
> -	do_or_die(drmModeMoveCursor(plane.state->desc->fd,
> plane.crtc_id,
> -				    plane.crtc_x, plane.crtc_y));
> -	plane_check_current_state(&plane, PLANE_RELAX_FB);
> +	igt_plane_set_position(cursor, x - 16, y - 16);
> +	plane_commit(cursor, COMMIT_LEGACY, PLANE_RELAX_FB);
>  
>  	/* Restore the plane to its original settings through the
> legacy cursor
>  	 * API, and verify through atomic. */
> -	do_or_die(drmModeSetCursor2(plane.state->desc->fd,
> plane.crtc_id,
> -				    0, 0, 0, 0, 0));
> -	plane_check_current_state(plane_old, ATOMIC_RELAX_NONE);
> -
> -	/* Finally, restore to the original state. */
> -	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
> -
> -	drmModeAtomicFree(req);
> +	igt_plane_set_fb(cursor, NULL);
> +	igt_plane_set_position(cursor, 0, 0);
> +	plane_commit(cursor, COMMIT_LEGACY, ATOMIC_RELAX_NONE);
>  }
>  
> -static void plane_invalid_params(struct kms_atomic_crtc_state *crtc,
> -				 struct kms_atomic_plane_state
> *plane_old,
> -				 struct kms_atomic_connector_state
> *conn)
> +static void plane_invalid_params(igt_pipe_t *pipe,
> +				 igt_output_t *output,
> +				 igt_plane_t *plane,
> +				 struct igt_fb *fb)
>  {
> -	struct drm_mode_modeinfo *mode = crtc->mode.data;
> -	struct kms_atomic_plane_state plane = *plane_old;
> -	uint32_t format = plane_get_igt_format(&plane);
> -	drmModeAtomicReq *req = drmModeAtomicAlloc();
> -	struct igt_fb fb;
> +	struct igt_fb fb2;
>  
>  	/* Pass a series of invalid object IDs for the FB ID. */
> -	plane.fb_id = plane.obj;
> -	plane_commit_atomic_err(&plane, plane_old, req,
> -	                        ATOMIC_RELAX_NONE, EINVAL);
> +	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, plane-
> >drm_plane->plane_id);
> +	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
>  
> -	plane.fb_id = crtc->obj;
> -	plane_commit_atomic_err(&plane, plane_old, req,
> -	                        ATOMIC_RELAX_NONE, EINVAL);
> +	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, pipe-
> >crtc_id);
> +	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
>  
> -	plane.fb_id = conn->obj;
> -	plane_commit_atomic_err(&plane, plane_old, req,
> -	                        ATOMIC_RELAX_NONE, EINVAL);
> +	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, output-
> >id);
> +	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
>  
> -	plane.fb_id = crtc->mode.id;
> -	plane_commit_atomic_err(&plane, plane_old, req,
> -	                        ATOMIC_RELAX_NONE, EINVAL);
> +	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, pipe-
> >values[IGT_CRTC_MODE_ID]);
> +	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
>  
> -	plane.fb_id = plane_old->fb_id;
> -	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
> +	igt_plane_set_fb(plane, fb);
> +	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>  
>  	/* Pass a series of invalid object IDs for the CRTC ID. */
> -	plane.crtc_id = plane.obj;
> -	plane_commit_atomic_err(&plane, plane_old, req,
> -	                        ATOMIC_RELAX_NONE, EINVAL);
> +	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, plane-
> >drm_plane->plane_id);
> +	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
>  
> -	plane.crtc_id = plane.fb_id;
> -	plane_commit_atomic_err(&plane, plane_old, req,
> -	                        ATOMIC_RELAX_NONE, EINVAL);
> +	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, fb-
> >fb_id);
> +	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
>  
> -	plane.crtc_id = conn->obj;
> -	plane_commit_atomic_err(&plane, plane_old, req,
> -	                        ATOMIC_RELAX_NONE, EINVAL);
> +	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, output-
> >id);
> +	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
>  
> -	plane.crtc_id = crtc->mode.id;
> -	plane_commit_atomic_err(&plane, plane_old, req,
> -	                        ATOMIC_RELAX_NONE, EINVAL);
> +	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, pipe-
> >values[IGT_CRTC_MODE_ID]);
> +	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
>  
> -	plane.crtc_id = plane_old->crtc_id;
> -	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
> +	igt_plane_set_fb(plane, fb);
> +	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>  
>  	/* Create a framebuffer too small for the plane
> configuration. */
> -	igt_require(format != 0);
> +	igt_create_pattern_fb(pipe->display->drm_fd,
> +			      fb->width - 1, fb->height - 1,
> +			      fb->drm_format, I915_TILING_NONE,
> &fb2);
>  
> -	plane.src_x = 0;
> -	plane.src_y = 0;
> -	plane.src_w = mode->hdisplay << 16;
> -	plane.src_h = mode->vdisplay << 16;
> -	plane.crtc_x = 0;
> -	plane.crtc_y = 0;
> -	plane.crtc_w = mode->hdisplay;
> -	plane.crtc_h = mode->vdisplay;
> -	plane.crtc_id = crtc->obj;
> -	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
> -					    plane.crtc_w - 1,
> plane.crtc_h - 1,
> -					    format,
> I915_TILING_NONE, &fb);
> -
> -	plane_commit_atomic_err(&plane, plane_old, req,
> -	                        ATOMIC_RELAX_NONE, ENOSPC);
> +	igt_plane_set_prop_value(plane, IGT_PLANE_FB_ID, fb2.fb_id);
> +	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, ENOSPC);
>  
>  	/* Restore the primary plane and check the state matches the
> old. */
> -	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
> -
> -	drmModeAtomicFree(req);
> +	igt_plane_set_fb(plane, fb);
> +	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>  }
>  
> -static void plane_invalid_params_fence(struct kms_atomic_crtc_state
> *crtc,
> -				struct kms_atomic_plane_state
> *plane_old,
> -				struct kms_atomic_connector_state
> *conn)
> +static void plane_invalid_params_fence(igt_pipe_t *pipe,
> +				       igt_output_t *output,
> +				       igt_plane_t *plane)
>  {
> -	struct kms_atomic_plane_state plane = *plane_old;
> -	drmModeAtomicReq *req = drmModeAtomicAlloc();
>  	int timeline, fence_fd;
>  
>  	igt_require_sw_sync();
>  
> +	timeline = sw_sync_timeline_create();
> +
>  	/* invalid fence fd */
> -	plane.fence_fd = plane.state->desc->fd;
> -	plane.crtc_id = plane_old->crtc_id;
> -	plane_commit_atomic_err(&plane, plane_old, req,
> -	                        ATOMIC_RELAX_NONE, EINVAL);
> +	igt_plane_set_fence_fd(plane, pipe->display->drm_fd);
> +	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
>  
>  	/* Valid fence_fd but invalid CRTC */
> -	timeline = sw_sync_timeline_create();
> -	fence_fd =  sw_sync_timeline_create_fence(timeline, 1);
> -	plane.fence_fd = fence_fd;
> -	plane.crtc_id = ~0U;
> -	plane_commit_atomic_err(&plane, plane_old, req,
> -	                        ATOMIC_RELAX_NONE, EINVAL);
> +	fence_fd = sw_sync_timeline_create_fence(timeline, 1);
> +
> +	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, ~0);
> +	igt_plane_set_fence_fd(plane, fence_fd);
> +	plane_commit_atomic_err(plane, ATOMIC_RELAX_NONE, EINVAL);
> +
> +	sw_sync_timeline_inc(timeline, 1);
> +	igt_plane_set_prop_value(plane, IGT_PLANE_CRTC_ID, pipe-
> >crtc_id);
> +	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>  
> -	plane.fence_fd = -1;
>  	close(fence_fd);
>  	close(timeline);
> -
> -	drmModeAtomicFree(req);
>  }
>  
> -static void crtc_invalid_params(struct kms_atomic_crtc_state
> *crtc_old,
> -				struct kms_atomic_plane_state
> *plane,
> -				struct kms_atomic_connector_state
> *conn)
> +static void crtc_invalid_params(igt_pipe_t *pipe,
> +				igt_output_t *output,
> +				igt_plane_t *plane,
> +				struct igt_fb *fb)
>  {
> -	struct kms_atomic_crtc_state crtc = *crtc_old;
> -	drmModeAtomicReq *req = drmModeAtomicAlloc();
> -
> -	igt_assert(req);
> +	uint64_t old_mode_id = pipe->values[IGT_CRTC_MODE_ID];
> +	drmModeModeInfo *mode = igt_output_get_mode(output);
>  
>  	/* Pass a series of invalid object IDs for the mode ID. */
> -	crtc.mode.id = plane->obj;
> -	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
> 0,
> -	                       ATOMIC_RELAX_NONE, EINVAL);
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, plane-
> >drm_plane->plane_id);
> +	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE,
> EINVAL);
>  
> -	crtc.mode.id = crtc.obj;
> -	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
> 0,
> -	                       ATOMIC_RELAX_NONE, EINVAL);
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, pipe-
> >crtc_id);
> +	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE,
> EINVAL);
>  
> -	crtc.mode.id = conn->obj;
> -	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
> 0,
> -	                       ATOMIC_RELAX_NONE, EINVAL);
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, output-
> >id);
> +	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE,
> EINVAL);
>  
> -	crtc.mode.id = plane->fb_id;
> -	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
> 0,
> -	                       ATOMIC_RELAX_NONE, EINVAL);
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, fb-
> >fb_id);
> +	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE,
> EINVAL);
>  
> -	/* successful TEST_ONLY with fences set */
> -	crtc.mode.id = crtc_old->mode.id;
> -	crtc_commit_atomic(&crtc, plane, req, ATOMIC_RELAX_NONE,
> -			   DRM_MODE_ATOMIC_TEST_ONLY);
> +	/* Can we restore mode? */
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID,
> old_mode_id);
> +	crtc_commit_atomic_flags_err(pipe, plane,
> DRM_MODE_ATOMIC_TEST_ONLY, ATOMIC_RELAX_NONE, 0);
>  
>  	/*
>  	 * TEST_ONLY cannot be combined with
> DRM_MODE_PAGE_FLIP_EVENT,
>  	 * but DRM_MODE_PAGE_FLIP_EVENT will always generate EINVAL
>  	 * without valid crtc, so test it here.
>  	 */
> -	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
> -			       DRM_MODE_ATOMIC_TEST_ONLY |
> DRM_MODE_PAGE_FLIP_EVENT,
> -			       ATOMIC_RELAX_NONE, EINVAL);
> +	crtc_commit_atomic_flags_err(pipe, plane,
> +				     DRM_MODE_ATOMIC_TEST_ONLY |
> DRM_MODE_PAGE_FLIP_EVENT,
> +				     ATOMIC_RELAX_NONE, EINVAL);
>  
>  	/* Create a blob which is the wrong size to be a valid mode.
> */
> -	do_or_die(drmModeCreatePropertyBlob(crtc.state->desc->fd,
> -					    crtc.mode.data,
> -					    sizeof(struct
> drm_mode_modeinfo) - 1,
> -					    &crtc.mode.id));
> -	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
> 0,
> -	                       ATOMIC_RELAX_NONE, EINVAL);
> +	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, mode,
> sizeof(*mode) - 1);
> +	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE,
> EINVAL);
>  
> -
> -	do_or_die(drmModeCreatePropertyBlob(crtc.state->desc->fd,
> -					    crtc.mode.data,
> -					    sizeof(struct
> drm_mode_modeinfo) + 1,
> -					    &crtc.mode.id));
> -	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
> 0,
> -	                       ATOMIC_RELAX_NONE, EINVAL);
> +	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, mode,
> sizeof(*mode) + 1);
> +	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE,
> EINVAL);
>  
>  
>  	/* Restore the CRTC and check the state matches the old. */
> -	crtc_commit_atomic(crtc_old, plane, req, ATOMIC_RELAX_NONE,
> 0);
> -
> -	drmModeAtomicFree(req);
> +	igt_pipe_obj_replace_prop_blob(pipe, IGT_CRTC_MODE_ID, mode,
> sizeof(*mode));
> +	crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>  }
>  
> -static void crtc_invalid_params_fence(struct kms_atomic_crtc_state
> *crtc_old,
> -				struct kms_atomic_plane_state
> *plane,
> -				struct kms_atomic_connector_state
> *conn)
> +static void crtc_invalid_params_fence(igt_pipe_t *pipe,
> +				      igt_output_t *output,
> +				      igt_plane_t *plane,
> +				      struct igt_fb *fb)
>  {
> -	struct kms_atomic_crtc_state crtc = *crtc_old;
> -	drmModeAtomicReq *req = drmModeAtomicAlloc();
> -	int timeline, fence_fd, *out_fence;
> +	int timeline, fence_fd;
> +	void *map;
> +	const ptrdiff_t PAGE_SIZE = sysconf(_SC_PAGE_SIZE);
> +	uint64_t old_mode_id = pipe->values[IGT_CRTC_MODE_ID];
>  
>  	igt_require_sw_sync();
>  
> +	timeline = sw_sync_timeline_create();
> +
> +	/* invalid out_fence_ptr */
> +	map = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_ANONYMOUS |
> MAP_PRIVATE, -1, 0);
> +	igt_assert(map != MAP_FAILED);
> +
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR,
> (ptrdiff_t)map);
> +	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE,
> EFAULT);
> +	munmap(map, PAGE_SIZE);
> +
>  	/* invalid out_fence_ptr */
> -	crtc.mode.id = crtc_old->mode.id;
> -	crtc.out_fence_ptr = (int32_t *) crtc_invalid_params;
> -	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
> 0,
> -	                       ATOMIC_RELAX_NONE, EFAULT);
> +	map = mmap(NULL, PAGE_SIZE, PROT_EXEC, MAP_ANONYMOUS |
> MAP_PRIVATE, -1, 0);
> +	igt_assert(map != MAP_FAILED);
> +
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR,
> (ptrdiff_t)map);
> +	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE,
> EFAULT);
> +	munmap(map, PAGE_SIZE);
>  
>  	/* invalid out_fence_ptr */
> -	crtc.mode.id = crtc_old->mode.id;
> -	crtc.out_fence_ptr = (int32_t *) 0x8;
> -	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
> 0,
> -	                       ATOMIC_RELAX_NONE, EFAULT);
> -	crtc.out_fence_ptr = (int32_t *) 0;
> +	map = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_ANONYMOUS |
> MAP_PRIVATE, -1, 0);
> +	igt_assert(map != MAP_FAILED);
> +
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR,
> (ptrdiff_t)map);
> +	crtc_commit_atomic_err(pipe, plane, ATOMIC_RELAX_NONE,
> EFAULT);
> +	munmap(map, PAGE_SIZE);
>  
>  	/* valid in fence but not allowed prop on crtc */
> -	timeline = sw_sync_timeline_create();
> -	fence_fd =  sw_sync_timeline_create_fence(timeline, 1);
> -	plane->fence_fd = fence_fd;
> -	crtc.active = false;
> -	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
> 0,
> -			       ATOMIC_RELAX_NONE, EINVAL);
> +	fence_fd = sw_sync_timeline_create_fence(timeline, 1);
> +	igt_plane_set_fence_fd(plane, fence_fd);
>  
> -	out_fence = malloc(sizeof(uint64_t));
> -	igt_assert(out_fence);
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_ACTIVE, 0);
> +	igt_pipe_obj_clear_prop_changed(pipe,
> IGT_CRTC_OUT_FENCE_PTR);
>  
> +	crtc_commit_atomic_flags_err(pipe, plane, 0,
> ATOMIC_RELAX_NONE, EINVAL);
>  
>  	/* valid out fence ptr and flip event but not allowed prop
> on crtc */
> -	crtc.out_fence_ptr = (int32_t *) out_fence;
> -	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
> 0,
> -			       ATOMIC_RELAX_NONE, EINVAL);
> +	igt_pipe_request_out_fence(pipe);
> +	crtc_commit_atomic_flags_err(pipe, plane,
> DRM_MODE_PAGE_FLIP_EVENT,
> +				     ATOMIC_RELAX_NONE, EINVAL);
>  
> -	/* valid out fence ptr and flip event but not allowed prop
> on crtc */
> -	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
> -			       DRM_MODE_PAGE_FLIP_EVENT,
> -			       ATOMIC_RELAX_NONE, EINVAL);
> -
> -	/* valid page flip event but not allowed prop on crtc */
> -	crtc.out_fence_ptr = (int32_t *) 0;
> -	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
> -			       DRM_MODE_PAGE_FLIP_EVENT,
> -			       ATOMIC_RELAX_NONE, EINVAL);
> -	crtc.active = true;
> -
> -	/* valid out fence  ptr and flip event but invalid prop on
> crtc */
> -	crtc.out_fence_ptr = (int32_t *) out_fence;
> -	crtc.mode.id = plane->fb_id;
> -	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
> 0,
> -			       ATOMIC_RELAX_NONE, EINVAL);
> +	/* valid flip event but not allowed prop on crtc */
> +	igt_pipe_obj_clear_prop_changed(pipe,
> IGT_CRTC_OUT_FENCE_PTR);
> +	crtc_commit_atomic_flags_err(pipe, plane,
> DRM_MODE_PAGE_FLIP_EVENT,
> +				     ATOMIC_RELAX_NONE, EINVAL);
> +
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_ACTIVE, 1);
> +
> +	/* Configuration should be valid again */
> +	crtc_commit_atomic_flags_err(pipe, plane,
> DRM_MODE_ATOMIC_TEST_ONLY,
> +				     ATOMIC_RELAX_NONE, 0);
> +
> +	/* Set invalid prop */
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID, fb-
> >fb_id);
> +
> +	/* valid out fence but invalid prop on crtc */
> +	igt_pipe_request_out_fence(pipe);
> +	crtc_commit_atomic_flags_err(pipe, plane, 0,
> +				     ATOMIC_RELAX_NONE, EINVAL);
>  
>  	/* valid out fence ptr and flip event but invalid prop on
> crtc */
> -	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
> -			       DRM_MODE_PAGE_FLIP_EVENT,
> -			       ATOMIC_RELAX_NONE, EINVAL);
> +	crtc_commit_atomic_flags_err(pipe, plane,
> DRM_MODE_PAGE_FLIP_EVENT,
> +				     ATOMIC_RELAX_NONE, EINVAL);
>  
>  	/* valid page flip event but invalid prop on crtc */
> -	crtc.out_fence_ptr = (int32_t *) 0;
> -	crtc_commit_atomic_err(&crtc, plane, crtc_old, plane, req,
> -			       DRM_MODE_PAGE_FLIP_EVENT,
> -			       ATOMIC_RELAX_NONE, EINVAL);
> +	crtc_commit_atomic_flags_err(pipe, plane,
> DRM_MODE_PAGE_FLIP_EVENT,
> +				     ATOMIC_RELAX_NONE, EINVAL);
>  
>  	/* successful TEST_ONLY with fences set */
> -	plane->fence_fd = fence_fd;
> -	crtc.mode.id = crtc_old->mode.id;
> -	crtc_commit_atomic(&crtc, plane, req, ATOMIC_RELAX_NONE,
> -			   DRM_MODE_ATOMIC_TEST_ONLY);
> -	igt_assert(*out_fence == -1);
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_MODE_ID,
> old_mode_id);
> +	crtc_commit_atomic_flags_err(pipe, plane,
> DRM_MODE_ATOMIC_TEST_ONLY,
> +				     ATOMIC_RELAX_NONE, 0);
> +	igt_assert(pipe->out_fence_fd == -1);
>  	close(fence_fd);
>  	close(timeline);
>  
>  	/* reset fences */
> -	plane->fence_fd = -1;
> -	crtc.out_fence_ptr = (int32_t *) 0;
> -	crtc_commit_atomic(&crtc, plane, req, ATOMIC_RELAX_NONE, 0);
> +	igt_plane_set_fence_fd(plane, -1);
> +	igt_pipe_obj_set_prop_value(pipe, IGT_CRTC_OUT_FENCE_PTR,
> 0);
> +	igt_pipe_obj_clear_prop_changed(pipe,
> IGT_CRTC_OUT_FENCE_PTR);
> +	crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>  
>  	/* out fence ptr but not page flip event */
> -	crtc.out_fence_ptr = (int32_t *) out_fence;
> -	crtc_commit_atomic(crtc_old, plane, req, ATOMIC_RELAX_NONE,
> 0);
> +	igt_pipe_request_out_fence(pipe);
> +	crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>  
> -	close(*out_fence);
> -	free(out_fence);
> -	drmModeAtomicFree(req);
> +	igt_assert(pipe->out_fence_fd != -1);
>  }
>  
>  /* Abuse the atomic ioctl directly in order to test various invalid
> conditions,
>   * which the libdrm wrapper won't allow us to create. */
> -static void atomic_invalid_params(struct kms_atomic_crtc_state
> *crtc,
> -				  struct kms_atomic_plane_state
> *plane,
> -				  struct kms_atomic_connector_state
> *connector)
> +static void atomic_invalid_params(igt_pipe_t *pipe,
> +				  igt_plane_t *plane,
> +				  igt_output_t *output,
> +				  struct igt_fb *fb)
>  {
> -	struct kms_atomic_desc *desc = crtc->state->desc;
> +	igt_display_t *display = pipe->display;
>  	struct drm_mode_atomic ioc;
>  	uint32_t obj_raw[16]; /* array of objects (sized by
> count_objs) */
>  	uint32_t num_props_raw[16]; /* array of num props per obj
> (ditto) */
> @@ -1346,7 +718,7 @@ static void atomic_invalid_params(struct
> kms_atomic_crtc_state *crtc,
>  	memset(&ioc, 0, sizeof(ioc));
>  
>  	/* An empty request should do nothing. */
> -	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
> +	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
>  
>  	for (i = 0; i < ARRAY_SIZE(obj_raw); i++)
>  		obj_raw[i] = 0;
> @@ -1363,248 +735,232 @@ static void atomic_invalid_params(struct
> kms_atomic_crtc_state *crtc,
>  	ioc.prop_values_ptr = (uintptr_t) values_raw;
>  
>  	/* Valid pointers, but still should copy nothing. */
> -	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
> +	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
>  
>  	/* Valid noop, but with event set should fail. */
>  	ioc.flags = DRM_MODE_PAGE_FLIP_EVENT;
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EINVAL);
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> EINVAL);
>  
>  	/* Nonsense flags. */
>  	ioc.flags = 0xdeadbeef;
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EINVAL);
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> EINVAL);
>  
>  	ioc.flags = 0;
>  	/* Safety check that flags is reset properly. */
> -	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
> +	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
>  
>  	/* Reserved/MBZ. */
>  	ioc.reserved = 1;
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EINVAL);
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> EINVAL);
>  	ioc.reserved = 0;
> -	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
> +	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
>  
>  	/* Zero is not a valid object ID. */
>  	ioc.count_objs = ARRAY_SIZE(obj_raw);
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> ENOENT);
>  
>  	/* Invalid object type (not a thing we can set properties
> on). */
>  	ioc.count_objs = 1;
> -	obj_raw[0] = crtc->mode.id;
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
> -	obj_raw[0] = plane->fb_id;
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
> +	obj_raw[0] = pipe->values[IGT_CRTC_MODE_ID];
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> ENOENT);
> +	obj_raw[0] = fb->fb_id;
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> ENOENT);
>  
>  	/* Filled object but with no properties; no-op. */
>  	for (i = 0; i < ARRAY_SIZE(obj_raw); i++)
> -		obj_raw[i] = crtc->obj;
> -	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
> +		obj_raw[i] = pipe->crtc_id;
> +	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
>  
>  	/* Pass in all sorts of things other than the property ID.
> */
>  	num_props_raw[0] = 1;
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
> -	props_raw[0] = crtc->obj;
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
> -	props_raw[0] = plane->obj;
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
> -	props_raw[0] = connector->obj;
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
> -	props_raw[0] = crtc->mode.id;
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> ENOENT);
> +	props_raw[0] = pipe->crtc_id;
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> ENOENT);
> +	props_raw[0] = plane->drm_plane->plane_id;
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> ENOENT);
> +	props_raw[0] = output->id;
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> ENOENT);
> +	props_raw[0] = pipe->values[IGT_CRTC_MODE_ID];
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> ENOENT);
>  
>  	/* Valid property, valid value. */
> +
>  	for (i = 0; i < ARRAY_SIZE(props_raw); i++) {
> -		props_raw[i] = desc->props_crtc[IGT_CRTC_MODE_ID];
> -		values_raw[i] = crtc->mode.id;
> +		props_raw[i] = pipe->props[IGT_CRTC_MODE_ID];
> +		values_raw[i] = pipe->values[IGT_CRTC_MODE_ID];
>  	}
> -	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
> +	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
>  
>  	/* Setting the same thing multiple times is OK. */
>  	for (i = 0; i < ARRAY_SIZE(obj_raw); i++)
>  		num_props_raw[i] = ARRAY_SIZE(props_raw) /
> ARRAY_SIZE(obj_raw);
> -	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
> +	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
>  	ioc.count_objs = ARRAY_SIZE(obj_raw);
> -	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
> +	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
>  
>  	/* Pass a series of outlandish addresses. */
>  	ioc.objs_ptr = 0;
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> EFAULT);
>  
>  	ioc.objs_ptr = (uintptr_t) obj_raw;
>  	ioc.count_props_ptr = 0;
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> EFAULT);
>  
>  	ioc.count_props_ptr = (uintptr_t) num_props_raw;
>  	ioc.props_ptr = 0;
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> EFAULT);
>  
>  	ioc.props_ptr = (uintptr_t) props_raw;
>  	ioc.prop_values_ptr = 0;
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> EFAULT);
>  
>  	ioc.prop_values_ptr = (uintptr_t) values_raw;
> -	do_ioctl(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
> +	do_ioctl(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc);
>  
>  	/* Attempt to overflow and/or trip various boundary
> conditions. */
>  	ioc.count_objs = UINT32_MAX / sizeof(uint32_t);
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, ENOENT);
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> ENOENT);
>  
>  	ioc.count_objs = ARRAY_SIZE(obj_raw);
>  	ioc.objs_ptr = UINT64_MAX - sizeof(uint32_t);
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> EFAULT);
>  	ioc.count_objs = 1;
>  	ioc.objs_ptr = UINT64_MAX - sizeof(uint32_t);
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> EFAULT);
>  
>  	num_props_raw[0] = UINT32_MAX / sizeof(uint32_t);
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> EFAULT);
>  	num_props_raw[0] = UINT32_MAX - 1;
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> EFAULT);
>  
>  	for (i = 0; i < ARRAY_SIZE(obj_raw); i++)
>  		num_props_raw[i] = (UINT32_MAX /
> ARRAY_SIZE(obj_raw)) + 1;
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> EFAULT);
>  	for (i = 0; i < ARRAY_SIZE(obj_raw); i++)
>  		num_props_raw[i] = ARRAY_SIZE(props_raw) /
> ARRAY_SIZE(obj_raw);
> -	do_ioctl_err(desc->fd, DRM_IOCTL_MODE_ATOMIC, &ioc, EFAULT);
> +	do_ioctl_err(display->drm_fd, DRM_IOCTL_MODE_ATOMIC, &ioc,
> EFAULT);
> +}
> +
> +static void atomic_setup(igt_display_t *display, enum pipe pipe,
> igt_output_t *output, igt_plane_t *primary, struct igt_fb *fb)
> +{
> +	igt_output_set_pipe(output, pipe);
> +	igt_plane_set_fb(primary, fb);
> +
> +	crtc_commit(primary->pipe, primary, COMMIT_ATOMIC,
> ATOMIC_RELAX_NONE);
> +}
> +
> +static void atomic_clear(igt_display_t *display, enum pipe pipe,
> igt_plane_t *primary, igt_output_t *output)
> +{
> +	igt_plane_t *plane;
> +
> +	for_each_plane_on_pipe(display, pipe, plane) {
> +		igt_plane_set_fb(plane, NULL);
> +		igt_plane_set_position(plane, 0, 0);
> +	}
> +
> +	igt_output_set_pipe(output, PIPE_NONE);
> +	crtc_commit(primary->pipe, primary, COMMIT_ATOMIC,
> ATOMIC_RELAX_NONE);
>  }
>  
>  igt_main
>  {
> -	struct kms_atomic_desc desc;
> -	struct kms_atomic_state *current;
> +	igt_display_t display;
> +	enum pipe pipe = PIPE_NONE;
> +	igt_pipe_t *pipe_obj;
> +	igt_output_t *output = NULL;
> +	igt_plane_t *primary = NULL;
> +	drmModeModeInfo *mode;
> +	struct igt_fb fb;
> +
> +	igt_fixture {
> +		display.drm_fd = drm_open_driver_master(DRIVER_ANY);
> +
> +		kmstest_set_vt_graphics_mode();
> +
> +		igt_display_init(&display, display.drm_fd);
> +
> +		igt_require(display.is_atomic);
> +		igt_display_require_output(&display);
>  
> -	memset(&desc, 0, sizeof(desc));
> +		for_each_pipe_with_valid_output(&display, pipe,
> output)
> +			break;
> +
> +		pipe_obj = &display.pipes[pipe];
> +		primary = igt_pipe_get_plane_type(pipe_obj,
> DRM_PLANE_TYPE_PRIMARY);
>  
> -	current = calloc(1, sizeof(*current));
> -	igt_assert(current);
> -	current->desc = &desc;
> +		mode = igt_output_get_mode(output);
>  
> -	igt_fixture
> -		atomic_setup(current);
> +		igt_create_pattern_fb(display.drm_fd,
> +				      mode->hdisplay, mode-
> >vdisplay,
> +				      plane_get_igt_format(primary),
> +				      LOCAL_DRM_FORMAT_MOD_NONE,
> &fb);
> +	}
>  
>  	igt_subtest("plane_overlay_legacy") {
> -		struct kms_atomic_state *scratch =
> atomic_state_dup(current);
> -		struct kms_atomic_crtc_state *crtc =
> find_crtc(scratch, true);
> -		struct kms_atomic_plane_state *plane =
> -			find_plane(scratch, PLANE_TYPE_OVERLAY,
> crtc);
> -
> -		igt_require(crtc);
> -		igt_require(plane);
> -		plane_overlay(crtc, plane);
> -		atomic_state_free(scratch);
> +		igt_plane_t *overlay =
> +			igt_pipe_get_plane_type(pipe_obj,
> DRM_PLANE_TYPE_OVERLAY);
> +
> +		igt_require(overlay);
> +
> +		atomic_setup(&display, pipe, output, primary, &fb);
> +		plane_overlay(pipe_obj, output, overlay);
>  	}
>  
>  	igt_subtest("plane_primary_legacy") {
> -		struct kms_atomic_state *scratch =
> atomic_state_dup(current);
> -		struct kms_atomic_crtc_state *crtc =
> find_crtc(scratch, true);
> -		struct kms_atomic_plane_state *plane =
> -			find_plane(scratch, PLANE_TYPE_PRIMARY,
> crtc);
> -
> -		igt_require(crtc);
> -		igt_require(plane);
> -		plane_primary(crtc, plane);
> -		atomic_state_free(scratch);
> +		atomic_setup(&display, pipe, output, primary, &fb);
> +
> +		plane_primary(pipe_obj, primary, &fb);
>  	}
>  
>  	igt_subtest("test_only") {
> -		struct kms_atomic_state *scratch =
> atomic_state_dup(current);
> -		struct kms_atomic_crtc_state *crtc =
> find_crtc(scratch, true);
> -		struct kms_atomic_plane_state *plane =
> -			find_plane(scratch, PLANE_TYPE_PRIMARY,
> crtc);
> -
> -		igt_require(crtc);
> -		igt_require(plane);
> -		test_only(crtc, plane);
> -		atomic_state_free(scratch);
> -	}
> +		atomic_clear(&display, pipe, primary, output);
>  
> +		test_only(pipe_obj, primary, output);
> +	}
>  	igt_subtest("plane_cursor_legacy") {
> -		struct kms_atomic_state *scratch =
> atomic_state_dup(current);
> -		struct kms_atomic_crtc_state *crtc =
> find_crtc(scratch, true);
> -		struct kms_atomic_plane_state *plane =
> -			find_plane(scratch, PLANE_TYPE_CURSOR,
> crtc);
> -
> -		igt_require(crtc);
> -		igt_require(plane);
> -		plane_cursor(crtc, plane);
> -		atomic_state_free(scratch);
> +		igt_plane_t *cursor =
> +			igt_pipe_get_plane_type(pipe_obj,
> DRM_PLANE_TYPE_CURSOR);
> +
> +		igt_require(cursor);
> +
> +		atomic_setup(&display, pipe, output, primary, &fb);
> +		plane_cursor(pipe_obj, output, cursor);
>  	}
>  
>  	igt_subtest("plane_invalid_params") {
> -		struct kms_atomic_state *scratch =
> atomic_state_dup(current);
> -		struct kms_atomic_crtc_state *crtc =
> find_crtc(scratch, true);
> -		struct kms_atomic_plane_state *plane =
> -			find_plane(current, PLANE_TYPE_PRIMARY,
> crtc);
> -		struct kms_atomic_connector_state *conn =
> -			find_connector(scratch, crtc);
> -
> -		igt_require(crtc);
> -		igt_require(plane);
> -		plane_invalid_params(crtc, plane, conn);
> -		atomic_state_free(scratch);
> +		atomic_setup(&display, pipe, output, primary, &fb);
> +
> +		plane_invalid_params(pipe_obj, output, primary,
> &fb);
>  	}
>  
>  	igt_subtest("plane_invalid_params_fence") {
> -		struct kms_atomic_state *scratch =
> atomic_state_dup(current);
> -		struct kms_atomic_crtc_state *crtc =
> find_crtc(scratch, true);
> -		struct kms_atomic_plane_state *plane =
> -			find_plane(current, PLANE_TYPE_PRIMARY,
> crtc);
> -		struct kms_atomic_connector_state *conn =
> -			find_connector(scratch, crtc);
> -
> -		igt_require(crtc);
> -		igt_require(plane);
> -		plane_invalid_params_fence(crtc, plane, conn);
> -		atomic_state_free(scratch);
> +		atomic_setup(&display, pipe, output, primary, &fb);
> +
> +		plane_invalid_params_fence(pipe_obj, output,
> primary);
>  	}
>  
>  	igt_subtest("crtc_invalid_params") {
> -		struct kms_atomic_state *scratch =
> atomic_state_dup(current);
> -		struct kms_atomic_crtc_state *crtc =
> find_crtc(scratch, true);
> -		struct kms_atomic_plane_state *plane =
> -			find_plane(scratch, NUM_PLANE_TYPE_PROPS,
> crtc);
> -		struct kms_atomic_connector_state *conn =
> -			find_connector(scratch, crtc);
> -
> -		igt_require(crtc);
> -		igt_require(plane);
> -		igt_require(conn);
> -		crtc_invalid_params(crtc, plane, conn);
> -		atomic_state_free(scratch);
> +		atomic_setup(&display, pipe, output, primary, &fb);
> +
> +		crtc_invalid_params(pipe_obj, output, primary, &fb);
>  	}
>  
>  	igt_subtest("crtc_invalid_params_fence") {
> -		struct kms_atomic_state *scratch =
> atomic_state_dup(current);
> -		struct kms_atomic_crtc_state *crtc =
> find_crtc(scratch, true);
> -		struct kms_atomic_plane_state *plane =
> -			find_plane(scratch, NUM_PLANE_TYPE_PROPS,
> crtc);
> -		struct kms_atomic_connector_state *conn =
> -			find_connector(scratch, crtc);
> -
> -		igt_require(crtc);
> -		igt_require(plane);
> -		igt_require(conn);
> -		crtc_invalid_params_fence(crtc, plane, conn);
> -		atomic_state_free(scratch);
> +		atomic_setup(&display, pipe, output, primary, &fb);
> +
> +		crtc_invalid_params_fence(pipe_obj, output, primary,
> &fb);
>  	}
>  
>  	igt_subtest("atomic_invalid_params") {
> -		struct kms_atomic_state *scratch =
> atomic_state_dup(current);
> -		struct kms_atomic_crtc_state *crtc =
> find_crtc(scratch, true);
> -		struct kms_atomic_plane_state *plane =
> -			find_plane(scratch, NUM_PLANE_TYPE_PROPS,
> crtc);
> -		struct kms_atomic_connector_state *conn =
> -			find_connector(scratch, crtc);
> -
> -		igt_require(crtc);
> -		igt_require(plane);
> -		igt_require(conn);
> -		atomic_invalid_params(crtc, plane, conn);
> -		atomic_state_free(scratch);
> +		atomic_setup(&display, pipe, output, primary, &fb);
> +
> +		atomic_invalid_params(pipe_obj, primary, output,
> &fb);
>  	}
>  
> -	atomic_state_free(current);
> +	igt_fixture {
> +		atomic_clear(&display, pipe, primary, output);
> +		igt_remove_fb(display.drm_fd, &fb);
>  
> -	igt_fixture
> -		close(desc.fd);
> +		igt_display_fini(&display);
> +	}
>  }
-- 
Mika Kahola - Intel OTC

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2] tests/kms_atomic: Convert/rewrite tests to use igt_kms framework, v2.
  2017-10-20 10:02     ` Mika Kahola
@ 2017-10-20 10:08       ` Maarten Lankhorst
  2017-10-20 10:16         ` Mika Kahola
  0 siblings, 1 reply; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-20 10:08 UTC (permalink / raw)
  To: mika.kahola, intel-gfx; +Cc: Daniel Stone

Op 20-10-17 om 12:02 schreef Mika Kahola:
> On Thu, 2017-10-12 at 17:33 +0200, Maarten Lankhorst wrote:
>> Now that we can set individual properties through the igt_kms api,
>> we no longer need to duplicate functionality from igt_kms. Set
>> invalid
>> properties directly, and rewrite kms_atomic.c to use igt_display.
>> This will allow us to remove a lot of code in kms_atomic.c,
>> and benefit from how igt_kms can set up a valid configuration,
>> instead of having to inherit it from fbcon.
>>
>> Changes since v1:
>> - Fix test failure when atomic_invalid_params is run standalone.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> Cc: Daniel Stone <daniels@collabora.com>
>> ---
>>  tests/kms_atomic.c | 1668 ++++++++++++++++------------------------
>> ------------
>>  1 file changed, 512 insertions(+), 1156 deletions(-)
>>
>> diff --git a/tests/kms_atomic.c b/tests/kms_atomic.c
>> index 042a7c263aab..e0fc324eab61 100644
>> --- a/tests/kms_atomic.c
>> +++ b/tests/kms_atomic.c
>> @@ -46,10 +46,6 @@
>>  #include "igt_aux.h"
>>  #include "sw_sync.h"
>>  
>> -#ifndef DRM_CLIENT_CAP_ATOMIC
>> -#define DRM_CLIENT_CAP_ATOMIC 3
>> -#endif
>> -
>>  #ifndef DRM_CAP_CURSOR_WIDTH
>>  #define DRM_CAP_CURSOR_WIDTH 0x8
>>  #endif
>> @@ -58,23 +54,6 @@
>>  #define DRM_CAP_CURSOR_HEIGHT 0x9
>>  #endif
>>  
>> -#ifndef DRM_MODE_ATOMIC_TEST_ONLY
>> -#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
>> -#define DRM_MODE_ATOMIC_NONBLOCK 0x0200
>> -#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
>> -
>> -struct drm_mode_atomic {
>> -	__u32 flags;
>> -	__u32 count_objs;
>> -	__u64 objs_ptr;
>> -	__u64 count_props_ptr;
>> -	__u64 props_ptr;
>> -	__u64 prop_values_ptr;
>> -	__u64 reserved;
>> -	__u64 user_data;
>> -};
>> -#endif
>> -
>>  IGT_TEST_DESCRIPTION("Test atomic modesetting API");
>>  
>>  enum kms_atomic_check_relax {
>> @@ -83,1259 +62,652 @@ enum kms_atomic_check_relax {
>>  	PLANE_RELAX_FB = (1 << 1)
>>  };
>>  
>> -/**
>> - * KMS plane type enum
>> - *
>> - * KMS plane types are represented by enums, which do not have
>> stable numeric
>> - * values, but must be looked up by their string value each time.
>> - *
>> - * To make the code more simple, we define a plane_type enum which
>> maps to
>> - * each KMS enum value. These values must be looked up through the
>> map, and
>> - * cannot be passed directly to KMS functions.
>> - */
>> -enum plane_type {
>> -	PLANE_TYPE_PRIMARY = 0,
>> -	PLANE_TYPE_OVERLAY,
>> -	PLANE_TYPE_CURSOR,
>> -	NUM_PLANE_TYPE_PROPS
>> -};
>> -
>> -static const char *plane_type_prop_names[NUM_PLANE_TYPE_PROPS] = {
>> -	"Primary",
>> -	"Overlay",
>> -	"Cursor"
>> -};
>> -
>> -struct kms_atomic_blob {
>> -	uint32_t id; /* 0 if not already allocated */
>> -	size_t len;
>> -	void *data;
>> -};
>> -
>> -struct kms_atomic_connector_state {
>> -	struct kms_atomic_state *state;
>> -	uint32_t obj;
>> -	uint32_t crtc_id;
>> -};
>> -
>> -struct kms_atomic_plane_state {
>> -	struct kms_atomic_state *state;
>> -	uint32_t obj;
>> -	enum plane_type type;
>> -	uint32_t crtc_mask;
>> -	uint32_t crtc_id; /* 0 to disable */
>> -	uint32_t fb_id; /* 0 to disable */
>> -	uint32_t src_x, src_y, src_w, src_h; /* 16.16 fixed-point */
>> -	uint32_t crtc_x, crtc_y, crtc_w, crtc_h; /* normal integers
>> */
>> -	int32_t fence_fd;
>> -};
>> -
>> -struct kms_atomic_crtc_state {
>> -	struct kms_atomic_state *state;
>> -	uint32_t obj;
>> -	int idx;
>> -	bool active;
>> -	int32_t *out_fence_ptr;
>> -	struct kms_atomic_blob mode;
>> -};
>> -
>> -struct kms_atomic_state {
>> -	struct kms_atomic_connector_state *connectors;
>> -	int num_connectors;
>> -	struct kms_atomic_crtc_state *crtcs;
>> -	int num_crtcs;
>> -	struct kms_atomic_plane_state *planes;
>> -	int num_planes;
>> -	struct kms_atomic_desc *desc;
>> -};
>> -
>> -struct kms_atomic_desc {
>> -	int fd;
>> -	uint32_t props_connector[IGT_NUM_CONNECTOR_PROPS];
>> -	uint32_t props_crtc[IGT_NUM_CRTC_PROPS];
>> -	uint32_t props_plane[IGT_NUM_PLANE_PROPS];
>> -	uint64_t props_plane_type[NUM_PLANE_TYPE_PROPS];
>> -};
>> -
>> -static uint32_t blob_duplicate(int fd, uint32_t id_orig)
>> +static bool plane_filter(enum igt_atomic_plane_properties prop)
>>  {
>> -	drmModePropertyBlobPtr orig = drmModeGetPropertyBlob(fd,
>> id_orig);
>> -	uint32_t id_new;
>> -
>> -	igt_assert(orig);
>> -	do_or_die(drmModeCreatePropertyBlob(fd, orig->data, orig-
>>> length,
>> -					    &id_new));
>> -	drmModeFreePropertyBlob(orig);
>> +	if ((1 << prop) & IGT_PLANE_COORD_CHANGED_MASK)
>> +		return false;
>>  
>> -	return id_new;
>> -}
>> -
>> -#define crtc_set_prop(req, crtc, prop, value) \
>> -	igt_assert_lt(0, drmModeAtomicAddProperty(req, crtc->obj, \
>> -						  crtc->state->desc-
>>> props_crtc[prop], \
>> -						  value));
>> -
>> -#define plane_set_prop(req, plane, prop, value) \
>> -	igt_assert_lt(0, drmModeAtomicAddProperty(req, plane->obj, \
>> -						  plane->state-
>>> desc->props_plane[prop], \
>> -						  value));
>> -
>> -#define do_atomic_commit(fd, req, flags) \
>> -	do_or_die(drmModeAtomicCommit(fd, req, flags, NULL));
>> +	if (prop == IGT_PLANE_CRTC_ID || prop == IGT_PLANE_FB_ID)
>> +		return false;
>>  
>> -#define do_atomic_commit_err(fd, req, flags, err) { \
>> -	igt_assert_neq(drmModeAtomicCommit(fd, req, flags, NULL),
>> 0); \
>> -	igt_assert_eq(errno, err); \
>> -}
>> -
>> -#define crtc_commit_atomic(crtc, plane, req, relax, flags) { \
>> -	drmModeAtomicSetCursor(req, 0); \
>> -	crtc_populate_req(crtc, req); \
>> -	plane_populate_req(plane, req); \
>> -	do_atomic_commit((crtc)->state->desc->fd, req, flags); \
>> -	if (!(flags & DRM_MODE_ATOMIC_TEST_ONLY)) { \
>> -		crtc_check_current_state(crtc, plane, relax); \
>> -		plane_check_current_state(plane, relax); \
>> -	} \
>> -}
>> +	if (prop == IGT_PLANE_IN_FENCE_FD)
>> +		return false;
>>  
>> -#define crtc_commit_atomic_err(crtc, plane, crtc_old, plane_old,
>> req, flags, relax, e) { \
>> -	drmModeAtomicSetCursor(req, 0); \
>> -	crtc_populate_req(crtc, req); \
>> -	plane_populate_req(plane, req); \
>> -	do_atomic_commit_err((crtc)->state->desc->fd, req, flags,
>> e); \
>> -	crtc_check_current_state(crtc_old, plane_old, relax); \
>> -	plane_check_current_state(plane_old, relax); \
>> +	/* Don't care about other properties */
>> +	return true;
>>  }
>>  
>> -#define plane_commit_atomic(plane, req, relax) { \
>> -	drmModeAtomicSetCursor(req, 0); \
>> -	plane_populate_req(plane, req); \
>> -	do_atomic_commit((plane)->state->desc->fd, req, 0); \
>> -	plane_check_current_state(plane, relax); \
>> -}
>> -
>> -#define plane_commit_atomic_err(plane, plane_old, req, relax, e) { \
>> -	drmModeAtomicSetCursor(req, 0); \
>> -	plane_populate_req(plane, req); \
>> -	do_atomic_commit_err((plane)->state->desc->fd, req, 0, e); \
>> -	plane_check_current_state(plane_old, relax); \
>> -}
>> -
>> -static void
>> -connector_get_current_state(struct kms_atomic_connector_state
>> *connector)
>> -{
>> -	drmModeObjectPropertiesPtr props;
>> -	int i;
>> -
>> -	props = drmModeObjectGetProperties(connector->state->desc-
>>> fd,
>> -					   connector->obj,
>> -					   DRM_MODE_OBJECT_CONNECTOR
>> );
>> -	igt_assert(props);
>> -
>> -	for (i = 0; i < props->count_props; i++) {
>> -		uint32_t *prop_ids = connector->state->desc-
>>> props_connector;
>> -
>> -		if (props->props[i] ==
>> prop_ids[IGT_CONNECTOR_CRTC_ID])
>> -			connector->crtc_id = props->prop_values[i];
>> -	}
>> -	drmModeFreeObjectProperties(props);
>> -}
>> -
>> -#if 0
>> -/* XXX: Checking this repeatedly actually hangs the GPU. I have
>> literally no
>> - *      idea why. */
>> -static void
>> -connector_check_current_state(struct kms_atomic_connector_state
>> *connector)
>> -{
>> -	struct kms_atomic_connector_state connector_kernel;
>> -	drmModeConnectorPtr legacy;
>> -	uint32_t crtc_id;
>> -
>> -	legacy = drmModeGetConnectorCurrent(connector->state->desc-
>>> fd,
>> -					    connector->obj);
>> -	igt_assert(legacy);
>> -
>> -	if (legacy->encoder_id) {
>> -		drmModeEncoderPtr legacy_enc;
>> -
>> -		legacy_enc = drmModeGetEncoder(connector->state-
>>> desc->fd,
>> -					       legacy->encoder_id);
>> -		igt_assert(legacy_enc);
>> -
>> -		crtc_id = legacy_enc->crtc_id;
>> -		drmModeFreeEncoder(legacy_enc);
>> -	} else {
>> -		crtc_id = 0;
>> -	}
>> -
>> -	igt_assert_eq_u32(crtc_id, connector->crtc_id);
>> -
>> -	memcpy(&connector_kernel, connector,
>> sizeof(connector_kernel));
>> -	connector_get_current_state(&connector_kernel);
>> -	do_or_die(memcmp(&connector_kernel, connector,
>> -			 sizeof(connector_kernel)));
>> -
>> -	drmModeFreeConnector(legacy);
>> -}
>> -#endif
>> -
>> -static struct kms_atomic_connector_state *
>> -find_connector(struct kms_atomic_state *state,
>> -	       struct kms_atomic_crtc_state *crtc)
>> +static void plane_get_current_state(igt_plane_t *plane, uint64_t
>> *values)
>>  {
>>  	int i;
>>  
>> -	for (i = 0; i < state->num_connectors; i++) {
>> -		struct kms_atomic_connector_state *connector =
>> -			&state->connectors[i];
>> -
>> -		if (!connector->obj)
>> +	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++) {
>> +		if (plane_filter(i)) {
>> +			values[i] = 0;
>>  			continue;
>> -		if (crtc && connector->crtc_id != crtc->obj)
>> -			continue;
>> -
>> -		return connector;
>> -	}
>> -
>> -	return NULL;
>> -}
>> -
>> -static void plane_populate_req(struct kms_atomic_plane_state *plane,
>> -			       drmModeAtomicReq *req)
>> -{
>> -	if (plane->fence_fd)
>> -		plane_set_prop(req, plane, IGT_PLANE_IN_FENCE_FD,
>> plane->fence_fd);
>> -
>> -	plane_set_prop(req, plane, IGT_PLANE_CRTC_ID, plane-
>>> crtc_id);
>> -	plane_set_prop(req, plane, IGT_PLANE_FB_ID, plane->fb_id);
>> -	plane_set_prop(req, plane, IGT_PLANE_SRC_X, plane->src_x);
>> -	plane_set_prop(req, plane, IGT_PLANE_SRC_Y, plane->src_y);
>> -	plane_set_prop(req, plane, IGT_PLANE_SRC_W, plane->src_w);
>> -	plane_set_prop(req, plane, IGT_PLANE_SRC_H, plane->src_h);
>> -	plane_set_prop(req, plane, IGT_PLANE_CRTC_X, plane->crtc_x);
>> -	plane_set_prop(req, plane, IGT_PLANE_CRTC_Y, plane->crtc_y);
>> -	plane_set_prop(req, plane, IGT_PLANE_CRTC_W, plane->crtc_w);
>> -	plane_set_prop(req, plane, IGT_PLANE_CRTC_H, plane->crtc_h);
>> -}
>> -
>> -static void plane_get_current_state(struct kms_atomic_plane_state
>> *plane)
>> -{
>> -	struct kms_atomic_desc *desc = plane->state->desc;
>> -	drmModeObjectPropertiesPtr props;
>> -	int i;
>> -
>> -	props = drmModeObjectGetProperties(desc->fd, plane->obj,
>> -					   DRM_MODE_OBJECT_PLANE);
>> -	igt_assert(props);
>> -
>> -	for (i = 0; i < props->count_props; i++) {
>> -		uint32_t *prop_ids = desc->props_plane;
>> -
>> -		if (props->props[i] == prop_ids[IGT_PLANE_CRTC_ID])
>> -			plane->crtc_id = props->prop_values[i];
>> -		else if (props->props[i] ==
>> prop_ids[IGT_PLANE_FB_ID])
>> -			plane->fb_id = props->prop_values[i];
>> -		else if (props->props[i] ==
>> prop_ids[IGT_PLANE_CRTC_X])
>> -			plane->crtc_x = props->prop_values[i];
>> -		else if (props->props[i] ==
>> prop_ids[IGT_PLANE_CRTC_Y])
>> -			plane->crtc_y = props->prop_values[i];
>> -		else if (props->props[i] ==
>> prop_ids[IGT_PLANE_CRTC_W])
>> -			plane->crtc_w = props->prop_values[i];
>> -		else if (props->props[i] ==
>> prop_ids[IGT_PLANE_CRTC_H])
>> -			plane->crtc_h = props->prop_values[i];
>> -		else if (props->props[i] ==
>> prop_ids[IGT_PLANE_SRC_X])
>> -			plane->src_x = props->prop_values[i];
>> -		else if (props->props[i] ==
>> prop_ids[IGT_PLANE_SRC_Y])
>> -			plane->src_y = props->prop_values[i];
>> -		else if (props->props[i] ==
>> prop_ids[IGT_PLANE_SRC_W])
>> -			plane->src_w = props->prop_values[i];
>> -		else if (props->props[i] ==
>> prop_ids[IGT_PLANE_SRC_H])
>> -			plane->src_h = props->prop_values[i];
>> -		else if (props->props[i] ==
>> prop_ids[IGT_PLANE_TYPE]) {
>> -			int j;
>> -
>> -			for (j = 0; j < ARRAY_SIZE(desc-
>>> props_plane_type); j++) {
>> -				if (props->prop_values[i] == desc-
>>> props_plane_type[j]) {
>> -					plane->type = j;
>> -					break;
>> -				}
>> -			}
>>  		}
>> -	}
>>  
>> -	drmModeFreeObjectProperties(props);
>> +		values[i] = igt_plane_get_prop(plane, i);
>> +	}
>>  }
>>  
>> -static void plane_check_current_state(struct kms_atomic_plane_state
>> *plane,
>> +static void plane_check_current_state(igt_plane_t *plane, const
>> uint64_t *values,
>>  				      enum kms_atomic_check_relax
>> relax)
>>  {
>>  	drmModePlanePtr legacy;
>> -	struct kms_atomic_plane_state plane_kernel;
>> +	uint64_t current_values[IGT_NUM_PLANE_PROPS];
>> +	int i;
>>  
>> -	legacy = drmModeGetPlane(plane->state->desc->fd, plane-
>>> obj);
>> +	legacy = drmModeGetPlane(plane->pipe->display->drm_fd,
>> plane->drm_plane->plane_id);
>>  	igt_assert(legacy);
>>  
>> -	igt_assert_eq_u32(legacy->crtc_id, plane->crtc_id);
>> +	igt_assert_eq_u32(legacy->crtc_id,
>> values[IGT_PLANE_CRTC_ID]);
>>  
>>  	if (!(relax & PLANE_RELAX_FB))
>> -		igt_assert_eq_u32(legacy->fb_id, plane->fb_id);
>> +		igt_assert_eq_u32(legacy->fb_id,
>> values[IGT_PLANE_FB_ID]);
>>  
>> -	memcpy(&plane_kernel, plane, sizeof(plane_kernel));
>> -	plane_get_current_state(&plane_kernel);
>> +	plane_get_current_state(plane, current_values);
>>  
>>  	/* Legacy cursor ioctls create their own, unknowable,
>> internal
>>  	 * framebuffer which we can't reason about. */
>>  	if (relax & PLANE_RELAX_FB)
>> -		plane_kernel.fb_id = plane->fb_id;
>> -	do_or_die(memcmp(&plane_kernel, plane,
>> sizeof(plane_kernel)));
>> +		current_values[IGT_PLANE_FB_ID] =
>> values[IGT_PLANE_FB_ID];
>> +
>> +	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++)
>> +		if (!plane_filter(i))
>> +			igt_assert_eq_u64(current_values[i],
>> values[i]);
>>  
>>  	drmModeFreePlane(legacy);
>>  }
>>  
>> -static void plane_commit_legacy(struct kms_atomic_plane_state
>> *plane,
>> +static void plane_commit(igt_plane_t *plane, enum igt_commit_style
>> s,
>>                                  enum kms_atomic_check_relax relax)
>>  {
>> -	do_or_die(drmModeSetPlane(plane->state->desc->fd, plane-
>>> obj,
>> -				  plane->crtc_id,
>> -				  plane->fb_id, 0,
>> -				  plane->crtc_x, plane->crtc_y,
>> -				  plane->crtc_w, plane->crtc_h,
>> -				  plane->src_x, plane->src_y,
>> -				  plane->src_w, plane->src_h));
>> -	plane_check_current_state(plane, relax);
>> +	igt_display_commit2(plane->pipe->display, s);
>> +	plane_check_current_state(plane, plane->values, relax);
>>  }
>>  
>> -static struct kms_atomic_plane_state *
>> -find_plane(struct kms_atomic_state *state, enum plane_type type,
>> -	   struct kms_atomic_crtc_state *crtc)
>> +static void plane_commit_atomic_err(igt_plane_t *plane,
>> +				    enum kms_atomic_check_relax
>> relax,
>> +				    int err)
>>  {
>> -	struct kms_atomic_plane_state *ret = NULL;
>> -	int i;
>> -
>> -	for (i = 0; i < state->num_planes; i++) {
>> -		struct kms_atomic_plane_state *plane = &state-
>>> planes[i];
>> -
>> -		if (!plane->obj)
>> -			continue;
>> -		if (type != NUM_PLANE_TYPE_PROPS && plane->type !=
>> type)
>> -			continue;
>> -		if (crtc && !(plane->crtc_mask & (1 << crtc->idx)))
>> -			continue;
>> +	uint64_t current_values[IGT_NUM_PLANE_PROPS];
>>  
>> -		plane_get_current_state(plane);
>> +	plane_get_current_state(plane, current_values);
>>  
>> -		/* Try to find a plane that's already on this CRTC.
>> In
>> -		 * particular, this ensures that for special
>> (primary/cursor)
>> -		 * planes that can be on multiple CRTCs, we find the
>> same
>> -		 * one that the legacy ioctls will. */
>> -		if (!crtc || plane->crtc_id == crtc->obj)
>> -			return plane;
>> -
>> -		ret = plane;
>> -	}
>> +	igt_assert_eq(-err, igt_display_try_commit2(plane->pipe-
>>> display, COMMIT_ATOMIC));
>>  
>> -	return ret;
>> +	plane_check_current_state(plane, current_values, relax);
>>  }
>>  
>> -static void crtc_populate_req(struct kms_atomic_crtc_state *crtc,
>> -			      drmModeAtomicReq *req)
>> +static bool crtc_filter(enum igt_atomic_crtc_properties prop)
>>  {
>> -	if (crtc->out_fence_ptr)
>> -		crtc_set_prop(req, crtc, IGT_CRTC_OUT_FENCE_PTR,
>> -			      to_user_pointer(crtc->out_fence_ptr));
>> +	if (prop == IGT_CRTC_MODE_ID || prop == IGT_CRTC_ACTIVE)
>> +		return false;
>>  
>> -	crtc_set_prop(req, crtc, IGT_CRTC_MODE_ID, crtc->mode.id);
>> -	crtc_set_prop(req, crtc, IGT_CRTC_ACTIVE, crtc->active);
>> +	return true;
>>  }
>>  
>> -static void crtc_get_current_state(struct kms_atomic_crtc_state
>> *crtc)
>> +static void crtc_get_current_state(igt_pipe_t *pipe, uint64_t
>> *values)
>>  {
>> -	drmModeObjectPropertiesPtr props;
>>  	int i;
>>  
>> -	props = drmModeObjectGetProperties(crtc->state->desc->fd,
>> crtc->obj,
>> -					   DRM_MODE_OBJECT_CRTC);
>> -	igt_assert(props);
>> -
>> -	for (i = 0; i < props->count_props; i++) {
>> -		uint32_t *prop_ids = crtc->state->desc->props_crtc;
>> -
>> -		if (props->props[i] == prop_ids[IGT_CRTC_MODE_ID]) {
>> -			drmModePropertyBlobPtr blob;
>> -
>> -			crtc->mode.id = props->prop_values[i];
>> -			if (!crtc->mode.id) {
>> -				crtc->mode.len = 0;
>> -				continue;
>> -			}
>> -
>> -			blob = drmModeGetPropertyBlob(crtc->state-
>>> desc->fd,
>> -						      crtc-
>>> mode.id);
>> -			igt_assert(blob);
>> -			igt_assert_eq_u32(blob->length,
>> -					  sizeof(struct
>> drm_mode_modeinfo));
>> -
>> -			if (!crtc->mode.data ||
>> -			    memcmp(crtc->mode.data, blob->data,
>> blob->length) != 0)
>> -				crtc->mode.data = blob->data;
>> -			crtc->mode.len = blob->length;
>> -		}
>> -		else if (props->props[i] ==
>> prop_ids[IGT_CRTC_ACTIVE]) {
>> -			crtc->active = props->prop_values[i];
>> +	for (i = 0; i < IGT_NUM_CRTC_PROPS; i++) {
>> +		if (crtc_filter(i)) {
>> +			values[i] = 0;
>> +			continue;
>>  		}
>> -	}
>>  
>> -	drmModeFreeObjectProperties(props);
>> +		values[i] = igt_pipe_obj_get_prop(pipe, i);
>> +	}
>>  }
>>  
>> -static void crtc_check_current_state(struct kms_atomic_crtc_state
>> *crtc,
>> -				     struct kms_atomic_plane_state
>> *primary,
>> +static void crtc_check_current_state(igt_pipe_t *pipe,
>> +				     const uint64_t *pipe_values,
>> +				     const uint64_t *primary_values,
>>  				     enum kms_atomic_check_relax
>> relax)
>>  {
>> -	struct kms_atomic_crtc_state crtc_kernel;
>> +	uint64_t current_pipe_values[IGT_NUM_CRTC_PROPS];
>>  	drmModeCrtcPtr legacy;
>> +	drmModePropertyBlobRes *mode_prop = NULL;
>> +	struct drm_mode_modeinfo *mode = NULL;
>>  
>> -	legacy = drmModeGetCrtc(crtc->state->desc->fd, crtc->obj);
>> -	igt_assert(legacy);
>> -
>> -	igt_assert_eq_u32(legacy->crtc_id, crtc->obj);
>> -	igt_assert_eq_u32(legacy->x, primary->src_x >> 16);
>> -	igt_assert_eq_u32(legacy->y, primary->src_y >> 16);
>> -
>> -	if (crtc->active)
>> -		igt_assert_eq_u32(legacy->buffer_id, primary-
>>> fb_id);
>> -	else
>> -		igt_assert_eq_u32(legacy->buffer_id, 0);
>> +	if (pipe_values[IGT_CRTC_MODE_ID]) {
>> +		mode_prop = drmModeGetPropertyBlob(pipe->display-
>>> drm_fd,
>> +						   pipe_values[IGT_C
>> RTC_MODE_ID]);
>>  
>> -	if (legacy->mode_valid) {
>> -		igt_assert_neq(legacy->mode_valid, 0);
>> -		igt_assert_eq(crtc->mode.len,
>> -		              sizeof(struct drm_mode_modeinfo));
>> -		do_or_die(memcmp(&legacy->mode, crtc->mode.data,
>> -		                 crtc->mode.len));
>> -		igt_assert_eq(legacy->width, legacy->mode.hdisplay);
>> -		igt_assert_eq(legacy->height, legacy-
>>> mode.vdisplay);
>> -	} else {
>> -		igt_assert_eq(legacy->mode_valid, 0);
>> -	}
>> +		igt_assert(mode_prop);
>>  
>> -	memcpy(&crtc_kernel, crtc, sizeof(crtc_kernel));
>> -	crtc_get_current_state(&crtc_kernel);
>> -
>> -	if (crtc_kernel.mode.id != 0)
>> -		igt_assert_eq(crtc_kernel.mode.len,
>> +		igt_assert_eq(mode_prop->length,
>>  		              sizeof(struct drm_mode_modeinfo));
>> -
>> -	/* Optionally relax the check for MODE_ID: using the legacy
>> SetCrtc
>> -	 * API can potentially change MODE_ID even if the mode
>> itself remains
>> -	 * unchanged. */
>> -	if (((relax & CRTC_RELAX_MODE) &&
>> -	    (crtc_kernel.mode.id != crtc->mode.id &&
>> -	     crtc_kernel.mode.id != 0 && crtc->mode.id != 0)) &&
>> -	    memcmp(crtc_kernel.mode.data, crtc->mode.data,
>> -		   sizeof(struct drm_mode_modeinfo)) == 0) {
>> -		crtc_kernel.mode.id = crtc->mode.id;
>> -		crtc_kernel.mode.data = crtc->mode.data;
>> -	}
>> -
>> -	do_or_die(memcmp(&crtc_kernel, crtc, sizeof(crtc_kernel)));
>> -
>> -	drmModeFreeCrtc(legacy);
>> -}
>> -
>> -static void crtc_commit_legacy(struct kms_atomic_crtc_state *crtc,
>> -			       struct kms_atomic_plane_state *plane,
>> -			       enum kms_atomic_check_relax relax)
>> -{
>> -	drmModeObjectPropertiesPtr props;
>> -	uint32_t *connectors;
>> -	int num_connectors = 0;
>> -	int i;
>> -
>> -	if (!crtc->active) {
>> -		do_or_die(drmModeSetCrtc(crtc->state->desc->fd,
>> -					 crtc->obj, 0, 0, 0, NULL,
>> 0, NULL));
>> -		return;
>> -	}
>> -
>> -	connectors = calloc(crtc->state->num_connectors,
>> -			    sizeof(*connectors));
>> -	igt_assert(connectors);
>> -
>> -	igt_assert_neq_u32(crtc->mode.id, 0);
>> -
>> -	for (i = 0; i < crtc->state->num_connectors; i++) {
>> -		struct kms_atomic_connector_state *connector =
>> -			&crtc->state->connectors[i];
>> -
>> -		if (connector->crtc_id != crtc->obj)
>> -			continue;
>> -
>> -		connectors[num_connectors++] = connector->obj;
>> +		mode = mode_prop->data;
>>  	}
>>  
>> -	do_or_die(drmModeSetCrtc(crtc->state->desc->fd, crtc->obj,
>> -	                         plane->fb_id,
>> -				 plane->src_x >> 16, plane->src_y >>
>> 16,
>> -				 (num_connectors) ? connectors :
>> NULL,
>> -				 num_connectors,
>> -				 crtc->mode.data));
>> -	/* When doing a legacy commit, the core may update MODE_ID
>> to be a new
>> -	 * blob implicitly created by the legacy request. Hence we
>> backfill
>> -	 * the value in the state object to ensure they match. */
>> -	props = drmModeObjectGetProperties(crtc->state->desc->fd,
>> crtc->obj,
>> -					   DRM_MODE_OBJECT_CRTC);
>> -	igt_assert(props);
>> -
>> -	for (i = 0; i < props->count_props; i++) {
>> -		if (props->props[i] !=
>> -		    crtc->state->desc->props_crtc[IGT_CRTC_MODE_ID])
>> -			continue;
>> -		crtc->mode.id = props->prop_values[i];
>> -		break;
>> -	}
>> +	legacy = drmModeGetCrtc(pipe->display->drm_fd, pipe-
>>> crtc_id);
>> +	igt_assert(legacy);
>>  
>> -	drmModeFreeObjectProperties(props);
>> +	igt_assert_eq_u32(legacy->crtc_id, pipe->crtc_id);
>> +	igt_assert_eq_u32(legacy->x, primary_values[IGT_PLANE_SRC_X]
>>>> 16);
>> +	igt_assert_eq_u32(legacy->y, primary_values[IGT_PLANE_SRC_Y]
>>>> 16);
>>  
>> -	crtc_check_current_state(crtc, plane, relax);
>> -	plane_check_current_state(plane, relax);
>> -}
>> +	igt_assert_eq_u32(legacy->buffer_id,
>> primary_values[IGT_PLANE_FB_ID]);
>>  
>> -static struct kms_atomic_crtc_state *find_crtc(struct
>> kms_atomic_state *state,
>> -					       bool must_be_enabled)
>> -{
>> -	int i;
>> +	if (legacy->mode_valid) {
>> +		igt_assert(mode_prop);
>>  
>> -	for (i = 0; i < state->num_crtcs; i++) {
>> -		struct kms_atomic_crtc_state *crtc = &state-
>>> crtcs[i];
>> +		do_or_die(memcmp(&legacy->mode, mode,
>> sizeof(*mode)));
>>  
>> -		if (!crtc->obj)
>> -			continue;
>> -		if (must_be_enabled && !crtc->active)
>> -			continue;
>> +		igt_assert_eq(legacy->width, legacy->mode.hdisplay);
>> +		igt_assert_eq(legacy->height, legacy-
>>> mode.vdisplay);
>>  
>> -		crtc_get_current_state(crtc);
>> -		return crtc;
>> +		igt_assert_neq(pipe_values[IGT_CRTC_MODE_ID], 0);
>> +	} else {
>> +		igt_assert(!mode_prop);
>>  	}
>>  
>> -	return NULL;
>> -}
>> +	crtc_get_current_state(pipe, current_pipe_values);
>>  
>> -static void fill_obj_props(int fd, uint32_t id, int type, int
>> num_props,
>> -			   const char **prop_names, uint32_t
>> *prop_ids)
>> -{
>> -	drmModeObjectPropertiesPtr props;
>> -	int i, j;
>> -
>> -	props = drmModeObjectGetProperties(fd, id, type);
>> -	igt_assert(props);
>> +	/* Optionally relax the check for MODE_ID: using the legacy
>> SetCrtc
>> +	 * API can potentially change MODE_ID even if the mode
>> itself remains
>> +	 * unchanged. */
>> +	if (relax & CRTC_RELAX_MODE && mode &&
>> current_pipe_values[IGT_CRTC_MODE_ID] &&
>> +	    current_pipe_values[IGT_CRTC_MODE_ID] !=
>> pipe_values[IGT_CRTC_MODE_ID]) {
>> +		drmModePropertyBlobRes *cur_prop =
>> +			drmModeGetPropertyBlob(pipe->display-
>>> drm_fd,
>> +					       current_pipe_values[I
>> GT_CRTC_MODE_ID]);
>>  
>> -	for (i = 0; i < props->count_props; i++) {
>> -		drmModePropertyPtr prop =
>> -			drmModeGetProperty(fd, props->props[i]);
>> +		igt_assert(cur_prop);
>> +		igt_assert_eq(cur_prop->length, sizeof(struct
>> drm_mode_modeinfo));
>>  
>> -		for (j = 0; j < num_props; j++) {
>> -			if (strcmp(prop->name, prop_names[j]) != 0)
>> -				continue;
>> -			prop_ids[j] = props->props[i];
>> -			break;
>> -		}
>> +		if (!memcmp(cur_prop->data, mode, sizeof(*mode)))
>> +			current_pipe_values[IGT_CRTC_MODE_ID] =
>> pipe_values[IGT_CRTC_MODE_ID];
>>  
>> -		drmModeFreeProperty(prop);
>> +		drmModeFreePropertyBlob(cur_prop);
>>  	}
>>  
>> -	drmModeFreeObjectProperties(props);
>> -}
>> +	do_or_die(memcmp(pipe_values, current_pipe_values,
>> sizeof(current_pipe_values)));
>>  
>> -static void fill_obj_prop_map(int fd, uint32_t id, int type, const
>> char *name,
>> -			      int num_enums, const char
>> **enum_names,
>> -			      uint64_t *enum_ids)
>> -{
>> -	drmModeObjectPropertiesPtr props;
>> -	int i, j, k;
>> -
>> -	props = drmModeObjectGetProperties(fd, id, type);
>> -	igt_assert(props);
>> -
>> -	for (i = 0; i < props->count_props; i++) {
>> -		drmModePropertyPtr prop =
>> -			drmModeGetProperty(fd, props->props[i]);
>> -
>> -		igt_assert(prop);
>> -
>> -		if (strcmp(prop->name, name) != 0) {
>> -			drmModeFreeProperty(prop);
>> -			continue;
>> -		}
>> -
>> -		for (j = 0; j < prop->count_enums; j++) {
>> -			struct drm_mode_property_enum *e = &prop-
>>> enums[j];
>> -
>> -			for (k = 0; k < num_enums; k++) {
>> -				if (strcmp(e->name, enum_names[k])
>> != 0)
>> -					continue;
>> -
>> -				enum_ids[k] = e->value;
>> -				break;
>> -			}
>> -		}
>> -
>> -		drmModeFreeProperty(prop);
>> -	}
>> +	drmModeFreeCrtc(legacy);
>> +	drmModeFreePropertyBlob(mode_prop);
>>  }
>>  
>> -static void atomic_setup(struct kms_atomic_state *state)
>> +static void crtc_commit(igt_pipe_t *pipe, igt_plane_t *plane,
>> +			enum igt_commit_style s,
>> +			enum kms_atomic_check_relax relax)
>>  {
>> -	struct kms_atomic_desc *desc = state->desc;
>> -	drmModeResPtr res;
>> -	drmModePlaneResPtr res_plane;
>> -	int i;
>> -
>> -	desc->fd = drm_open_driver_master(DRIVER_ANY);
>> -	igt_assert_fd(desc->fd);
>> -
>> -	igt_skip_on(drmSetClientCap(desc->fd, DRM_CLIENT_CAP_ATOMIC,
>> 1));
>> -
>> -	res = drmModeGetResources(desc->fd);
>> -	res_plane = drmModeGetPlaneResources(desc->fd);
>> -	igt_assert(res);
>> -	igt_assert(res_plane);
>> -
>> -	igt_assert_lt(0, res->count_crtcs);
>> -	state->num_crtcs = res->count_crtcs;
>> -	state->crtcs = calloc(state->num_crtcs, sizeof(*state-
>>> crtcs));
>> -	igt_assert(state->crtcs);
>> -
>> -	igt_assert_lt(0, res_plane->count_planes);
>> -	state->num_planes = res_plane->count_planes;
>> -	state->planes = calloc(state->num_planes, sizeof(*state-
>>> planes));
>> -	igt_assert(state->planes);
>> -
>> -	igt_assert_lt(0, res->count_connectors);
>> -	state->num_connectors = res->count_connectors;
>> -	state->connectors = calloc(state->num_connectors,
>> -				   sizeof(*state->connectors));
>> -	igt_assert(state->connectors);
>> -
>> -	fill_obj_props(desc->fd, res->crtcs[0],
>> -		       DRM_MODE_OBJECT_CRTC, IGT_NUM_CRTC_PROPS,
>> -		       igt_crtc_prop_names, desc->props_crtc);
>> -
>> -	fill_obj_props(desc->fd, res_plane->planes[0],
>> -		       DRM_MODE_OBJECT_PLANE, IGT_NUM_PLANE_PROPS,
>> -		       igt_plane_prop_names, desc->props_plane);
>> -	fill_obj_prop_map(desc->fd, res_plane->planes[0],
>> -			  DRM_MODE_OBJECT_PLANE, "type",
>> -			  NUM_PLANE_TYPE_PROPS,
>> plane_type_prop_names,
>> -			  desc->props_plane_type);
>> -
>> -	fill_obj_props(desc->fd, res->connectors[0],
>> -		       DRM_MODE_OBJECT_CONNECTOR,
>> IGT_NUM_CONNECTOR_PROPS,
>> -		       igt_connector_prop_names, desc-
>>> props_connector);
>> -
>> -	for (i = 0; i < state->num_crtcs; i++) {
>> -		struct kms_atomic_crtc_state *crtc = &state-
>>> crtcs[i];
>> -
>> -		crtc->state = state;
>> -		crtc->obj = res->crtcs[i];
>> -		crtc->idx = i;
>> -		crtc_get_current_state(crtc);
>> -
>> -		/* The blob pointed to by MODE_ID could well be
>> transient,
>> -		 * and lose its last reference as we switch away
>> from it.
>> -		 * Duplicate the blob here so we have a reference we
>> know we
>> -		 * own. */
>> -		if (crtc->mode.id != 0)
>> -		    crtc->mode.id = blob_duplicate(desc->fd, crtc-
>>> mode.id);
>> -	}
>> +	igt_display_commit2(pipe->display, s);
>>  
>> -	for (i = 0; i < state->num_planes; i++) {
>> -		drmModePlanePtr plane =
>> -			drmModeGetPlane(desc->fd, res_plane-
>>> planes[i]);
>> -		igt_assert(plane);
>> -
>> -		state->planes[i].state = state;
>> -		state->planes[i].obj = res_plane->planes[i];
>> -		state->planes[i].crtc_mask = plane->possible_crtcs;
>> -		plane_get_current_state(&state->planes[i]);
>> -	}
>> -
>> -	for (i = 0; i < state->num_connectors; i++) {
>> -		state->connectors[i].state = state;
>> -		state->connectors[i].obj = res->connectors[i];
>> -		connector_get_current_state(&state->connectors[i]);
>> -	}
>> -
>> -	drmModeFreePlaneResources(res_plane);
>> -	drmModeFreeResources(res);
>> +	crtc_check_current_state(pipe, pipe->values, plane->values,
>> relax);
>> +	plane_check_current_state(plane, plane->values, relax);
>>  }
>>  
>> -static struct kms_atomic_state *
>> -atomic_state_dup(const struct kms_atomic_state *state)
>> +static void crtc_commit_atomic_flags_err(igt_pipe_t *pipe,
>> igt_plane_t *plane,
>> +					 unsigned flags,
>> +					 enum kms_atomic_check_relax
>> relax,
>> +					 int err)
>>  {
>> -	struct kms_atomic_state *ret = calloc(1, sizeof(*ret));
>> -
>> -	igt_assert(ret);
>> -	*ret = *state;
>> +	uint64_t current_pipe_values[IGT_NUM_CRTC_PROPS];
>> +	uint64_t current_plane_values[IGT_NUM_PLANE_PROPS];
>>  
>> -	ret->crtcs = calloc(ret->num_crtcs, sizeof(*ret->crtcs));
>> -	igt_assert(ret->crtcs);
>> -	memcpy(ret->crtcs, state->crtcs, ret->num_crtcs *
>> sizeof(*ret->crtcs));
>> +	crtc_get_current_state(pipe, current_pipe_values);
>> +	plane_get_current_state(plane, current_plane_values);
>>  
>> -	ret->planes = calloc(ret->num_planes, sizeof(*ret->planes));
>> -	igt_assert(ret->planes);
>> -	memcpy(ret->planes, state->planes,
>> -	       ret->num_planes * sizeof(*ret->planes));
>> +	igt_assert_eq(-err, igt_display_try_commit_atomic(pipe-
>>> display, flags, NULL));
>>  
>> -	ret->connectors = calloc(ret->num_connectors, sizeof(*ret-
>>> connectors));
>> -	igt_assert(ret->connectors);
>> -	memcpy(ret->connectors, state->connectors,
>> -	       ret->num_connectors * sizeof(*ret->connectors));
>> -
>> -	return ret;
>> +	crtc_check_current_state(pipe, current_pipe_values,
>> current_plane_values, relax);
>> +	plane_check_current_state(plane, current_plane_values,
>> relax);
>>  }
>>  
>> -static void atomic_state_free(struct kms_atomic_state *state)
>> -{
>> -	free(state->crtcs);
>> -	free(state->planes);
>> -	free(state->connectors);
>> -	free(state);
>> -}
>> +#define crtc_commit_atomic_err(pipe, plane, relax, err) \
>> +	crtc_commit_atomic_flags_err(pipe, plane,
>> DRM_MODE_ATOMIC_ALLOW_MODESET, relax, err)
>>  
>> -static uint32_t plane_get_igt_format(struct kms_atomic_plane_state
>> *plane)
>> +static uint32_t plane_get_igt_format(igt_plane_t *plane)
>>  {
>>  	drmModePlanePtr plane_kms;
>>  	const uint32_t *igt_formats;
>> -	uint32_t ret = 0;
>>  	int num_igt_formats;
>>  	int i;
>>  
>> -	plane_kms = drmModeGetPlane(plane->state->desc->fd, plane-
>>> obj);
>> -	igt_assert(plane_kms);
>> +	plane_kms = plane->drm_plane;
>>  
>>  	igt_get_all_cairo_formats(&igt_formats, &num_igt_formats);
>>  	for (i = 0; i < num_igt_formats; i++) {
>>  		int j;
>>  
>>  		for (j = 0; j < plane_kms->count_formats; j++) {
>> -			if (plane_kms->formats[j] == igt_formats[i])
>> {
>> -				ret = plane_kms->formats[j];
>> -				break;
>> -			}
>> +			if (plane_kms->formats[j] == igt_formats[i])
>> +				return plane_kms->formats[j];
>>  		}
>>  	}
>>  
>> -	drmModeFreePlane(plane_kms);
>> -	return ret;
>> +	return 0;
>>  }
>>  
>>  static void
>> -set_dpms(int fd, int mode)
>> +set_dpms(igt_output_t *output, int mode)
>>  {
>> -	int i;
>> -	drmModeConnector *connector;
>> -	uint32_t id;
>> -	drmModeRes *resources = drmModeGetResources(fd);
>> -
>> -	for (i = 0; i < resources->count_connectors; i++) {
>> -		id = resources->connectors[i];
>> -
>> -		connector = drmModeGetConnectorCurrent(fd, id);
>> -
>> -		kmstest_set_connector_dpms(fd, connector, mode);
>> -
>> -		drmModeFreeConnector(connector);
>> -	}
>> +	do_or_die(drmModeConnectorSetProperty(output->display-
>>> drm_fd, output->id,
>> +					      output-
>>> props[IGT_CONNECTOR_DPMS], mode));
>>  }
>>  
>> -static void plane_overlay(struct kms_atomic_crtc_state *crtc,
>> -			  struct kms_atomic_plane_state *plane_old)
>> +static void plane_overlay(igt_pipe_t *pipe, igt_output_t *output,
>> igt_plane_t *plane)
>>  {
>> -	struct drm_mode_modeinfo *mode = crtc->mode.data;
>> -	struct kms_atomic_plane_state plane = *plane_old;
>> -	uint32_t format = plane_get_igt_format(&plane);
>> -	drmModeAtomicReq *req = drmModeAtomicAlloc();
>> +	drmModeModeInfo *mode = igt_output_get_mode(output);
>> +	uint32_t format = plane_get_igt_format(plane);
>>  	struct igt_fb fb;
>> +	uint32_t w = mode->hdisplay / 2;
>> +	uint32_t h = mode->vdisplay / 2;
>>  
>> -	igt_require(req);
>>  	igt_require(format != 0);
>>  
>> -	plane.src_x = 0;
>> -	plane.src_y = 0;
>> -	plane.src_w = (mode->hdisplay / 2) << 16;
>> -	plane.src_h = (mode->vdisplay / 2) << 16;
>> -	plane.crtc_x = mode->hdisplay / 4;
>> -	plane.crtc_y = mode->vdisplay / 4;
>> -	plane.crtc_w = mode->hdisplay / 2;
>> -	plane.crtc_h = mode->vdisplay / 2;
>> -	plane.crtc_id = crtc->obj;
>> -	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
>> -					    plane.crtc_w,
>> plane.crtc_h,
>> -					    format,
>> I915_TILING_NONE, &fb);
>> +	igt_create_pattern_fb(pipe->display->drm_fd, w, h,
>> +			      format, I915_TILING_NONE, &fb);
>> +
>> +	igt_plane_set_fb(plane, &fb);
>> +	igt_plane_set_position(plane, w/2, h/2);
>>  
>>  	/* Enable the overlay plane using the atomic API, and
>> double-check
>>  	 * state is what we think it should be. */
>> -	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
>> +	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>>  
>>  	/* Disable the plane and check the state matches the old. */
>> -	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
>> +	igt_plane_set_fb(plane, NULL);
>> +	igt_plane_set_position(plane, 0, 0);
>> +	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>>  
>>  	/* Re-enable the plane through the legacy plane API, and
>> verify through
>>  	 * atomic. */
>> -	plane_commit_legacy(&plane, ATOMIC_RELAX_NONE);
>> +	igt_plane_set_fb(plane, &fb);
>> +	igt_plane_set_position(plane, w/2, h/2);
>> +	plane_commit(plane, COMMIT_LEGACY, ATOMIC_RELAX_NONE);
>>  
>>  	/* Restore the plane to its original settings through the
>> legacy plane
>>  	 * API, and verify through atomic. */
>> -	plane_commit_legacy(plane_old, ATOMIC_RELAX_NONE);
>> +	igt_plane_set_fb(plane, NULL);
>> +	igt_plane_set_position(plane, 0, 0);
>> +	plane_commit(plane, COMMIT_LEGACY, ATOMIC_RELAX_NONE);
>>  
>> -	drmModeAtomicFree(req);
>> +	igt_remove_fb(pipe->display->drm_fd, &fb);
>>  }
>>  
>> -static void plane_primary(struct kms_atomic_crtc_state *crtc,
>> -			  struct kms_atomic_plane_state *plane_old)
>> +static void plane_primary(igt_pipe_t *pipe, igt_plane_t *plane,
>> struct igt_fb *fb)
>>  {
>> -	struct drm_mode_modeinfo *mode = crtc->mode.data;
>> -	struct kms_atomic_plane_state plane = *plane_old;
>> -	uint32_t format = plane_get_igt_format(&plane);
>> -	drmModeAtomicReq *req = drmModeAtomicAlloc();
>> -	struct igt_fb fb;
>> -	uint32_t flags = 0;
>> -	int ret;
>> -
>> -	igt_require(format != 0);
>> +	struct igt_fb fb2;
>>  
>> -	plane.src_x = 0;
>> -	plane.src_y = 0;
>> -	plane.src_w = mode->hdisplay << 16;
>> -	plane.src_h = mode->vdisplay << 16;
>> -	plane.crtc_x = 0;
>> -	plane.crtc_y = 0;
>> -	plane.crtc_w = mode->hdisplay;
>> -	plane.crtc_h = mode->vdisplay;
>> -	plane.crtc_id = crtc->obj;
>> -	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
>> -					    plane.crtc_w,
>> plane.crtc_h,
>> -					    format,
>> I915_TILING_NONE, &fb);
>> -
>> -	drmModeAtomicSetCursor(req, 0);
>> -	crtc_populate_req(crtc, req);
>> -	plane_populate_req(&plane, req);
>> -	ret = drmModeAtomicCommit(crtc->state->desc->fd, req,
>> -				  DRM_MODE_ATOMIC_TEST_ONLY, NULL);
>> -	/* Try harder in case the failure is caused by disallowing
>> modeset. */
>> -	if (ret == -EINVAL)
>> -		flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
>> +	igt_create_color_pattern_fb(pipe->display->drm_fd,
>> +				    fb->width, fb->height,
>> +				    fb->drm_format,
>> I915_TILING_NONE,
>> +				    0.2, 0.2, 0.2, &fb2);
>>  
>>  	/* Flip the primary plane using the atomic API, and double-
>> check
>>  	 * state is what we think it should be. */
>> -	crtc_commit_atomic(crtc, &plane, req, ATOMIC_RELAX_NONE,
>> flags);
>> +	igt_plane_set_fb(plane, &fb2);
>> +	crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>>  
>>  	/* Restore the primary plane and check the state matches the
>> old. */
>> -	crtc_commit_atomic(crtc, plane_old, req, ATOMIC_RELAX_NONE,
>> flags);
>> +	igt_plane_set_fb(plane, fb);
>> +	crtc_commit(pipe, plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>>  
>> -	/* Re-enable the plane through the legacy CRTC/primary-plane 
>> API, and
>> +	/* Set the plane through the legacy CRTC/primary-plane API,
>> and
>>  	 * verify through atomic. */
>> -	crtc_commit_legacy(crtc, &plane, CRTC_RELAX_MODE);
>> +	igt_plane_set_fb(plane, &fb2);
>> +	crtc_commit(pipe, plane, COMMIT_LEGACY, CRTC_RELAX_MODE);
>>  
>>  	/* Restore the plane to its original settings through the
>> legacy CRTC
>>  	 * API, and verify through atomic. */
>> -	crtc_commit_legacy(crtc, plane_old, CRTC_RELAX_MODE);
>> -
>> -	/* Finally, restore to the original state. */
>> -	crtc_commit_atomic(crtc, plane_old, req, ATOMIC_RELAX_NONE,
>> flags);
>> +	igt_plane_set_fb(plane, fb);
>> +	crtc_commit(pipe, plane, COMMIT_LEGACY, CRTC_RELAX_MODE);
>>  
>> -	drmModeAtomicFree(req);
>> +	/* Set the plane through the universal setplane API, and
>> +	 * verify through atomic. */
>> +	igt_plane_set_fb(plane, &fb2);
>> +	plane_commit(plane, COMMIT_UNIVERSAL, ATOMIC_RELAX_NONE);
>>  }
>>  
>>  /* test to ensure that DRM_MODE_ATOMIC_TEST_ONLY really only touches
>> the
>>   * free-standing state objects and nothing else.
>>   */
>> -static void test_only(struct kms_atomic_crtc_state *crtc,
>> -		      struct kms_atomic_plane_state *plane_old)
>> +static void test_only(igt_pipe_t *pipe_obj,
>> +		      igt_plane_t *primary,
>> +		      igt_output_t *output)
>>  {
>> -	struct drm_mode_modeinfo *mode = crtc->mode.data;
>> -	struct kms_atomic_plane_state plane = *plane_old;
>> -	uint32_t format = plane_get_igt_format(&plane);
>> -	drmModeAtomicReq *req = drmModeAtomicAlloc();
>> +	drmModeModeInfo *mode = igt_output_get_mode(output);
>> +	uint32_t format = plane_get_igt_format(primary);
>>  	struct igt_fb fb;
>> -	int ret;
>> +	uint64_t old_plane_values[IGT_NUM_PLANE_PROPS],
>> old_crtc_values[IGT_NUM_CRTC_PROPS];
>>  
>>  	igt_require(format != 0);
>>  
>> -	plane.src_x = 0;
>> -	plane.src_y = 0;
>> -	plane.src_w = mode->hdisplay << 16;
>> -	plane.src_h = mode->vdisplay << 16;
>> -	plane.crtc_x = 0;
>> -	plane.crtc_y = 0;
>> -	plane.crtc_w = mode->hdisplay;
>> -	plane.crtc_h = mode->vdisplay;
>> -	plane.crtc_id = crtc->obj;
>> -	plane.fb_id = igt_create_pattern_fb(plane.state->desc->fd,
>> -					    plane.crtc_w,
>> plane.crtc_h,
>> -					    format,
>> I915_TILING_NONE, &fb);
>> -
>> -	drmModeAtomicSetCursor(req, 0);
>> -	crtc_populate_req(crtc, req);
>> -	plane_populate_req(&plane, req);
>> -	ret = drmModeAtomicCommit(crtc->state->desc->fd, req,
>> -				  DRM_MODE_ATOMIC_TEST_ONLY, NULL);
>> -
>> -	igt_assert_eq(ret, 0);
>> -
>> -	/* go through dpms off/on cycle */
>> -	set_dpms(crtc->state->desc->fd, DRM_MODE_DPMS_OFF);
>> -	set_dpms(crtc->state->desc->fd, DRM_MODE_DPMS_ON);
>> -
>> -	/* check the state */
>> -	crtc_check_current_state(crtc, plane_old,
>> ATOMIC_RELAX_NONE);
>> -	plane_check_current_state(plane_old, ATOMIC_RELAX_NONE);
>> -
>> -	/* Re-enable the plane through the legacy CRTC/primary-plane 
>> API, and
>> -	 * verify through atomic. */
>> -	crtc_commit_legacy(crtc, plane_old, CRTC_RELAX_MODE);
>> +	plane_get_current_state(primary, old_plane_values);
>> +	crtc_get_current_state(pipe_obj, old_crtc_values);
>> +
>> +	igt_assert(!old_crtc_values[IGT_CRTC_MODE_ID]);
>> +
>> +	igt_create_pattern_fb(pipe_obj->display->drm_fd,
>> +			     mode->hdisplay, mode->vdisplay,
>> +			     format, I915_TILING_NONE, &fb);
>> +	igt_plane_set_fb(primary, &fb);
>> +	igt_output_set_pipe(output, pipe_obj->pipe);
>> +
>> +	igt_display_commit_atomic(pipe_obj->display,
>> DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
>> +
>> +	/* check the state, should still be old state */
>> +	crtc_check_current_state(pipe_obj, old_crtc_values,
>> old_plane_values, ATOMIC_RELAX_NONE);
>> +	plane_check_current_state(primary, old_plane_values,
>> ATOMIC_RELAX_NONE);
>> +
>> +	/*
>> +	 * Enable the plane through the legacy CRTC/primary-plane
>> API, and
>> +	 * verify through atomic.
>> +	 */
>> +	crtc_commit(pipe_obj, primary, COMMIT_LEGACY,
>> CRTC_RELAX_MODE);
>> +
>> +	/* Same for disable.. */
>> +	plane_get_current_state(primary, old_plane_values);
>> +	crtc_get_current_state(pipe_obj, old_crtc_values);
>> +
>> +	igt_plane_set_fb(primary, NULL);
>> +	igt_output_set_pipe(output, PIPE_NONE);
>> +
>> +	igt_display_commit_atomic(pipe_obj->display,
>> DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
>>  
>> -	drmModeAtomicFree(req);
>> +	/* for extra stress, go through dpms off/on cycle */
>> +	set_dpms(output, DRM_MODE_DPMS_OFF);
>> +	set_dpms(output, DRM_MODE_DPMS_ON);
> There is this library function 'kmstest_set_connector_dpms()'. Could we
> utilize this function here instead?
Sure, I never understood what the dpms call was supposed to expose though..

Want me to resend or is replacing the call with kmstest_set_connector_dpms(s, output->config.connector, DRM_MODE_DPMS_OFF); enough?
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2] tests/kms_atomic: Convert/rewrite tests to use igt_kms framework, v2.
  2017-10-20 10:08       ` Maarten Lankhorst
@ 2017-10-20 10:16         ` Mika Kahola
  2017-10-20 11:43           ` Maarten Lankhorst
  0 siblings, 1 reply; 45+ messages in thread
From: Mika Kahola @ 2017-10-20 10:16 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx; +Cc: Daniel Stone

On Fri, 2017-10-20 at 12:08 +0200, Maarten Lankhorst wrote:
> Op 20-10-17 om 12:02 schreef Mika Kahola:
> > 
> > On Thu, 2017-10-12 at 17:33 +0200, Maarten Lankhorst wrote:
> > > 
> > > Now that we can set individual properties through the igt_kms
> > > api,
> > > we no longer need to duplicate functionality from igt_kms. Set
> > > invalid
> > > properties directly, and rewrite kms_atomic.c to use igt_display.
> > > This will allow us to remove a lot of code in kms_atomic.c,
> > > and benefit from how igt_kms can set up a valid configuration,
> > > instead of having to inherit it from fbcon.
> > > 
> > > Changes since v1:
> > > - Fix test failure when atomic_invalid_params is run standalone.
> > > 
> > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.c
> > > om>
> > > Cc: Daniel Stone <daniels@collabora.com>
> > > ---
> > >  tests/kms_atomic.c | 1668 ++++++++++++++++--------------------
> > > ----
> > > ------------
> > >  1 file changed, 512 insertions(+), 1156 deletions(-)
> > > 
> > > diff --git a/tests/kms_atomic.c b/tests/kms_atomic.c
> > > index 042a7c263aab..e0fc324eab61 100644
> > > --- a/tests/kms_atomic.c
> > > +++ b/tests/kms_atomic.c
> > > @@ -46,10 +46,6 @@
> > >  #include "igt_aux.h"
> > >  #include "sw_sync.h"
> > >  
> > > -#ifndef DRM_CLIENT_CAP_ATOMIC
> > > -#define DRM_CLIENT_CAP_ATOMIC 3
> > > -#endif
> > > -
> > >  #ifndef DRM_CAP_CURSOR_WIDTH
> > >  #define DRM_CAP_CURSOR_WIDTH 0x8
> > >  #endif
> > > @@ -58,23 +54,6 @@
> > >  #define DRM_CAP_CURSOR_HEIGHT 0x9
> > >  #endif
> > >  
> > > -#ifndef DRM_MODE_ATOMIC_TEST_ONLY
> > > -#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
> > > -#define DRM_MODE_ATOMIC_NONBLOCK 0x0200
> > > -#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
> > > -
> > > -struct drm_mode_atomic {
> > > -	__u32 flags;
> > > -	__u32 count_objs;
> > > -	__u64 objs_ptr;
> > > -	__u64 count_props_ptr;
> > > -	__u64 props_ptr;
> > > -	__u64 prop_values_ptr;
> > > -	__u64 reserved;
> > > -	__u64 user_data;
> > > -};
> > > -#endif
> > > -
> > >  IGT_TEST_DESCRIPTION("Test atomic modesetting API");
> > >  
> > >  enum kms_atomic_check_relax {
> > > @@ -83,1259 +62,652 @@ enum kms_atomic_check_relax {
> > >  	PLANE_RELAX_FB = (1 << 1)
> > >  };
> > >  
> > > -/**
> > > - * KMS plane type enum
> > > - *
> > > - * KMS plane types are represented by enums, which do not have
> > > stable numeric
> > > - * values, but must be looked up by their string value each
> > > time.
> > > - *
> > > - * To make the code more simple, we define a plane_type enum
> > > which
> > > maps to
> > > - * each KMS enum value. These values must be looked up through
> > > the
> > > map, and
> > > - * cannot be passed directly to KMS functions.
> > > - */
> > > -enum plane_type {
> > > -	PLANE_TYPE_PRIMARY = 0,
> > > -	PLANE_TYPE_OVERLAY,
> > > -	PLANE_TYPE_CURSOR,
> > > -	NUM_PLANE_TYPE_PROPS
> > > -};
> > > -
> > > -static const char *plane_type_prop_names[NUM_PLANE_TYPE_PROPS] =
> > > {
> > > -	"Primary",
> > > -	"Overlay",
> > > -	"Cursor"
> > > -};
> > > -
> > > -struct kms_atomic_blob {
> > > -	uint32_t id; /* 0 if not already allocated */
> > > -	size_t len;
> > > -	void *data;
> > > -};
> > > -
> > > -struct kms_atomic_connector_state {
> > > -	struct kms_atomic_state *state;
> > > -	uint32_t obj;
> > > -	uint32_t crtc_id;
> > > -};
> > > -
> > > -struct kms_atomic_plane_state {
> > > -	struct kms_atomic_state *state;
> > > -	uint32_t obj;
> > > -	enum plane_type type;
> > > -	uint32_t crtc_mask;
> > > -	uint32_t crtc_id; /* 0 to disable */
> > > -	uint32_t fb_id; /* 0 to disable */
> > > -	uint32_t src_x, src_y, src_w, src_h; /* 16.16 fixed-
> > > point */
> > > -	uint32_t crtc_x, crtc_y, crtc_w, crtc_h; /* normal
> > > integers
> > > */
> > > -	int32_t fence_fd;
> > > -};
> > > -
> > > -struct kms_atomic_crtc_state {
> > > -	struct kms_atomic_state *state;
> > > -	uint32_t obj;
> > > -	int idx;
> > > -	bool active;
> > > -	int32_t *out_fence_ptr;
> > > -	struct kms_atomic_blob mode;
> > > -};
> > > -
> > > -struct kms_atomic_state {
> > > -	struct kms_atomic_connector_state *connectors;
> > > -	int num_connectors;
> > > -	struct kms_atomic_crtc_state *crtcs;
> > > -	int num_crtcs;
> > > -	struct kms_atomic_plane_state *planes;
> > > -	int num_planes;
> > > -	struct kms_atomic_desc *desc;
> > > -};
> > > -
> > > -struct kms_atomic_desc {
> > > -	int fd;
> > > -	uint32_t props_connector[IGT_NUM_CONNECTOR_PROPS];
> > > -	uint32_t props_crtc[IGT_NUM_CRTC_PROPS];
> > > -	uint32_t props_plane[IGT_NUM_PLANE_PROPS];
> > > -	uint64_t props_plane_type[NUM_PLANE_TYPE_PROPS];
> > > -};
> > > -
> > > -static uint32_t blob_duplicate(int fd, uint32_t id_orig)
> > > +static bool plane_filter(enum igt_atomic_plane_properties prop)
> > >  {
> > > -	drmModePropertyBlobPtr orig = drmModeGetPropertyBlob(fd,
> > > id_orig);
> > > -	uint32_t id_new;
> > > -
> > > -	igt_assert(orig);
> > > -	do_or_die(drmModeCreatePropertyBlob(fd, orig->data,
> > > orig-
> > > > 
> > > > length,
> > > -					    &id_new));
> > > -	drmModeFreePropertyBlob(orig);
> > > +	if ((1 << prop) & IGT_PLANE_COORD_CHANGED_MASK)
> > > +		return false;
> > >  
> > > -	return id_new;
> > > -}
> > > -
> > > -#define crtc_set_prop(req, crtc, prop, value) \
> > > -	igt_assert_lt(0, drmModeAtomicAddProperty(req, crtc-
> > > >obj, \
> > > -						  crtc->state-
> > > >desc-
> > > > 
> > > > props_crtc[prop], \
> > > -						  value));
> > > -
> > > -#define plane_set_prop(req, plane, prop, value) \
> > > -	igt_assert_lt(0, drmModeAtomicAddProperty(req, plane-
> > > >obj, \
> > > -						  plane->state-
> > > > 
> > > > desc->props_plane[prop], \
> > > -						  value));
> > > -
> > > -#define do_atomic_commit(fd, req, flags) \
> > > -	do_or_die(drmModeAtomicCommit(fd, req, flags, NULL));
> > > +	if (prop == IGT_PLANE_CRTC_ID || prop ==
> > > IGT_PLANE_FB_ID)
> > > +		return false;
> > >  
> > > -#define do_atomic_commit_err(fd, req, flags, err) { \
> > > -	igt_assert_neq(drmModeAtomicCommit(fd, req, flags,
> > > NULL),
> > > 0); \
> > > -	igt_assert_eq(errno, err); \
> > > -}
> > > -
> > > -#define crtc_commit_atomic(crtc, plane, req, relax, flags) { \
> > > -	drmModeAtomicSetCursor(req, 0); \
> > > -	crtc_populate_req(crtc, req); \
> > > -	plane_populate_req(plane, req); \
> > > -	do_atomic_commit((crtc)->state->desc->fd, req, flags); \
> > > -	if (!(flags & DRM_MODE_ATOMIC_TEST_ONLY)) { \
> > > -		crtc_check_current_state(crtc, plane, relax); \
> > > -		plane_check_current_state(plane, relax); \
> > > -	} \
> > > -}
> > > +	if (prop == IGT_PLANE_IN_FENCE_FD)
> > > +		return false;
> > >  
> > > -#define crtc_commit_atomic_err(crtc, plane, crtc_old, plane_old,
> > > req, flags, relax, e) { \
> > > -	drmModeAtomicSetCursor(req, 0); \
> > > -	crtc_populate_req(crtc, req); \
> > > -	plane_populate_req(plane, req); \
> > > -	do_atomic_commit_err((crtc)->state->desc->fd, req,
> > > flags,
> > > e); \
> > > -	crtc_check_current_state(crtc_old, plane_old, relax); \
> > > -	plane_check_current_state(plane_old, relax); \
> > > +	/* Don't care about other properties */
> > > +	return true;
> > >  }
> > >  
> > > -#define plane_commit_atomic(plane, req, relax) { \
> > > -	drmModeAtomicSetCursor(req, 0); \
> > > -	plane_populate_req(plane, req); \
> > > -	do_atomic_commit((plane)->state->desc->fd, req, 0); \
> > > -	plane_check_current_state(plane, relax); \
> > > -}
> > > -
> > > -#define plane_commit_atomic_err(plane, plane_old, req, relax, e)
> > > { \
> > > -	drmModeAtomicSetCursor(req, 0); \
> > > -	plane_populate_req(plane, req); \
> > > -	do_atomic_commit_err((plane)->state->desc->fd, req, 0,
> > > e); \
> > > -	plane_check_current_state(plane_old, relax); \
> > > -}
> > > -
> > > -static void
> > > -connector_get_current_state(struct kms_atomic_connector_state
> > > *connector)
> > > -{
> > > -	drmModeObjectPropertiesPtr props;
> > > -	int i;
> > > -
> > > -	props = drmModeObjectGetProperties(connector->state-
> > > >desc-
> > > > 
> > > > fd,
> > > -					   connector->obj,
> > > -					   DRM_MODE_OBJECT_CONNE
> > > CTOR
> > > );
> > > -	igt_assert(props);
> > > -
> > > -	for (i = 0; i < props->count_props; i++) {
> > > -		uint32_t *prop_ids = connector->state->desc-
> > > > 
> > > > props_connector;
> > > -
> > > -		if (props->props[i] ==
> > > prop_ids[IGT_CONNECTOR_CRTC_ID])
> > > -			connector->crtc_id = props-
> > > >prop_values[i];
> > > -	}
> > > -	drmModeFreeObjectProperties(props);
> > > -}
> > > -
> > > -#if 0
> > > -/* XXX: Checking this repeatedly actually hangs the GPU. I have
> > > literally no
> > > - *      idea why. */
> > > -static void
> > > -connector_check_current_state(struct kms_atomic_connector_state
> > > *connector)
> > > -{
> > > -	struct kms_atomic_connector_state connector_kernel;
> > > -	drmModeConnectorPtr legacy;
> > > -	uint32_t crtc_id;
> > > -
> > > -	legacy = drmModeGetConnectorCurrent(connector->state-
> > > >desc-
> > > > 
> > > > fd,
> > > -					    connector->obj);
> > > -	igt_assert(legacy);
> > > -
> > > -	if (legacy->encoder_id) {
> > > -		drmModeEncoderPtr legacy_enc;
> > > -
> > > -		legacy_enc = drmModeGetEncoder(connector->state-
> > > > 
> > > > desc->fd,
> > > -					       legacy-
> > > >encoder_id);
> > > -		igt_assert(legacy_enc);
> > > -
> > > -		crtc_id = legacy_enc->crtc_id;
> > > -		drmModeFreeEncoder(legacy_enc);
> > > -	} else {
> > > -		crtc_id = 0;
> > > -	}
> > > -
> > > -	igt_assert_eq_u32(crtc_id, connector->crtc_id);
> > > -
> > > -	memcpy(&connector_kernel, connector,
> > > sizeof(connector_kernel));
> > > -	connector_get_current_state(&connector_kernel);
> > > -	do_or_die(memcmp(&connector_kernel, connector,
> > > -			 sizeof(connector_kernel)));
> > > -
> > > -	drmModeFreeConnector(legacy);
> > > -}
> > > -#endif
> > > -
> > > -static struct kms_atomic_connector_state *
> > > -find_connector(struct kms_atomic_state *state,
> > > -	       struct kms_atomic_crtc_state *crtc)
> > > +static void plane_get_current_state(igt_plane_t *plane, uint64_t
> > > *values)
> > >  {
> > >  	int i;
> > >  
> > > -	for (i = 0; i < state->num_connectors; i++) {
> > > -		struct kms_atomic_connector_state *connector =
> > > -			&state->connectors[i];
> > > -
> > > -		if (!connector->obj)
> > > +	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++) {
> > > +		if (plane_filter(i)) {
> > > +			values[i] = 0;
> > >  			continue;
> > > -		if (crtc && connector->crtc_id != crtc->obj)
> > > -			continue;
> > > -
> > > -		return connector;
> > > -	}
> > > -
> > > -	return NULL;
> > > -}
> > > -
> > > -static void plane_populate_req(struct kms_atomic_plane_state
> > > *plane,
> > > -			       drmModeAtomicReq *req)
> > > -{
> > > -	if (plane->fence_fd)
> > > -		plane_set_prop(req, plane,
> > > IGT_PLANE_IN_FENCE_FD,
> > > plane->fence_fd);
> > > -
> > > -	plane_set_prop(req, plane, IGT_PLANE_CRTC_ID, plane-
> > > > 
> > > > crtc_id);
> > > -	plane_set_prop(req, plane, IGT_PLANE_FB_ID, plane-
> > > >fb_id);
> > > -	plane_set_prop(req, plane, IGT_PLANE_SRC_X, plane-
> > > >src_x);
> > > -	plane_set_prop(req, plane, IGT_PLANE_SRC_Y, plane-
> > > >src_y);
> > > -	plane_set_prop(req, plane, IGT_PLANE_SRC_W, plane-
> > > >src_w);
> > > -	plane_set_prop(req, plane, IGT_PLANE_SRC_H, plane-
> > > >src_h);
> > > -	plane_set_prop(req, plane, IGT_PLANE_CRTC_X, plane-
> > > >crtc_x);
> > > -	plane_set_prop(req, plane, IGT_PLANE_CRTC_Y, plane-
> > > >crtc_y);
> > > -	plane_set_prop(req, plane, IGT_PLANE_CRTC_W, plane-
> > > >crtc_w);
> > > -	plane_set_prop(req, plane, IGT_PLANE_CRTC_H, plane-
> > > >crtc_h);
> > > -}
> > > -
> > > -static void plane_get_current_state(struct
> > > kms_atomic_plane_state
> > > *plane)
> > > -{
> > > -	struct kms_atomic_desc *desc = plane->state->desc;
> > > -	drmModeObjectPropertiesPtr props;
> > > -	int i;
> > > -
> > > -	props = drmModeObjectGetProperties(desc->fd, plane->obj,
> > > -					   DRM_MODE_OBJECT_PLANE
> > > );
> > > -	igt_assert(props);
> > > -
> > > -	for (i = 0; i < props->count_props; i++) {
> > > -		uint32_t *prop_ids = desc->props_plane;
> > > -
> > > -		if (props->props[i] ==
> > > prop_ids[IGT_PLANE_CRTC_ID])
> > > -			plane->crtc_id = props->prop_values[i];
> > > -		else if (props->props[i] ==
> > > prop_ids[IGT_PLANE_FB_ID])
> > > -			plane->fb_id = props->prop_values[i];
> > > -		else if (props->props[i] ==
> > > prop_ids[IGT_PLANE_CRTC_X])
> > > -			plane->crtc_x = props->prop_values[i];
> > > -		else if (props->props[i] ==
> > > prop_ids[IGT_PLANE_CRTC_Y])
> > > -			plane->crtc_y = props->prop_values[i];
> > > -		else if (props->props[i] ==
> > > prop_ids[IGT_PLANE_CRTC_W])
> > > -			plane->crtc_w = props->prop_values[i];
> > > -		else if (props->props[i] ==
> > > prop_ids[IGT_PLANE_CRTC_H])
> > > -			plane->crtc_h = props->prop_values[i];
> > > -		else if (props->props[i] ==
> > > prop_ids[IGT_PLANE_SRC_X])
> > > -			plane->src_x = props->prop_values[i];
> > > -		else if (props->props[i] ==
> > > prop_ids[IGT_PLANE_SRC_Y])
> > > -			plane->src_y = props->prop_values[i];
> > > -		else if (props->props[i] ==
> > > prop_ids[IGT_PLANE_SRC_W])
> > > -			plane->src_w = props->prop_values[i];
> > > -		else if (props->props[i] ==
> > > prop_ids[IGT_PLANE_SRC_H])
> > > -			plane->src_h = props->prop_values[i];
> > > -		else if (props->props[i] ==
> > > prop_ids[IGT_PLANE_TYPE]) {
> > > -			int j;
> > > -
> > > -			for (j = 0; j < ARRAY_SIZE(desc-
> > > > 
> > > > props_plane_type); j++) {
> > > -				if (props->prop_values[i] ==
> > > desc-
> > > > 
> > > > props_plane_type[j]) {
> > > -					plane->type = j;
> > > -					break;
> > > -				}
> > > -			}
> > >  		}
> > > -	}
> > >  
> > > -	drmModeFreeObjectProperties(props);
> > > +		values[i] = igt_plane_get_prop(plane, i);
> > > +	}
> > >  }
> > >  
> > > -static void plane_check_current_state(struct
> > > kms_atomic_plane_state
> > > *plane,
> > > +static void plane_check_current_state(igt_plane_t *plane, const
> > > uint64_t *values,
> > >  				      enum
> > > kms_atomic_check_relax
> > > relax)
> > >  {
> > >  	drmModePlanePtr legacy;
> > > -	struct kms_atomic_plane_state plane_kernel;
> > > +	uint64_t current_values[IGT_NUM_PLANE_PROPS];
> > > +	int i;
> > >  
> > > -	legacy = drmModeGetPlane(plane->state->desc->fd, plane-
> > > > 
> > > > obj);
> > > +	legacy = drmModeGetPlane(plane->pipe->display->drm_fd,
> > > plane->drm_plane->plane_id);
> > >  	igt_assert(legacy);
> > >  
> > > -	igt_assert_eq_u32(legacy->crtc_id, plane->crtc_id);
> > > +	igt_assert_eq_u32(legacy->crtc_id,
> > > values[IGT_PLANE_CRTC_ID]);
> > >  
> > >  	if (!(relax & PLANE_RELAX_FB))
> > > -		igt_assert_eq_u32(legacy->fb_id, plane->fb_id);
> > > +		igt_assert_eq_u32(legacy->fb_id,
> > > values[IGT_PLANE_FB_ID]);
> > >  
> > > -	memcpy(&plane_kernel, plane, sizeof(plane_kernel));
> > > -	plane_get_current_state(&plane_kernel);
> > > +	plane_get_current_state(plane, current_values);
> > >  
> > >  	/* Legacy cursor ioctls create their own, unknowable,
> > > internal
> > >  	 * framebuffer which we can't reason about. */
> > >  	if (relax & PLANE_RELAX_FB)
> > > -		plane_kernel.fb_id = plane->fb_id;
> > > -	do_or_die(memcmp(&plane_kernel, plane,
> > > sizeof(plane_kernel)));
> > > +		current_values[IGT_PLANE_FB_ID] =
> > > values[IGT_PLANE_FB_ID];
> > > +
> > > +	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++)
> > > +		if (!plane_filter(i))
> > > +			igt_assert_eq_u64(current_values[i],
> > > values[i]);
> > >  
> > >  	drmModeFreePlane(legacy);
> > >  }
> > >  
> > > -static void plane_commit_legacy(struct kms_atomic_plane_state
> > > *plane,
> > > +static void plane_commit(igt_plane_t *plane, enum
> > > igt_commit_style
> > > s,
> > >                                  enum kms_atomic_check_relax
> > > relax)
> > >  {
> > > -	do_or_die(drmModeSetPlane(plane->state->desc->fd, plane-
> > > > 
> > > > obj,
> > > -				  plane->crtc_id,
> > > -				  plane->fb_id, 0,
> > > -				  plane->crtc_x, plane->crtc_y,
> > > -				  plane->crtc_w, plane->crtc_h,
> > > -				  plane->src_x, plane->src_y,
> > > -				  plane->src_w, plane->src_h));
> > > -	plane_check_current_state(plane, relax);
> > > +	igt_display_commit2(plane->pipe->display, s);
> > > +	plane_check_current_state(plane, plane->values, relax);
> > >  }
> > >  
> > > -static struct kms_atomic_plane_state *
> > > -find_plane(struct kms_atomic_state *state, enum plane_type type,
> > > -	   struct kms_atomic_crtc_state *crtc)
> > > +static void plane_commit_atomic_err(igt_plane_t *plane,
> > > +				    enum kms_atomic_check_relax
> > > relax,
> > > +				    int err)
> > >  {
> > > -	struct kms_atomic_plane_state *ret = NULL;
> > > -	int i;
> > > -
> > > -	for (i = 0; i < state->num_planes; i++) {
> > > -		struct kms_atomic_plane_state *plane = &state-
> > > > 
> > > > planes[i];
> > > -
> > > -		if (!plane->obj)
> > > -			continue;
> > > -		if (type != NUM_PLANE_TYPE_PROPS && plane->type
> > > !=
> > > type)
> > > -			continue;
> > > -		if (crtc && !(plane->crtc_mask & (1 << crtc-
> > > >idx)))
> > > -			continue;
> > > +	uint64_t current_values[IGT_NUM_PLANE_PROPS];
> > >  
> > > -		plane_get_current_state(plane);
> > > +	plane_get_current_state(plane, current_values);
> > >  
> > > -		/* Try to find a plane that's already on this
> > > CRTC.
> > > In
> > > -		 * particular, this ensures that for special
> > > (primary/cursor)
> > > -		 * planes that can be on multiple CRTCs, we find
> > > the
> > > same
> > > -		 * one that the legacy ioctls will. */
> > > -		if (!crtc || plane->crtc_id == crtc->obj)
> > > -			return plane;
> > > -
> > > -		ret = plane;
> > > -	}
> > > +	igt_assert_eq(-err, igt_display_try_commit2(plane->pipe-
> > > > 
> > > > display, COMMIT_ATOMIC));
> > >  
> > > -	return ret;
> > > +	plane_check_current_state(plane, current_values, relax);
> > >  }
> > >  
> > > -static void crtc_populate_req(struct kms_atomic_crtc_state
> > > *crtc,
> > > -			      drmModeAtomicReq *req)
> > > +static bool crtc_filter(enum igt_atomic_crtc_properties prop)
> > >  {
> > > -	if (crtc->out_fence_ptr)
> > > -		crtc_set_prop(req, crtc, IGT_CRTC_OUT_FENCE_PTR,
> > > -			      to_user_pointer(crtc-
> > > >out_fence_ptr));
> > > +	if (prop == IGT_CRTC_MODE_ID || prop == IGT_CRTC_ACTIVE)
> > > +		return false;
> > >  
> > > -	crtc_set_prop(req, crtc, IGT_CRTC_MODE_ID, crtc-
> > > >mode.id);
> > > -	crtc_set_prop(req, crtc, IGT_CRTC_ACTIVE, crtc->active);
> > > +	return true;
> > >  }
> > >  
> > > -static void crtc_get_current_state(struct kms_atomic_crtc_state
> > > *crtc)
> > > +static void crtc_get_current_state(igt_pipe_t *pipe, uint64_t
> > > *values)
> > >  {
> > > -	drmModeObjectPropertiesPtr props;
> > >  	int i;
> > >  
> > > -	props = drmModeObjectGetProperties(crtc->state->desc-
> > > >fd,
> > > crtc->obj,
> > > -					   DRM_MODE_OBJECT_CRTC)
> > > ;
> > > -	igt_assert(props);
> > > -
> > > -	for (i = 0; i < props->count_props; i++) {
> > > -		uint32_t *prop_ids = crtc->state->desc-
> > > >props_crtc;
> > > -
> > > -		if (props->props[i] ==
> > > prop_ids[IGT_CRTC_MODE_ID]) {
> > > -			drmModePropertyBlobPtr blob;
> > > -
> > > -			crtc->mode.id = props->prop_values[i];
> > > -			if (!crtc->mode.id) {
> > > -				crtc->mode.len = 0;
> > > -				continue;
> > > -			}
> > > -
> > > -			blob = drmModeGetPropertyBlob(crtc-
> > > >state-
> > > > 
> > > > desc->fd,
> > > -						      crtc-
> > > > 
> > > > mode.id);
> > > -			igt_assert(blob);
> > > -			igt_assert_eq_u32(blob->length,
> > > -					  sizeof(struct
> > > drm_mode_modeinfo));
> > > -
> > > -			if (!crtc->mode.data ||
> > > -			    memcmp(crtc->mode.data, blob->data,
> > > blob->length) != 0)
> > > -				crtc->mode.data = blob->data;
> > > -			crtc->mode.len = blob->length;
> > > -		}
> > > -		else if (props->props[i] ==
> > > prop_ids[IGT_CRTC_ACTIVE]) {
> > > -			crtc->active = props->prop_values[i];
> > > +	for (i = 0; i < IGT_NUM_CRTC_PROPS; i++) {
> > > +		if (crtc_filter(i)) {
> > > +			values[i] = 0;
> > > +			continue;
> > >  		}
> > > -	}
> > >  
> > > -	drmModeFreeObjectProperties(props);
> > > +		values[i] = igt_pipe_obj_get_prop(pipe, i);
> > > +	}
> > >  }
> > >  
> > > -static void crtc_check_current_state(struct
> > > kms_atomic_crtc_state
> > > *crtc,
> > > -				     struct
> > > kms_atomic_plane_state
> > > *primary,
> > > +static void crtc_check_current_state(igt_pipe_t *pipe,
> > > +				     const uint64_t
> > > *pipe_values,
> > > +				     const uint64_t
> > > *primary_values,
> > >  				     enum kms_atomic_check_relax
> > > relax)
> > >  {
> > > -	struct kms_atomic_crtc_state crtc_kernel;
> > > +	uint64_t current_pipe_values[IGT_NUM_CRTC_PROPS];
> > >  	drmModeCrtcPtr legacy;
> > > +	drmModePropertyBlobRes *mode_prop = NULL;
> > > +	struct drm_mode_modeinfo *mode = NULL;
> > >  
> > > -	legacy = drmModeGetCrtc(crtc->state->desc->fd, crtc-
> > > >obj);
> > > -	igt_assert(legacy);
> > > -
> > > -	igt_assert_eq_u32(legacy->crtc_id, crtc->obj);
> > > -	igt_assert_eq_u32(legacy->x, primary->src_x >> 16);
> > > -	igt_assert_eq_u32(legacy->y, primary->src_y >> 16);
> > > -
> > > -	if (crtc->active)
> > > -		igt_assert_eq_u32(legacy->buffer_id, primary-
> > > > 
> > > > fb_id);
> > > -	else
> > > -		igt_assert_eq_u32(legacy->buffer_id, 0);
> > > +	if (pipe_values[IGT_CRTC_MODE_ID]) {
> > > +		mode_prop = drmModeGetPropertyBlob(pipe-
> > > >display-
> > > > 
> > > > drm_fd,
> > > +						   pipe_values[I
> > > GT_C
> > > RTC_MODE_ID]);
> > >  
> > > -	if (legacy->mode_valid) {
> > > -		igt_assert_neq(legacy->mode_valid, 0);
> > > -		igt_assert_eq(crtc->mode.len,
> > > -		              sizeof(struct drm_mode_modeinfo));
> > > -		do_or_die(memcmp(&legacy->mode, crtc->mode.data,
> > > -		                 crtc->mode.len));
> > > -		igt_assert_eq(legacy->width, legacy-
> > > >mode.hdisplay);
> > > -		igt_assert_eq(legacy->height, legacy-
> > > > 
> > > > mode.vdisplay);
> > > -	} else {
> > > -		igt_assert_eq(legacy->mode_valid, 0);
> > > -	}
> > > +		igt_assert(mode_prop);
> > >  
> > > -	memcpy(&crtc_kernel, crtc, sizeof(crtc_kernel));
> > > -	crtc_get_current_state(&crtc_kernel);
> > > -
> > > -	if (crtc_kernel.mode.id != 0)
> > > -		igt_assert_eq(crtc_kernel.mode.len,
> > > +		igt_assert_eq(mode_prop->length,
> > >  		              sizeof(struct drm_mode_modeinfo));
> > > -
> > > -	/* Optionally relax the check for MODE_ID: using the
> > > legacy
> > > SetCrtc
> > > -	 * API can potentially change MODE_ID even if the mode
> > > itself remains
> > > -	 * unchanged. */
> > > -	if (((relax & CRTC_RELAX_MODE) &&
> > > -	    (crtc_kernel.mode.id != crtc->mode.id &&
> > > -	     crtc_kernel.mode.id != 0 && crtc->mode.id != 0)) &&
> > > -	    memcmp(crtc_kernel.mode.data, crtc->mode.data,
> > > -		   sizeof(struct drm_mode_modeinfo)) == 0) {
> > > -		crtc_kernel.mode.id = crtc->mode.id;
> > > -		crtc_kernel.mode.data = crtc->mode.data;
> > > -	}
> > > -
> > > -	do_or_die(memcmp(&crtc_kernel, crtc,
> > > sizeof(crtc_kernel)));
> > > -
> > > -	drmModeFreeCrtc(legacy);
> > > -}
> > > -
> > > -static void crtc_commit_legacy(struct kms_atomic_crtc_state
> > > *crtc,
> > > -			       struct kms_atomic_plane_state
> > > *plane,
> > > -			       enum kms_atomic_check_relax
> > > relax)
> > > -{
> > > -	drmModeObjectPropertiesPtr props;
> > > -	uint32_t *connectors;
> > > -	int num_connectors = 0;
> > > -	int i;
> > > -
> > > -	if (!crtc->active) {
> > > -		do_or_die(drmModeSetCrtc(crtc->state->desc->fd,
> > > -					 crtc->obj, 0, 0, 0,
> > > NULL,
> > > 0, NULL));
> > > -		return;
> > > -	}
> > > -
> > > -	connectors = calloc(crtc->state->num_connectors,
> > > -			    sizeof(*connectors));
> > > -	igt_assert(connectors);
> > > -
> > > -	igt_assert_neq_u32(crtc->mode.id, 0);
> > > -
> > > -	for (i = 0; i < crtc->state->num_connectors; i++) {
> > > -		struct kms_atomic_connector_state *connector =
> > > -			&crtc->state->connectors[i];
> > > -
> > > -		if (connector->crtc_id != crtc->obj)
> > > -			continue;
> > > -
> > > -		connectors[num_connectors++] = connector->obj;
> > > +		mode = mode_prop->data;
> > >  	}
> > >  
> > > -	do_or_die(drmModeSetCrtc(crtc->state->desc->fd, crtc-
> > > >obj,
> > > -	                         plane->fb_id,
> > > -				 plane->src_x >> 16, plane-
> > > >src_y >>
> > > 16,
> > > -				 (num_connectors) ? connectors :
> > > NULL,
> > > -				 num_connectors,
> > > -				 crtc->mode.data));
> > > -	/* When doing a legacy commit, the core may update
> > > MODE_ID
> > > to be a new
> > > -	 * blob implicitly created by the legacy request. Hence
> > > we
> > > backfill
> > > -	 * the value in the state object to ensure they match.
> > > */
> > > -	props = drmModeObjectGetProperties(crtc->state->desc-
> > > >fd,
> > > crtc->obj,
> > > -					   DRM_MODE_OBJECT_CRTC)
> > > ;
> > > -	igt_assert(props);
> > > -
> > > -	for (i = 0; i < props->count_props; i++) {
> > > -		if (props->props[i] !=
> > > -		    crtc->state->desc-
> > > >props_crtc[IGT_CRTC_MODE_ID])
> > > -			continue;
> > > -		crtc->mode.id = props->prop_values[i];
> > > -		break;
> > > -	}
> > > +	legacy = drmModeGetCrtc(pipe->display->drm_fd, pipe-
> > > > 
> > > > crtc_id);
> > > +	igt_assert(legacy);
> > >  
> > > -	drmModeFreeObjectProperties(props);
> > > +	igt_assert_eq_u32(legacy->crtc_id, pipe->crtc_id);
> > > +	igt_assert_eq_u32(legacy->x,
> > > primary_values[IGT_PLANE_SRC_X]
> > > > 
> > > > > 
> > > > > 16);
> > > +	igt_assert_eq_u32(legacy->y,
> > > primary_values[IGT_PLANE_SRC_Y]
> > > > 
> > > > > 
> > > > > 16);
> > >  
> > > -	crtc_check_current_state(crtc, plane, relax);
> > > -	plane_check_current_state(plane, relax);
> > > -}
> > > +	igt_assert_eq_u32(legacy->buffer_id,
> > > primary_values[IGT_PLANE_FB_ID]);
> > >  
> > > -static struct kms_atomic_crtc_state *find_crtc(struct
> > > kms_atomic_state *state,
> > > -					       bool
> > > must_be_enabled)
> > > -{
> > > -	int i;
> > > +	if (legacy->mode_valid) {
> > > +		igt_assert(mode_prop);
> > >  
> > > -	for (i = 0; i < state->num_crtcs; i++) {
> > > -		struct kms_atomic_crtc_state *crtc = &state-
> > > > 
> > > > crtcs[i];
> > > +		do_or_die(memcmp(&legacy->mode, mode,
> > > sizeof(*mode)));
> > >  
> > > -		if (!crtc->obj)
> > > -			continue;
> > > -		if (must_be_enabled && !crtc->active)
> > > -			continue;
> > > +		igt_assert_eq(legacy->width, legacy-
> > > >mode.hdisplay);
> > > +		igt_assert_eq(legacy->height, legacy-
> > > > 
> > > > mode.vdisplay);
> > >  
> > > -		crtc_get_current_state(crtc);
> > > -		return crtc;
> > > +		igt_assert_neq(pipe_values[IGT_CRTC_MODE_ID],
> > > 0);
> > > +	} else {
> > > +		igt_assert(!mode_prop);
> > >  	}
> > >  
> > > -	return NULL;
> > > -}
> > > +	crtc_get_current_state(pipe, current_pipe_values);
> > >  
> > > -static void fill_obj_props(int fd, uint32_t id, int type, int
> > > num_props,
> > > -			   const char **prop_names, uint32_t
> > > *prop_ids)
> > > -{
> > > -	drmModeObjectPropertiesPtr props;
> > > -	int i, j;
> > > -
> > > -	props = drmModeObjectGetProperties(fd, id, type);
> > > -	igt_assert(props);
> > > +	/* Optionally relax the check for MODE_ID: using the
> > > legacy
> > > SetCrtc
> > > +	 * API can potentially change MODE_ID even if the mode
> > > itself remains
> > > +	 * unchanged. */
> > > +	if (relax & CRTC_RELAX_MODE && mode &&
> > > current_pipe_values[IGT_CRTC_MODE_ID] &&
> > > +	    current_pipe_values[IGT_CRTC_MODE_ID] !=
> > > pipe_values[IGT_CRTC_MODE_ID]) {
> > > +		drmModePropertyBlobRes *cur_prop =
> > > +			drmModeGetPropertyBlob(pipe->display-
> > > > 
> > > > drm_fd,
> > > +					       current_pipe_valu
> > > es[I
> > > GT_CRTC_MODE_ID]);
> > >  
> > > -	for (i = 0; i < props->count_props; i++) {
> > > -		drmModePropertyPtr prop =
> > > -			drmModeGetProperty(fd, props->props[i]);
> > > +		igt_assert(cur_prop);
> > > +		igt_assert_eq(cur_prop->length, sizeof(struct
> > > drm_mode_modeinfo));
> > >  
> > > -		for (j = 0; j < num_props; j++) {
> > > -			if (strcmp(prop->name, prop_names[j]) !=
> > > 0)
> > > -				continue;
> > > -			prop_ids[j] = props->props[i];
> > > -			break;
> > > -		}
> > > +		if (!memcmp(cur_prop->data, mode,
> > > sizeof(*mode)))
> > > +			current_pipe_values[IGT_CRTC_MODE_ID] =
> > > pipe_values[IGT_CRTC_MODE_ID];
> > >  
> > > -		drmModeFreeProperty(prop);
> > > +		drmModeFreePropertyBlob(cur_prop);
> > >  	}
> > >  
> > > -	drmModeFreeObjectProperties(props);
> > > -}
> > > +	do_or_die(memcmp(pipe_values, current_pipe_values,
> > > sizeof(current_pipe_values)));
> > >  
> > > -static void fill_obj_prop_map(int fd, uint32_t id, int type,
> > > const
> > > char *name,
> > > -			      int num_enums, const char
> > > **enum_names,
> > > -			      uint64_t *enum_ids)
> > > -{
> > > -	drmModeObjectPropertiesPtr props;
> > > -	int i, j, k;
> > > -
> > > -	props = drmModeObjectGetProperties(fd, id, type);
> > > -	igt_assert(props);
> > > -
> > > -	for (i = 0; i < props->count_props; i++) {
> > > -		drmModePropertyPtr prop =
> > > -			drmModeGetProperty(fd, props->props[i]);
> > > -
> > > -		igt_assert(prop);
> > > -
> > > -		if (strcmp(prop->name, name) != 0) {
> > > -			drmModeFreeProperty(prop);
> > > -			continue;
> > > -		}
> > > -
> > > -		for (j = 0; j < prop->count_enums; j++) {
> > > -			struct drm_mode_property_enum *e =
> > > &prop-
> > > > 
> > > > enums[j];
> > > -
> > > -			for (k = 0; k < num_enums; k++) {
> > > -				if (strcmp(e->name,
> > > enum_names[k])
> > > != 0)
> > > -					continue;
> > > -
> > > -				enum_ids[k] = e->value;
> > > -				break;
> > > -			}
> > > -		}
> > > -
> > > -		drmModeFreeProperty(prop);
> > > -	}
> > > +	drmModeFreeCrtc(legacy);
> > > +	drmModeFreePropertyBlob(mode_prop);
> > >  }
> > >  
> > > -static void atomic_setup(struct kms_atomic_state *state)
> > > +static void crtc_commit(igt_pipe_t *pipe, igt_plane_t *plane,
> > > +			enum igt_commit_style s,
> > > +			enum kms_atomic_check_relax relax)
> > >  {
> > > -	struct kms_atomic_desc *desc = state->desc;
> > > -	drmModeResPtr res;
> > > -	drmModePlaneResPtr res_plane;
> > > -	int i;
> > > -
> > > -	desc->fd = drm_open_driver_master(DRIVER_ANY);
> > > -	igt_assert_fd(desc->fd);
> > > -
> > > -	igt_skip_on(drmSetClientCap(desc->fd,
> > > DRM_CLIENT_CAP_ATOMIC,
> > > 1));
> > > -
> > > -	res = drmModeGetResources(desc->fd);
> > > -	res_plane = drmModeGetPlaneResources(desc->fd);
> > > -	igt_assert(res);
> > > -	igt_assert(res_plane);
> > > -
> > > -	igt_assert_lt(0, res->count_crtcs);
> > > -	state->num_crtcs = res->count_crtcs;
> > > -	state->crtcs = calloc(state->num_crtcs, sizeof(*state-
> > > > 
> > > > crtcs));
> > > -	igt_assert(state->crtcs);
> > > -
> > > -	igt_assert_lt(0, res_plane->count_planes);
> > > -	state->num_planes = res_plane->count_planes;
> > > -	state->planes = calloc(state->num_planes, sizeof(*state-
> > > > 
> > > > planes));
> > > -	igt_assert(state->planes);
> > > -
> > > -	igt_assert_lt(0, res->count_connectors);
> > > -	state->num_connectors = res->count_connectors;
> > > -	state->connectors = calloc(state->num_connectors,
> > > -				   sizeof(*state->connectors));
> > > -	igt_assert(state->connectors);
> > > -
> > > -	fill_obj_props(desc->fd, res->crtcs[0],
> > > -		       DRM_MODE_OBJECT_CRTC, IGT_NUM_CRTC_PROPS,
> > > -		       igt_crtc_prop_names, desc->props_crtc);
> > > -
> > > -	fill_obj_props(desc->fd, res_plane->planes[0],
> > > -		       DRM_MODE_OBJECT_PLANE,
> > > IGT_NUM_PLANE_PROPS,
> > > -		       igt_plane_prop_names, desc->props_plane);
> > > -	fill_obj_prop_map(desc->fd, res_plane->planes[0],
> > > -			  DRM_MODE_OBJECT_PLANE, "type",
> > > -			  NUM_PLANE_TYPE_PROPS,
> > > plane_type_prop_names,
> > > -			  desc->props_plane_type);
> > > -
> > > -	fill_obj_props(desc->fd, res->connectors[0],
> > > -		       DRM_MODE_OBJECT_CONNECTOR,
> > > IGT_NUM_CONNECTOR_PROPS,
> > > -		       igt_connector_prop_names, desc-
> > > > 
> > > > props_connector);
> > > -
> > > -	for (i = 0; i < state->num_crtcs; i++) {
> > > -		struct kms_atomic_crtc_state *crtc = &state-
> > > > 
> > > > crtcs[i];
> > > -
> > > -		crtc->state = state;
> > > -		crtc->obj = res->crtcs[i];
> > > -		crtc->idx = i;
> > > -		crtc_get_current_state(crtc);
> > > -
> > > -		/* The blob pointed to by MODE_ID could well be
> > > transient,
> > > -		 * and lose its last reference as we switch away
> > > from it.
> > > -		 * Duplicate the blob here so we have a
> > > reference we
> > > know we
> > > -		 * own. */
> > > -		if (crtc->mode.id != 0)
> > > -		    crtc->mode.id = blob_duplicate(desc->fd,
> > > crtc-
> > > > 
> > > > mode.id);
> > > -	}
> > > +	igt_display_commit2(pipe->display, s);
> > >  
> > > -	for (i = 0; i < state->num_planes; i++) {
> > > -		drmModePlanePtr plane =
> > > -			drmModeGetPlane(desc->fd, res_plane-
> > > > 
> > > > planes[i]);
> > > -		igt_assert(plane);
> > > -
> > > -		state->planes[i].state = state;
> > > -		state->planes[i].obj = res_plane->planes[i];
> > > -		state->planes[i].crtc_mask = plane-
> > > >possible_crtcs;
> > > -		plane_get_current_state(&state->planes[i]);
> > > -	}
> > > -
> > > -	for (i = 0; i < state->num_connectors; i++) {
> > > -		state->connectors[i].state = state;
> > > -		state->connectors[i].obj = res->connectors[i];
> > > -		connector_get_current_state(&state-
> > > >connectors[i]);
> > > -	}
> > > -
> > > -	drmModeFreePlaneResources(res_plane);
> > > -	drmModeFreeResources(res);
> > > +	crtc_check_current_state(pipe, pipe->values, plane-
> > > >values,
> > > relax);
> > > +	plane_check_current_state(plane, plane->values, relax);
> > >  }
> > >  
> > > -static struct kms_atomic_state *
> > > -atomic_state_dup(const struct kms_atomic_state *state)
> > > +static void crtc_commit_atomic_flags_err(igt_pipe_t *pipe,
> > > igt_plane_t *plane,
> > > +					 unsigned flags,
> > > +					 enum
> > > kms_atomic_check_relax
> > > relax,
> > > +					 int err)
> > >  {
> > > -	struct kms_atomic_state *ret = calloc(1, sizeof(*ret));
> > > -
> > > -	igt_assert(ret);
> > > -	*ret = *state;
> > > +	uint64_t current_pipe_values[IGT_NUM_CRTC_PROPS];
> > > +	uint64_t current_plane_values[IGT_NUM_PLANE_PROPS];
> > >  
> > > -	ret->crtcs = calloc(ret->num_crtcs, sizeof(*ret-
> > > >crtcs));
> > > -	igt_assert(ret->crtcs);
> > > -	memcpy(ret->crtcs, state->crtcs, ret->num_crtcs *
> > > sizeof(*ret->crtcs));
> > > +	crtc_get_current_state(pipe, current_pipe_values);
> > > +	plane_get_current_state(plane, current_plane_values);
> > >  
> > > -	ret->planes = calloc(ret->num_planes, sizeof(*ret-
> > > >planes));
> > > -	igt_assert(ret->planes);
> > > -	memcpy(ret->planes, state->planes,
> > > -	       ret->num_planes * sizeof(*ret->planes));
> > > +	igt_assert_eq(-err, igt_display_try_commit_atomic(pipe-
> > > > 
> > > > display, flags, NULL));
> > >  
> > > -	ret->connectors = calloc(ret->num_connectors,
> > > sizeof(*ret-
> > > > 
> > > > connectors));
> > > -	igt_assert(ret->connectors);
> > > -	memcpy(ret->connectors, state->connectors,
> > > -	       ret->num_connectors * sizeof(*ret->connectors));
> > > -
> > > -	return ret;
> > > +	crtc_check_current_state(pipe, current_pipe_values,
> > > current_plane_values, relax);
> > > +	plane_check_current_state(plane, current_plane_values,
> > > relax);
> > >  }
> > >  
> > > -static void atomic_state_free(struct kms_atomic_state *state)
> > > -{
> > > -	free(state->crtcs);
> > > -	free(state->planes);
> > > -	free(state->connectors);
> > > -	free(state);
> > > -}
> > > +#define crtc_commit_atomic_err(pipe, plane, relax, err) \
> > > +	crtc_commit_atomic_flags_err(pipe, plane,
> > > DRM_MODE_ATOMIC_ALLOW_MODESET, relax, err)
> > >  
> > > -static uint32_t plane_get_igt_format(struct
> > > kms_atomic_plane_state
> > > *plane)
> > > +static uint32_t plane_get_igt_format(igt_plane_t *plane)
> > >  {
> > >  	drmModePlanePtr plane_kms;
> > >  	const uint32_t *igt_formats;
> > > -	uint32_t ret = 0;
> > >  	int num_igt_formats;
> > >  	int i;
> > >  
> > > -	plane_kms = drmModeGetPlane(plane->state->desc->fd,
> > > plane-
> > > > 
> > > > obj);
> > > -	igt_assert(plane_kms);
> > > +	plane_kms = plane->drm_plane;
> > >  
> > >  	igt_get_all_cairo_formats(&igt_formats,
> > > &num_igt_formats);
> > >  	for (i = 0; i < num_igt_formats; i++) {
> > >  		int j;
> > >  
> > >  		for (j = 0; j < plane_kms->count_formats; j++) {
> > > -			if (plane_kms->formats[j] ==
> > > igt_formats[i])
> > > {
> > > -				ret = plane_kms->formats[j];
> > > -				break;
> > > -			}
> > > +			if (plane_kms->formats[j] ==
> > > igt_formats[i])
> > > +				return plane_kms->formats[j];
> > >  		}
> > >  	}
> > >  
> > > -	drmModeFreePlane(plane_kms);
> > > -	return ret;
> > > +	return 0;
> > >  }
> > >  
> > >  static void
> > > -set_dpms(int fd, int mode)
> > > +set_dpms(igt_output_t *output, int mode)
> > >  {
> > > -	int i;
> > > -	drmModeConnector *connector;
> > > -	uint32_t id;
> > > -	drmModeRes *resources = drmModeGetResources(fd);
> > > -
> > > -	for (i = 0; i < resources->count_connectors; i++) {
> > > -		id = resources->connectors[i];
> > > -
> > > -		connector = drmModeGetConnectorCurrent(fd, id);
> > > -
> > > -		kmstest_set_connector_dpms(fd, connector, mode);
> > > -
> > > -		drmModeFreeConnector(connector);
> > > -	}
> > > +	do_or_die(drmModeConnectorSetProperty(output->display-
> > > > 
> > > > drm_fd, output->id,
> > > +					      output-
> > > > 
> > > > props[IGT_CONNECTOR_DPMS], mode));
> > >  }
> > >  
> > > -static void plane_overlay(struct kms_atomic_crtc_state *crtc,
> > > -			  struct kms_atomic_plane_state
> > > *plane_old)
> > > +static void plane_overlay(igt_pipe_t *pipe, igt_output_t
> > > *output,
> > > igt_plane_t *plane)
> > >  {
> > > -	struct drm_mode_modeinfo *mode = crtc->mode.data;
> > > -	struct kms_atomic_plane_state plane = *plane_old;
> > > -	uint32_t format = plane_get_igt_format(&plane);
> > > -	drmModeAtomicReq *req = drmModeAtomicAlloc();
> > > +	drmModeModeInfo *mode = igt_output_get_mode(output);
> > > +	uint32_t format = plane_get_igt_format(plane);
> > >  	struct igt_fb fb;
> > > +	uint32_t w = mode->hdisplay / 2;
> > > +	uint32_t h = mode->vdisplay / 2;
> > >  
> > > -	igt_require(req);
> > >  	igt_require(format != 0);
> > >  
> > > -	plane.src_x = 0;
> > > -	plane.src_y = 0;
> > > -	plane.src_w = (mode->hdisplay / 2) << 16;
> > > -	plane.src_h = (mode->vdisplay / 2) << 16;
> > > -	plane.crtc_x = mode->hdisplay / 4;
> > > -	plane.crtc_y = mode->vdisplay / 4;
> > > -	plane.crtc_w = mode->hdisplay / 2;
> > > -	plane.crtc_h = mode->vdisplay / 2;
> > > -	plane.crtc_id = crtc->obj;
> > > -	plane.fb_id = igt_create_pattern_fb(plane.state->desc-
> > > >fd,
> > > -					    plane.crtc_w,
> > > plane.crtc_h,
> > > -					    format,
> > > I915_TILING_NONE, &fb);
> > > +	igt_create_pattern_fb(pipe->display->drm_fd, w, h,
> > > +			      format, I915_TILING_NONE, &fb);
> > > +
> > > +	igt_plane_set_fb(plane, &fb);
> > > +	igt_plane_set_position(plane, w/2, h/2);
> > >  
> > >  	/* Enable the overlay plane using the atomic API, and
> > > double-check
> > >  	 * state is what we think it should be. */
> > > -	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
> > > +	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
> > >  
> > >  	/* Disable the plane and check the state matches the
> > > old. */
> > > -	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
> > > +	igt_plane_set_fb(plane, NULL);
> > > +	igt_plane_set_position(plane, 0, 0);
> > > +	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
> > >  
> > >  	/* Re-enable the plane through the legacy plane API, and
> > > verify through
> > >  	 * atomic. */
> > > -	plane_commit_legacy(&plane, ATOMIC_RELAX_NONE);
> > > +	igt_plane_set_fb(plane, &fb);
> > > +	igt_plane_set_position(plane, w/2, h/2);
> > > +	plane_commit(plane, COMMIT_LEGACY, ATOMIC_RELAX_NONE);
> > >  
> > >  	/* Restore the plane to its original settings through
> > > the
> > > legacy plane
> > >  	 * API, and verify through atomic. */
> > > -	plane_commit_legacy(plane_old, ATOMIC_RELAX_NONE);
> > > +	igt_plane_set_fb(plane, NULL);
> > > +	igt_plane_set_position(plane, 0, 0);
> > > +	plane_commit(plane, COMMIT_LEGACY, ATOMIC_RELAX_NONE);
> > >  
> > > -	drmModeAtomicFree(req);
> > > +	igt_remove_fb(pipe->display->drm_fd, &fb);
> > >  }
> > >  
> > > -static void plane_primary(struct kms_atomic_crtc_state *crtc,
> > > -			  struct kms_atomic_plane_state
> > > *plane_old)
> > > +static void plane_primary(igt_pipe_t *pipe, igt_plane_t *plane,
> > > struct igt_fb *fb)
> > >  {
> > > -	struct drm_mode_modeinfo *mode = crtc->mode.data;
> > > -	struct kms_atomic_plane_state plane = *plane_old;
> > > -	uint32_t format = plane_get_igt_format(&plane);
> > > -	drmModeAtomicReq *req = drmModeAtomicAlloc();
> > > -	struct igt_fb fb;
> > > -	uint32_t flags = 0;
> > > -	int ret;
> > > -
> > > -	igt_require(format != 0);
> > > +	struct igt_fb fb2;
> > >  
> > > -	plane.src_x = 0;
> > > -	plane.src_y = 0;
> > > -	plane.src_w = mode->hdisplay << 16;
> > > -	plane.src_h = mode->vdisplay << 16;
> > > -	plane.crtc_x = 0;
> > > -	plane.crtc_y = 0;
> > > -	plane.crtc_w = mode->hdisplay;
> > > -	plane.crtc_h = mode->vdisplay;
> > > -	plane.crtc_id = crtc->obj;
> > > -	plane.fb_id = igt_create_pattern_fb(plane.state->desc-
> > > >fd,
> > > -					    plane.crtc_w,
> > > plane.crtc_h,
> > > -					    format,
> > > I915_TILING_NONE, &fb);
> > > -
> > > -	drmModeAtomicSetCursor(req, 0);
> > > -	crtc_populate_req(crtc, req);
> > > -	plane_populate_req(&plane, req);
> > > -	ret = drmModeAtomicCommit(crtc->state->desc->fd, req,
> > > -				  DRM_MODE_ATOMIC_TEST_ONLY,
> > > NULL);
> > > -	/* Try harder in case the failure is caused by
> > > disallowing
> > > modeset. */
> > > -	if (ret == -EINVAL)
> > > -		flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
> > > +	igt_create_color_pattern_fb(pipe->display->drm_fd,
> > > +				    fb->width, fb->height,
> > > +				    fb->drm_format,
> > > I915_TILING_NONE,
> > > +				    0.2, 0.2, 0.2, &fb2);
> > >  
> > >  	/* Flip the primary plane using the atomic API, and
> > > double-
> > > check
> > >  	 * state is what we think it should be. */
> > > -	crtc_commit_atomic(crtc, &plane, req, ATOMIC_RELAX_NONE,
> > > flags);
> > > +	igt_plane_set_fb(plane, &fb2);
> > > +	crtc_commit(pipe, plane, COMMIT_ATOMIC,
> > > ATOMIC_RELAX_NONE);
> > >  
> > >  	/* Restore the primary plane and check the state matches
> > > the
> > > old. */
> > > -	crtc_commit_atomic(crtc, plane_old, req,
> > > ATOMIC_RELAX_NONE,
> > > flags);
> > > +	igt_plane_set_fb(plane, fb);
> > > +	crtc_commit(pipe, plane, COMMIT_ATOMIC,
> > > ATOMIC_RELAX_NONE);
> > >  
> > > -	/* Re-enable the plane through the legacy CRTC/primary-
> > > plane 
> > > API, and
> > > +	/* Set the plane through the legacy CRTC/primary-plane
> > > API,
> > > and
> > >  	 * verify through atomic. */
> > > -	crtc_commit_legacy(crtc, &plane, CRTC_RELAX_MODE);
> > > +	igt_plane_set_fb(plane, &fb2);
> > > +	crtc_commit(pipe, plane, COMMIT_LEGACY,
> > > CRTC_RELAX_MODE);
> > >  
> > >  	/* Restore the plane to its original settings through
> > > the
> > > legacy CRTC
> > >  	 * API, and verify through atomic. */
> > > -	crtc_commit_legacy(crtc, plane_old, CRTC_RELAX_MODE);
> > > -
> > > -	/* Finally, restore to the original state. */
> > > -	crtc_commit_atomic(crtc, plane_old, req,
> > > ATOMIC_RELAX_NONE,
> > > flags);
> > > +	igt_plane_set_fb(plane, fb);
> > > +	crtc_commit(pipe, plane, COMMIT_LEGACY,
> > > CRTC_RELAX_MODE);
> > >  
> > > -	drmModeAtomicFree(req);
> > > +	/* Set the plane through the universal setplane API, and
> > > +	 * verify through atomic. */
> > > +	igt_plane_set_fb(plane, &fb2);
> > > +	plane_commit(plane, COMMIT_UNIVERSAL,
> > > ATOMIC_RELAX_NONE);
> > >  }
> > >  
> > >  /* test to ensure that DRM_MODE_ATOMIC_TEST_ONLY really only
> > > touches
> > > the
> > >   * free-standing state objects and nothing else.
> > >   */
> > > -static void test_only(struct kms_atomic_crtc_state *crtc,
> > > -		      struct kms_atomic_plane_state *plane_old)
> > > +static void test_only(igt_pipe_t *pipe_obj,
> > > +		      igt_plane_t *primary,
> > > +		      igt_output_t *output)
> > >  {
> > > -	struct drm_mode_modeinfo *mode = crtc->mode.data;
> > > -	struct kms_atomic_plane_state plane = *plane_old;
> > > -	uint32_t format = plane_get_igt_format(&plane);
> > > -	drmModeAtomicReq *req = drmModeAtomicAlloc();
> > > +	drmModeModeInfo *mode = igt_output_get_mode(output);
> > > +	uint32_t format = plane_get_igt_format(primary);
> > >  	struct igt_fb fb;
> > > -	int ret;
> > > +	uint64_t old_plane_values[IGT_NUM_PLANE_PROPS],
> > > old_crtc_values[IGT_NUM_CRTC_PROPS];
> > >  
> > >  	igt_require(format != 0);
> > >  
> > > -	plane.src_x = 0;
> > > -	plane.src_y = 0;
> > > -	plane.src_w = mode->hdisplay << 16;
> > > -	plane.src_h = mode->vdisplay << 16;
> > > -	plane.crtc_x = 0;
> > > -	plane.crtc_y = 0;
> > > -	plane.crtc_w = mode->hdisplay;
> > > -	plane.crtc_h = mode->vdisplay;
> > > -	plane.crtc_id = crtc->obj;
> > > -	plane.fb_id = igt_create_pattern_fb(plane.state->desc-
> > > >fd,
> > > -					    plane.crtc_w,
> > > plane.crtc_h,
> > > -					    format,
> > > I915_TILING_NONE, &fb);
> > > -
> > > -	drmModeAtomicSetCursor(req, 0);
> > > -	crtc_populate_req(crtc, req);
> > > -	plane_populate_req(&plane, req);
> > > -	ret = drmModeAtomicCommit(crtc->state->desc->fd, req,
> > > -				  DRM_MODE_ATOMIC_TEST_ONLY,
> > > NULL);
> > > -
> > > -	igt_assert_eq(ret, 0);
> > > -
> > > -	/* go through dpms off/on cycle */
> > > -	set_dpms(crtc->state->desc->fd, DRM_MODE_DPMS_OFF);
> > > -	set_dpms(crtc->state->desc->fd, DRM_MODE_DPMS_ON);
> > > -
> > > -	/* check the state */
> > > -	crtc_check_current_state(crtc, plane_old,
> > > ATOMIC_RELAX_NONE);
> > > -	plane_check_current_state(plane_old, ATOMIC_RELAX_NONE);
> > > -
> > > -	/* Re-enable the plane through the legacy CRTC/primary-
> > > plane 
> > > API, and
> > > -	 * verify through atomic. */
> > > -	crtc_commit_legacy(crtc, plane_old, CRTC_RELAX_MODE);
> > > +	plane_get_current_state(primary, old_plane_values);
> > > +	crtc_get_current_state(pipe_obj, old_crtc_values);
> > > +
> > > +	igt_assert(!old_crtc_values[IGT_CRTC_MODE_ID]);
> > > +
> > > +	igt_create_pattern_fb(pipe_obj->display->drm_fd,
> > > +			     mode->hdisplay, mode->vdisplay,
> > > +			     format, I915_TILING_NONE, &fb);
> > > +	igt_plane_set_fb(primary, &fb);
> > > +	igt_output_set_pipe(output, pipe_obj->pipe);
> > > +
> > > +	igt_display_commit_atomic(pipe_obj->display,
> > > DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
> > > +
> > > +	/* check the state, should still be old state */
> > > +	crtc_check_current_state(pipe_obj, old_crtc_values,
> > > old_plane_values, ATOMIC_RELAX_NONE);
> > > +	plane_check_current_state(primary, old_plane_values,
> > > ATOMIC_RELAX_NONE);
> > > +
> > > +	/*
> > > +	 * Enable the plane through the legacy CRTC/primary-
> > > plane
> > > API, and
> > > +	 * verify through atomic.
> > > +	 */
> > > +	crtc_commit(pipe_obj, primary, COMMIT_LEGACY,
> > > CRTC_RELAX_MODE);
> > > +
> > > +	/* Same for disable.. */
> > > +	plane_get_current_state(primary, old_plane_values);
> > > +	crtc_get_current_state(pipe_obj, old_crtc_values);
> > > +
> > > +	igt_plane_set_fb(primary, NULL);
> > > +	igt_output_set_pipe(output, PIPE_NONE);
> > > +
> > > +	igt_display_commit_atomic(pipe_obj->display,
> > > DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
> > >  
> > > -	drmModeAtomicFree(req);
> > > +	/* for extra stress, go through dpms off/on cycle */
> > > +	set_dpms(output, DRM_MODE_DPMS_OFF);
> > > +	set_dpms(output, DRM_MODE_DPMS_ON);
> > There is this library function 'kmstest_set_connector_dpms()'.
> > Could we
> > utilize this function here instead?
> Sure, I never understood what the dpms call was supposed to expose
> though..
> 
> Want me to resend or is replacing the call with
> kmstest_set_connector_dpms(s, output->config.connector,
> DRM_MODE_DPMS_OFF); enough?
Well, my point of view is that we should use library functions as much
as possible. I guess that's the reason why we have the libraries in the
first place. So a vote for a replacement.

-- 
Mika Kahola - Intel OTC

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2] tests/kms_atomic: Convert/rewrite tests to use igt_kms framework, v2.
  2017-10-20 10:16         ` Mika Kahola
@ 2017-10-20 11:43           ` Maarten Lankhorst
  0 siblings, 0 replies; 45+ messages in thread
From: Maarten Lankhorst @ 2017-10-20 11:43 UTC (permalink / raw)
  To: mika.kahola, intel-gfx; +Cc: Daniel Stone

Op 20-10-17 om 12:16 schreef Mika Kahola:
> On Fri, 2017-10-20 at 12:08 +0200, Maarten Lankhorst wrote:
>> Op 20-10-17 om 12:02 schreef Mika Kahola:
>>> On Thu, 2017-10-12 at 17:33 +0200, Maarten Lankhorst wrote:
>>>> Now that we can set individual properties through the igt_kms
>>>> api,
>>>> we no longer need to duplicate functionality from igt_kms. Set
>>>> invalid
>>>> properties directly, and rewrite kms_atomic.c to use igt_display.
>>>> This will allow us to remove a lot of code in kms_atomic.c,
>>>> and benefit from how igt_kms can set up a valid configuration,
>>>> instead of having to inherit it from fbcon.
>>>>
>>>> Changes since v1:
>>>> - Fix test failure when atomic_invalid_params is run standalone.
>>>>
>>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.c
>>>> om>
>>>> Cc: Daniel Stone <daniels@collabora.com>
>>>> ---
>>>>  tests/kms_atomic.c | 1668 ++++++++++++++++--------------------
>>>> ----
>>>> ------------
>>>>  1 file changed, 512 insertions(+), 1156 deletions(-)
>>>>
>>>> diff --git a/tests/kms_atomic.c b/tests/kms_atomic.c
>>>> index 042a7c263aab..e0fc324eab61 100644
>>>> --- a/tests/kms_atomic.c
>>>> +++ b/tests/kms_atomic.c
>>>> @@ -46,10 +46,6 @@
>>>>  #include "igt_aux.h"
>>>>  #include "sw_sync.h"
>>>>  
>>>> -#ifndef DRM_CLIENT_CAP_ATOMIC
>>>> -#define DRM_CLIENT_CAP_ATOMIC 3
>>>> -#endif
>>>> -
>>>>  #ifndef DRM_CAP_CURSOR_WIDTH
>>>>  #define DRM_CAP_CURSOR_WIDTH 0x8
>>>>  #endif
>>>> @@ -58,23 +54,6 @@
>>>>  #define DRM_CAP_CURSOR_HEIGHT 0x9
>>>>  #endif
>>>>  
>>>> -#ifndef DRM_MODE_ATOMIC_TEST_ONLY
>>>> -#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
>>>> -#define DRM_MODE_ATOMIC_NONBLOCK 0x0200
>>>> -#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
>>>> -
>>>> -struct drm_mode_atomic {
>>>> -	__u32 flags;
>>>> -	__u32 count_objs;
>>>> -	__u64 objs_ptr;
>>>> -	__u64 count_props_ptr;
>>>> -	__u64 props_ptr;
>>>> -	__u64 prop_values_ptr;
>>>> -	__u64 reserved;
>>>> -	__u64 user_data;
>>>> -};
>>>> -#endif
>>>> -
>>>>  IGT_TEST_DESCRIPTION("Test atomic modesetting API");
>>>>  
>>>>  enum kms_atomic_check_relax {
>>>> @@ -83,1259 +62,652 @@ enum kms_atomic_check_relax {
>>>>  	PLANE_RELAX_FB = (1 << 1)
>>>>  };
>>>>  
>>>> -/**
>>>> - * KMS plane type enum
>>>> - *
>>>> - * KMS plane types are represented by enums, which do not have
>>>> stable numeric
>>>> - * values, but must be looked up by their string value each
>>>> time.
>>>> - *
>>>> - * To make the code more simple, we define a plane_type enum
>>>> which
>>>> maps to
>>>> - * each KMS enum value. These values must be looked up through
>>>> the
>>>> map, and
>>>> - * cannot be passed directly to KMS functions.
>>>> - */
>>>> -enum plane_type {
>>>> -	PLANE_TYPE_PRIMARY = 0,
>>>> -	PLANE_TYPE_OVERLAY,
>>>> -	PLANE_TYPE_CURSOR,
>>>> -	NUM_PLANE_TYPE_PROPS
>>>> -};
>>>> -
>>>> -static const char *plane_type_prop_names[NUM_PLANE_TYPE_PROPS] =
>>>> {
>>>> -	"Primary",
>>>> -	"Overlay",
>>>> -	"Cursor"
>>>> -};
>>>> -
>>>> -struct kms_atomic_blob {
>>>> -	uint32_t id; /* 0 if not already allocated */
>>>> -	size_t len;
>>>> -	void *data;
>>>> -};
>>>> -
>>>> -struct kms_atomic_connector_state {
>>>> -	struct kms_atomic_state *state;
>>>> -	uint32_t obj;
>>>> -	uint32_t crtc_id;
>>>> -};
>>>> -
>>>> -struct kms_atomic_plane_state {
>>>> -	struct kms_atomic_state *state;
>>>> -	uint32_t obj;
>>>> -	enum plane_type type;
>>>> -	uint32_t crtc_mask;
>>>> -	uint32_t crtc_id; /* 0 to disable */
>>>> -	uint32_t fb_id; /* 0 to disable */
>>>> -	uint32_t src_x, src_y, src_w, src_h; /* 16.16 fixed-
>>>> point */
>>>> -	uint32_t crtc_x, crtc_y, crtc_w, crtc_h; /* normal
>>>> integers
>>>> */
>>>> -	int32_t fence_fd;
>>>> -};
>>>> -
>>>> -struct kms_atomic_crtc_state {
>>>> -	struct kms_atomic_state *state;
>>>> -	uint32_t obj;
>>>> -	int idx;
>>>> -	bool active;
>>>> -	int32_t *out_fence_ptr;
>>>> -	struct kms_atomic_blob mode;
>>>> -};
>>>> -
>>>> -struct kms_atomic_state {
>>>> -	struct kms_atomic_connector_state *connectors;
>>>> -	int num_connectors;
>>>> -	struct kms_atomic_crtc_state *crtcs;
>>>> -	int num_crtcs;
>>>> -	struct kms_atomic_plane_state *planes;
>>>> -	int num_planes;
>>>> -	struct kms_atomic_desc *desc;
>>>> -};
>>>> -
>>>> -struct kms_atomic_desc {
>>>> -	int fd;
>>>> -	uint32_t props_connector[IGT_NUM_CONNECTOR_PROPS];
>>>> -	uint32_t props_crtc[IGT_NUM_CRTC_PROPS];
>>>> -	uint32_t props_plane[IGT_NUM_PLANE_PROPS];
>>>> -	uint64_t props_plane_type[NUM_PLANE_TYPE_PROPS];
>>>> -};
>>>> -
>>>> -static uint32_t blob_duplicate(int fd, uint32_t id_orig)
>>>> +static bool plane_filter(enum igt_atomic_plane_properties prop)
>>>>  {
>>>> -	drmModePropertyBlobPtr orig = drmModeGetPropertyBlob(fd,
>>>> id_orig);
>>>> -	uint32_t id_new;
>>>> -
>>>> -	igt_assert(orig);
>>>> -	do_or_die(drmModeCreatePropertyBlob(fd, orig->data,
>>>> orig-
>>>>> length,
>>>> -					    &id_new));
>>>> -	drmModeFreePropertyBlob(orig);
>>>> +	if ((1 << prop) & IGT_PLANE_COORD_CHANGED_MASK)
>>>> +		return false;
>>>>  
>>>> -	return id_new;
>>>> -}
>>>> -
>>>> -#define crtc_set_prop(req, crtc, prop, value) \
>>>> -	igt_assert_lt(0, drmModeAtomicAddProperty(req, crtc-
>>>>> obj, \
>>>> -						  crtc->state-
>>>>> desc-
>>>>>
>>>>> props_crtc[prop], \
>>>> -						  value));
>>>> -
>>>> -#define plane_set_prop(req, plane, prop, value) \
>>>> -	igt_assert_lt(0, drmModeAtomicAddProperty(req, plane-
>>>>> obj, \
>>>> -						  plane->state-
>>>>> desc->props_plane[prop], \
>>>> -						  value));
>>>> -
>>>> -#define do_atomic_commit(fd, req, flags) \
>>>> -	do_or_die(drmModeAtomicCommit(fd, req, flags, NULL));
>>>> +	if (prop == IGT_PLANE_CRTC_ID || prop ==
>>>> IGT_PLANE_FB_ID)
>>>> +		return false;
>>>>  
>>>> -#define do_atomic_commit_err(fd, req, flags, err) { \
>>>> -	igt_assert_neq(drmModeAtomicCommit(fd, req, flags,
>>>> NULL),
>>>> 0); \
>>>> -	igt_assert_eq(errno, err); \
>>>> -}
>>>> -
>>>> -#define crtc_commit_atomic(crtc, plane, req, relax, flags) { \
>>>> -	drmModeAtomicSetCursor(req, 0); \
>>>> -	crtc_populate_req(crtc, req); \
>>>> -	plane_populate_req(plane, req); \
>>>> -	do_atomic_commit((crtc)->state->desc->fd, req, flags); \
>>>> -	if (!(flags & DRM_MODE_ATOMIC_TEST_ONLY)) { \
>>>> -		crtc_check_current_state(crtc, plane, relax); \
>>>> -		plane_check_current_state(plane, relax); \
>>>> -	} \
>>>> -}
>>>> +	if (prop == IGT_PLANE_IN_FENCE_FD)
>>>> +		return false;
>>>>  
>>>> -#define crtc_commit_atomic_err(crtc, plane, crtc_old, plane_old,
>>>> req, flags, relax, e) { \
>>>> -	drmModeAtomicSetCursor(req, 0); \
>>>> -	crtc_populate_req(crtc, req); \
>>>> -	plane_populate_req(plane, req); \
>>>> -	do_atomic_commit_err((crtc)->state->desc->fd, req,
>>>> flags,
>>>> e); \
>>>> -	crtc_check_current_state(crtc_old, plane_old, relax); \
>>>> -	plane_check_current_state(plane_old, relax); \
>>>> +	/* Don't care about other properties */
>>>> +	return true;
>>>>  }
>>>>  
>>>> -#define plane_commit_atomic(plane, req, relax) { \
>>>> -	drmModeAtomicSetCursor(req, 0); \
>>>> -	plane_populate_req(plane, req); \
>>>> -	do_atomic_commit((plane)->state->desc->fd, req, 0); \
>>>> -	plane_check_current_state(plane, relax); \
>>>> -}
>>>> -
>>>> -#define plane_commit_atomic_err(plane, plane_old, req, relax, e)
>>>> { \
>>>> -	drmModeAtomicSetCursor(req, 0); \
>>>> -	plane_populate_req(plane, req); \
>>>> -	do_atomic_commit_err((plane)->state->desc->fd, req, 0,
>>>> e); \
>>>> -	plane_check_current_state(plane_old, relax); \
>>>> -}
>>>> -
>>>> -static void
>>>> -connector_get_current_state(struct kms_atomic_connector_state
>>>> *connector)
>>>> -{
>>>> -	drmModeObjectPropertiesPtr props;
>>>> -	int i;
>>>> -
>>>> -	props = drmModeObjectGetProperties(connector->state-
>>>>> desc-
>>>>>
>>>>> fd,
>>>> -					   connector->obj,
>>>> -					   DRM_MODE_OBJECT_CONNE
>>>> CTOR
>>>> );
>>>> -	igt_assert(props);
>>>> -
>>>> -	for (i = 0; i < props->count_props; i++) {
>>>> -		uint32_t *prop_ids = connector->state->desc-
>>>>> props_connector;
>>>> -
>>>> -		if (props->props[i] ==
>>>> prop_ids[IGT_CONNECTOR_CRTC_ID])
>>>> -			connector->crtc_id = props-
>>>>> prop_values[i];
>>>> -	}
>>>> -	drmModeFreeObjectProperties(props);
>>>> -}
>>>> -
>>>> -#if 0
>>>> -/* XXX: Checking this repeatedly actually hangs the GPU. I have
>>>> literally no
>>>> - *      idea why. */
>>>> -static void
>>>> -connector_check_current_state(struct kms_atomic_connector_state
>>>> *connector)
>>>> -{
>>>> -	struct kms_atomic_connector_state connector_kernel;
>>>> -	drmModeConnectorPtr legacy;
>>>> -	uint32_t crtc_id;
>>>> -
>>>> -	legacy = drmModeGetConnectorCurrent(connector->state-
>>>>> desc-
>>>>>
>>>>> fd,
>>>> -					    connector->obj);
>>>> -	igt_assert(legacy);
>>>> -
>>>> -	if (legacy->encoder_id) {
>>>> -		drmModeEncoderPtr legacy_enc;
>>>> -
>>>> -		legacy_enc = drmModeGetEncoder(connector->state-
>>>>> desc->fd,
>>>> -					       legacy-
>>>>> encoder_id);
>>>> -		igt_assert(legacy_enc);
>>>> -
>>>> -		crtc_id = legacy_enc->crtc_id;
>>>> -		drmModeFreeEncoder(legacy_enc);
>>>> -	} else {
>>>> -		crtc_id = 0;
>>>> -	}
>>>> -
>>>> -	igt_assert_eq_u32(crtc_id, connector->crtc_id);
>>>> -
>>>> -	memcpy(&connector_kernel, connector,
>>>> sizeof(connector_kernel));
>>>> -	connector_get_current_state(&connector_kernel);
>>>> -	do_or_die(memcmp(&connector_kernel, connector,
>>>> -			 sizeof(connector_kernel)));
>>>> -
>>>> -	drmModeFreeConnector(legacy);
>>>> -}
>>>> -#endif
>>>> -
>>>> -static struct kms_atomic_connector_state *
>>>> -find_connector(struct kms_atomic_state *state,
>>>> -	       struct kms_atomic_crtc_state *crtc)
>>>> +static void plane_get_current_state(igt_plane_t *plane, uint64_t
>>>> *values)
>>>>  {
>>>>  	int i;
>>>>  
>>>> -	for (i = 0; i < state->num_connectors; i++) {
>>>> -		struct kms_atomic_connector_state *connector =
>>>> -			&state->connectors[i];
>>>> -
>>>> -		if (!connector->obj)
>>>> +	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++) {
>>>> +		if (plane_filter(i)) {
>>>> +			values[i] = 0;
>>>>  			continue;
>>>> -		if (crtc && connector->crtc_id != crtc->obj)
>>>> -			continue;
>>>> -
>>>> -		return connector;
>>>> -	}
>>>> -
>>>> -	return NULL;
>>>> -}
>>>> -
>>>> -static void plane_populate_req(struct kms_atomic_plane_state
>>>> *plane,
>>>> -			       drmModeAtomicReq *req)
>>>> -{
>>>> -	if (plane->fence_fd)
>>>> -		plane_set_prop(req, plane,
>>>> IGT_PLANE_IN_FENCE_FD,
>>>> plane->fence_fd);
>>>> -
>>>> -	plane_set_prop(req, plane, IGT_PLANE_CRTC_ID, plane-
>>>>> crtc_id);
>>>> -	plane_set_prop(req, plane, IGT_PLANE_FB_ID, plane-
>>>>> fb_id);
>>>> -	plane_set_prop(req, plane, IGT_PLANE_SRC_X, plane-
>>>>> src_x);
>>>> -	plane_set_prop(req, plane, IGT_PLANE_SRC_Y, plane-
>>>>> src_y);
>>>> -	plane_set_prop(req, plane, IGT_PLANE_SRC_W, plane-
>>>>> src_w);
>>>> -	plane_set_prop(req, plane, IGT_PLANE_SRC_H, plane-
>>>>> src_h);
>>>> -	plane_set_prop(req, plane, IGT_PLANE_CRTC_X, plane-
>>>>> crtc_x);
>>>> -	plane_set_prop(req, plane, IGT_PLANE_CRTC_Y, plane-
>>>>> crtc_y);
>>>> -	plane_set_prop(req, plane, IGT_PLANE_CRTC_W, plane-
>>>>> crtc_w);
>>>> -	plane_set_prop(req, plane, IGT_PLANE_CRTC_H, plane-
>>>>> crtc_h);
>>>> -}
>>>> -
>>>> -static void plane_get_current_state(struct
>>>> kms_atomic_plane_state
>>>> *plane)
>>>> -{
>>>> -	struct kms_atomic_desc *desc = plane->state->desc;
>>>> -	drmModeObjectPropertiesPtr props;
>>>> -	int i;
>>>> -
>>>> -	props = drmModeObjectGetProperties(desc->fd, plane->obj,
>>>> -					   DRM_MODE_OBJECT_PLANE
>>>> );
>>>> -	igt_assert(props);
>>>> -
>>>> -	for (i = 0; i < props->count_props; i++) {
>>>> -		uint32_t *prop_ids = desc->props_plane;
>>>> -
>>>> -		if (props->props[i] ==
>>>> prop_ids[IGT_PLANE_CRTC_ID])
>>>> -			plane->crtc_id = props->prop_values[i];
>>>> -		else if (props->props[i] ==
>>>> prop_ids[IGT_PLANE_FB_ID])
>>>> -			plane->fb_id = props->prop_values[i];
>>>> -		else if (props->props[i] ==
>>>> prop_ids[IGT_PLANE_CRTC_X])
>>>> -			plane->crtc_x = props->prop_values[i];
>>>> -		else if (props->props[i] ==
>>>> prop_ids[IGT_PLANE_CRTC_Y])
>>>> -			plane->crtc_y = props->prop_values[i];
>>>> -		else if (props->props[i] ==
>>>> prop_ids[IGT_PLANE_CRTC_W])
>>>> -			plane->crtc_w = props->prop_values[i];
>>>> -		else if (props->props[i] ==
>>>> prop_ids[IGT_PLANE_CRTC_H])
>>>> -			plane->crtc_h = props->prop_values[i];
>>>> -		else if (props->props[i] ==
>>>> prop_ids[IGT_PLANE_SRC_X])
>>>> -			plane->src_x = props->prop_values[i];
>>>> -		else if (props->props[i] ==
>>>> prop_ids[IGT_PLANE_SRC_Y])
>>>> -			plane->src_y = props->prop_values[i];
>>>> -		else if (props->props[i] ==
>>>> prop_ids[IGT_PLANE_SRC_W])
>>>> -			plane->src_w = props->prop_values[i];
>>>> -		else if (props->props[i] ==
>>>> prop_ids[IGT_PLANE_SRC_H])
>>>> -			plane->src_h = props->prop_values[i];
>>>> -		else if (props->props[i] ==
>>>> prop_ids[IGT_PLANE_TYPE]) {
>>>> -			int j;
>>>> -
>>>> -			for (j = 0; j < ARRAY_SIZE(desc-
>>>>> props_plane_type); j++) {
>>>> -				if (props->prop_values[i] ==
>>>> desc-
>>>>> props_plane_type[j]) {
>>>> -					plane->type = j;
>>>> -					break;
>>>> -				}
>>>> -			}
>>>>  		}
>>>> -	}
>>>>  
>>>> -	drmModeFreeObjectProperties(props);
>>>> +		values[i] = igt_plane_get_prop(plane, i);
>>>> +	}
>>>>  }
>>>>  
>>>> -static void plane_check_current_state(struct
>>>> kms_atomic_plane_state
>>>> *plane,
>>>> +static void plane_check_current_state(igt_plane_t *plane, const
>>>> uint64_t *values,
>>>>  				      enum
>>>> kms_atomic_check_relax
>>>> relax)
>>>>  {
>>>>  	drmModePlanePtr legacy;
>>>> -	struct kms_atomic_plane_state plane_kernel;
>>>> +	uint64_t current_values[IGT_NUM_PLANE_PROPS];
>>>> +	int i;
>>>>  
>>>> -	legacy = drmModeGetPlane(plane->state->desc->fd, plane-
>>>>> obj);
>>>> +	legacy = drmModeGetPlane(plane->pipe->display->drm_fd,
>>>> plane->drm_plane->plane_id);
>>>>  	igt_assert(legacy);
>>>>  
>>>> -	igt_assert_eq_u32(legacy->crtc_id, plane->crtc_id);
>>>> +	igt_assert_eq_u32(legacy->crtc_id,
>>>> values[IGT_PLANE_CRTC_ID]);
>>>>  
>>>>  	if (!(relax & PLANE_RELAX_FB))
>>>> -		igt_assert_eq_u32(legacy->fb_id, plane->fb_id);
>>>> +		igt_assert_eq_u32(legacy->fb_id,
>>>> values[IGT_PLANE_FB_ID]);
>>>>  
>>>> -	memcpy(&plane_kernel, plane, sizeof(plane_kernel));
>>>> -	plane_get_current_state(&plane_kernel);
>>>> +	plane_get_current_state(plane, current_values);
>>>>  
>>>>  	/* Legacy cursor ioctls create their own, unknowable,
>>>> internal
>>>>  	 * framebuffer which we can't reason about. */
>>>>  	if (relax & PLANE_RELAX_FB)
>>>> -		plane_kernel.fb_id = plane->fb_id;
>>>> -	do_or_die(memcmp(&plane_kernel, plane,
>>>> sizeof(plane_kernel)));
>>>> +		current_values[IGT_PLANE_FB_ID] =
>>>> values[IGT_PLANE_FB_ID];
>>>> +
>>>> +	for (i = 0; i < IGT_NUM_PLANE_PROPS; i++)
>>>> +		if (!plane_filter(i))
>>>> +			igt_assert_eq_u64(current_values[i],
>>>> values[i]);
>>>>  
>>>>  	drmModeFreePlane(legacy);
>>>>  }
>>>>  
>>>> -static void plane_commit_legacy(struct kms_atomic_plane_state
>>>> *plane,
>>>> +static void plane_commit(igt_plane_t *plane, enum
>>>> igt_commit_style
>>>> s,
>>>>                                  enum kms_atomic_check_relax
>>>> relax)
>>>>  {
>>>> -	do_or_die(drmModeSetPlane(plane->state->desc->fd, plane-
>>>>> obj,
>>>> -				  plane->crtc_id,
>>>> -				  plane->fb_id, 0,
>>>> -				  plane->crtc_x, plane->crtc_y,
>>>> -				  plane->crtc_w, plane->crtc_h,
>>>> -				  plane->src_x, plane->src_y,
>>>> -				  plane->src_w, plane->src_h));
>>>> -	plane_check_current_state(plane, relax);
>>>> +	igt_display_commit2(plane->pipe->display, s);
>>>> +	plane_check_current_state(plane, plane->values, relax);
>>>>  }
>>>>  
>>>> -static struct kms_atomic_plane_state *
>>>> -find_plane(struct kms_atomic_state *state, enum plane_type type,
>>>> -	   struct kms_atomic_crtc_state *crtc)
>>>> +static void plane_commit_atomic_err(igt_plane_t *plane,
>>>> +				    enum kms_atomic_check_relax
>>>> relax,
>>>> +				    int err)
>>>>  {
>>>> -	struct kms_atomic_plane_state *ret = NULL;
>>>> -	int i;
>>>> -
>>>> -	for (i = 0; i < state->num_planes; i++) {
>>>> -		struct kms_atomic_plane_state *plane = &state-
>>>>> planes[i];
>>>> -
>>>> -		if (!plane->obj)
>>>> -			continue;
>>>> -		if (type != NUM_PLANE_TYPE_PROPS && plane->type
>>>> !=
>>>> type)
>>>> -			continue;
>>>> -		if (crtc && !(plane->crtc_mask & (1 << crtc-
>>>>> idx)))
>>>> -			continue;
>>>> +	uint64_t current_values[IGT_NUM_PLANE_PROPS];
>>>>  
>>>> -		plane_get_current_state(plane);
>>>> +	plane_get_current_state(plane, current_values);
>>>>  
>>>> -		/* Try to find a plane that's already on this
>>>> CRTC.
>>>> In
>>>> -		 * particular, this ensures that for special
>>>> (primary/cursor)
>>>> -		 * planes that can be on multiple CRTCs, we find
>>>> the
>>>> same
>>>> -		 * one that the legacy ioctls will. */
>>>> -		if (!crtc || plane->crtc_id == crtc->obj)
>>>> -			return plane;
>>>> -
>>>> -		ret = plane;
>>>> -	}
>>>> +	igt_assert_eq(-err, igt_display_try_commit2(plane->pipe-
>>>>> display, COMMIT_ATOMIC));
>>>>  
>>>> -	return ret;
>>>> +	plane_check_current_state(plane, current_values, relax);
>>>>  }
>>>>  
>>>> -static void crtc_populate_req(struct kms_atomic_crtc_state
>>>> *crtc,
>>>> -			      drmModeAtomicReq *req)
>>>> +static bool crtc_filter(enum igt_atomic_crtc_properties prop)
>>>>  {
>>>> -	if (crtc->out_fence_ptr)
>>>> -		crtc_set_prop(req, crtc, IGT_CRTC_OUT_FENCE_PTR,
>>>> -			      to_user_pointer(crtc-
>>>>> out_fence_ptr));
>>>> +	if (prop == IGT_CRTC_MODE_ID || prop == IGT_CRTC_ACTIVE)
>>>> +		return false;
>>>>  
>>>> -	crtc_set_prop(req, crtc, IGT_CRTC_MODE_ID, crtc-
>>>>> mode.id);
>>>> -	crtc_set_prop(req, crtc, IGT_CRTC_ACTIVE, crtc->active);
>>>> +	return true;
>>>>  }
>>>>  
>>>> -static void crtc_get_current_state(struct kms_atomic_crtc_state
>>>> *crtc)
>>>> +static void crtc_get_current_state(igt_pipe_t *pipe, uint64_t
>>>> *values)
>>>>  {
>>>> -	drmModeObjectPropertiesPtr props;
>>>>  	int i;
>>>>  
>>>> -	props = drmModeObjectGetProperties(crtc->state->desc-
>>>>> fd,
>>>> crtc->obj,
>>>> -					   DRM_MODE_OBJECT_CRTC)
>>>> ;
>>>> -	igt_assert(props);
>>>> -
>>>> -	for (i = 0; i < props->count_props; i++) {
>>>> -		uint32_t *prop_ids = crtc->state->desc-
>>>>> props_crtc;
>>>> -
>>>> -		if (props->props[i] ==
>>>> prop_ids[IGT_CRTC_MODE_ID]) {
>>>> -			drmModePropertyBlobPtr blob;
>>>> -
>>>> -			crtc->mode.id = props->prop_values[i];
>>>> -			if (!crtc->mode.id) {
>>>> -				crtc->mode.len = 0;
>>>> -				continue;
>>>> -			}
>>>> -
>>>> -			blob = drmModeGetPropertyBlob(crtc-
>>>>> state-
>>>>>
>>>>> desc->fd,
>>>> -						      crtc-
>>>>> mode.id);
>>>> -			igt_assert(blob);
>>>> -			igt_assert_eq_u32(blob->length,
>>>> -					  sizeof(struct
>>>> drm_mode_modeinfo));
>>>> -
>>>> -			if (!crtc->mode.data ||
>>>> -			    memcmp(crtc->mode.data, blob->data,
>>>> blob->length) != 0)
>>>> -				crtc->mode.data = blob->data;
>>>> -			crtc->mode.len = blob->length;
>>>> -		}
>>>> -		else if (props->props[i] ==
>>>> prop_ids[IGT_CRTC_ACTIVE]) {
>>>> -			crtc->active = props->prop_values[i];
>>>> +	for (i = 0; i < IGT_NUM_CRTC_PROPS; i++) {
>>>> +		if (crtc_filter(i)) {
>>>> +			values[i] = 0;
>>>> +			continue;
>>>>  		}
>>>> -	}
>>>>  
>>>> -	drmModeFreeObjectProperties(props);
>>>> +		values[i] = igt_pipe_obj_get_prop(pipe, i);
>>>> +	}
>>>>  }
>>>>  
>>>> -static void crtc_check_current_state(struct
>>>> kms_atomic_crtc_state
>>>> *crtc,
>>>> -				     struct
>>>> kms_atomic_plane_state
>>>> *primary,
>>>> +static void crtc_check_current_state(igt_pipe_t *pipe,
>>>> +				     const uint64_t
>>>> *pipe_values,
>>>> +				     const uint64_t
>>>> *primary_values,
>>>>  				     enum kms_atomic_check_relax
>>>> relax)
>>>>  {
>>>> -	struct kms_atomic_crtc_state crtc_kernel;
>>>> +	uint64_t current_pipe_values[IGT_NUM_CRTC_PROPS];
>>>>  	drmModeCrtcPtr legacy;
>>>> +	drmModePropertyBlobRes *mode_prop = NULL;
>>>> +	struct drm_mode_modeinfo *mode = NULL;
>>>>  
>>>> -	legacy = drmModeGetCrtc(crtc->state->desc->fd, crtc-
>>>>> obj);
>>>> -	igt_assert(legacy);
>>>> -
>>>> -	igt_assert_eq_u32(legacy->crtc_id, crtc->obj);
>>>> -	igt_assert_eq_u32(legacy->x, primary->src_x >> 16);
>>>> -	igt_assert_eq_u32(legacy->y, primary->src_y >> 16);
>>>> -
>>>> -	if (crtc->active)
>>>> -		igt_assert_eq_u32(legacy->buffer_id, primary-
>>>>> fb_id);
>>>> -	else
>>>> -		igt_assert_eq_u32(legacy->buffer_id, 0);
>>>> +	if (pipe_values[IGT_CRTC_MODE_ID]) {
>>>> +		mode_prop = drmModeGetPropertyBlob(pipe-
>>>>> display-
>>>>>
>>>>> drm_fd,
>>>> +						   pipe_values[I
>>>> GT_C
>>>> RTC_MODE_ID]);
>>>>  
>>>> -	if (legacy->mode_valid) {
>>>> -		igt_assert_neq(legacy->mode_valid, 0);
>>>> -		igt_assert_eq(crtc->mode.len,
>>>> -		              sizeof(struct drm_mode_modeinfo));
>>>> -		do_or_die(memcmp(&legacy->mode, crtc->mode.data,
>>>> -		                 crtc->mode.len));
>>>> -		igt_assert_eq(legacy->width, legacy-
>>>>> mode.hdisplay);
>>>> -		igt_assert_eq(legacy->height, legacy-
>>>>> mode.vdisplay);
>>>> -	} else {
>>>> -		igt_assert_eq(legacy->mode_valid, 0);
>>>> -	}
>>>> +		igt_assert(mode_prop);
>>>>  
>>>> -	memcpy(&crtc_kernel, crtc, sizeof(crtc_kernel));
>>>> -	crtc_get_current_state(&crtc_kernel);
>>>> -
>>>> -	if (crtc_kernel.mode.id != 0)
>>>> -		igt_assert_eq(crtc_kernel.mode.len,
>>>> +		igt_assert_eq(mode_prop->length,
>>>>  		              sizeof(struct drm_mode_modeinfo));
>>>> -
>>>> -	/* Optionally relax the check for MODE_ID: using the
>>>> legacy
>>>> SetCrtc
>>>> -	 * API can potentially change MODE_ID even if the mode
>>>> itself remains
>>>> -	 * unchanged. */
>>>> -	if (((relax & CRTC_RELAX_MODE) &&
>>>> -	    (crtc_kernel.mode.id != crtc->mode.id &&
>>>> -	     crtc_kernel.mode.id != 0 && crtc->mode.id != 0)) &&
>>>> -	    memcmp(crtc_kernel.mode.data, crtc->mode.data,
>>>> -		   sizeof(struct drm_mode_modeinfo)) == 0) {
>>>> -		crtc_kernel.mode.id = crtc->mode.id;
>>>> -		crtc_kernel.mode.data = crtc->mode.data;
>>>> -	}
>>>> -
>>>> -	do_or_die(memcmp(&crtc_kernel, crtc,
>>>> sizeof(crtc_kernel)));
>>>> -
>>>> -	drmModeFreeCrtc(legacy);
>>>> -}
>>>> -
>>>> -static void crtc_commit_legacy(struct kms_atomic_crtc_state
>>>> *crtc,
>>>> -			       struct kms_atomic_plane_state
>>>> *plane,
>>>> -			       enum kms_atomic_check_relax
>>>> relax)
>>>> -{
>>>> -	drmModeObjectPropertiesPtr props;
>>>> -	uint32_t *connectors;
>>>> -	int num_connectors = 0;
>>>> -	int i;
>>>> -
>>>> -	if (!crtc->active) {
>>>> -		do_or_die(drmModeSetCrtc(crtc->state->desc->fd,
>>>> -					 crtc->obj, 0, 0, 0,
>>>> NULL,
>>>> 0, NULL));
>>>> -		return;
>>>> -	}
>>>> -
>>>> -	connectors = calloc(crtc->state->num_connectors,
>>>> -			    sizeof(*connectors));
>>>> -	igt_assert(connectors);
>>>> -
>>>> -	igt_assert_neq_u32(crtc->mode.id, 0);
>>>> -
>>>> -	for (i = 0; i < crtc->state->num_connectors; i++) {
>>>> -		struct kms_atomic_connector_state *connector =
>>>> -			&crtc->state->connectors[i];
>>>> -
>>>> -		if (connector->crtc_id != crtc->obj)
>>>> -			continue;
>>>> -
>>>> -		connectors[num_connectors++] = connector->obj;
>>>> +		mode = mode_prop->data;
>>>>  	}
>>>>  
>>>> -	do_or_die(drmModeSetCrtc(crtc->state->desc->fd, crtc-
>>>>> obj,
>>>> -	                         plane->fb_id,
>>>> -				 plane->src_x >> 16, plane-
>>>>> src_y >>
>>>> 16,
>>>> -				 (num_connectors) ? connectors :
>>>> NULL,
>>>> -				 num_connectors,
>>>> -				 crtc->mode.data));
>>>> -	/* When doing a legacy commit, the core may update
>>>> MODE_ID
>>>> to be a new
>>>> -	 * blob implicitly created by the legacy request. Hence
>>>> we
>>>> backfill
>>>> -	 * the value in the state object to ensure they match.
>>>> */
>>>> -	props = drmModeObjectGetProperties(crtc->state->desc-
>>>>> fd,
>>>> crtc->obj,
>>>> -					   DRM_MODE_OBJECT_CRTC)
>>>> ;
>>>> -	igt_assert(props);
>>>> -
>>>> -	for (i = 0; i < props->count_props; i++) {
>>>> -		if (props->props[i] !=
>>>> -		    crtc->state->desc-
>>>>> props_crtc[IGT_CRTC_MODE_ID])
>>>> -			continue;
>>>> -		crtc->mode.id = props->prop_values[i];
>>>> -		break;
>>>> -	}
>>>> +	legacy = drmModeGetCrtc(pipe->display->drm_fd, pipe-
>>>>> crtc_id);
>>>> +	igt_assert(legacy);
>>>>  
>>>> -	drmModeFreeObjectProperties(props);
>>>> +	igt_assert_eq_u32(legacy->crtc_id, pipe->crtc_id);
>>>> +	igt_assert_eq_u32(legacy->x,
>>>> primary_values[IGT_PLANE_SRC_X]
>>>>>> 16);
>>>> +	igt_assert_eq_u32(legacy->y,
>>>> primary_values[IGT_PLANE_SRC_Y]
>>>>>> 16);
>>>>  
>>>> -	crtc_check_current_state(crtc, plane, relax);
>>>> -	plane_check_current_state(plane, relax);
>>>> -}
>>>> +	igt_assert_eq_u32(legacy->buffer_id,
>>>> primary_values[IGT_PLANE_FB_ID]);
>>>>  
>>>> -static struct kms_atomic_crtc_state *find_crtc(struct
>>>> kms_atomic_state *state,
>>>> -					       bool
>>>> must_be_enabled)
>>>> -{
>>>> -	int i;
>>>> +	if (legacy->mode_valid) {
>>>> +		igt_assert(mode_prop);
>>>>  
>>>> -	for (i = 0; i < state->num_crtcs; i++) {
>>>> -		struct kms_atomic_crtc_state *crtc = &state-
>>>>> crtcs[i];
>>>> +		do_or_die(memcmp(&legacy->mode, mode,
>>>> sizeof(*mode)));
>>>>  
>>>> -		if (!crtc->obj)
>>>> -			continue;
>>>> -		if (must_be_enabled && !crtc->active)
>>>> -			continue;
>>>> +		igt_assert_eq(legacy->width, legacy-
>>>>> mode.hdisplay);
>>>> +		igt_assert_eq(legacy->height, legacy-
>>>>> mode.vdisplay);
>>>>  
>>>> -		crtc_get_current_state(crtc);
>>>> -		return crtc;
>>>> +		igt_assert_neq(pipe_values[IGT_CRTC_MODE_ID],
>>>> 0);
>>>> +	} else {
>>>> +		igt_assert(!mode_prop);
>>>>  	}
>>>>  
>>>> -	return NULL;
>>>> -}
>>>> +	crtc_get_current_state(pipe, current_pipe_values);
>>>>  
>>>> -static void fill_obj_props(int fd, uint32_t id, int type, int
>>>> num_props,
>>>> -			   const char **prop_names, uint32_t
>>>> *prop_ids)
>>>> -{
>>>> -	drmModeObjectPropertiesPtr props;
>>>> -	int i, j;
>>>> -
>>>> -	props = drmModeObjectGetProperties(fd, id, type);
>>>> -	igt_assert(props);
>>>> +	/* Optionally relax the check for MODE_ID: using the
>>>> legacy
>>>> SetCrtc
>>>> +	 * API can potentially change MODE_ID even if the mode
>>>> itself remains
>>>> +	 * unchanged. */
>>>> +	if (relax & CRTC_RELAX_MODE && mode &&
>>>> current_pipe_values[IGT_CRTC_MODE_ID] &&
>>>> +	    current_pipe_values[IGT_CRTC_MODE_ID] !=
>>>> pipe_values[IGT_CRTC_MODE_ID]) {
>>>> +		drmModePropertyBlobRes *cur_prop =
>>>> +			drmModeGetPropertyBlob(pipe->display-
>>>>> drm_fd,
>>>> +					       current_pipe_valu
>>>> es[I
>>>> GT_CRTC_MODE_ID]);
>>>>  
>>>> -	for (i = 0; i < props->count_props; i++) {
>>>> -		drmModePropertyPtr prop =
>>>> -			drmModeGetProperty(fd, props->props[i]);
>>>> +		igt_assert(cur_prop);
>>>> +		igt_assert_eq(cur_prop->length, sizeof(struct
>>>> drm_mode_modeinfo));
>>>>  
>>>> -		for (j = 0; j < num_props; j++) {
>>>> -			if (strcmp(prop->name, prop_names[j]) !=
>>>> 0)
>>>> -				continue;
>>>> -			prop_ids[j] = props->props[i];
>>>> -			break;
>>>> -		}
>>>> +		if (!memcmp(cur_prop->data, mode,
>>>> sizeof(*mode)))
>>>> +			current_pipe_values[IGT_CRTC_MODE_ID] =
>>>> pipe_values[IGT_CRTC_MODE_ID];
>>>>  
>>>> -		drmModeFreeProperty(prop);
>>>> +		drmModeFreePropertyBlob(cur_prop);
>>>>  	}
>>>>  
>>>> -	drmModeFreeObjectProperties(props);
>>>> -}
>>>> +	do_or_die(memcmp(pipe_values, current_pipe_values,
>>>> sizeof(current_pipe_values)));
>>>>  
>>>> -static void fill_obj_prop_map(int fd, uint32_t id, int type,
>>>> const
>>>> char *name,
>>>> -			      int num_enums, const char
>>>> **enum_names,
>>>> -			      uint64_t *enum_ids)
>>>> -{
>>>> -	drmModeObjectPropertiesPtr props;
>>>> -	int i, j, k;
>>>> -
>>>> -	props = drmModeObjectGetProperties(fd, id, type);
>>>> -	igt_assert(props);
>>>> -
>>>> -	for (i = 0; i < props->count_props; i++) {
>>>> -		drmModePropertyPtr prop =
>>>> -			drmModeGetProperty(fd, props->props[i]);
>>>> -
>>>> -		igt_assert(prop);
>>>> -
>>>> -		if (strcmp(prop->name, name) != 0) {
>>>> -			drmModeFreeProperty(prop);
>>>> -			continue;
>>>> -		}
>>>> -
>>>> -		for (j = 0; j < prop->count_enums; j++) {
>>>> -			struct drm_mode_property_enum *e =
>>>> &prop-
>>>>> enums[j];
>>>> -
>>>> -			for (k = 0; k < num_enums; k++) {
>>>> -				if (strcmp(e->name,
>>>> enum_names[k])
>>>> != 0)
>>>> -					continue;
>>>> -
>>>> -				enum_ids[k] = e->value;
>>>> -				break;
>>>> -			}
>>>> -		}
>>>> -
>>>> -		drmModeFreeProperty(prop);
>>>> -	}
>>>> +	drmModeFreeCrtc(legacy);
>>>> +	drmModeFreePropertyBlob(mode_prop);
>>>>  }
>>>>  
>>>> -static void atomic_setup(struct kms_atomic_state *state)
>>>> +static void crtc_commit(igt_pipe_t *pipe, igt_plane_t *plane,
>>>> +			enum igt_commit_style s,
>>>> +			enum kms_atomic_check_relax relax)
>>>>  {
>>>> -	struct kms_atomic_desc *desc = state->desc;
>>>> -	drmModeResPtr res;
>>>> -	drmModePlaneResPtr res_plane;
>>>> -	int i;
>>>> -
>>>> -	desc->fd = drm_open_driver_master(DRIVER_ANY);
>>>> -	igt_assert_fd(desc->fd);
>>>> -
>>>> -	igt_skip_on(drmSetClientCap(desc->fd,
>>>> DRM_CLIENT_CAP_ATOMIC,
>>>> 1));
>>>> -
>>>> -	res = drmModeGetResources(desc->fd);
>>>> -	res_plane = drmModeGetPlaneResources(desc->fd);
>>>> -	igt_assert(res);
>>>> -	igt_assert(res_plane);
>>>> -
>>>> -	igt_assert_lt(0, res->count_crtcs);
>>>> -	state->num_crtcs = res->count_crtcs;
>>>> -	state->crtcs = calloc(state->num_crtcs, sizeof(*state-
>>>>> crtcs));
>>>> -	igt_assert(state->crtcs);
>>>> -
>>>> -	igt_assert_lt(0, res_plane->count_planes);
>>>> -	state->num_planes = res_plane->count_planes;
>>>> -	state->planes = calloc(state->num_planes, sizeof(*state-
>>>>> planes));
>>>> -	igt_assert(state->planes);
>>>> -
>>>> -	igt_assert_lt(0, res->count_connectors);
>>>> -	state->num_connectors = res->count_connectors;
>>>> -	state->connectors = calloc(state->num_connectors,
>>>> -				   sizeof(*state->connectors));
>>>> -	igt_assert(state->connectors);
>>>> -
>>>> -	fill_obj_props(desc->fd, res->crtcs[0],
>>>> -		       DRM_MODE_OBJECT_CRTC, IGT_NUM_CRTC_PROPS,
>>>> -		       igt_crtc_prop_names, desc->props_crtc);
>>>> -
>>>> -	fill_obj_props(desc->fd, res_plane->planes[0],
>>>> -		       DRM_MODE_OBJECT_PLANE,
>>>> IGT_NUM_PLANE_PROPS,
>>>> -		       igt_plane_prop_names, desc->props_plane);
>>>> -	fill_obj_prop_map(desc->fd, res_plane->planes[0],
>>>> -			  DRM_MODE_OBJECT_PLANE, "type",
>>>> -			  NUM_PLANE_TYPE_PROPS,
>>>> plane_type_prop_names,
>>>> -			  desc->props_plane_type);
>>>> -
>>>> -	fill_obj_props(desc->fd, res->connectors[0],
>>>> -		       DRM_MODE_OBJECT_CONNECTOR,
>>>> IGT_NUM_CONNECTOR_PROPS,
>>>> -		       igt_connector_prop_names, desc-
>>>>> props_connector);
>>>> -
>>>> -	for (i = 0; i < state->num_crtcs; i++) {
>>>> -		struct kms_atomic_crtc_state *crtc = &state-
>>>>> crtcs[i];
>>>> -
>>>> -		crtc->state = state;
>>>> -		crtc->obj = res->crtcs[i];
>>>> -		crtc->idx = i;
>>>> -		crtc_get_current_state(crtc);
>>>> -
>>>> -		/* The blob pointed to by MODE_ID could well be
>>>> transient,
>>>> -		 * and lose its last reference as we switch away
>>>> from it.
>>>> -		 * Duplicate the blob here so we have a
>>>> reference we
>>>> know we
>>>> -		 * own. */
>>>> -		if (crtc->mode.id != 0)
>>>> -		    crtc->mode.id = blob_duplicate(desc->fd,
>>>> crtc-
>>>>> mode.id);
>>>> -	}
>>>> +	igt_display_commit2(pipe->display, s);
>>>>  
>>>> -	for (i = 0; i < state->num_planes; i++) {
>>>> -		drmModePlanePtr plane =
>>>> -			drmModeGetPlane(desc->fd, res_plane-
>>>>> planes[i]);
>>>> -		igt_assert(plane);
>>>> -
>>>> -		state->planes[i].state = state;
>>>> -		state->planes[i].obj = res_plane->planes[i];
>>>> -		state->planes[i].crtc_mask = plane-
>>>>> possible_crtcs;
>>>> -		plane_get_current_state(&state->planes[i]);
>>>> -	}
>>>> -
>>>> -	for (i = 0; i < state->num_connectors; i++) {
>>>> -		state->connectors[i].state = state;
>>>> -		state->connectors[i].obj = res->connectors[i];
>>>> -		connector_get_current_state(&state-
>>>>> connectors[i]);
>>>> -	}
>>>> -
>>>> -	drmModeFreePlaneResources(res_plane);
>>>> -	drmModeFreeResources(res);
>>>> +	crtc_check_current_state(pipe, pipe->values, plane-
>>>>> values,
>>>> relax);
>>>> +	plane_check_current_state(plane, plane->values, relax);
>>>>  }
>>>>  
>>>> -static struct kms_atomic_state *
>>>> -atomic_state_dup(const struct kms_atomic_state *state)
>>>> +static void crtc_commit_atomic_flags_err(igt_pipe_t *pipe,
>>>> igt_plane_t *plane,
>>>> +					 unsigned flags,
>>>> +					 enum
>>>> kms_atomic_check_relax
>>>> relax,
>>>> +					 int err)
>>>>  {
>>>> -	struct kms_atomic_state *ret = calloc(1, sizeof(*ret));
>>>> -
>>>> -	igt_assert(ret);
>>>> -	*ret = *state;
>>>> +	uint64_t current_pipe_values[IGT_NUM_CRTC_PROPS];
>>>> +	uint64_t current_plane_values[IGT_NUM_PLANE_PROPS];
>>>>  
>>>> -	ret->crtcs = calloc(ret->num_crtcs, sizeof(*ret-
>>>>> crtcs));
>>>> -	igt_assert(ret->crtcs);
>>>> -	memcpy(ret->crtcs, state->crtcs, ret->num_crtcs *
>>>> sizeof(*ret->crtcs));
>>>> +	crtc_get_current_state(pipe, current_pipe_values);
>>>> +	plane_get_current_state(plane, current_plane_values);
>>>>  
>>>> -	ret->planes = calloc(ret->num_planes, sizeof(*ret-
>>>>> planes));
>>>> -	igt_assert(ret->planes);
>>>> -	memcpy(ret->planes, state->planes,
>>>> -	       ret->num_planes * sizeof(*ret->planes));
>>>> +	igt_assert_eq(-err, igt_display_try_commit_atomic(pipe-
>>>>> display, flags, NULL));
>>>>  
>>>> -	ret->connectors = calloc(ret->num_connectors,
>>>> sizeof(*ret-
>>>>> connectors));
>>>> -	igt_assert(ret->connectors);
>>>> -	memcpy(ret->connectors, state->connectors,
>>>> -	       ret->num_connectors * sizeof(*ret->connectors));
>>>> -
>>>> -	return ret;
>>>> +	crtc_check_current_state(pipe, current_pipe_values,
>>>> current_plane_values, relax);
>>>> +	plane_check_current_state(plane, current_plane_values,
>>>> relax);
>>>>  }
>>>>  
>>>> -static void atomic_state_free(struct kms_atomic_state *state)
>>>> -{
>>>> -	free(state->crtcs);
>>>> -	free(state->planes);
>>>> -	free(state->connectors);
>>>> -	free(state);
>>>> -}
>>>> +#define crtc_commit_atomic_err(pipe, plane, relax, err) \
>>>> +	crtc_commit_atomic_flags_err(pipe, plane,
>>>> DRM_MODE_ATOMIC_ALLOW_MODESET, relax, err)
>>>>  
>>>> -static uint32_t plane_get_igt_format(struct
>>>> kms_atomic_plane_state
>>>> *plane)
>>>> +static uint32_t plane_get_igt_format(igt_plane_t *plane)
>>>>  {
>>>>  	drmModePlanePtr plane_kms;
>>>>  	const uint32_t *igt_formats;
>>>> -	uint32_t ret = 0;
>>>>  	int num_igt_formats;
>>>>  	int i;
>>>>  
>>>> -	plane_kms = drmModeGetPlane(plane->state->desc->fd,
>>>> plane-
>>>>> obj);
>>>> -	igt_assert(plane_kms);
>>>> +	plane_kms = plane->drm_plane;
>>>>  
>>>>  	igt_get_all_cairo_formats(&igt_formats,
>>>> &num_igt_formats);
>>>>  	for (i = 0; i < num_igt_formats; i++) {
>>>>  		int j;
>>>>  
>>>>  		for (j = 0; j < plane_kms->count_formats; j++) {
>>>> -			if (plane_kms->formats[j] ==
>>>> igt_formats[i])
>>>> {
>>>> -				ret = plane_kms->formats[j];
>>>> -				break;
>>>> -			}
>>>> +			if (plane_kms->formats[j] ==
>>>> igt_formats[i])
>>>> +				return plane_kms->formats[j];
>>>>  		}
>>>>  	}
>>>>  
>>>> -	drmModeFreePlane(plane_kms);
>>>> -	return ret;
>>>> +	return 0;
>>>>  }
>>>>  
>>>>  static void
>>>> -set_dpms(int fd, int mode)
>>>> +set_dpms(igt_output_t *output, int mode)
>>>>  {
>>>> -	int i;
>>>> -	drmModeConnector *connector;
>>>> -	uint32_t id;
>>>> -	drmModeRes *resources = drmModeGetResources(fd);
>>>> -
>>>> -	for (i = 0; i < resources->count_connectors; i++) {
>>>> -		id = resources->connectors[i];
>>>> -
>>>> -		connector = drmModeGetConnectorCurrent(fd, id);
>>>> -
>>>> -		kmstest_set_connector_dpms(fd, connector, mode);
>>>> -
>>>> -		drmModeFreeConnector(connector);
>>>> -	}
>>>> +	do_or_die(drmModeConnectorSetProperty(output->display-
>>>>> drm_fd, output->id,
>>>> +					      output-
>>>>> props[IGT_CONNECTOR_DPMS], mode));
>>>>  }
>>>>  
>>>> -static void plane_overlay(struct kms_atomic_crtc_state *crtc,
>>>> -			  struct kms_atomic_plane_state
>>>> *plane_old)
>>>> +static void plane_overlay(igt_pipe_t *pipe, igt_output_t
>>>> *output,
>>>> igt_plane_t *plane)
>>>>  {
>>>> -	struct drm_mode_modeinfo *mode = crtc->mode.data;
>>>> -	struct kms_atomic_plane_state plane = *plane_old;
>>>> -	uint32_t format = plane_get_igt_format(&plane);
>>>> -	drmModeAtomicReq *req = drmModeAtomicAlloc();
>>>> +	drmModeModeInfo *mode = igt_output_get_mode(output);
>>>> +	uint32_t format = plane_get_igt_format(plane);
>>>>  	struct igt_fb fb;
>>>> +	uint32_t w = mode->hdisplay / 2;
>>>> +	uint32_t h = mode->vdisplay / 2;
>>>>  
>>>> -	igt_require(req);
>>>>  	igt_require(format != 0);
>>>>  
>>>> -	plane.src_x = 0;
>>>> -	plane.src_y = 0;
>>>> -	plane.src_w = (mode->hdisplay / 2) << 16;
>>>> -	plane.src_h = (mode->vdisplay / 2) << 16;
>>>> -	plane.crtc_x = mode->hdisplay / 4;
>>>> -	plane.crtc_y = mode->vdisplay / 4;
>>>> -	plane.crtc_w = mode->hdisplay / 2;
>>>> -	plane.crtc_h = mode->vdisplay / 2;
>>>> -	plane.crtc_id = crtc->obj;
>>>> -	plane.fb_id = igt_create_pattern_fb(plane.state->desc-
>>>>> fd,
>>>> -					    plane.crtc_w,
>>>> plane.crtc_h,
>>>> -					    format,
>>>> I915_TILING_NONE, &fb);
>>>> +	igt_create_pattern_fb(pipe->display->drm_fd, w, h,
>>>> +			      format, I915_TILING_NONE, &fb);
>>>> +
>>>> +	igt_plane_set_fb(plane, &fb);
>>>> +	igt_plane_set_position(plane, w/2, h/2);
>>>>  
>>>>  	/* Enable the overlay plane using the atomic API, and
>>>> double-check
>>>>  	 * state is what we think it should be. */
>>>> -	plane_commit_atomic(&plane, req, ATOMIC_RELAX_NONE);
>>>> +	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>>>>  
>>>>  	/* Disable the plane and check the state matches the
>>>> old. */
>>>> -	plane_commit_atomic(plane_old, req, ATOMIC_RELAX_NONE);
>>>> +	igt_plane_set_fb(plane, NULL);
>>>> +	igt_plane_set_position(plane, 0, 0);
>>>> +	plane_commit(plane, COMMIT_ATOMIC, ATOMIC_RELAX_NONE);
>>>>  
>>>>  	/* Re-enable the plane through the legacy plane API, and
>>>> verify through
>>>>  	 * atomic. */
>>>> -	plane_commit_legacy(&plane, ATOMIC_RELAX_NONE);
>>>> +	igt_plane_set_fb(plane, &fb);
>>>> +	igt_plane_set_position(plane, w/2, h/2);
>>>> +	plane_commit(plane, COMMIT_LEGACY, ATOMIC_RELAX_NONE);
>>>>  
>>>>  	/* Restore the plane to its original settings through
>>>> the
>>>> legacy plane
>>>>  	 * API, and verify through atomic. */
>>>> -	plane_commit_legacy(plane_old, ATOMIC_RELAX_NONE);
>>>> +	igt_plane_set_fb(plane, NULL);
>>>> +	igt_plane_set_position(plane, 0, 0);
>>>> +	plane_commit(plane, COMMIT_LEGACY, ATOMIC_RELAX_NONE);
>>>>  
>>>> -	drmModeAtomicFree(req);
>>>> +	igt_remove_fb(pipe->display->drm_fd, &fb);
>>>>  }
>>>>  
>>>> -static void plane_primary(struct kms_atomic_crtc_state *crtc,
>>>> -			  struct kms_atomic_plane_state
>>>> *plane_old)
>>>> +static void plane_primary(igt_pipe_t *pipe, igt_plane_t *plane,
>>>> struct igt_fb *fb)
>>>>  {
>>>> -	struct drm_mode_modeinfo *mode = crtc->mode.data;
>>>> -	struct kms_atomic_plane_state plane = *plane_old;
>>>> -	uint32_t format = plane_get_igt_format(&plane);
>>>> -	drmModeAtomicReq *req = drmModeAtomicAlloc();
>>>> -	struct igt_fb fb;
>>>> -	uint32_t flags = 0;
>>>> -	int ret;
>>>> -
>>>> -	igt_require(format != 0);
>>>> +	struct igt_fb fb2;
>>>>  
>>>> -	plane.src_x = 0;
>>>> -	plane.src_y = 0;
>>>> -	plane.src_w = mode->hdisplay << 16;
>>>> -	plane.src_h = mode->vdisplay << 16;
>>>> -	plane.crtc_x = 0;
>>>> -	plane.crtc_y = 0;
>>>> -	plane.crtc_w = mode->hdisplay;
>>>> -	plane.crtc_h = mode->vdisplay;
>>>> -	plane.crtc_id = crtc->obj;
>>>> -	plane.fb_id = igt_create_pattern_fb(plane.state->desc-
>>>>> fd,
>>>> -					    plane.crtc_w,
>>>> plane.crtc_h,
>>>> -					    format,
>>>> I915_TILING_NONE, &fb);
>>>> -
>>>> -	drmModeAtomicSetCursor(req, 0);
>>>> -	crtc_populate_req(crtc, req);
>>>> -	plane_populate_req(&plane, req);
>>>> -	ret = drmModeAtomicCommit(crtc->state->desc->fd, req,
>>>> -				  DRM_MODE_ATOMIC_TEST_ONLY,
>>>> NULL);
>>>> -	/* Try harder in case the failure is caused by
>>>> disallowing
>>>> modeset. */
>>>> -	if (ret == -EINVAL)
>>>> -		flags |= DRM_MODE_ATOMIC_ALLOW_MODESET;
>>>> +	igt_create_color_pattern_fb(pipe->display->drm_fd,
>>>> +				    fb->width, fb->height,
>>>> +				    fb->drm_format,
>>>> I915_TILING_NONE,
>>>> +				    0.2, 0.2, 0.2, &fb2);
>>>>  
>>>>  	/* Flip the primary plane using the atomic API, and
>>>> double-
>>>> check
>>>>  	 * state is what we think it should be. */
>>>> -	crtc_commit_atomic(crtc, &plane, req, ATOMIC_RELAX_NONE,
>>>> flags);
>>>> +	igt_plane_set_fb(plane, &fb2);
>>>> +	crtc_commit(pipe, plane, COMMIT_ATOMIC,
>>>> ATOMIC_RELAX_NONE);
>>>>  
>>>>  	/* Restore the primary plane and check the state matches
>>>> the
>>>> old. */
>>>> -	crtc_commit_atomic(crtc, plane_old, req,
>>>> ATOMIC_RELAX_NONE,
>>>> flags);
>>>> +	igt_plane_set_fb(plane, fb);
>>>> +	crtc_commit(pipe, plane, COMMIT_ATOMIC,
>>>> ATOMIC_RELAX_NONE);
>>>>  
>>>> -	/* Re-enable the plane through the legacy CRTC/primary-
>>>> plane 
>>>> API, and
>>>> +	/* Set the plane through the legacy CRTC/primary-plane
>>>> API,
>>>> and
>>>>  	 * verify through atomic. */
>>>> -	crtc_commit_legacy(crtc, &plane, CRTC_RELAX_MODE);
>>>> +	igt_plane_set_fb(plane, &fb2);
>>>> +	crtc_commit(pipe, plane, COMMIT_LEGACY,
>>>> CRTC_RELAX_MODE);
>>>>  
>>>>  	/* Restore the plane to its original settings through
>>>> the
>>>> legacy CRTC
>>>>  	 * API, and verify through atomic. */
>>>> -	crtc_commit_legacy(crtc, plane_old, CRTC_RELAX_MODE);
>>>> -
>>>> -	/* Finally, restore to the original state. */
>>>> -	crtc_commit_atomic(crtc, plane_old, req,
>>>> ATOMIC_RELAX_NONE,
>>>> flags);
>>>> +	igt_plane_set_fb(plane, fb);
>>>> +	crtc_commit(pipe, plane, COMMIT_LEGACY,
>>>> CRTC_RELAX_MODE);
>>>>  
>>>> -	drmModeAtomicFree(req);
>>>> +	/* Set the plane through the universal setplane API, and
>>>> +	 * verify through atomic. */
>>>> +	igt_plane_set_fb(plane, &fb2);
>>>> +	plane_commit(plane, COMMIT_UNIVERSAL,
>>>> ATOMIC_RELAX_NONE);
>>>>  }
>>>>  
>>>>  /* test to ensure that DRM_MODE_ATOMIC_TEST_ONLY really only
>>>> touches
>>>> the
>>>>   * free-standing state objects and nothing else.
>>>>   */
>>>> -static void test_only(struct kms_atomic_crtc_state *crtc,
>>>> -		      struct kms_atomic_plane_state *plane_old)
>>>> +static void test_only(igt_pipe_t *pipe_obj,
>>>> +		      igt_plane_t *primary,
>>>> +		      igt_output_t *output)
>>>>  {
>>>> -	struct drm_mode_modeinfo *mode = crtc->mode.data;
>>>> -	struct kms_atomic_plane_state plane = *plane_old;
>>>> -	uint32_t format = plane_get_igt_format(&plane);
>>>> -	drmModeAtomicReq *req = drmModeAtomicAlloc();
>>>> +	drmModeModeInfo *mode = igt_output_get_mode(output);
>>>> +	uint32_t format = plane_get_igt_format(primary);
>>>>  	struct igt_fb fb;
>>>> -	int ret;
>>>> +	uint64_t old_plane_values[IGT_NUM_PLANE_PROPS],
>>>> old_crtc_values[IGT_NUM_CRTC_PROPS];
>>>>  
>>>>  	igt_require(format != 0);
>>>>  
>>>> -	plane.src_x = 0;
>>>> -	plane.src_y = 0;
>>>> -	plane.src_w = mode->hdisplay << 16;
>>>> -	plane.src_h = mode->vdisplay << 16;
>>>> -	plane.crtc_x = 0;
>>>> -	plane.crtc_y = 0;
>>>> -	plane.crtc_w = mode->hdisplay;
>>>> -	plane.crtc_h = mode->vdisplay;
>>>> -	plane.crtc_id = crtc->obj;
>>>> -	plane.fb_id = igt_create_pattern_fb(plane.state->desc-
>>>>> fd,
>>>> -					    plane.crtc_w,
>>>> plane.crtc_h,
>>>> -					    format,
>>>> I915_TILING_NONE, &fb);
>>>> -
>>>> -	drmModeAtomicSetCursor(req, 0);
>>>> -	crtc_populate_req(crtc, req);
>>>> -	plane_populate_req(&plane, req);
>>>> -	ret = drmModeAtomicCommit(crtc->state->desc->fd, req,
>>>> -				  DRM_MODE_ATOMIC_TEST_ONLY,
>>>> NULL);
>>>> -
>>>> -	igt_assert_eq(ret, 0);
>>>> -
>>>> -	/* go through dpms off/on cycle */
>>>> -	set_dpms(crtc->state->desc->fd, DRM_MODE_DPMS_OFF);
>>>> -	set_dpms(crtc->state->desc->fd, DRM_MODE_DPMS_ON);
>>>> -
>>>> -	/* check the state */
>>>> -	crtc_check_current_state(crtc, plane_old,
>>>> ATOMIC_RELAX_NONE);
>>>> -	plane_check_current_state(plane_old, ATOMIC_RELAX_NONE);
>>>> -
>>>> -	/* Re-enable the plane through the legacy CRTC/primary-
>>>> plane 
>>>> API, and
>>>> -	 * verify through atomic. */
>>>> -	crtc_commit_legacy(crtc, plane_old, CRTC_RELAX_MODE);
>>>> +	plane_get_current_state(primary, old_plane_values);
>>>> +	crtc_get_current_state(pipe_obj, old_crtc_values);
>>>> +
>>>> +	igt_assert(!old_crtc_values[IGT_CRTC_MODE_ID]);
>>>> +
>>>> +	igt_create_pattern_fb(pipe_obj->display->drm_fd,
>>>> +			     mode->hdisplay, mode->vdisplay,
>>>> +			     format, I915_TILING_NONE, &fb);
>>>> +	igt_plane_set_fb(primary, &fb);
>>>> +	igt_output_set_pipe(output, pipe_obj->pipe);
>>>> +
>>>> +	igt_display_commit_atomic(pipe_obj->display,
>>>> DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
>>>> +
>>>> +	/* check the state, should still be old state */
>>>> +	crtc_check_current_state(pipe_obj, old_crtc_values,
>>>> old_plane_values, ATOMIC_RELAX_NONE);
>>>> +	plane_check_current_state(primary, old_plane_values,
>>>> ATOMIC_RELAX_NONE);
>>>> +
>>>> +	/*
>>>> +	 * Enable the plane through the legacy CRTC/primary-
>>>> plane
>>>> API, and
>>>> +	 * verify through atomic.
>>>> +	 */
>>>> +	crtc_commit(pipe_obj, primary, COMMIT_LEGACY,
>>>> CRTC_RELAX_MODE);
>>>> +
>>>> +	/* Same for disable.. */
>>>> +	plane_get_current_state(primary, old_plane_values);
>>>> +	crtc_get_current_state(pipe_obj, old_crtc_values);
>>>> +
>>>> +	igt_plane_set_fb(primary, NULL);
>>>> +	igt_output_set_pipe(output, PIPE_NONE);
>>>> +
>>>> +	igt_display_commit_atomic(pipe_obj->display,
>>>> DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
>>>>  
>>>> -	drmModeAtomicFree(req);
>>>> +	/* for extra stress, go through dpms off/on cycle */
>>>> +	set_dpms(output, DRM_MODE_DPMS_OFF);
>>>> +	set_dpms(output, DRM_MODE_DPMS_ON);
>>> There is this library function 'kmstest_set_connector_dpms()'.
>>> Could we
>>> utilize this function here instead?
>> Sure, I never understood what the dpms call was supposed to expose
>> though..
>>
>> Want me to resend or is replacing the call with
>> kmstest_set_connector_dpms(s, output->config.connector,
>> DRM_MODE_DPMS_OFF); enough?
> Well, my point of view is that we should use library functions as much
> as possible. I guess that's the reason why we have the libraries in the
> first place. So a vote for a replacement.
>
Thanks for review and irc r-b with fixes, pushed. :)

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2 03/14] lib/igt_kms: Rework pipe properties to be more atomic, v7.
  2017-10-12 11:54 ` [PATCH i-g-t v2 03/14] lib/igt_kms: Rework pipe properties to be more atomic, v7 Maarten Lankhorst
@ 2018-03-05 14:37     ` Maxime Ripard
  2018-03-05 14:37     ` [igt-dev] [Intel-gfx] " Maxime Ripard
  1 sibling, 0 replies; 45+ messages in thread
From: Maxime Ripard @ 2018-03-05 14:37 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Paul Kocialkowski, igt-dev, intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1716 bytes --]

Hi,

On Thu, Oct 12, 2017 at 01:54:24PM +0200, Maarten Lankhorst wrote:
> In the future I want to allow tests to commit more properties,
> but for this to work I have to fix all properties to work better
> with atomic commit. Instead of special casing each
> property make a bitmask for all property changed flags, and try to
> commit all properties.
> 
> This has been the most involved one, since legacy pipe commit still
> handles a lot of the properties differently from the rest.
> 
> Changes since v1:
> - Dump all changed properties on commit.
> - Fix bug in igt_pipe_refresh().
> Changes since v2:
> - Set pipe ACTIVE property changed flag on init.
> Changes since v3:
> - Add a missing igt_pipe_refresh() to kms_atomic_interruptible.
> Changes since v4:
> - Perform error handling when setting custom crtc properties.
> Changes since v5:
> - Only attempt to commit changes properties.
> Changes since v6:
> - Clear OUT_FENCE_PTR on succesful commit.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

I'm a bit late to the party on this one, but this commit broke the
chamelium tests on vc4, with every kernel since at least 4.12.

This is the error message:
http://code.bulix.org/32fw1l-293842

From the stack trace, it looks like the atomic commit was failing, and
indeed it fails here:
https://elixir.bootlin.com/linux/v4.16-rc4/source/drivers/gpu/drm/drm_atomic.c#L2319

with prop_id being 0 for some reason.

I had a look at that patch, but I can't see anything wrong with it. Do
you have any ideas?

Thanks!
Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [igt-dev] [Intel-gfx] [PATCH i-g-t v2 03/14] lib/igt_kms: Rework pipe properties to be more atomic, v7.
@ 2018-03-05 14:37     ` Maxime Ripard
  0 siblings, 0 replies; 45+ messages in thread
From: Maxime Ripard @ 2018-03-05 14:37 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: Paul Kocialkowski, igt-dev, intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 1716 bytes --]

Hi,

On Thu, Oct 12, 2017 at 01:54:24PM +0200, Maarten Lankhorst wrote:
> In the future I want to allow tests to commit more properties,
> but for this to work I have to fix all properties to work better
> with atomic commit. Instead of special casing each
> property make a bitmask for all property changed flags, and try to
> commit all properties.
> 
> This has been the most involved one, since legacy pipe commit still
> handles a lot of the properties differently from the rest.
> 
> Changes since v1:
> - Dump all changed properties on commit.
> - Fix bug in igt_pipe_refresh().
> Changes since v2:
> - Set pipe ACTIVE property changed flag on init.
> Changes since v3:
> - Add a missing igt_pipe_refresh() to kms_atomic_interruptible.
> Changes since v4:
> - Perform error handling when setting custom crtc properties.
> Changes since v5:
> - Only attempt to commit changes properties.
> Changes since v6:
> - Clear OUT_FENCE_PTR on succesful commit.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

I'm a bit late to the party on this one, but this commit broke the
chamelium tests on vc4, with every kernel since at least 4.12.

This is the error message:
http://code.bulix.org/32fw1l-293842

From the stack trace, it looks like the atomic commit was failing, and
indeed it fails here:
https://elixir.bootlin.com/linux/v4.16-rc4/source/drivers/gpu/drm/drm_atomic.c#L2319

with prop_id being 0 for some reason.

I had a look at that patch, but I can't see anything wrong with it. Do
you have any ideas?

Thanks!
Maxime

-- 
Maxime Ripard, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 154 bytes --]

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2 03/14] lib/igt_kms: Rework pipe properties to be more atomic, v7.
  2018-03-05 14:37     ` [igt-dev] [Intel-gfx] " Maxime Ripard
@ 2018-03-06 13:41       ` Daniel Vetter
  -1 siblings, 0 replies; 45+ messages in thread
From: Daniel Vetter @ 2018-03-06 13:41 UTC (permalink / raw)
  To: Maxime Ripard; +Cc: Paul Kocialkowski, igt-dev, intel-gfx

On Mon, Mar 05, 2018 at 03:37:30PM +0100, Maxime Ripard wrote:
> Hi,
> 
> On Thu, Oct 12, 2017 at 01:54:24PM +0200, Maarten Lankhorst wrote:
> > In the future I want to allow tests to commit more properties,
> > but for this to work I have to fix all properties to work better
> > with atomic commit. Instead of special casing each
> > property make a bitmask for all property changed flags, and try to
> > commit all properties.
> > 
> > This has been the most involved one, since legacy pipe commit still
> > handles a lot of the properties differently from the rest.
> > 
> > Changes since v1:
> > - Dump all changed properties on commit.
> > - Fix bug in igt_pipe_refresh().
> > Changes since v2:
> > - Set pipe ACTIVE property changed flag on init.
> > Changes since v3:
> > - Add a missing igt_pipe_refresh() to kms_atomic_interruptible.
> > Changes since v4:
> > - Perform error handling when setting custom crtc properties.
> > Changes since v5:
> > - Only attempt to commit changes properties.
> > Changes since v6:
> > - Clear OUT_FENCE_PTR on succesful commit.
> > 
> > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> 
> I'm a bit late to the party on this one, but this commit broke the
> chamelium tests on vc4, with every kernel since at least 4.12.
> 
> This is the error message:
> http://code.bulix.org/32fw1l-293842
> 
> From the stack trace, it looks like the atomic commit was failing, and
> indeed it fails here:
> https://elixir.bootlin.com/linux/v4.16-rc4/source/drivers/gpu/drm/drm_atomic.c#L2319
> 
> with prop_id being 0 for some reason.
> 
> I had a look at that patch, but I can't see anything wrong with it. Do
> you have any ideas?

No idea tbh, I guess we need to start tracing where the igt library tries
to set property 0. Would probably be really good to catch that in the
libdrm atomic support (same with trying to set a prop on obj 0, neither
makes any sense at all).
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [igt-dev] [Intel-gfx] [PATCH i-g-t v2 03/14] lib/igt_kms: Rework pipe properties to be more atomic, v7.
@ 2018-03-06 13:41       ` Daniel Vetter
  0 siblings, 0 replies; 45+ messages in thread
From: Daniel Vetter @ 2018-03-06 13:41 UTC (permalink / raw)
  To: Maxime Ripard; +Cc: Paul Kocialkowski, igt-dev, intel-gfx

On Mon, Mar 05, 2018 at 03:37:30PM +0100, Maxime Ripard wrote:
> Hi,
> 
> On Thu, Oct 12, 2017 at 01:54:24PM +0200, Maarten Lankhorst wrote:
> > In the future I want to allow tests to commit more properties,
> > but for this to work I have to fix all properties to work better
> > with atomic commit. Instead of special casing each
> > property make a bitmask for all property changed flags, and try to
> > commit all properties.
> > 
> > This has been the most involved one, since legacy pipe commit still
> > handles a lot of the properties differently from the rest.
> > 
> > Changes since v1:
> > - Dump all changed properties on commit.
> > - Fix bug in igt_pipe_refresh().
> > Changes since v2:
> > - Set pipe ACTIVE property changed flag on init.
> > Changes since v3:
> > - Add a missing igt_pipe_refresh() to kms_atomic_interruptible.
> > Changes since v4:
> > - Perform error handling when setting custom crtc properties.
> > Changes since v5:
> > - Only attempt to commit changes properties.
> > Changes since v6:
> > - Clear OUT_FENCE_PTR on succesful commit.
> > 
> > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> 
> I'm a bit late to the party on this one, but this commit broke the
> chamelium tests on vc4, with every kernel since at least 4.12.
> 
> This is the error message:
> http://code.bulix.org/32fw1l-293842
> 
> From the stack trace, it looks like the atomic commit was failing, and
> indeed it fails here:
> https://elixir.bootlin.com/linux/v4.16-rc4/source/drivers/gpu/drm/drm_atomic.c#L2319
> 
> with prop_id being 0 for some reason.
> 
> I had a look at that patch, but I can't see anything wrong with it. Do
> you have any ideas?

No idea tbh, I guess we need to start tracing where the igt library tries
to set property 0. Would probably be really good to catch that in the
libdrm atomic support (same with trying to set a prop on obj 0, neither
makes any sense at all).
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH i-g-t v2 03/14] lib/igt_kms: Rework pipe properties to be more atomic, v7.
  2018-03-06 13:41       ` [igt-dev] [Intel-gfx] " Daniel Vetter
@ 2018-03-06 13:47         ` Maarten Lankhorst
  -1 siblings, 0 replies; 45+ messages in thread
From: Maarten Lankhorst @ 2018-03-06 13:47 UTC (permalink / raw)
  To: Daniel Vetter, Maxime Ripard; +Cc: Paul Kocialkowski, igt-dev, intel-gfx

Op 06-03-18 om 14:41 schreef Daniel Vetter:
> On Mon, Mar 05, 2018 at 03:37:30PM +0100, Maxime Ripard wrote:
>> Hi,
>>
>> On Thu, Oct 12, 2017 at 01:54:24PM +0200, Maarten Lankhorst wrote:
>>> In the future I want to allow tests to commit more properties,
>>> but for this to work I have to fix all properties to work better
>>> with atomic commit. Instead of special casing each
>>> property make a bitmask for all property changed flags, and try to
>>> commit all properties.
>>>
>>> This has been the most involved one, since legacy pipe commit still
>>> handles a lot of the properties differently from the rest.
>>>
>>> Changes since v1:
>>> - Dump all changed properties on commit.
>>> - Fix bug in igt_pipe_refresh().
>>> Changes since v2:
>>> - Set pipe ACTIVE property changed flag on init.
>>> Changes since v3:
>>> - Add a missing igt_pipe_refresh() to kms_atomic_interruptible.
>>> Changes since v4:
>>> - Perform error handling when setting custom crtc properties.
>>> Changes since v5:
>>> - Only attempt to commit changes properties.
>>> Changes since v6:
>>> - Clear OUT_FENCE_PTR on succesful commit.
>>>
>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> I'm a bit late to the party on this one, but this commit broke the
>> chamelium tests on vc4, with every kernel since at least 4.12.
>>
>> This is the error message:
>> http://code.bulix.org/32fw1l-293842
>>
>> From the stack trace, it looks like the atomic commit was failing, and
>> indeed it fails here:
>> https://elixir.bootlin.com/linux/v4.16-rc4/source/drivers/gpu/drm/drm_atomic.c#L2319
>>
>> with prop_id being 0 for some reason.
>>
>> I had a look at that patch, but I can't see anything wrong with it. Do
>> you have any ideas?
> No idea tbh, I guess we need to start tracing where the igt library tries
> to set property 0. Would probably be really good to catch that in the
> libdrm atomic support (same with trying to set a prop on obj 0, neither
> makes any sense at all).
> -Daniel

Sorry, I cc'd the original posters on it but already have a fix:

https://patchwork.freedesktop.org/patch/208058/

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [Intel-gfx] [PATCH i-g-t v2 03/14] lib/igt_kms: Rework pipe properties to be more atomic, v7.
@ 2018-03-06 13:47         ` Maarten Lankhorst
  0 siblings, 0 replies; 45+ messages in thread
From: Maarten Lankhorst @ 2018-03-06 13:47 UTC (permalink / raw)
  To: Daniel Vetter, Maxime Ripard; +Cc: Paul Kocialkowski, igt-dev, intel-gfx

Op 06-03-18 om 14:41 schreef Daniel Vetter:
> On Mon, Mar 05, 2018 at 03:37:30PM +0100, Maxime Ripard wrote:
>> Hi,
>>
>> On Thu, Oct 12, 2017 at 01:54:24PM +0200, Maarten Lankhorst wrote:
>>> In the future I want to allow tests to commit more properties,
>>> but for this to work I have to fix all properties to work better
>>> with atomic commit. Instead of special casing each
>>> property make a bitmask for all property changed flags, and try to
>>> commit all properties.
>>>
>>> This has been the most involved one, since legacy pipe commit still
>>> handles a lot of the properties differently from the rest.
>>>
>>> Changes since v1:
>>> - Dump all changed properties on commit.
>>> - Fix bug in igt_pipe_refresh().
>>> Changes since v2:
>>> - Set pipe ACTIVE property changed flag on init.
>>> Changes since v3:
>>> - Add a missing igt_pipe_refresh() to kms_atomic_interruptible.
>>> Changes since v4:
>>> - Perform error handling when setting custom crtc properties.
>>> Changes since v5:
>>> - Only attempt to commit changes properties.
>>> Changes since v6:
>>> - Clear OUT_FENCE_PTR on succesful commit.
>>>
>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> I'm a bit late to the party on this one, but this commit broke the
>> chamelium tests on vc4, with every kernel since at least 4.12.
>>
>> This is the error message:
>> http://code.bulix.org/32fw1l-293842
>>
>> From the stack trace, it looks like the atomic commit was failing, and
>> indeed it fails here:
>> https://elixir.bootlin.com/linux/v4.16-rc4/source/drivers/gpu/drm/drm_atomic.c#L2319
>>
>> with prop_id being 0 for some reason.
>>
>> I had a look at that patch, but I can't see anything wrong with it. Do
>> you have any ideas?
> No idea tbh, I guess we need to start tracing where the igt library tries
> to set property 0. Would probably be really good to catch that in the
> libdrm atomic support (same with trying to set a prop on obj 0, neither
> makes any sense at all).
> -Daniel

Sorry, I cc'd the original posters on it but already have a fix:

https://patchwork.freedesktop.org/patch/208058/

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 45+ messages in thread

end of thread, other threads:[~2018-03-06 13:47 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-12 11:54 [PATCH i-g-t v2 00/14] lib/igt_kms: Rewrite property handling to better match atomic Maarten Lankhorst
2017-10-12 11:54 ` [PATCH i-g-t v2 01/14] lib/igt_kms: Rework connector properties to be more atomic, v2 Maarten Lankhorst
2017-10-12 11:54 ` [PATCH i-g-t v2 02/14] lib/igt_kms: Rework plane properties to be more atomic, v5 Maarten Lankhorst
2017-10-19  9:08   ` Mika Kahola
2017-10-19  9:44     ` Maarten Lankhorst
2017-10-20  8:03       ` Mika Kahola
2017-10-12 11:54 ` [PATCH i-g-t v2 03/14] lib/igt_kms: Rework pipe properties to be more atomic, v7 Maarten Lankhorst
2017-10-19 10:28   ` Mika Kahola
2018-03-05 14:37   ` Maxime Ripard
2018-03-05 14:37     ` [igt-dev] [Intel-gfx] " Maxime Ripard
2018-03-06 13:41     ` Daniel Vetter
2018-03-06 13:41       ` [igt-dev] [Intel-gfx] " Daniel Vetter
2018-03-06 13:47       ` Maarten Lankhorst
2018-03-06 13:47         ` [Intel-gfx] " Maarten Lankhorst
2017-10-12 11:54 ` [PATCH i-g-t v2 04/14] lib/igt_kms: Allow setting any plane property through the universal path Maarten Lankhorst
2017-10-19 11:04   ` Mika Kahola
2017-10-12 11:54 ` [PATCH i-g-t v2 05/14] lib/igt_kms: Allow setting any output property through the !atomic paths Maarten Lankhorst
2017-10-20  9:38   ` Mika Kahola
2017-10-12 11:54 ` [PATCH i-g-t v2 06/14] lib/igt_kms: Export property blob functions for output/pipe/plane, v2 Maarten Lankhorst
2017-10-19 11:24   ` Mika Kahola
2017-10-12 11:54 ` [PATCH i-g-t v2 07/14] lib/igt_kms: Unexport broadcast rgb API Maarten Lankhorst
2017-10-19 11:28   ` Mika Kahola
2017-10-12 11:54 ` [PATCH i-g-t v2 08/14] lib/igt_kms: Add igt_$obj_has_prop functions Maarten Lankhorst
2017-10-12 15:33   ` [PATCH i-g-t v2] lib/igt_kms: Add igt_$obj_has_prop functions, v2 Maarten Lankhorst
2017-10-19 12:06     ` Mika Kahola
2017-10-12 11:54 ` [PATCH i-g-t v2 09/14] lib/igt_kms: Add igt_$obj_get_prop functions Maarten Lankhorst
2017-10-19 12:58   ` Mika Kahola
2017-10-12 11:54 ` [PATCH i-g-t v2 10/14] lib/igt_kms: Remove igt_pipe_get_property Maarten Lankhorst
2017-10-19 13:18   ` Mika Kahola
2017-10-12 11:54 ` [PATCH i-g-t v2 11/14] lib/igt_kms: Remove igt_crtc_set_background() Maarten Lankhorst
2017-10-20  6:33   ` Mika Kahola
2017-10-12 11:54 ` [PATCH i-g-t v2 12/14] tests/kms_color: Rework tests slightly to work better with new atomic api Maarten Lankhorst
2017-10-20  7:14   ` Mika Kahola
2017-10-12 11:54 ` [PATCH i-g-t v2 13/14] tests/chamelium: Remove reliance on output->config.pipe Maarten Lankhorst
2017-10-20  7:15   ` Mika Kahola
2017-10-12 11:54 ` [PATCH i-g-t v2 14/14] tests/kms_atomic: Convert/rewrite tests to use igt_kms framework Maarten Lankhorst
2017-10-12 15:33   ` [PATCH i-g-t v2] tests/kms_atomic: Convert/rewrite tests to use igt_kms framework, v2 Maarten Lankhorst
2017-10-20 10:02     ` Mika Kahola
2017-10-20 10:08       ` Maarten Lankhorst
2017-10-20 10:16         ` Mika Kahola
2017-10-20 11:43           ` Maarten Lankhorst
2017-10-12 12:28 ` ✓ Fi.CI.BAT: success for lib/igt_kms: Rewrite property handling to better match atomic. (rev4) Patchwork
2017-10-12 15:01 ` ✗ Fi.CI.IGT: failure " Patchwork
2017-10-12 16:04 ` ✓ Fi.CI.BAT: success for lib/igt_kms: Rewrite property handling to better match atomic. (rev6) Patchwork
2017-10-12 23:47 ` ✗ Fi.CI.IGT: failure " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.