[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