[Intel-gfx] [PATCH i-g-t 1/2] lib/igt_kms: Add for_each_pipe_with_valid_output and for_each_valid_output_on_pipe.

Maarten Lankhorst maarten.lankhorst at linux.intel.com
Mon Jun 13 13:47:54 UTC 2016


There are a lot of places where we do either

for_each_pipe {
	igt_subtest_f(... "-pipe-C", pipe_name())
		for_each_connected_output()
			/* Run subtest */
}

or:
igt_subtest_f(...) {
	for_each_pipe()
		for_each_connected_output()
			/* Run subtest */
}

The former should be replaced with for_each_valid_output_on_pipe,
the latter with for_each_pipe_with_valid_output.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
---
 lib/igt_kms.c | 29 ++++++++++++++++-------------
 lib/igt_kms.h | 23 ++++++++++++++++++++++-
 2 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index af72b90800e4..f9e32a5a2e3d 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -773,8 +773,8 @@ static bool _kmstest_connector_config(int drm_fd, uint32_t connector_id,
 {
 	drmModeRes *resources;
 	drmModeConnector *connector;
-	drmModeEncoder *encoder;
-	int i, j;
+	drmModeEncoder *encoder, *found = NULL;
+	int i, j, pipe;
 
 	resources = drmModeGetResources(drm_fd);
 	if (!resources) {
@@ -810,9 +810,9 @@ static bool _kmstest_connector_config(int drm_fd, uint32_t connector_id,
 	 * In both cases find the first compatible encoder and skip the CRTC
 	 * if there is non such.
 	 */
-	encoder = NULL;		/* suppress GCC warning */
+	config->valid_crtc_idx_mask = 0;
 	for (i = 0; i < resources->count_crtcs; i++) {
-		if (!resources->crtcs[i] || !(crtc_idx_mask & (1 << i)))
+		if (!resources->crtcs[i])
 			continue;
 
 		/* Now get a compatible encoder */
@@ -828,24 +828,27 @@ static bool _kmstest_connector_config(int drm_fd, uint32_t connector_id,
 				continue;
 			}
 
-			if (encoder->possible_crtcs & (1 << i))
-				goto found;
+			config->valid_crtc_idx_mask |= encoder->possible_crtcs;
 
-			drmModeFreeEncoder(encoder);
+			if (!found && (crtc_idx_mask & encoder->possible_crtcs & (1 << i))) {
+				found = encoder;
+				pipe = i;
+			} else
+				drmModeFreeEncoder(encoder);
 		}
 	}
 
-	goto err3;
+	if (!found)
+		goto err3;
 
-found:
 	if (!kmstest_get_connector_default_mode(drm_fd, connector,
 						&config->default_mode))
 		goto err4;
 
 	config->connector = connector;
-	config->encoder = encoder;
-	config->crtc = drmModeGetCrtc(drm_fd, resources->crtcs[i]);
-	config->crtc_idx = i;
+	config->encoder = found;
+	config->crtc = drmModeGetCrtc(drm_fd, resources->crtcs[pipe]);
+	config->crtc_idx = pipe;
 	config->pipe = kmstest_get_pipe_from_crtc_id(drm_fd,
 						     config->crtc->crtc_id);
 
@@ -853,7 +856,7 @@ found:
 
 	return true;
 err4:
-	drmModeFreeEncoder(encoder);
+	drmModeFreeEncoder(found);
 err3:
 	drmModeFreeConnector(connector);
 err2:
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 7aad8c8c2153..b66743a29027 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -114,6 +114,7 @@ struct kmstest_connector_config {
 	uint32_t atomic_props_connector[IGT_NUM_CONNECTOR_PROPS];
 	int crtc_idx;
 	int pipe;
+	unsigned valid_crtc_idx_mask;
 };
 
 /**
@@ -327,13 +328,33 @@ void igt_fb_set_size(struct igt_fb *fb, igt_plane_t *plane,
 
 void igt_wait_for_vblank(int drm_fd, enum pipe pipe);
 
+static inline bool igt_pipe_connector_valid(enum pipe pipe,
+					    igt_output_t *output)
+{
+	return output->valid && (output->config.valid_crtc_idx_mask & (1 << pipe));
+}
+
+#define for_each_if(condition) if (!(condition)) {} else
+
 #define for_each_connected_output(display, output)		\
 	for (int i__ = 0;  i__ < (display)->n_outputs; i__++)	\
-		if ((output = &(display)->outputs[i__]), output->valid)
+		for_each_if (((output = &(display)->outputs[i__]), output->valid))
 
 #define for_each_pipe(display, pipe)					\
 	for (pipe = 0; pipe < igt_display_get_n_pipes(display); pipe++)	\
 
+/* Big complex macro to make 'break' work as expected. */
+#define for_each_pipe_with_valid_output(display, pipe, output) \
+	for (int con__ = pipe = 0; \
+	     pipe < igt_display_get_n_pipes((display)) && con__ < (display)->n_outputs; \
+	     con__ = (con__ + 1 < (display)->n_outputs) ? con__ + 1 : (pipe = pipe + 1, 0)) \
+		for_each_if (((output = &(display)->outputs[con__]), \
+			     igt_pipe_connector_valid(pipe, output)))
+
+#define for_each_valid_output_on_pipe(display, pipe, output) \
+	for_each_connected_output(display, output) \
+		for_each_if (igt_pipe_connector_valid(pipe, output))
+
 #define for_each_plane_on_pipe(display, pipe, plane)			\
 	for (int j__ = 0; (plane) = &(display)->pipes[(pipe)].planes[j__], \
 		     j__ < (display)->pipes[(pipe)].n_planes; j__++)
-- 
2.5.5



More information about the Intel-gfx mailing list