[Intel-gfx] [PATCH igt 18/28] lib/display: Add support for DRM planes

Damien Lespiau damien.lespiau at intel.com
Fri Feb 7 15:49:02 CET 2014


We can now extend our plane support beyond primary and cursor planes.

Signed-off-by: Damien Lespiau <damien.lespiau at intel.com>
---
 lib/igt_kms.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 lib/igt_kms.h |   6 +++
 2 files changed, 120 insertions(+), 2 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 1933fa6..23a7318 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -862,6 +862,7 @@ static void igt_output_refresh(igt_output_t *output)
 void igt_display_init(igt_display_t *display, int drm_fd)
 {
 	drmModeRes *resources;
+	drmModePlaneRes *plane_resources;
 	bool verbose;
 	char *env;
 	int i;
@@ -892,10 +893,13 @@ void igt_display_init(igt_display_t *display, int drm_fd)
 	 */
 	display->n_pipes = resources->count_crtcs;
 
+	plane_resources = drmModeGetPlaneResources(display->drm_fd);
+	igt_assert(plane_resources);
+
 	for (i = 0; i < display->n_pipes; i++) {
 		igt_pipe_t *pipe = &display->pipes[i];
 		igt_plane_t *plane;
-		int p;
+		int p, j;
 
 		pipe->display = display;
 		pipe->pipe = i;
@@ -907,6 +911,26 @@ void igt_display_init(igt_display_t *display, int drm_fd)
 		plane->index = p;
 		plane->is_primary = true;
 
+		/* add the planes that can be used with that pipe */
+		for (j = 0; j < plane_resources->count_planes; j++) {
+			drmModePlane *drm_plane;
+
+			drm_plane = drmModeGetPlane(display->drm_fd,
+						    plane_resources->planes[j]);
+			igt_assert(drm_plane);
+
+			if (!(drm_plane->possible_crtcs & (1 << i))) {
+				drmModeFreePlane(drm_plane);
+				continue;
+			}
+
+			p++;
+			plane = &pipe->planes[p];
+			plane->pipe = pipe;
+			plane->index = p;
+			plane->drm_plane = drm_plane;
+		}
+
 		/* cursor plane */
 		p++;
 		plane = &pipe->planes[p];
@@ -943,6 +967,7 @@ void igt_display_init(igt_display_t *display, int drm_fd)
 		igt_output_refresh(output);
 	}
 
+	drmModeFreePlaneResources(plane_resources);
 	drmModeFreeResources(resources);
 
 	LOG_UNINDENT(display);
@@ -958,6 +983,20 @@ int igt_display_get_n_pipes(igt_display_t *display)
 	return display->n_pipes;
 }
 
