[Intel-gfx] [PATCH igt 4/5] kms_frontbuffer_tracking: try harder to find suitable connectors

Paulo Zanoni paulo.r.zanoni at intel.com
Fri Feb 26 19:39:57 UTC 2016


Instead of just giving preference to an eDP primary connector, give
preference to one that's eDP and supports pipe A, then try lesser
optimal combinations later.

We could try to make our test suite use different sets of connectors
when testing FBC and PSR, but that would require some rework, and we
would still be helpless when testing the combination of FBC+PSR.

Also notice that we still hardcode pipe A for the primary connector,
regardless of whether it supports it. This will be solved in the next
commits.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni at intel.com>
---
 tests/kms_frontbuffer_tracking.c | 69 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 62 insertions(+), 7 deletions(-)

diff --git a/tests/kms_frontbuffer_tracking.c b/tests/kms_frontbuffer_tracking.c
index 3b2ca8a..47a37f4 100644
--- a/tests/kms_frontbuffer_tracking.c
+++ b/tests/kms_frontbuffer_tracking.c
@@ -152,10 +152,12 @@ struct rect {
 
 #define MAX_CONNECTORS 32
 #define MAX_PLANES 32
+#define MAX_ENCODERS 32
 struct {
 	int fd;
 	drmModeResPtr res;
 	drmModeConnectorPtr connectors[MAX_CONNECTORS];
+	drmModeEncoderPtr encoders[MAX_ENCODERS];
 	drmModePlaneResPtr plane_res;
 	drmModePlanePtr planes[MAX_PLANES];
 	uint64_t plane_types[MAX_PLANES];
@@ -357,6 +359,17 @@ static drmModeConnectorPtr get_connector(uint32_t id)
 	igt_assert(false);
 }
 
+static drmModeEncoderPtr get_encoder(uint32_t id)
+{
+	int i;
+
+	for (i = 0; i < drm.res->count_encoders; i++)
+		if (drm.res->encoders[i] == id)
+			return drm.encoders[i];
+
+	igt_assert(false);
+}
+
 static void print_mode_info(const char *screen, struct modeset_params *params)
 {
 	drmModeConnectorPtr c = get_connector(params->connector_id);
@@ -428,7 +441,18 @@ static bool connector_get_mode(drmModeConnectorPtr c, drmModeModeInfoPtr *mode)
 	return true;
 }
 
-static bool find_connector(bool edp_only, uint32_t forbidden_id,
+static bool connector_supports_pipe_a(drmModeConnectorPtr connector)
+{
+	int i;
+
+	for (i = 0; i < connector->count_encoders; i++)
+		if (get_encoder(connector->encoders[i])->possible_crtcs & 1)
+			return true;
+
+	return false;
+}
+
+static bool find_connector(bool edp_only, bool pipe_a, uint32_t forbidden_id,
 			   drmModeConnectorPtr *ret_connector,
 			   drmModeModeInfoPtr *ret_mode)
 {
@@ -441,6 +465,8 @@ static bool find_connector(bool edp_only, uint32_t forbidden_id,
 
 		if (edp_only && c->connector_type != DRM_MODE_CONNECTOR_eDP)
 			continue;
+		if (pipe_a && !connector_supports_pipe_a(c))
+			continue;
 		if (c->connector_id == forbidden_id)
 			continue;
 		if (!connector_get_mode(c, &mode))
@@ -459,17 +485,27 @@ static bool init_modeset_cached_params(void)
 	drmModeConnectorPtr prim_connector = NULL, scnd_connector = NULL;
 	drmModeModeInfoPtr prim_mode = NULL, scnd_mode = NULL;
 
-	/* First, try to find an eDP monitor since it's the only possible type
-	 * for PSR.  */
-	find_connector(true, 0, &prim_connector, &prim_mode);
+	/*
+	 * We have this problem where PSR is only present on eDP monitors and
+	 * FBC is only present on pipe A for some platforms. So we search first
+	 * for the ideal case of eDP supporting pipe A, and try the less optimal
+	 * configs later, sacrificing  one of the features.
+	 * TODO: refactor the code in a way that allows us to have different
+	 * sets of prim/scnd structs for different features.
+	 */
+	find_connector(true, true, 0, &prim_connector, &prim_mode);
+	if (!prim_connector)
+		find_connector(true, false, 0, &prim_connector, &prim_mode);
 	if (!prim_connector)
-		find_connector(false, 0, &prim_connector, &prim_mode);
+		find_connector(false, true, 0, &prim_connector, &prim_mode);
+	if (!prim_connector)
+		find_connector(false, false, 0, &prim_connector, &prim_mode);
 
 	if (!prim_connector)
 		return false;
 
-	find_connector(false, prim_connector->connector_id, &scnd_connector,
-		       &scnd_mode);
+	find_connector(false, false, prim_connector->connector_id,
+		       &scnd_connector, &scnd_mode);
 
 	init_mode_params(&prim_mode_params, drm.res->crtcs[0],
 			 prim_connector, prim_mode);
@@ -1291,10 +1327,14 @@ static void setup_drm(void)
 
 	drm.res = drmModeGetResources(drm.fd);
 	igt_assert(drm.res->count_connectors <= MAX_CONNECTORS);
+	igt_assert(drm.res->count_encoders <= MAX_ENCODERS);
 
 	for (i = 0; i < drm.res->count_connectors; i++)
 		drm.connectors[i] = drmModeGetConnectorCurrent(drm.fd,
 						drm.res->connectors[i]);
+	for (i = 0; i < drm.res->count_encoders; i++)
+		drm.encoders[i] = drmModeGetEncoder(drm.fd,
+						    drm.res->encoders[i]);
 
 	rc = drmSetClientCap(drm.fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
 	igt_require(rc == 0);
@@ -1322,6 +1362,8 @@ static void teardown_drm(void)
 		drmModeFreePlane(drm.planes[i]);
 	drmModeFreePlaneResources(drm.plane_res);
 
+	for (i = 0; i < drm.res->count_encoders; i++)
+		drmModeFreeEncoder(drm.encoders[i]);
 	for (i = 0; i < drm.res->count_connectors; i++)
 		drmModeFreeConnector(drm.connectors[i]);
 
@@ -1456,10 +1498,23 @@ static bool fbc_supported_on_chipset(void)
 
 static void setup_fbc(void)
 {
+	drmModeConnectorPtr c = get_connector(prim_mode_params.connector_id);
+
 	if (!fbc_supported_on_chipset()) {
 		igt_info("Can't test FBC: not supported on this chipset\n");
 		return;
 	}
+
+	/*
+	 * While some platforms do allow FBC on pipes B/C, this test suite
+	 * is not prepared for that yet.
+	 * TODO: solve this.
+	 */
+	if (!connector_supports_pipe_a(c)) {
+		igt_info("Can't test FBC: primary connector doesn't support "
+			 "pipe A\n");
+		return;
+	}
 	fbc.can_test = true;
 
 	fbc_setup_last_action();
-- 
2.7.0



More information about the Intel-gfx mailing list