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

Signed-off-by: Damien Lespiau <damien.lesp...@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

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

Reply via email to