+static void igt_pipe_fini(igt_pipe_t *pipe)
+{
+	int i;
+
+	for (i = 0; i < pipe->n_planes; i++) {
+		igt_plane_t *plane = &pipe->planes[i];
+
+		if (plane->drm_plane) {
+			drmModeFreePlane(plane->drm_plane);
+			plane->drm_plane = NULL;
+		}
+	}
+}
+
 static void igt_output_fini(igt_output_t *output)
 {
 	if (output->valid)
@@ -969,6 +1008,9 @@ void igt_display_fini(igt_display_t *display)
 {
 	int i;
 
+	for (i = 0; i < display->n_pipes; i++)
+		igt_pipe_fini(&display->pipes[i]);
+
 	for (i = 0; i < display->n_outputs; i++)
 		igt_output_fini(&display->outputs[i]);
 	free(display->outputs);
@@ -1110,10 +1152,76 @@ static int igt_cursor_commit(igt_plane_t *plane, igt_output_t *output)
 	return 0;
 }
 
+static int igt_drm_plane_commit(igt_plane_t *plane, igt_output_t *output)
+{
+	igt_display_t *display = output->display;
+	uint32_t fb_id, crtc_id;
+	int ret;
+
+	fb_id = igt_plane_get_fd_id(plane);
+	crtc_id = output->config.crtc->crtc_id;
+
+	if (plane->fb_changed && fb_id == 0) {
+		LOG(display,
+		    "%s: SetPlane pipe %c, plane %d, disabling\n",
+		    igt_output_name(output),
+		    pipe_name(output->config.pipe),
+		    plane->index);
+
+		ret = drmModeSetPlane(display->drm_fd,
+				      plane->drm_plane->plane_id,
+				      crtc_id,
+				      fb_id,
+				      0,    /* flags */
+				      0, 0, /* crtc_x, crtc_y */
+				      0, 0, /* crtc_w, crtc_h */
+				      IGT_FIXED(0,0), /* src_x */
+				      IGT_FIXED(0,0), /* src_y */
+				      IGT_FIXED(0,0), /* src_w */
+				      IGT_FIXED(0,0) /* src_h */);
+
+		igt_assert(ret == 0);
+
+		plane->fb_changed = false;
+	} else if (plane->fb_changed || plane->position_changed) {
+		LOG(display,
+		    "%s: SetPlane %c.%d, fb %u, position (%d, %d)\n",
+		    igt_output_name(output),
+		    pipe_name(output->config.pipe),
+		    plane->index,
+		    fb_id,
+		    plane->crtc_x, plane->crtc_y);
+
+		ret = drmModeSetPlane(display->drm_fd,
+				      plane->drm_plane->plane_id,
+				      crtc_id,
+				      fb_id,
+				      0,    /* flags */
+				      plane->crtc_x, plane->crtc_y,
+				      plane->fb->width, plane->fb->height,
+				      IGT_FIXED(0,0), /* src_x */
+				      IGT_FIXED(0,0), /* src_y */
+				      IGT_FIXED(plane->fb->width,0), /* src_w */
+				      IGT_FIXED(plane->fb->height,0) /* src_h */);
+
+		igt_assert(ret == 0);
+
+		plane->fb_changed = false;
+		plane->position_changed = false;
+	}
+
+	return 0;
+}
+
 static int igt_plane_commit(igt_plane_t *plane, igt_output_t *output)
 {
-	if (plane->is_cursor)
+	if (plane->is_cursor) {
 		igt_cursor_commit(plane, output);
+	} else if (plane->is_primary) {
+		/* state updated by SetCrtc */
+	} else {
+		igt_drm_plane_commit(plane, output);
+	}
 
 	return 0;
 }
@@ -1173,6 +1281,7 @@ static int igt_output_commit(igt_output_t *output)
 		igt_assert(ret == 0);
 
 		pipe->need_set_crtc = false;
+		primary->fb_changed = false;
 	}
 
 	if (pipe->need_set_cursor) {
@@ -1209,6 +1318,7 @@ static int igt_output_commit(igt_output_t *output)
 		igt_assert(ret == 0);
 
 		pipe->need_set_cursor = false;
+		cursor->fb_changed = false;
 	}
 
 	for (i = 0; i < pipe->n_planes; i++) {
@@ -1288,6 +1398,8 @@ void igt_plane_set_fb(igt_plane_t *plane, struct kmstest_fb *fb)
 		pipe->need_set_crtc = true;
 	else if (plane->is_cursor)
 		pipe->need_set_cursor = true;
+
+	plane->fb_changed = true;
 }
 
 void igt_plane_set_position(igt_plane_t *plane, int x, int y)
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 07cf8a2..a37f6b9 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -116,7 +116,13 @@ typedef struct {
 	int index;
 	unsigned int is_primary       : 1;
 	unsigned int is_cursor        : 1;
+	unsigned int fb_changed       : 1;
 	unsigned int position_changed : 1;
+	/*
+	 * drm_plane can be NULL for primary and cursor planes (when not
+	 * using the atomic modeset API)
+	 */
+	drmModePlane *drm_plane;
 	struct kmstest_fb *fb;
 	/* position within pipe_src_w x pipe_src_h */
 	int crtc_x, crtc_y;
-- 
1.8.3.1




More information about the Intel-gfx mailing list